Andrid6.0权限机制介绍及处理
来源:互联网 发布:全球网络电视 编辑:程序博客网 时间:2024/06/09 14:08
在Android M添加的权限机制中,Google将权限分为两类:
- Normal Permissions(普通权限):不涉及用户隐私,不需要用户进行授权,比如访问网络等
android.permission.ACCESS_LOCATION_EXTRA_COMMANDSandroid.permission.ACCESS_NETWORK_STATEandroid.permission.ACCESS_NOTIFICATION_POLICYandroid.permission.ACCESS_WIFI_STATEandroid.permission.ACCESS_WIMAX_STATEandroid.permission.BLUETOOTHandroid.permission.BLUETOOTH_ADMINandroid.permission.BROADCAST_STICKYandroid.permission.CHANGE_NETWORK_STATEandroid.permission.CHANGE_WIFI_MULTICAST_STATEandroid.permission.CHANGE_WIFI_STATEandroid.permission.CHANGE_WIMAX_STATEandroid.permission.DISABLE_KEYGUARDandroid.permission.EXPAND_STATUS_BARandroid.permission.FLASHLIGHTandroid.permission.GET_ACCOUNTSandroid.permission.GET_PACKAGE_SIZEandroid.permission.INTERNETandroid.permission.KILL_BACKGROUND_PROCESSESandroid.permission.MODIFY_AUDIO_SETTINGSandroid.permission.NFCandroid.permission.READ_SYNC_SETTINGSandroid.permission.READ_SYNC_STATSandroid.permission.RECEIVE_BOOT_COMPLETEDandroid.permission.REORDER_TASKSandroid.permission.REQUEST_INSTALL_PACKAGESandroid.permission.SET_TIME_ZONEandroid.permission.SET_WALLPAPERandroid.permission.SET_WALLPAPER_HINTSandroid.permission.SUBSCRIBED_FEEDS_READandroid.permission.TRANSMIT_IRandroid.permission.USE_FINGERPRINTandroid.permission.VIBRATEandroid.permission.WAKE_LOCKandroid.permission.WRITE_SYNC_SETTINGScom.android.alarm.permission.SET_ALARMcom.android.launcher.permission.INSTALL_SHORTCUTcom.android.launcher.permission.UNINSTALL_SHORTCUT
- Dangerous Permission(危险权限):涉及到用户隐私,需要用户进行授权,比如相机访问、读取SD卡等
group:android.permission-group.CONTACTS permission:android.permission.WRITE_CONTACTS permission:android.permission.GET_ACCOUNTS permission:android.permission.READ_CONTACTSgroup:android.permission-group.PHONE permission:android.permission.READ_CALL_LOG permission:android.permission.READ_PHONE_STATE permission:android.permission.CALL_PHONE permission:android.permission.WRITE_CALL_LOG permission:android.permission.USE_SIP permission:android.permission.PROCESS_OUTGOING_CALLS permission:com.android.voicemail.permission.ADD_VOICEMAILgroup:android.permission-group.CALENDAR permission:android.permission.READ_CALENDAR permission:android.permission.WRITE_CALENDARgroup:android.permission-group.CAMERA permission:android.permission.CAMERAgroup:android.permission-group.SENSORS permission:android.permission.BODY_SENSORSgroup:android.permission-group.LOCATION permission:android.permission.ACCESS_FINE_LOCATION permission:android.permission.ACCESS_COARSE_LOCATIONgroup:android.permission-group.STORAGE permission:android.permission.READ_EXTERNAL_STORAGE permission:android.permission.WRITE_EXTERNAL_STORAGEgroup:android.permission-group.MICROPHONE permission:android.permission.RECORD_AUDIOgroup:android.permission-group.SMS permission:android.permission.READ_SMS permission:android.permission.RECEIVE_WAP_PUSH permission:android.permission.RECEIVE_MMS permission:android.permission.RECEIVE_SMS permission:android.permission.SEND_SMS permission:android.permission.READ_CELL_BROADCASTS
运行时权限只适合APP运行在Android 6.x以上的机器,对于危险权限Google官方也对其进行了分组,只要一组中的某一权限被授权,同组的权限也同样会被授权。
操作步骤
新的权限机制操作步骤如下
在Androidmanifest.xml文件声明相关权限
通过ContextCompat.checkSelfPermission方法检查某项权限被授予情况
通过ActivityCompat.shouldShowRequestPermissionRationale方法检查权限是否被永久拒绝需要向用户说明
通过Activity.requestPermissions申请授权
处理Activity.onRequestPermissionsResult权限回调
Google给出的Demo实现方式
/** * Check that all given permissions have been granted by verifying that each entry in the * given array is of the value {@link PackageManager#PERMISSION_GRANTED}. * * @see Activity#onRequestPermissionsResult(int, String[], int[]) */public static boolean verifyPermissions(int[] grantResults) { // At least one result must be checked. if(grantResults.length < 1){ return false; } // Verify that each required permission has been granted, otherwise return false. for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { return false; } } return true;}public void showContacts(View v) { Log.i(TAG, "Show contacts button pressed. Checking permissions."); // 验证所有联系人权限是否已经获得 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) { // 通讯录权限未获得 Log.i(TAG, "Contact permissions has NOT been granted. Requesting permissions."); requestContactsPermissions(); } else { // 通讯录权限已获得,显示通讯录Fragment Log.i(TAG, "Contact permissions have already been granted. Displaying contact details."); showContactDetails(); }}/** * 请求通讯录权限 * 如果权限已经被拒绝了,那么会弹出一个弹框提醒用户去授予权限,否则会直接请求 */private void requestContactsPermissions() { // BEGIN_INCLUDE(contacts_permission_request) if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_CONTACTS)) { // 如果没有授予许可,请向用户提供额外的理由来让用户理解请求此权限的原因 // 例如,如果以前已经拒绝了权限请求 Log.i(TAG,"Displaying contacts permission rationale to provide additional context."); // 显示一个带有说明和按钮的SnackBar来触发请求。 Snackbar.make(mLayout, R.string.permission_contacts_rationale, Snackbar.LENGTH_INDEFINITE) .setAction(R.string.ok, new View.OnClickListener() { @Override public void onClick(View view) { ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_CONTACT, REQUEST_CONTACTS); } }) .show(); } else { // 通讯录权限尚未授予,直接请求 ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACT, REQUEST_CONTACTS); } // END_INCLUDE(contacts_permission_request)}//权限处理结果的回调@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) { if (requestCode == REQUEST_CONTACTS) { Log.i(TAG, "Received response for contact permissions request."); // 对请求的所有联系人权限再核实一遍 if (PermissionUtil.verifyPermissions(grantResults)) { // 所有权限都已经获得,显示联系人页面 Snackbar.make(mLayout, R.string.permision_available_contacts, Snackbar.LENGTH_SHORT) .show(); } else { Log.i(TAG, "Contacts permissions were NOT granted."); Snackbar.make(mLayout, R.string.permissions_not_granted, Snackbar.LENGTH_SHORT) .show(); } } else { super.onRequestPermissionsResult(requestCode, permissions,grantResults); }}
关键的几个方法
1.检查是否拥有指定权限
android.support.v4.content.ContextCompat.java
/*** Determine whether <em>you</em> have been granted a particular permission.** @param permission The name of the permission being checked.** @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if you have the* permission, or {@link android.content.pm.PackageManager#PERMISSION_DENIED} if not.** @see android.content.pm.PackageManager#checkPermission(String, String)*/public static int checkSelfPermission(@NonNull Context context, @NonNull String permission) { if (permission == null) { throw new IllegalArgumentException("permission is null"); } return context.checkPermission(permission, android.os.Process.myPid(), Process.myUid());}
2.判断是否彻底拒绝而了某项权限而需要对用户进行说明
android.support.v4.app.ActivityCompat.java
/** * Gets whether you should show UI with rationale for requesting a permission. * You should do this only if you do not have the permission and the context in * which the permission is requested does not clearly communicate to the user * what would be the benefit from granting this permission. * <p> * For example, if you write a camera app, requesting the camera permission * would be expected by the user and no rationale for why it is requested is * needed. If however, the app needs location for tagging photos then a non-tech * savvy user may wonder how location is related to taking photos. In this case * you may choose to show UI with rationale of requesting this permission. * </p> * * @param activity The target activity. * @param permission A permission your app wants to request. * @return Whether you can show permission rationale UI. * * @see #checkSelfPermission(android.content.Context, String) * @see #requestPermissions(android.app.Activity, String[], int) */public static boolean shouldShowRequestPermissionRationale(@NonNull Activity activity, @NonNull String permission) { if (Build.VERSION.SDK_INT >= 23) { return ActivityCompatApi23.shouldShowRequestPermissionRationale(activity, permission); } return false;}
3.发出权限请求
android.app.Activity
/** * Requests permissions to be granted to this application. These permissions * must be requested in your manifest, they should not be granted to your app, * and they should have protection level {@link android.content.pm.PermissionInfo * #PROTECTION_DANGEROUS dangerous}, regardless whether they are declared by * the platform or a third-party app. * <p> * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL} * are granted at install time if requested in the manifest. Signature permissions * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at * install time if requested in the manifest and the signature of your app matches * the signature of the app declaring the permissions. * </p> * <p> * If your app does not have the requested permissions the user will be presented * with UI for accepting them. After the user has accepted or rejected the * requested permissions you will receive a callback on {@link * #onRequestPermissionsResult(int, String[], int[])} reporting whether the * permissions were granted or not. * </p> * <p> * Note that requesting a permission does not guarantee it will be granted and * your app should be able to run without having this permission. * </p> * <p> * This method may start an activity allowing the user to choose which permissions * to grant and which to reject. Hence, you should be prepared that your activity * may be paused and resumed. Further, granting some permissions may require * a restart of you application. In such a case, the system will recreate the * activity stack before delivering the result to {@link * #onRequestPermissionsResult(int, String[], int[])}. * </p> * <p> * When checking whether you have a permission you should use {@link * #checkSelfPermission(String)}. * </p> * <p> * Calling this API for permissions already granted to your app would show UI * to the user to decide whether the app can still hold these permissions. This * can be useful if the way your app uses data guarded by the permissions * changes significantly. * </p> * <p> * You cannot request a permission if your activity sets {@link * android.R.styleable#AndroidManifestActivity_noHistory noHistory} to * <code>true</code> because in this case the activity would not receive * result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}. * </p> * <p> * The <a href="http://developer.android.com/samples/RuntimePermissions/index.html"> * RuntimePermissions</a> sample app demonstrates how to use this method to * request permissions at run time. * </p> * * @param permissions The requested permissions. Must me non-null and not empty. * @param requestCode Application specific request code to match with a result * reported to {@link #onRequestPermissionsResult(int, String[], int[])}. * Should be >= 0. * * @see #onRequestPermissionsResult(int, String[], int[]) * @see #checkSelfPermission(String) * @see #shouldShowRequestPermissionRationale(String) */public final void requestPermissions(@NonNull String[] permissions, int requestCode) { if (mHasCurrentPermissionsRequest) { Log.w(TAG, "Can reqeust only one set of permissions at a time"); // Dispatch the callback with empty arrays which means a cancellation. onRequestPermissionsResult(requestCode, new String[0], new int[0]); return; } Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions); startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null); mHasCurrentPermissionsRequest = true;}
4.在Activity中接受用户处理结果回调
android.app.Activity
/** * Callback for the result from requesting permissions. This method * is invoked for every call on {@link #requestPermissions(String[], int)}. * <p> * <strong>Note:</strong> It is possible that the permissions request interaction * with the user is interrupted. In this case you will receive empty permissions * and results arrays which should be treated as a cancellation. * </p> * * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}. * @param permissions The requested permissions. Never null. * @param grantResults The grant results for the corresponding permissions * which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED} * or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null. * * @see #requestPermissions(String[], int) */public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { /* callback - no nothing */}
为了便于使用可以在此基础上进行封装,可以参考下面这篇文章中的封装方式
http://www.jianshu.com/p/4a60b064a0ab
0 0
- Andrid6.0权限机制介绍及处理
- Andrid6.0申请SYSTEM_ALERT_WINDOW和WRITE_SETTINGS权限
- Java异常处理及异常机制介绍
- Java异常处理及异常机制介绍
- Java异常处理及异常机制介绍
- Java异常处理及异常机制介绍
- Oracle 权限介绍及管理
- session介绍及处理
- URL介绍及处理
- Android 6.0 权限申请机制处理
- Android6.0运行时权限的处理及解决办法
- Android6.0运行时权限的处理及解决办法
- Java异常处理及异常机制介绍 && long,int,short与byte数组之间的转换
- android学习笔记——AsyncTask异步消息处理机制简单介绍及使用
- ARC机制介绍及使用
- C#位运算处理权限问题介绍
- Android 6.0动态权限介绍与处理
- Android权限管理之Permission权限机制及使用
- LintCode:569 各位相加
- 剑指offer-反转链表-php
- 把排序数组转换为高度最小的二叉搜索树-LintCode
- Android6.0权限大全和权限分类
- angularjs框架的悬浮提示框实现
- Andrid6.0权限机制介绍及处理
- 栈的应用---括号匹配
- js判断是否在微信浏览器中打开
- js 判断多个时间段是否存在重叠的部分
- QT 线程学习
- 关于Http协议的小例子
- 纠正你读错的电脑英文词汇--(1)
- 命令行生成vue项目框架
- 服务发现与注册