Android M(6.0)相比之前的版本,做了比较多的优化与改进。其中变化最大的一点是权限管理方面的改变,即不再是应用安装时授权,而改为运行时授权机制;一直以来,系统安全都是用户非常关心的问题,而之前的版本都是在安装应用时统一、强制的进行授权。一般用户在安装某个应用时,可能并不想授予应用某个权限,或是很容易忽略应用权限列表。致使很多应用肆意的申请权限,做一些不法的事情!这个问题在Android M将得到解决,它采用了运行时授权机制,在应用申请权限的时候提示用户,是否授权。提高用户对权限的认识!
对用户来说是非常有利的,但是对于开发者来说,则需要做更多的工作。
1.对于已经上线的应用
对于这类应用(targetSdkVersion < 23),Android M 系统做了兼容性处理。这类应用仍然按照之前的权限认证机制(用户在安装的时候不得不接受所有权限,安装后app就有了那些权限)工作。但是对于这类应用,用户仍然可以在设置中对应用的权限进行管理,可以取消授权。此时,当应用使用到用户取消的权限时,仍然不会出现异常,但是却不会执行相关操作,他将什么都不干,直接null或者0,这对于未做处理的程序来说,仍然会出现异常。只有祈求用户不随便取消权限和对新版本app中拥抱新的权限机制!
2.还未上线应用
随着Android M的发布,会陆续有很多的设备,使用新版本的系统。因此对我们来说拥抱新的权限机制是解决问题的最好办法!
(1)设置compileSdkVersion and targetSdkVersion为 23
1 android { 2 compileSdkVersion 23 3 ... 4 5 defaultConfig { 6 targetSdkVersion 23 7 ... 8 } 9 }
(2)同以前一样在AndroidManifest.xml添加声明权限
1 <uses-permission android:name="android.permission.BLUETOOTH" /> 2 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 3 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
(3)权限检查,申请
1 /** 2 * 检查,申请权限 3 * */ 4 private void addPremission() { 5 // 系统版本检查 6 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 7 // 检查权限 8 int permission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS); 9 // 检查权限(兼容操作,可不判断系统版本) 10 // int permission = ActivityCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_CONTACTS); 11 if (permission != PackageManager.PERMISSION_GRANTED) { 12 // if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_CONTACTS)) { 13 if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) { 14 showMessageOKCancel("You need to allow access to Contacts", 15 new DialogInterface.OnClickListener() { 16 @Override 17 public void onClick(DialogInterface dialog, int which) { 18 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 19 requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS}, 20 REQUEST_CODE_WRITE_CONTACTS_PERMISSIONS); 21 } 22 } 23 }); 24 return; 25 } 26 // 申请权限 27 // ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_WRITE_CONTACTS_PERMISSIONS); 28 requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_WRITE_CONTACTS_PERMISSIONS); 29 return; 30 } 31 } 32 } 33 34 35 /** 36 * 权限结果申请处理 37 * */ 38 @Override 39 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 40 super.onRequestPermissionsResult(requestCode, permissions, grantResults); 41 switch (requestCode) { 42 case REQUEST_CODE_WRITE_CONTACTS_PERMISSIONS: 43 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 44 // Permission Granted 45 adapter.setData(getLocalContactsInfos()); 46 } else { 47 // Permission Denied 48 Toast.makeText(MainActivity.this, "WRITE_CONTACTS Denied", Toast.LENGTH_SHORT) 49 .show(); 50 this.finish(); 51 } 52 break; 53 default: 54 super.onRequestPermissionsResult(requestCode, permissions, grantResults); 55 } 56 }
(4)权限使用
检查有相关权限,或没权限申请到权限后才能执行具体操作,否则每次使用时,提醒用户授权!