摘要:無論是,還是,都必須在文件中。,沒有授權,執行下一步檢查是否需要顯示請求權限原因。一個多個使用申請處理返回結果授權了,執行,此處是發送短信操作。沒有被授權,給出對應提示信息。
Android runtime permission 收尾1 demo 環境:
OS: mac OS 10.13.1 (17B1003)
android studio 3.0
gradle 4.1
Code Base
RuntTimePermissionTestActivity.java
classpath "com.android.tools.build:gradle:3.0.0"
compile "com.android.support:appcompat-v7:26.+"
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需要動態申請權限。
問題解決:方案1 將targetSDKVersion人為地降到小于23,這樣就變成了還是默認使用權限,但是這種并不是Google所推薦使用的。治標不治本。
方案2 When Android 6.0 (API 23),or targetSdkVersion Android 6.0 (API 23),實現APP支持運行時權限
正文 1. normal permissions and dangerous permissionsAndroid 6.0 (API 23) 開始,引入了normal permissions(普通權限) 和dangerous permissions(危險權限) 的概念。
[PASS]無論是normal permissions ,還是dangerous permissions ,都必須list在manifest文件中。
[PASS]For dangerous permissions,當運行OS <=Android 5.1 (API level 22),或者targetSdkVersion <=22時,不需要做特殊的處理。因為在安裝時會用戶必須授權權限。如果用戶不授權,system不會安裝app。
[PASS]For dangerous permissions,當運行OS >= Android 6.0 (API level 23),或者targetSdkVersion >=23時,要做特殊的處理。使用每個dangerous permissions之前, 必須request。
From android 官網:
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:
● 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.html
2. dangerous permissionshttps://developer.android.com/guide/topics/permissions/requesting.html#normal-dangerous
3. For dangerous permissions,when not needs request runtime permission?When device is running Android 6.0 (API level 23) or higher, and your app"s target SDK is 23 or higher (targetSdkVersion >=23)
Your app only needs permissions for actions that it performs directly.
Your app does not need permission if it is requesting that another app perform the task or provide the information.
4. How to request dangerous permissions? 重要的函數:checkSelfPermission():檢查是否已經具有了相關權限。
shouldShowRequestPermissionRationale():判斷是否需要向用戶解釋,為什么需要這些權限。
requestPermissions() :申請相關權限
SampleRuntTimePermissionTestActivity.java
RuntTimePermissionTestActivity.java 以SEND_SMS(發送短信)、RECEIVE_SMS(使用SMSReceiver接收短信)、permission_group.SMS 為例子。
android SMS 是什么縮寫SMS是Short Messaging Service(短消息服務)的縮寫,是一種使用移動設備可以發送和接收文本信息的技術。
以例子說明如何request runtime permission. Step1,檢查Permission是否granted。PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), permission)
true,已經授權,直接執行doSendMessage。
false,沒有授權,執行下一步檢查是否需要顯示請求權限原因。
(1) 檢查一個Permission是否granted:
PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), Manifest.permission.SEND_SMS)
(2) 檢查多個Permissions是否granted:
PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), Manifest.permission.SEND_SMS) && PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), Manifest.permission.RECEIVE_SMS)
(3) 檢查permission_group是否granted:
PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(getContext(), Manifest.permission_group.SMS)Step2,檢查Permission是否顯示請求權限原因。
true,需要顯示請求權限原因,顯示一個dialog/Snarkbar,允許用戶做選擇。
false,不需要顯示請求權限原因,直接執行requestPermissions。
(1)檢查一個Permission是否顯示請求權限原因:
ActivityCompat.shouldShowRequestPermissionRationale(getContext(), Manifest.permission.SEND_SMS)
(2)檢查多個Permissions是否顯示請求權限原因:
ActivityCompat.shouldShowRequestPermissionRationale(getContext(), Manifest.permission.SEND_SMS) && ActivityCompat.shouldShowRequestPermissionRationale(getContext(), Manifest.permission.RECEIVE_SMS)
(2)檢查permission_group是否顯示請求權限原因:
ActivityCompat.shouldShowRequestPermissionRationale(getContext(), Manifest.permission_group.SMS)Step3,Request permission
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設置要不同。
(1) request一個permission:
ActivityCompat.requestPermissions(getContext(), new String[]{Manifest.permission.SEND_SMS}, REQUEST_CODE_4_REQUEST_PERMISSIONS_4_SEND_MESSAGE);
(2) request多個permissions:
ActivityCompat.requestPermissions(getContext(), new String[]{Manifest.permission.SEND_SMS,Manifest.permission.RECEIVE_SMS}, REQUEST_CODE_4_REQUEST_PERMISSIONS_4_SEND_RECEIVE_MESSAGE);
(3)使用permission_group申請:
ActivityCompat.requestPermissions(getContext(), new String[]{Manifest.permission_group.SMS}, REQUEST_CODE_4_REQUEST_PERMISSIONS_GROUP_4_SMS)Step4 處理 request Permission返回結果
@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(); } }5. request runtime permission 流程總結
6 總結
不要使用Permission Group來request dangerous permissions。原因是將來API 不同,permissions groups可能不同。
僅僅申請需要的權限,申請太多不要的dangerous permissions可能會使得用戶感覺app不安全,導致用戶卸載app。
Show dangerous permissions rationale,簡潔明了。
任何時候APP都要在執行危險權限前去檢查是否具有相關權限,即使剛剛執行過這項操作,因為用戶很有可能去設置應用中關閉了相關權限。
[pass]申請權限時,如果組內有別的權限已經獲得了用戶授權,系統不再彈出詢問對話框,而是自動授權該權限。
例如,申請Manifest.permission.SEND_SMS權限時,用戶已經授權了Manifest.permission.SEND_SMS權限,系統則會自動授權group SMS中的所有權限,不再詢問用戶;
兼容問題:Use the Android Support Library to check for, and request, permissions.
checkSelfPermission和requestPermissions從API 23才加入,低于23版本,需要在運行時判斷。
使用Support Library v4中提供的方法,可以避免判斷。
ContextCompat.checkSelfPermission ActivityCompat.requestPermissions ActivityCompat.shouldShowRequestPermissionRationale
例如:使用ContextCompat.checkSelfPermission , 而不是Activity.checkSelfPermission()。google 官網推薦這種方式。
6 遺留的問題:Android官方開發指導還提到一點,為避免給用戶帶來糟糕的用戶體驗,shouldShowRequestPermissionRationale 這里的解釋說明應該是異步的,不要阻塞用戶的操作。
沒有看懂是什么意思。
大家知道了,可以告訴我,我會非常感謝。
準備創建一個BaseActivity,或一個工具類,把request runtime permission 代碼抽離。
寫關于Runtime permission library的總結。
Refhttps://developer.android.com/training/permissions/index.html
https://developer.android.com/training/permissions/declaring.html
https://developer.android.com/training/permissions/requesting.html
-https://developer.android.com/guide/topics/permissions/requesting.html#normal-dangerous
PS: 中國訪問, 把com -> google.cn 就可以打開了。
http://www.jianshu.com/p/0beb6243d650
http://www.jianshu.com/p/e1ab1a179fbb/
https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en
http://www.jianshu.com/p/f346b7446610
EasyPermissions
https://www.cnblogs.com/whycxb/p/6818685.html
rxpermissions
https://github.com/tbruyelle/RxPermissions
android send sms
http://www.cnblogs.com/huhx/p/sendMessage.html
snackbars:
http://wiki.jikexueyuan.com/project/material-design/components/snackbars-and-toasts.html
http://blog.csdn.net/qq_22706515/article/details/51151654
http://blog.csdn.net/sdjianfei/article/details/51583023
Android Support v4,v7,v13的區別以及 v4,v7包沖突問題
http://blog.csdn.net/shuaiyou_comon/article/details/75425639?locationNum=5&fps=1
謝謝瀏覽
歡迎大家交流,留言、指點。
文中有誤,歡迎大家指出來。我會更正過來。
我的GitHub
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70876.html
閱讀 1669·2021-11-17 09:33
閱讀 3531·2021-11-16 11:40
閱讀 3055·2019-08-30 11:23
閱讀 1048·2019-08-29 16:36
閱讀 2464·2019-08-29 13:23
閱讀 1738·2019-08-29 12:59
閱讀 1542·2019-08-29 12:42
閱讀 1979·2019-08-28 18:22