网站建设标书模板下载/ks免费刷粉网站推广
一、目标
在Html5代码已经移植至Android工程后,完成Android App开发的基本框架之权限设置部分的代码设计与开发;
二、步骤
1、在AndroidManifest.xml中定义需要使用到的权限,如本项目中使用的权限如下:
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.CAMERA" />
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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 1.打开权限设置loadPermission(this);}@Overridepublic 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<Integer, Set<String>> allPermission = new HashMap<Integer, Set<String>>();Set<String> locationPermission = new HashSet<String>();locationPermission.add(Manifest.permission.ACCESS_FINE_LOCATION);locationPermission.add(Manifest.permission.ACCESS_COARSE_LOCATION);allPermission.put(Constant.LOCATION_PERMISSION_CODE, locationPermission);Set<String> audioPermission = new HashSet<String>();audioPermission.add(Manifest.permission.RECORD_AUDIO);allPermission.put(Constant.RECORD_PERMISSION_CODE, audioPermission);Set<String> cameraPermission = new HashSet<String>();cameraPermission.add(Manifest.permission.CAMERA);allPermission.put(Constant.CAMERA_PERMISSION_CODE, cameraPermission);Set<String> storagePermission = new HashSet<String>();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<Integer> requestedPermissionCode;private Set<Integer> grantPermissionCode;private Map<Integer, Set<String>> allPermission;private PermissionMgr(){requestedPermissionCode = new HashSet<Integer>();grantPermissionCode = new HashSet<Integer>();}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<Integer, Set<String>> 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<Integer, Set<String>> ungrantPermission = new HashMap<Integer, Set<String>>();ungrantPermission.putAll(allPermission);ungrantPermission.keySet().removeAll(requestedPermissionCode);Log.i(TAG, "Left permission:" + ungrantPermission.keySet());requestLeftPermission(activity, ungrantPermission);}/*** 是否已经申请了足够的权限** @return*/public boolean hasRequestAllPermission(){Map<Integer, Set<String>> ungrantPermission = new HashMap<Integer, Set<String>>();ungrantPermission.putAll(allPermission);ungrantPermission.keySet().removeAll(requestedPermissionCode);return ungrantPermission.isEmpty();}/*** 请求剩余权限* * @param activity* @param allPermission*/private void requestLeftPermission(Activity activity, Map<Integer, Set<String>> allPermission){for (Map.Entry<Integer, Set<String>> entry : allPermission.entrySet()){int grantPermission = -1;boolean isLocationPermission = false;int requestCode = entry.getKey();Set<String> 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<String> 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<String> 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<String> getLocationProvider(Activity activity){LocationManager locationManager = (LocationManager)activity.getSystemService(Activity.LOCATION_SERVICE);Criteria criteria = new Criteria();List<String> 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