一、目标

    在Html5代码已经移植至Android工程后,完成Android App开发的基本框架之权限设置部分的代码设计与开发;

二、步骤

    1、在AndroidManifest.xml中定义需要使用到的权限,如本项目中使用的权限如下:

                                

    2、配置以后,需要在代码中去检查是否有权限,核心代码如下:

                int resultPermission = ContextCompat.checkSelfPermission(activity, permission);

    该返回值为PackageManager.PERMISSION_GRANTED时,表示已经授权,否则需要下一步去申请权限;

    3、申请权限核心代码:

ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)

    注意:shouldShowRequestPermissionRationale为异步方法,负责调取一个申请授权的弹窗,如果同时申请多个这种权限的弹窗,则只弹出第一个,后面的弹窗直接跳过。

    4、获取授权结果,需要基于请求权限的请求码,在MainActivity中的onRequestPermissionsResult回调方法中去处理;

    5、上面基于第3步,由于多次弹窗被跳过了,则需要调用第3步的申请权限方法,继续申请下一个权限项,直到所有权限申请完毕;

    6、基于上述逻辑,汇总下核心代码逻辑(完整代码见github):

MainActivity中与权限相关的代码:

package com.justinsoft.activity;import android.Manifest;import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.os.StrictMode;import android.support.v7.app.AppCompatActivity;import android.util.Log;import com.justinsoft.R;import com.justinsoft.constant.Constant;import com.justinsoft.permission.PermissionMgr;import com.justinsoft.util.LogUtil;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set;public class MainActivity extends AppCompatActivity {    // 日志句柄    private static final String TAG = LogUtil.getClassTag(MainActivity.class);    private BtWebView webView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 1.打开权限设置        loadPermission(this);    }    @Override    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {        Log.i(TAG, "update permission now.");        PermissionMgr permissionMgr = PermissionMgr.getInstance();        permissionMgr.updatePermission(this, requestCode, permissions, grantResults);        if (permissionMgr.hasRequestAllPermission()) {            refreshHomepage();        }    }    /**     * 检查并请求打开权限设置     *     * @param activity     */    private void loadPermission(Activity activity) {        Map> allPermission = new HashMap>();        Set locationPermission = new HashSet();        locationPermission.add(Manifest.permission.ACCESS_FINE_LOCATION);        locationPermission.add(Manifest.permission.ACCESS_COARSE_LOCATION);        allPermission.put(Constant.LOCATION_PERMISSION_CODE, locationPermission);        Set audioPermission = new HashSet();        audioPermission.add(Manifest.permission.RECORD_AUDIO);        allPermission.put(Constant.RECORD_PERMISSION_CODE, audioPermission);        Set cameraPermission = new HashSet();        cameraPermission.add(Manifest.permission.CAMERA);        allPermission.put(Constant.CAMERA_PERMISSION_CODE, cameraPermission);        Set storagePermission = new HashSet();        storagePermission.add(Manifest.permission.READ_EXTERNAL_STORAGE);        storagePermission.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);        allPermission.put(Constant.STORAGE_PERMISSION_CODE, storagePermission);        PermissionMgr.getInstance().requestPermission(activity, allPermission);    }}

抽取的权限管理类PermissionMgr:

package com.justinsoft.permission;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import com.justinsoft.util.LogUtil;import android.Manifest;import android.app.Activity;import android.content.pm.PackageManager;import android.location.Criteria;import android.location.LocationManager;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.util.Log;public final class PermissionMgr{    // 日志标记    private static final String TAG = LogUtil.getClassTag(PermissionMgr.class);        // 权限管理    private static PermissionMgr permissionMgr;        private static final Lock LOCK = new ReentrantLock();        private Set requestedPermissionCode;        private Set grantPermissionCode;        private Map> allPermission;        private PermissionMgr()    {        requestedPermissionCode = new HashSet();        grantPermissionCode = new HashSet();    }        public static PermissionMgr getInstance()    {        if (null == permissionMgr)        {            LOCK.tryLock();            try            {                if (null == permissionMgr)                {                    permissionMgr = new PermissionMgr();                }                return permissionMgr;            }            catch (Exception e)            {                Log.e(TAG, "failed to get permission", e);            }            finally            {                LOCK.unlock();            }        }        return permissionMgr;    }        /**     * 请求权限     *     * @param activity     * @param allPermission     */    public void requestPermission(Activity activity, Map> allPermission)    {        this.allPermission = allPermission;        requestLeftPermission(activity, allPermission);    }        /**     * 判断权限请求结束后,是否获取到权限     *     * @param activity     * @param requestCode     * @param permissions     * @param grantResults     * @return     */    public void updatePermission(Activity activity, int requestCode, String permissions[], int[] grantResults)    {        Log.i(TAG, "request permission code:" + requestCode);        Log.i(TAG, "all permission code:" + allPermission.keySet());        Log.i(TAG, "all permission:" + permissions);        if (!allPermission.keySet().contains(requestCode))        {            Log.i(TAG, "invalid permission");            return;        }        requestedPermissionCode.add(requestCode);                // If request is cancelled, the result arrays are empty.        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)        {            // permission was granted, yay! Do the            // contacts-related task you need to do.            Log.i(TAG, "grant permission now:" + requestCode);            grantPermissionCode.add(requestCode);        }        else        {            // permission denied, boo! Disable the            // functionality that depends on this permission.            Log.i(TAG, "no permission now:" + requestCode);        }                Map> ungrantPermission = new HashMap>();        ungrantPermission.putAll(allPermission);        ungrantPermission.keySet().removeAll(requestedPermissionCode);        Log.i(TAG, "Left permission:" + ungrantPermission.keySet());        requestLeftPermission(activity, ungrantPermission);    }        /**     * 是否已经申请了足够的权限     *     * @return     */    public boolean hasRequestAllPermission()    {        Map> ungrantPermission = new HashMap>();        ungrantPermission.putAll(allPermission);        ungrantPermission.keySet().removeAll(requestedPermissionCode);        return ungrantPermission.isEmpty();    }        /**     * 请求剩余权限     *      * @param activity     * @param allPermission     */    private void requestLeftPermission(Activity activity, Map> allPermission)    {        for (Map.Entry> entry : allPermission.entrySet())        {            int grantPermission = -1;            boolean isLocationPermission = false;            int requestCode = entry.getKey();            Set batchPermission = entry.getValue();            for (String permission : batchPermission)            {                int resultPermission = ContextCompat.checkSelfPermission(activity, permission);                if (resultPermission == PackageManager.PERMISSION_GRANTED)                {                    this.requestedPermissionCode.add(requestCode);                    grantPermission = PackageManager.PERMISSION_GRANTED;                }                                if (permission.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)                    || permission.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION))                {                    isLocationPermission = true;                }            }                        if (grantPermission != PackageManager.PERMISSION_GRANTED)            {                boolean result = shouldPermission(activity, batchPermission);                if (isLocationPermission)                {                    List allProvider = getLocationProvider(activity);                    if (null == allProvider || allProvider.isEmpty())                    {                        result = false;                    }                }                if (!result)                {                    Log.i(TAG, "It needs to request permission now.");                    ActivityCompat.requestPermissions(activity, batchPermission.toArray(new String[] {}), requestCode);                }                return;            }        }    }        private boolean shouldPermission(Activity activity, Set batchPermission)    {        for (String permission : batchPermission)        {            if (!this.requestedPermissionCode.contains(permission))            {                if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission))                {                    Log.i(TAG, "grant permission:" + permission);                    return true;                }            }        }        return false;    }        private List getLocationProvider(Activity activity)    {        LocationManager locationManager = (LocationManager)activity.getSystemService(Activity.LOCATION_SERVICE);        Criteria criteria = new Criteria();        List allProviderName = locationManager.getProviders(criteria, true);        Log.i(TAG, "provider:" + allProviderName);        return allProviderName;    }}

三、总结

    权限申请是Android开发的基本诉求之一,在开发过程中,先是一股脑全申请了弹窗,结果发现只弹了一次就不弹了,后面就想到在Activity中的回调方法onRequestPermissionsResult中继续申请下一个权限,终于达成一个接一个弹窗的目标;

四、参考资料

[1]https://www.cnblogs.com/Free-Thinker/p/6014765.html

 

上一篇:Vue.js实战——移植Html5 App为Android App_10   下一篇:Vue.js实战——开发Android Hybird App之Webview基础配置_12

 

更多相关文章

  1. Android程序的签名保护及绕过方法
  2. android悬浮窗及权限
  3. AOSP: 如何恢复出厂设置?
  4. Android高手进阶教程(八)之----Android(安卓)Widget开发案例(世
  5. 跟Android初学者分享几点经验
  6. Android(安卓)自定义权限 ( )
  7. android中webview控件和javascript交互实例
  8. Android:Dagger2系列2 实例解析(更新完毕)
  9. android分享图片到微信,无需申请APP_ID

随机推荐

  1. Android(安卓)Studio - 安卓开发工具 打
  2. Android调用H5的方法.Js交互
  3. 破解某国外收费的RTMP Client并成功在And
  4. Android(三)数据存储之XML解析技术
  5. Flutter调用Android和iOS原生代码的方法
  6. 别让Android(安卓)Studio占据你的C盘
  7. Android入门教程(六)之------拿来主义.ap
  8. 局域网内android设备发现及通讯
  9. 闲鱼如何在2个月内实现Android启动速度翻
  10. Android(安卓)解码播放GIF图像