1. 程式人生 > >Android6.0執行時許可權

Android6.0執行時許可權

一、執行時許可權

所謂執行時許可權,指的是在Android6.0及以上版本中,在app執行時才請求相關許可權,從而讓每項許可權都在使用者知情的情況下被授權(當然使用者可以拒絕)。而不同於Android6.0之前在安裝app時告知使用者獲取全部許可權。
關於許可權,分為正常許可權(一般和裝置相關)、危險許可權(使用者資料相關)和特殊許可權。具體可見https://developer.android.com/guide/topics/security/permissions.html?hl=zh-cn#normal-dangerous,其中特殊許可權(懸浮窗許可權和系統設定)。

二、檢查是否具有許可權API

 private boolean checkPermissions(){
        if (Build.VERSION.SDK_INT < 23) {//一般android6以下會在安裝時自動獲取許可權,但在小米機上,可能通過使用者許可權管理更改許可權
            return true;
        }else {

            if (getApplicationInfo().targetSdkVersion < 23) {
                //targetSdkVersion<23時 即便執行在android6及以上裝置 ContextWrapper.checkSelfPermission和Context.checkSelfPermission失效
//返回值始終為PERMISSION_GRANTED //此時必須使用PermissionChecker.checkSelfPermission if (PermissionChecker.checkPermission(this, Manifest.permission.CAMERA, Binder.getCallingPid(), Binder.getCallingUid(), getPackageName()) == PackageManager.PERMISSION_GRANTED) { return
true; } else { return false; } } else { if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { return true; } else { return false; } } } }

檢查是否具有許可權主要涉及3個方法:
1、ContextWrapper.checkSelfPermission和Context.checkSelfPermission
只有Build.VERSION.SDK_INT>=23才能呼叫,且targetSdkVersion>=23結果才有效。因此在targetSdkVersion<23時要用PermissionChecker.checkSelfPermission。
2、PermissionChecker.checkPermission
當在小米4.4上使用者手動改變許可權後,再次檢查許可權返回結果有誤。適用於Android6.0以上的許可權判斷。小米4.4需要使用AppOpsManager的許可權檢驗方法。
綜上:以上兩種,優先選擇PermissionChecker.checkPermission。
3、AppOpsManager
為了相容小米4.4使用者可以改變許可權的情況,只能使用AppOpsManager。(其實PermissionChecker.checkPermission底層用了Context.checkPermission和AppOpsManager)用法如下:

private boolean checkPermissionForXiaomi(){
        AppOpsManager manager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);

        try {

            Method method = manager.getClass().getDeclaredMethod("checkOp", int.class, int.class, String.class);
            int property = (Integer) method.invoke(manager, 26,
                    Binder.getCallingUid(), getPackageName());

            if (AppOpsManager.MODE_ALLOWED == property) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

三、請求許可權API

請求許可權主要涉及shouldShowRequestPermissionRationale和requestPermissions方法,用法如下:

if (checkPermissions()) {
                Toast.makeText(this,"已經獲取許可權",Toast.LENGTH_SHORT).show();
            } else {
                Log.d("haha", "no permission.");
                //請求許可權
                if (Build.VERSION.SDK_INT < 23) return;
                if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {//上次請求許可權被拒絕
                    //這裡一般自定義一個介面告知使用者為何需要此許可權
                    //一般手機還是會彈出使用者授權介面,但小米4.4對此作了處理  需通過intent跳轉到對應的許可權管理介面
                    //requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
                } else {
                    requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
                }

            }

1、shouldShowRequestPermissionRationale
上一次請求被拒絕則返回true,此時開發者應該有一個頁面說明請求許可權的原因。
2、requestPermissions
會直接到使用者授權介面,注意小米4.4有自己的許可權管理設定,這裡不會彈出許可權介面,需要作特殊處理直接跳轉到對應的設定介面。如下:

/**
     * 開啟許可權設定介面
     */
    public void openXiaomiSetting() {
        try {
            Intent localIntent = new Intent(
                    "miui.intent.action.APP_PERM_EDITOR");
            localIntent.setClassName("com.miui.securitycenter",
                    "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
            localIntent.putExtra("extra_pkgname", getPackageName());
            startActivityForResult(localIntent, 2);
        } catch (ActivityNotFoundException localActivityNotFoundException) {
            Intent intent1 = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            Uri uri = Uri.fromParts("package", getPackageName(), null);
            intent1.setData(uri);
            startActivityForResult(intent1, 2);
        }

    }

3、使用者授權結果的回撥是onRequestPermissionsResult,覆寫該方法進行相應處理即可。

 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //許可權處理結果的回撥
        switch (requestCode){
            case 1:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    Log.d("haha",permissions[0]+" granted.");
                    Toast.makeText(this,"獲取許可權成功!",Toast.LENGTH_SHORT).show();
                }
                break;
            case 2:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    Log.d("haha",permissions[0]+" granted.");
                    Toast.makeText(this,"小米獲取許可權成功!",Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                break;
        }
    }

注:經測試特殊許可權只能用AppOpsManager

相關推薦

Android學習筆記-Android6.0執行許可權

Android許可權機制,在Android6.0之前,其實一直很簡單,在AndroidManifest.xml中進行許可權宣告,通過一個Intent呼叫即可。 以打電話為例: <uses-permission android:name="andro

Android6.0執行許可權處理-超簡單封裝

之前除錯的時候,出現了一個問題,就是當我開啟二維碼掃描介面的時候,對於一部分手機一直不會出現那個掃描框,這點我也很是鬱悶,這不好整啊,畢竟二維碼介面是用的別人的,怎麼改啊?這個時候我分析了一下原因,最後知道只有部分6.0的手機才會出現這種情況,那麼這就簡單了。下

這可能是最精簡的Android6.0執行許可權處理,70行程式碼的工具類。附:各種許可權詳細處理

0x00:前言 對於Android6.0執行時許可權的處理方式網上有很多,包括註解,RxJava等等。一直沒有正面提到我關心的問題--如果我不在Activity或者Fragment裡面,需要執行時許可權該怎麼去做?導致我開始一直以為執行時許可權的處理必需要在Activity

Android6.0執行許可權-sd卡許可權處理方式

我們的app一般都會需要快取和一些圖片的儲存,當然我們的目錄可以是自己的私有目錄, getExternalCacheDir 或者 getCacheDir 是不需要許可權的,但是如果需要在sd卡下儲存呢,此時需要 WRITE_EXTERNAL_STORAGE 許可權.實際上

android6.0執行許可權完美封裝

前幾天看了郭大神的執行時許可權的專講,深受啟發,由於現在基於目前專案中的執行時許可權封裝的還不是那麼完美,趁著郭神建議的還是歷歷在目。於是把它完整的敲了下來。並在此基礎上新增上自己的一些見解,封裝成一個完整的demo,希望與大家進行交流與。 在這裡我進行了簡單的在acti

Android6.0執行許可權

一、執行時許可權 所謂執行時許可權,指的是在Android6.0及以上版本中,在app執行時才請求相關許可權,從而讓每項許可權都在使用者知情的情況下被授權(當然使用者可以拒絕)。而不同於Android6.0之前在安裝app時告知使用者獲取全部許可權。 關於許

淺談Android6.0執行許可權

引言 從 Android 6.0(API 23)開始,使用者開始在應用執行時向其授予許可權,而不是在應用安裝時授予。這種許可權機制可以讓使用者更好的管理應用的許可權,保障使用者隱私。 系統許可權分類 正常許可權不會直接給使用者隱私權帶來風險。如果您的應用

Android6.0執行許可權,拒絕了許可權還返回獲取成功

如題:禁用、詢問的許可權,居然還返回許可權獲取成功 推薦一個很好的專案:AndPermission 不用回來感謝了喂! 這個問題在專案中,一直存在, 主要是第三方廠商各種改,返回的狀態不正常

Android6.0執行許可權-----AndPermission的使用

最近才開始用AndPermission庫,感覺非常不錯,在使用的過程中,順便就將它的用法寫下來吧。 首先是AndPermission庫的引入,通過新增依賴即可: dependencies { ...compile 'com.yanzhenjie:permissi

Android6.0執行許可權處理(專案中使用到的一種形式,沒有使用第三方庫)

相信大家都知道Android6.0之後的許可權申請跟之前的版本有一個很大的差別,那就是任何危險許可權都必須經過使用者的手動選擇是否接受來做相應的操作,而Android6.0之前安裝應用的過程中是預設選

Android 6.0執行許可權勾選不再詢問後該如何處理?

Android 6.0執行時許可權勾選不再詢問後該如何處理? 當第一次請求許可權申請被拒絕後再進行第二次申請時,對話方塊中會多出一個 不再詢問 的複選框。如果勾選了該複選框並且拒絕請求,那麼以後將無法再申請該許可權。也就是說在呼叫 requestPermissions() 後,onRequest

Android 6 0 執行許可權處理

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android 6 0 執行許可權處理完全解析

                     一、概述ok,本篇文章目的之一就是對執行時許可權處理的一個介紹,以及對目前許可權相關的庫的一些瞭解。當然非常推薦閱讀官網許可權相關文章:本文也是在上述文章基礎上理解、實驗以及封裝。二、執行時許可權的變化及特點對於6.0以下的許可權及在安裝的時候,根據許可權宣告產生一個

以呼叫系統相機拍照為例瞭解Android 6.0執行許可權

首先扯點別的,聽說這個週末是好天氣,想約她一起去公園賞賞梅花,只有我自己估計她也不一定去啊,哈哈。 在android6.0及以上系統,Android在安裝一個應用的時候不再需要列出一大堆許可權,讓使用者點選同意以後才可以安裝。Instead, 當應用在執行的時

談談Android 6.0執行許可權理解

前言  谷歌在2015年8月份時候,釋出了Android 6.0版本,代號叫做“棉花糖”(Marshmallow ),其中的很大的一部分變化,是在使用者許可權授權上,或許是感覺之前預設授權的不合理,現在6.0出來,使得使用者許可權授權變得合理。這可能也是參考IOS系統的,只有在使用者需要使用許可權的時候,才

Android 6.0執行許可權申請和一些坑

1.概述 大家知道在Android6.0(Api23)之前,使用者許可權的申請都是在AndroidManifest.xml 宣告的,而在6.0之後,對某些涉及到使用者隱私的許可權可在執行時根據使用者的需要動態授予。如果你的應用設定targetSdkVersio

Android 6.0 執行許可權處理

執行時許可權介紹 Android 6.0在我們原有的AndroidManifest.xml宣告許可權的基礎上, 又新增了執行時許可權動態檢測,以下許可權都需要在執行時判斷: 執行時許可權處理 Android6.0系統預設為targetSdkVersion小於23的應用預設授予了所申請的所有許可權,

Android 6.0 執行許可權管理最佳實踐

這是一篇遲來的部落格,Android M已經發布一年多了(6.0的變化),在Android M中許可權系統被重新設計,發生了顛覆性的變化,很多人把握不好這個變化,一是對這個許可權策略和套路還沒有摸透,二是沒有一個很好的實踐來支撐,在我的技術開發群裡很多人問我

6.0執行許可權與targetSdkVersion選擇

targetSDKVersion 簡單來說就代表著你的App能夠適配的系統版本,意味著你的App在這個版本的手機上做了充分的 前向 相容性處理和實際測試。其實我們寫程式碼時都是經常幹這麼一件事,就是 if(Build.VERSION.SDK_INT >= 23) {

android 6.0執行許可權應用之相簿圖片選取

public class MainActivity extends AppCompatActivity { public static final int REQUEST_CODE=200; public static final int REQUEST_C