您的位置:首页 > 移动开发 > Android开发

Android实战——第三方服务之Bmob后端云的云应用收纳集小项目(五)

2016-08-16 18:56 633 查看
第三方服务之Bmob后端云的云应用收纳集小项目(五)

事先说明:这里的一切操作都是在集成了BmobSDK之后实现的,如果对Bmob还不了解的话,请关注我第一篇Bmob文章

项目上线:项目已经上线百度市场,需要的同学可下载反编来学习,应用袋:http://shouji.baidu.com/software/9529251.html

项目同时也涉及到百度自动更新组件,后续我会在我的博客中推出百度自动更新组件的集成

请关注我的CSDN博客,Hensen_的博客:http://blog.csdn.net/qq_30379689

项目意义:对于2016年Google I/O大会上提出的Instant
Apps,即用户不需下载app,就可以运行app的这个新鲜的理念

聪明你的可能会联想到H5App,webApp也是如此的效果,没错,今天带大家做一个免下载,免安装,即点即用的应用收纳集

具体思路:



项目效果图:



后台数据库表的结构:(右键在新标签打开可看原图)





步骤一:javaBean的介绍

分类实体类:

public class Item {
//分类名
private String type;
//分类名下面的2个应用名
private String type_1;
private String type_2;
//根据id可排序
private int typeId;
//分类图标
private BmobFile typeIcon_file;

public String getType_1() {
return type_1;
}

public void setType_1(String type_1) {
this.type_1 = type_1;
}

public String getType_2() {
return type_2;
}

public void setType_2(String type_2) {
this.type_2 = type_2;
}

public BmobFile getTypeIcon_file() {
return typeIcon_file;
}

public void setTypeIcon_file(BmobFile typeIcon_file) {
this.typeIcon_file = typeIcon_file;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public int getTypeId() {
return typeId;
}

public void setTypeId(int typeId) {
this.typeId = typeId;
}
}
应用实体类:

public class More {
//应用名
private String name;
//应用图标
private BmobFile icon;
//应用跳转的H5页面
private String toUrl;
//根据pid可以排序
private int typePid;
//对应的分类
private String type;

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public BmobFile getIcon() {
return icon;
}

public void setIcon(BmobFile icon) {
this.icon = icon;
}

public String getToUrl() {
return toUrl;
}

public void setToUrl(String toUrl) {
this.toUrl = toUrl;
}

public int getTypePid() {
return typePid;
}

public void setTypePid(int typePid) {
this.typePid = typePid;
}
}


步骤二:选择分类页面和选择应用页面,GridView的填充(这里只介绍分类页的填充,应用页的填充步骤是一样的)

创建一个GridView布局(由于前面带有一个搜索栏,所以用到的是开源框架GridViewWithHeaderAndFooter):

<in.srain.cube.views.GridViewWithHeaderAndFooter
android:id="@+id/gv_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"
android:scrollbars="none"
android:verticalSpacing="12dp"
android:horizontalSpacing="-8dp"/>
创建一个View布局用于填充GridView(左边文字右边图片,可看效果图分类页):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp">

<LinearLayout
android:id="@+id/ly_type"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="@drawable/mine_common_border"
android:padding="8dp">

<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:paddingLeft="2dp">

<TextView
android:id="@+id/tv_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:textColor="#000000"
android:textSize="16dp" />

<TextView
android:id="@+id/tv_type_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:textColor="#888888"
android:textSize="12dp" />

<TextView
android:id="@+id/tv_type_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:textColor="#888888"
android:textSize="12dp" />
</LinearLayout>

<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">

<ImageView
android:id="@+id/iv_type"
android:layout_width="50dp"
android:layout_height="50dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
创建一个GridView的Adapter来适配View(这里用Xutils来加载图片,通过下面2句代码,new一个对象,display就可以了):

public class HomeAdapter extends BaseAdapter {
//模块数据
private List<Item> list;
private LayoutInflater mInflater;
private Context context;
private Item item;
private Intent intent;
private BitmapUtils bitmapUtils;

public HomeAdapter(Context context, List<Item> list) {
this.list = list;
mInflater = LayoutInflater.from(context);
this.context = context;
bitmapUtils = new BitmapUtils(context);
}

@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return list.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.adapter_home, null);
}
final ViewHolder holder = getViewHolder(convertView);
item = list.get(position);
//模块名称
holder.tv_type.setText(item.getType());
holder.tv_type.setTag(item.getType());
holder.tv_type_1.setText(item.getType_1());
holder.tv_type_2.setText(item.getType_2());
//模块导航图片
if (item.getTypeIcon_file() != null) {
bitmapUtils.display(holder.iv_type, item.getTypeIcon_file().getFileUrl(context));
}
//模块点击事件
holder.ly_type.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(context, MoreActivity.class);
intent.putExtra("title", holder.tv_type.getTag() + "");
context.startActivity(intent);
}
});
return convertView;
}

/**
* 获得控件管理对象
*
* @param view
* @return
*/
private ViewHolder getViewHolder(View view) {
ViewHolder holder = (ViewHolder) view.getTag();
if (holder == null) {
holder = new ViewHolder(view);
view.setTag(holder);
}
return holder;
}

/**
* 控件管理类
*/
private class ViewHolder {

private TextView tv_type,tv_type_1,tv_type_2;
private LinearLayout ly_type;
private ImageView iv_type;

ViewHolder(View view) {
tv_type = (TextView) view.findViewById(R.id.tv_type);
tv_type_1 = (TextView) view.findViewById(R.id.tv_type_1);
tv_type_2 = (TextView) view.findViewById(R.id.tv_type_2);
ly_type = (LinearLayout) view.findViewById(R.id.ly_type);
iv_type = (ImageView) view.findViewById(R.id.iv_type);
}
}
}
代码填充GridView数据:

/**
* 初始化模块数据
*/
private void initItemData() {
query = new BmobQuery<>();
query.setCachePolicy(BmobQuery.CachePolicy.CACHE_THEN_NETWORK);
query.order("typeId");
query.setLimit(200);
query.findObjects(getActivity(), new FindListener<Item>() {
@Override
public void onSuccess(List<Item> object) {
itemList = object;
//显示模块数据
adapter = new HomeAdapter(getActivity(), itemList);
gv_home.setNumColumns(2);
gv_home.setAdapter(adapter);
}

@Override
public void onError(int code, String msg) {
}

@Override
public void postOnFailure(int code, String msg) {
}
});
}


步骤三:WebView页面(即第三个页面)对WebView页面处理

这里可以关注我博客上面的有关对WebView处理的文章:http://blog.csdn.net/qq_30379689/article/details/51898640

步骤四:部分H5App出现定位功能(百度地图等),那么应该对必须解决安卓6.0系统的权限问题,将权限请求放在应用页面开启之前的页面,之后检查到H5App需要定位功能时会自动弹出权限申请,这里使用的是Bmob封装好的
PermissionManager


以下是Bmob的官方说明:

Android6.0中对特定的权限进行了动态授权的方式,需要在运行时用户手动授予,如果用户拒绝后再次申请还可以向用户弹框说明权限的作用,用户点击确认后再去申请。

因此,我们提供了一个权限管理的工具类
PermissionManager(cn.bmob.v3.helper)
,具体使用如下:

注:在
v3.4.6
的BmobSDK内部集成
PermissionManager
类,自
v3.4.7
以后的SDK内部将不再提供该类,开发者可以在下载的配套官方Demo的
com.example.bmobexample.permission
包下面查看该类源码。

第一步:在项目的Gradle上添加下面这些信息:

android {
compileSdkVersion 23
buildToolsVersion '23.0.2'

//**bmob-sdk:3.4.6版本依赖包,用于兼容Android6.0系统**
useLibrary 'org.apache.http.legacy'
添加依赖:

compile 'com.android.support:support-v4:23.2.1'
第二步:构建PremissionManager类

PermissionManager helper;
helper = PermissionManager.with(MainActivity.this)
//添加权限请求码
.addRequestCode(MainActivity.REQUEST_CODE_CAMERA)
//设置权限,可以添加多个权限
.permissions(Manifest.permission.ACCESS_FINE_LOCATION<span style="font-family: 'microsoft yahei';">)</span>
//设置权限监听器
.setPermissionsListener(new PermissionListener() {

@Override
public void onGranted() {
//当权限被授予时调用
Toast.makeText(MainActivity.this, "Camera Permission granted",Toast.LENGTH_LONG).show();
}

@Override
public void onDenied() {
//用户拒绝该权限时调用
Toast.makeText(MainActivity.this, "Camera Permission denied",Toast.LENGTH_LONG).show();
}

@Override
public void onShowRationale(String[] permissions) {
//当用户拒绝某权限时并点击`不再提醒`的按钮时,下次应用再请求该权限时,需要给出合适的响应(比如,给个展示对话框来解释应用为什么需要该权限)
Snackbar.make(btn_camera, "需要相机权限去拍照", Snackbar.LENGTH_INDEFINITE)
.setAction("ok", new View.OnClickListener() {
@Override
public void onClick(View v) {
//必须调用该`setIsPositive(true)`方法
helper.setIsPositive(true);
helper.request();
}
}).show();
}
})
//请求权限
.request();
第三步:覆写onResultPermissionResult方法:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CODE_CAMERA:
helper.onPermissionResult(permissions, grantResults);
break;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐