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

来源:互联网 发布:网络主播直播内容 编辑:程序博客网 时间:2024/05/03 08:42

第三方服务之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方法:

@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {    super.onRequestPermissionsResult(requestCode, permissions, grantResults);    switch (requestCode) {        case REQUEST_CODE_CAMERA:            helper.onPermissionResult(permissions, grantResults);            break;    }}







2 0
原创粉丝点击