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

第三方服务之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也是如此的效果,没错,今天带大家做一个免下载,免安装,即点即用的应用收纳集


具体思路:

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

项目效果图:


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

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


步骤一: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;
    }
}







你可能感兴趣的:(Web,android,APP,GridView,Studio,bmob,android实战)