RuntTimePermissionTestActivity.java html
classpath 'com.android.tools.build:gradle:3.0.0'
compile 'com.android.support:appcompat-v7:26.+'java
ERROR: java.lang.SecurityException: Sending SMS message: uid 10078 does not have android.permission.SEND_SMS.
查android 官网发现,When run on Android 6.0 (API 23),or targetSdkVersion Android 6.0 (API 23),danger permission须要动态申请权限。android
Android 6.0 (API 23) 开始,引入了normal permissions(普通权限) 和dangerous permissions(危险权限) 的概念。git
On all versions of Android, your app needs to declare both the normal and the dangerous permissions it needs in its app manifest, as described in Declaring Permissions. However, the effect of that declaration is different depending on the system version and your app's target SDK level:github
● If the device is running Android 5.1 (API level 22)or lower, or your app's target SDKis 22 or lower(targetSdkVersion <=22) : If you list a dangerous permission in your manifest, the user has to grant the permission when they install the app; if they do not grant the permission, the system does not install the app at all.
● If the device is running Android 6.0 (API level 23) or higher, and your app's target SDK is 23 or higher (targetSdkVersion >=23): The app has to list the permissions in the manifest, and it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.
Note: Beginning with Android 6.0 (API level 23), users can revoke permissions from any app at any time, even if the app targets a lower API level. You should test your app to verify that it behaves properly when it's missing a needed permission, regardless of what API level your app targets.Note: Your app still needs to explicitly request every permission it needs, even if the user has already granted another permission in the same group. In addition, the grouping of permissions into groups may change in future Android releases. Your code should not rely on the assumption that particular permissions are or are not in the same group.安全
https://developer.android.google.cn/training/permissions/requesting.htmlapp
https://developer.android.com/guide/topics/permissions/requesting.html#normal-dangerousless
When device is running Android 6.0 (API level 23) or higher, and your app's target SDK is 23 or higher (targetSdkVersion >=23)异步
RuntTimePermissionTestActivity.javaide
RuntTimePermissionTestActivity.java 以SEND_SMS(发送短信)、RECEIVE_SMS(使用SMSReceiver接收短信)、permission_group.SMS 为例子。
SMS是Short Messaging Service(短消息服务)的缩写,是一种使用移动设备能够发送和接收文本信息的技术。
PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), permission)
true,已经受权,直接执行doSendMessage。
false,没有受权,执行下一步检查是否须要显示请求权限缘由。
PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), Manifest.permission.SEND_SMS)
PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), Manifest.permission.SEND_SMS) && PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), Manifest.permission.RECEIVE_SMS)
PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), Manifest.permission_group.SMS)
true,须要显示请求权限缘由,显示一个dialog/Snarkbar,容许用户作选择。
false,不须要显示请求权限缘由,直接执行requestPermissions。
ActivityCompat.shouldShowRequestPermissionRationale(getContext(), Manifest.permission.SEND_SMS)
ActivityCompat.shouldShowRequestPermissionRationale(getContext(), Manifest.permission.SEND_SMS) && ActivityCompat.shouldShowRequestPermissionRationale(getContext(), Manifest.permission.RECEIVE_SMS)
ActivityCompat.shouldShowRequestPermissionRationale(getContext(), Manifest.permission_group.SMS)
ActivityCompat.requestPermissions 调用后,在onRequestPermissionsResult()中根据requestCode判断是否grandted,并作对应处理。
public static void requestPermissions(final @NonNull Activity activity,final @NonNull String[] permissions, final @IntRange(from = 0) int requestCode)
说明:
(1) permissions:是一个String[],能够放一个或多个permission。
(2) requestCode:在onRequestPermissionsResult()中处理。每次请求request permissions时requestCode设置要不一样。
ActivityCompat.requestPermissions(getContext(), new String[]{Manifest.permission.SEND_SMS}, REQUEST_CODE_4_REQUEST_PERMISSIONS_4_SEND_MESSAGE);
ActivityCompat.requestPermissions(getContext(), new String[]{Manifest.permission.SEND_SMS,Manifest.permission.RECEIVE_SMS}, REQUEST_CODE_4_REQUEST_PERMISSIONS_4_SEND_RECEIVE_MESSAGE);
ActivityCompat.requestPermissions(getContext(), new String[]{Manifest.permission_group.SMS}, REQUEST_CODE_4_REQUEST_PERMISSIONS_GROUP_4_SMS)
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { Log.d(TAG, "onRequestPermissionsResult: requestCode=" + requestCode); switch (requestCode) { case REQUEST_CODE_4_REQUEST_PERMISSIONS_4_SEND_MESSAGE: { onRequestPermissionsResult4SendMessage(requestCode, permissions, grantResults); break; } default: // other 'case' lines to check for other permissions this app might request super.onRequestPermissionsResult(requestCode, permissions, grantResults); break; } } private void onRequestPermissionsResult4SendMessage(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (REQUEST_CODE_4_REQUEST_PERMISSIONS_4_SEND_MESSAGE != requestCode) { Log.e(TAG, "onRequestPermissionsResult4SendMessage: requestCode is wrong"); return; } // Check if the only required permission has been granted // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 受权了,执行task,此处是发送短信操做。 doSendMessage(); // Send message permission has been granted, Message can be sent. Log.i(TAG, "Send message permission has now been granted. Can send message."); // 受权了,给出对应提示信息。 showPermissionAvailable4SendMessage(); } else { // permission denied, boo! Disable the functionality that depends on this permission. Log.i(TAG, "Send message permission was NOT granted."); // 没有被受权,给出对应提示信息。 showPermissionsNotGranted(); } }
6 总结
例如,申请Manifest.permission.SEND_SMS权限时,用户已经受权了Manifest.permission.SEND_SMS权限,系统则会自动受权group SMS中的全部权限,再也不询问用户;
checkSelfPermission和requestPermissions从API 23才加入,低于23版本,须要在运行时判断。
使用Support Library v4中提供的方法,能够避免判断。
ContextCompat.checkSelfPermission ActivityCompat.requestPermissions ActivityCompat.shouldShowRequestPermissionRationale
例如:使用ContextCompat.checkSelfPermission , 而不是Activity.checkSelfPermission()。google 官网推荐这种方式。
-https://developer.android.com/guide/topics/permissions/requesting.html#normal-dangerous
PS: 中国访问, 把com -> google.cn 就能够打开了。
EasyPermissions
rxpermissions
android send sms
snackbars:
Android Support v4,v7,v13的区别以及 v4,v7包冲突问题
谢谢浏览
欢迎你们交流,留言、指点。
文中有误,欢迎你们指出来。我会更正过来。