• Android M以上运行时权限(Google官方出品)


    转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6690152.html 

    网上运行时权限的例子、Demo无计其数,但是和Google官方出品的比起来,都显得很啰嗦。作为Android开发人员应该以Google的实例为样本。官方出品,必属精品!!!

    Google官方Runtime Permissions Demo地址:https://github.com/googlesamples/android-RuntimePermissions

    Demo如下(这里强调一下,Google推荐使用Snackbar代替Toast)

    在 Android M 版本(即6.0以后的版本),多了一个特殊权限处理。开发者的开发工具Android Studio 如果是 Android API 23 Platform或以上版本,需要在调用特殊权限的地方手动将权限打开,在 AndroidManifest 直接说明是不好用的。

    那么都有哪些权限是需要特殊处理的呢。下面我就把这些特殊权限按类罗列出来,并告诉你如何在代码中进行手动调用。

    需要单独申请的权限共分为9组,每组只要有一个权限申请成功,默认整组权限都可以使用了。

    ①使用您的通讯录

    group:android.permission-group.CONTACTS  
              permission:android.permission.WRITE_CONTACTS  
              permission:android.permission.GET_ACCOUNTS  
              permission:android.permission.READ_CONTACTS

    ②拨打电话和管理通话

    group: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_VOICEMAIL

    ③访问您的日历

    group:android.permission-group.CALENDAR  
              permission:android.permission.READ_CALENDAR  
              permission:android.permission.WRITE_CALENDAR

    ④拍摄照片和录制视频

    group:android.permission-group.CAMERA  
              permission:android.permission.CAMERA 

    ⑤访问与您的生命体征相关的传感器数据

    group:android.permission-group.SENSORS  
              permission:android.permission.BODY_SENSORS

    ⑥使用此设备的位置信息

    group:android.permission-group.LOCATION  
              permission:android.permission.ACCESS_FINE_LOCATION  
              permission:android.permission.ACCESS_COARSE_LOCATION

    ⑦访问您设备上的照片、媒体内容和文件

    group:android.permission-group.STORAGE  
              permission:android.permission.READ_EXTERNAL_STORAGE  
              permission:android.permission.WRITE_EXTERNAL_STORAGE

    ⑧录制音频

    group:android.permission-group.MICROPHONE  
              permission:android.permission.RECORD_AUDIO

    ⑨发送和查看短信

    group: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

    废话不多说,让我们一探究竟Google是如何处理Android M以上运行时权限的。

    以"联系人权限"为例做演示,其他的权限大同小异。

    1.创建一个工具类PermissionUtil

    Google对这个工具类作出的解释是 Utility class that wraps access to the runtime permissions API in M and provides basic helper methods.

    即:在M中包含对运行时权限API的访问的实用程序类,并提供基本的帮助方法。

    public abstract class PermissionUtil {
    
        /**
         * 检查所有给定的权限是否通过验证给定数组中的每个条目都具有该值*/
        public static boolean verifyPermissions(int[] grantResults) {
            // 至少检查一个结果
            if (grantResults.length < 1) {
                return false;
            }
    
            // 验证是否已授予每个必需的权限,否则返回false
            for (int result : grantResults) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        }
    
    }

    2.联系人权限已在Android M及以上版本中声明。 它们在旧平台上不可用,因此我们隐藏按钮以访问联系人数据库。这显示了如何添加新的运行时权限,不适用于较旧的平台版本。 这对于其他权限可能会提示用户进行升级的自动更新非常有用。

    public class RuntimePermissionsFragment extends Fragment {
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View root = inflater.inflate(R.layout.fragment_main, null);
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                root.findViewById(R.id.button_contacts).setVisibility(View.GONE);
            }
            return root;
        }
    }

    3.主类

    public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
    
        private static final String TAG = "MainActivity";
    
        /**
         * 用于标识请求联系人权限的Id
         */
        private static final int REQUEST_CONTACTS = 0;
    
        /**
         * 联系人读、写所需的权限
         */
        private static String[] PERMISSIONS_CONTACT = {
                Manifest.permission.READ_CONTACTS,
                Manifest.permission.WRITE_CONTACTS
        };
    
        /**
         * Activity的根布局
         */
        private View mLayout;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mLayout = findViewById(R.id.content_fragment);
    
            if (savedInstanceState == null) {
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                RuntimePermissionsFragment fragment = new RuntimePermissionsFragment();
                transaction.replace(R.id.content_fragment, fragment);
                transaction.commit();
            }
        }
    
        /**
         * 当点击“显示联系人”按钮时调用
         * 回调在布局文件中定义
         */
        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 {
                // 联系权限已被授予。 显示联系人片段
                Log.i(TAG, "Contact permissions have already been granted. Displaying contact details.");
            }
        }
    
        /**
         * 请求联系人权限
         * 如果以前已经拒绝许可,SnackBar将提示用户授予权限,否则直接请求
         */
        private void requestContactsPermissions() {
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS)
                    || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_CONTACTS)) {

    // 显示一个带有说明和按钮的SnackBar来触发请求 Snackbar.make(mLayout, R.string.permission_contacts_rationale, Snackbar.LENGTH_INDEFINITE) .setAction(R.string.ok, new View.OnClickListener() { @Override public void onClick(View v) { ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_CONTACT, REQUEST_CONTACTS); } }).show(); } else { // 联系人权限尚未被授予,直接请求 ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACT, REQUEST_CONTACTS); } } @Override public 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); } } }

    4.在AndroidManifest加上需要申请的权限

    <!-- 仅当设备在M或更高版本上时,才需要以下权限。在较旧的平台上,这些权限不被请求,并且将不可用。 -->
        <uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS" />
        <uses-permission-sdk-23 android:name="android.permission.WRITE_CONTACTS" />

    以上就是Google官方提供的完整而且简洁的运行时权限Demo

    关注我的新浪微博,获取更多Android开发资讯!
    关注科技评论家,领略科技、创新、教育以及最大化人类智慧与想象力!

  • 相关阅读:
    mas_makeConstraints && mas_remakeConstraints && mas_updateConstraints 用法与注意事项
    iOS特性一 关闭系统日志打印
    React-Native -课后练习
    RN 项目导入WebStorm 组件没有依赖
    React-Native需要css和布局-20160902
    方式 隐藏导航栏
    svn status状态
    spring整合redis
    maven编译跳过TEST
    linux自动登录脚本expect
  • 原文地址:https://www.cnblogs.com/cnwutianhao/p/6690152.html
Copyright © 2020-2023  润新知