1. 程式人生 > >6.0許可權

6.0許可權

轉自--》http://blog.yanzhenjie.com

由於專案一直在更新,更多新內容請直接看AndPermission開源主頁: 
https://github.com/yanzhenjie/AndPermission

AndPermission能解決大部分國產機遇到的許可權問題,請參考:國產手機許可權適配方案

AndPermission特性

  1. 鏈式呼叫,一句話申請許可權,為你省去複雜的邏輯判斷。
  2. 支援註解回撥結果、支援Listener回撥結果。
  3. 拒絕一次某許可權後,再次申請該許可權時可使用Rationale向用戶說明申請該許可權的目的,在使用者同意後再繼續申請,避免使用者勾選不再提示
    而導致不能再次申請該許可權。
  4. 就算使用者拒絕許可權並勾選不再提示,可使用SettingDialog提示使用者去設定中授權。
  5. RationaleDialogSettingDialog允許開發者自定義。
  6. AndPermission自帶預設對話方塊除可自定義外,也支援國際化。
  7. 支援在任何地方申請許可權,不僅限於ActivityFragment等。

如果你的英文夠好,推薦你閱讀官網的文章:


關於執行時許可權

在舊的許可權管理系統中,許可權僅僅在App安裝時詢問使用者一次,使用者同意了這些許可權App才能被安裝(某些深度定製系統另說),App一旦安裝後就可以偷偷的做一些不為人知的事情了。

在Android6.0開始,App可以直接安裝,App在執行時一個一個詢問使用者授予許可權,系統會彈出一個對話方塊讓使用者選擇是否授權某個許可權給App(這個Dialog不能由開發者定製),當App需要使用者授予不恰當的許可權的時候,使用者可以拒絕,使用者也可以在設定頁面對每個App的許可權進行管理。

特別注意:這個對話方塊不是開發者呼叫某個許可權的功能時由系統自動彈出,而是需要開發者手動呼叫,如果你直接呼叫而沒有去申請許可權的話,將會導致App崩潰。

也許你已經開始慌了,這對於使用者來說是好事,但是對於開發者來說我們不能直接呼叫方法了,我們不得不在每一個需要許可權的地方檢查並請求使用者授權,所以就引出了以下兩個問題。

哪些許可權需要動態申請

新的許可權策略講許可權分為兩類,第一類是不涉及使用者隱私的,只需要在Manifest中宣告即可,比如網路、藍芽、NFC等;第二類是涉及到使用者隱私資訊的,需要使用者授權後才可使用,比如SD卡讀寫、聯絡人、簡訊讀寫等。

不需要執行時申請的許可權

此類許可權都是正常保護的許可權,只需要在AndroidManifest.xml中簡單宣告這些許可權即可,安裝即授權,不需要每次使用時都檢查許可權,而且使用者不能取消以上授權,除非使用者解除安裝App。

  • ACCESS_LOCATION_EXTRA_COMMANDS
  • ACCESS_NETWORK_STATE
  • ACCESS_NOTIFICATION_POLICY
  • ACCESS_WIFI_STATE
  • BLUETOOTH
  • BLUETOOTH_ADMIN
  • BROADCAST_STICKY
  • CHANGE_NETWORK_STATE
  • CHANGE_WIFI_MULTICAST_STATE
  • CHANGE_WIFI_STATE
  • DISABLE_KEYGUARD
  • EXPAND_STATUS_BAR
  • GET_PACKAGE_SIZE
  • INSTALL_SHORTCUT
  • INTERNET
  • KILL_BACKGROUND_PROCESSES
  • MODIFY_AUDIO_SETTINGS
  • NFC
  • READ_SYNC_SETTINGS
  • READ_SYNC_STATS
  • RECEIVE_BOOT_COMPLETED
  • REORDER_TASKS
  • REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
  • REQUEST_INSTALL_PACKAGES
  • SET_ALARM
  • SET_TIME_ZONE
  • SET_WALLPAPER
  • SET_WALLPAPER_HINTS
  • TRANSMIT_IR
  • UNINSTALL_SHORTCUT
  • USE_FINGERPRINT
  • VIBRATE
  • WAKE_LOCK
  • WRITE_SYNC_SETTINGS

需要執行時申請的許可權

所有危險的Android系統許可權屬於許可權組,如果APP執行在Android 6.0 (API level 23)或者更高級別的裝置中,而且targetSdkVersion>=23時,系統將會自動採用動態許可權管理策略,如果你在涉及到特殊許可權操作時沒有申請許可權許可權而直接呼叫了相關程式碼,你的App可能就崩潰了,綜上所述你需要注意:

  • 此類許可權也必須在Manifest中申明,否則申請時不提示使用者,直接回調開發者許可權被拒絕。
  • 同一個許可權組的任何一個許可權被授權了,這個許可權組的其他許可權也自動被授權。例如一旦WRITE_CONTACTS被授權了,App也有READ_CONTACTSGET_ACCOUNTS了。
  • 申請某一個許可權的時候系統彈出的Dialog是對整個許可權組的說明,而不是單個許可權。例如我申請READ_EXTERNAL_STORAGE,系統會提示"允許xxx訪問裝置上的照片、媒體內容和檔案嗎?"

如果App執行在Android 5.1 (API level 22)或者更低級別的裝置中,或者targetSdkVersion<=22時(此時裝置可以是Android 6.0 (API level 23)或者更高),在所有系統中仍將採用舊的許可權管理策略,系統會要求使用者在安裝的時候授予許可權。其次,系統就告訴使用者App需要什麼許可權組,而不是個別的某個許可權。

  • CALENDAR(日曆) 
    • READ_CALENDAR
    • WRITE_CALENDAR
  • CAMERA(相機) 
    • CAMERA
  • CONTACTS(聯絡人) 
    • READ_CONTACTS
    • WRITE_CONTACTS
    • GET_ACCOUNTS
  • LOCATION(位置) 
    • ACCESS_FINE_LOCATION
    • ACCESS_COARSE_LOCATION
  • MICROPHONE(麥克風) 
    • RECORD_AUDIO
  • PHONE(手機) 
    • READ_PHONE_STATE
    • CALL_PHONE
    • READ_CALL_LOG
    • WRITE_CALL_LOG
    • ADD_VOICEMAIL
    • USE_SIP
    • PROCESS_OUTGOING_CALLS
  • SENSORS(感測器) 
    • BODY_SENSORS
  • SMS(簡訊) 
    • SEND_SMS
    • RECEIVE_SMS
    • READ_SMS
    • RECEIVE_WAP_PUSH
    • RECEIVE_MMS
  • STORAGE(儲存卡) 
    • READ_EXTERNAL_STORAGE
    • WRITE_EXTERNAL_STORAGE

使用adb命令可以檢視這些需要授權的許可權組:

adb shell pm list permissions -d -g
  • 1
  • 1

使用adb命令同樣可以授權/撤銷某個許可權:

adb shell pm [grant|revoke] <permission-name>...
  • 1
  • 1

關於執行時許可權的一些建議

  1. 只請求你需要的許可權,減少請求的次數,或用隱式Intent來讓其他的應用來處理。

    1. 如果你使用Intent,你不需要設計介面,由第三方的應用來完成所有操作。比如打電話、選擇圖片等。
    2. 如果你請求許可權,你可以完全控制使用者體驗,自己定義UI。但是使用者也可以拒絕許可權,就意味著你的應用不能執行這個特殊操作。
  2. 防止一次請求太多的許可權或請求次數太多,使用者可能對你的應用感到厭煩,在應用啟動的時候,最好先請求應用必須的一些許可權,非必須許可權在使用的時候才請求,建議整理並按照上述分類管理自己的許可權:

    1. 普通許可權(Normal PNermissions):只需要在Androidmanifest.xml中宣告相應的許可權,安裝即許可。
    2. 需要執行時申請的許可權(Dangerous Permissions): 
      • 必要許可權:最好在應用啟動的時候,進行請求許可的一些許可權(主要是應用中主要功能需要的許可權)。
      • 附帶許可權:不是應用主要功能需要的許可權(如:選擇圖片時,需要讀取SD卡許可權)。
  3. 解釋你的應用為什麼需要這些許可權:在你呼叫requestPermissions()之前,你為什麼需要這個許可權。

    1. 例如,一個攝影的App可能需要使用定位服務,因為它需要用位置標記照片。一般的使用者可能會不理解,他們會困惑為什麼他們的App想要知道他的位置。所以在這種情況下,所以你需要在requestpermissions()之前告訴使用者你為什麼需要這個許可權。
  4. 使用相容庫support-v4中的方法

ContextCompat.checkSelfPermission()
ActivityCompat.requestPermissions()
ActivityCompat.shouldShowRequestPermissionRationale()
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

幾個重要的方法與常量解釋

  • PackageManager中的兩個常量:

    • PackageManager.PERMISSION_DENIED:該許可權是被拒絕的。
    • PackageManager.PERMISSION_GRANTED:該許可權是被授權的。
  • Activity中或者Fragment都會有以下幾個方法:

int checkSelfPermission(String)
void requestPermissions(int, String...)
boolean shouldShowRequestPermissionRationale(String)
void onRequestPermissionsResult()
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

上述四個方法中,前三個方法在support-v4ActivityCompat中都有,建議使用相容庫中的方法。最後一個方法是使用者授權或者拒絕某個許可權組時系統會回撥Activity或者Fragment中的方法。

checkSelfPermission() 檢查許可權

  1. 檢查某一個許可權的當前狀態,你應該在請求某個許可權時檢查這個許可權是否已經被使用者授權,已經授權的許可權重複申請可能會讓使用者產生厭煩。
  2. 該方法有一個引數是許可權名稱,有一個int的返回值,用這個值與上面提到的兩個常量做比較可判斷檢查的許可權當前的狀態。
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
    // 沒有許可權,申請許可權。
}else{
    // 有許可權了,去放肆吧。
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

requestPermissions() 申請許可權

  1. 請求使用者授權幾個許可權,呼叫後系統會顯示一個請求使用者授權的提示對話方塊,App不能配置和修改這個對話方塊,如果需要提示使用者這個許可權相關的資訊或說明,需要在呼叫 requestPermissions() 之前處理,該方法有兩個引數: 
    • int requestCode,會在回撥onRequestPermissionsResult()時返回,用來判斷是哪個授權申請的回撥。
    • String[] permissions,許可權陣列,你需要申請的的許可權的陣列。
  2. 由於該方法是非同步的,所以無返回值,當用戶處理完授權操作時,會回撥Activity或者Fragment的onRequestPermissionsResult()方法。

對於Activity我們直接呼叫requestPermissions(int, String[])即可,不過這個方法是在api leve 23以上,所以我們為了適配可以是使用相容包提供的方法:

ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_CONTACTS}, MMM);
  • 1
  • 1

對於support包的Fragment就可以直接呼叫requestPermissions(int, String[]),對於app包的Fragment就需要做版本判斷了,這樣就顯得比較麻煩。

onRequestPermissionsResult() 處理許可權結果回撥

  1. 該方法在Activity/Fragment中應該被重寫,當用戶處理完授權操作時,系統會自動回撥該方法,該方法有三個引數: 
    • int requestCode,在呼叫requestPermissions()時的第一個引數。
    • String[] permissions,許可權陣列,在呼叫requestPermissions()時的第二個引數。
    • int[] grantResults,授權結果陣列,對應permissions,具體值和上方提到的PackageManager中的兩個常量做比較。
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MMM: {
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 許可權被使用者同意,可以去放肆了。
            } else {
                // 許可權被使用者拒絕了,洗洗睡吧。
            }
            return;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

shouldShowRequestPermissionRationale()

  1. 望文生義,是否應該顯示請求許可權的說明。
  2. 第一次請求許可權時,使用者拒絕了,呼叫shouldShowRequestPermissionRationale()後返回true,應該顯示一些為什麼需要這個許可權的說明。
  3. 使用者在第一次拒絕某個許可權後,下次再次申請時,授權的dialog中將會出現“不再提醒”選項,一旦選中勾選了,那麼下次申請將不會提示使用者。
  4. 第二次請求許可權時,使用者拒絕了,並選擇了“不再提醒”的選項,呼叫shouldShowRequestPermissionRationale()後返回false。
  5. 裝置的策略禁止當前應用獲取這個許可權的授權:shouldShowRequestPermissionRationale()返回false 。
  6. 加這個提醒的好處在於,使用者拒絕過一次許可權後我們再次申請時可以提醒該許可權的重要性,免得再次申請時使用者勾選“不再提醒”並決絕,導致下次申請許可權直接失敗。

綜上所述,整合程式碼後:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
    // 沒有許可權。
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS)) {
            // 使用者拒絕過這個許可權了,應該提示使用者,為什麼需要這個許可權。
    } else {
        // 申請授權。
        ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS}, MMM);
    }
}

...

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MMM: {
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 許可權被使用者同意,可以去放肆了。
            } else {
                // 許可權被使用者拒絕了,洗洗睡吧。
            }
            return;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

總結

從上面來看,判斷很多,邏輯也很多,這樣就加重了我們開發的負擔,加上很多人反饋說國產手機有各種各樣的bug,這樣相容起來就更加麻煩了,那麼下面我就為大家介紹一個開源內褲來解決這一系列問題。

AndPermission

這個開源庫名叫AndPermission:https://github.com/yanzhenjie/AndPermission,經過我的實踐是完全解決了上述問題,推薦大家使用。

  • Gradle
compile 'com.yanzhenjie:permission:1.0.6'
  • 1
  • 1
  • Maven
<dependency>
  <groupId>com.yanzhenjie</groupId>
  <artifactId>permission</artifactId>
  <version>1.0.5</version>
  <type>pom</type>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • Eclipse 請放棄治療

使用介紹

我建議看官去Github下載Demo並閱讀本文會幫助你理解。

申請許可權

// 在Activity:
AndPermission.with(activity)
    .requestCode(100)
    .permission(Manifest.permission.WRITE_CONTACTS)
    .rationale(...)
    .callback(...)
    .start();

// 在Fragment:
AndPermission.with(fragment)
    .requestCode(100)
    .permission(
        // 多個許可權,以陣列的形式傳入。
        Manifest.permission.WRITE_CONTACTS,
        Manifest.permission.READ_SMS
    )
    .rationale(...)
    .callback(...)
    .start();

// 在其它任何地方:
AndPermission.with(context)
    .requestCode(100)
    .permission(
        Manifest.permission.WRITE_CONTACTS,
        Manifest.permission.READ_SMS
    )
    .rationale(...)
    .callback(...)
    .start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

接受回撥結果

接受回撥結果目前有兩種方式:一、Listener方式,二、註解方式。

方式一:Listener方式回撥

callback()方法傳入PermissionListener即可,授權成功或者失敗至少會回撥其中一個方法。

AndPermission.with(context)
    ...
    .requestCode(200)
    .callback(listener)
    .start();

private PermissionListener listener = new PermissionListener() {
    @Override
    public void onSucceed(int requestCode, List<String> grantedPermissions) {
        // 許可權申請成功回撥。

        // 這裡的requestCode就是申請時設定的requestCode。
        // 和onActivityResult()的requestCode一樣,用來區分多個不同的請求。
        if(requestCode == 200) {
            // TODO ...
        }
    }

    @Override
    public void onFailed(int requestCode, List<String> deniedPermissions) {
        // 許可權申請失敗回撥。
        if(requestCode == 200) {
            // TODO ...
        }
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

方式二:註解方式回撥

callback()方法傳入你的回撥方法所在例項的物件即可。

AndPermission.with(context)
    ...
    .requestCode(300)
    .callback(this)
    .start();

// 成功回撥的方法,用註解即可,這裡的300就是請求時的requestCode。
@PermissionYes(300)
private void getPermissionYes(List<String> grantedPermissions) {
    // TODO 申請許可權成功。
}

@PermissionNo(300)
private void getPermissionNo(List<String> deniedPermissions) {
    // TODO 申請許可權失敗。
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

如果你會用了,你就可以大刀闊斧的幹了,部落格中講到的各種複雜邏輯,AndPermission自動完成。

Rationale能力

Android執行時許可權有一個特點,在拒絕過一次許可權後,再此申請該許可權,在申請框會多一個[不再提示]的複選框,當用戶勾選了[不再提示]並拒絕了許可權後,下次再申請該許可權將直接回調申請失敗。 
因此Rationale功能是在使用者拒絕一次許可權後,再次申請時檢測到已經申請過一次該許可權了,允許開發者彈窗說明申請許可權的目的,獲取使用者的同意後再申請許可權,避免使用者勾選不再提示,導致不能再次申請許可權。

方式一:使用AndPermssion預設MD風格對話方塊

AndPermission.with(this)
    ...
    .requestCode(...)
    .rationale((requestCode, rationale) ->
        // 此對話方塊可以自定義,呼叫rationale.resume()就可以繼續申請。
        AndPermission.rationaleDialog(context, rationale).show()
    )
    .start()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

方式二:自定義對話方塊

AndPermission.with(this)
    ...
    .requestCode(...)
    .rationale(rationaleListener)
    .start()

/**
 * Rationale支援,這裡自定義對話方塊。
 */
private RationaleListener rationaleListener = (requestCode, rationale) -> {
    AlertDialog.newBuilder(this)
        .setTitle("友好提醒")
        .setMessage("你已拒絕過定位許可權,沒有定位定位許可權無法為你推薦附近的妹子,你看著辦!")
        .setPositiveButton("好,給你", (dialog, which) -> {
            rationale.resume();
        })
        .setNegativeButton("我拒絕", (dialog, which) -> {
            rationale.cancel();
        }).show();
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

提示使用者在系統設定中授權

當用戶拒絕許可權並勾選了不再提示時,此時再次申請許可權時將會直接回調申請失敗,因此AndPermission提供了一個供使用者在系統Setting中給我們授權的能力。

我們在授權失敗的回撥方法中新增如下程式碼,以下三種選擇一種即可:

// 是否有不再提示並拒絕的許可權。
if (AndPermission.hasAlwaysDeniedPermission(activity, deniedPermissions)) {
    // 第一種:用AndPermission預設的提示語。
    AndPermission.defaultSettingDialog(activity, 400).show();

    // 第二種:用自定義的提示語。
    AndPermission.defaultSettingDialog(activity, 400)
    .setTitle("許可權申請失敗")
    .setMessage("您拒絕了我們必要的一些許可權,已經沒法愉快的玩耍了,請在設定中授權!")
    .setPositiveButton("好,去設定")
    .show();

    // 第三種:自定義dialog樣式。
    SettingService settingService = AndPermission.defineSettingDialog(activity, 400);
    ...
    // 你的dialog點選了確定呼叫:
    settingService.execute();
    // 你的dialog點選了取消呼叫:
    settingService.cancel();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

如果你是在Activity/Fragment中呼叫的上述程式碼,那麼當用戶在系統Setting中操作完成後,會回撥Activity/Fragment中的這個方法:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case 400: { // 這個400就是你上面傳入的數字。
            // 你可以在這裡檢查你需要的許可權是否被允許,並做相應的操作。
            break;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

混淆

  1. 如果使用Listener接受回撥結果,不用任何配置。
  2. 使用註解的方式回撥結果,在proguard中新增如下配置:
-keepclassmembers class ** {
    @com.yanzhenjie.permission.PermissionYes <methods>;
}
-keepclassmembers class ** {
    @com.yanzhenjie.permission.PermissionNo <methods>;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

國產手機適配方案

AndPermission是嚴格按照Android系統的執行時許可權設計的,並最大限度上相容了國產手機,目前發現的國產手機bug及解決方案:

  • 部分中國廠商生產手機(例如小米某型號)的Rationale功能,在第一次拒絕後,第二次申請時不會返回true,並且會回撥申請失敗,也就是說在第一次決絕後預設勾選了不再提示,所以建議一定使用SettingDialog提示使用者在系統設定中授權
  • 部分中國廠商生產手機(例如小米、華為某型號)在申請許可權時,使用者點選確定授權後,還是回撥我們申請失敗,這個時候其實我們是擁有許可權的,所以我們可以在失敗的方法中使用AppOpsManager進行許可權判斷,AndPermission已經封裝好了:
            
           

相關推薦

6.0許可權

轉自--》http://blog.yanzhenjie.com 由於專案一直在更新,更多新內容請直接看AndPermission開源主頁: https://github.com/yanzhenjie/AndPermission AndPermission能解決大部分國產機遇到

Location許可權,因系統版本不同,6.0許可權對話方塊沒有,7.0,8.0正常,開發時要注意

1、一個獲取Location許可權引發的刺激,就這三個Location許可權 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission an

android 6.0許可權管理

轉載 https://blog.csdn.net/android2me/article/details/69525975 private void checkPermission() { //檢查許可權(NEED_PERMISSION)是否被授權 PackageManager.

android 6.0 + 許可權之 打電話

下面看看我怎麼調出去的… 第一步,我們還是要在AndroidManifolest.xml裡面新增 如果你沒有判斷請求許可權會報以下錯誤 AndroidRuntime: FATAL EXCEPTION: main Process: com.example.jie.demo, PI

android 6.0許可權,onRequestPermissionsResult回撥不執行問題

許可權是目前APP必不可少的,這裡介紹一下onRequestPermissionsResult回撥不執行問題。 一,正常使用android 6.0許可權: 思路: 1.檢查判斷 如果應用具有此許可權,方法將返回PackageManager.PERMISSION_GRA

android 6 0許可權全面詳細分析和解決方案

原文: http://www.2cto.com/kf/201512/455888.html http://blog.csdn.net/yangqingqo/article/details/48371123 http://inthecheesefactory.com/blog/things-y

高德地圖中安卓6.0許可權處理方案

package com.amap.location.demo; import java.util.ArrayList; import java.util.List; import android.Manifest; import android.app.Ac

Android 6.0許可權機制及開發流程詳解

許可權機制變更的背景 在Android6.0之前,app在安裝時會提示使用者此app需要使用哪些許可權,但使用者只能選擇同意或拒絕安裝,而不能單獨對某項許可權進行授予或拒絕。只要使用者選擇了安裝,即表示使用者接受了app對這些許可權的使用,如果使用者不希望app獲取某些涉及隱

Android 6.0許可權管理以及動態申請,以定位許可權為例

前言: 我們都知道現在手機系統已經到了很高的版本,在我們的Android6.0以後很多許可權都被列入危險許可權,都需要使用者手動去確認 1.我們先來看一下6.0以後被列為危險級別的一些許可權

安卓6.0許可權中 很全狠好理解的文章

文章轉載:http://blog.csdn.net/yanzhenjie1003/article/details/52503533 Android 6.0 執行時許可權管理最佳實踐 這是一篇遲來的部落格,Android M已經發布一年多了(6.0的變化),在An

android 6.0許可權判斷 音訊 拍照 相簿

/*------------------------------------------開啟音訊許可權------------------------------------------------*/ if (PackageManager.PERMISSION_GRANT

Android 6.0 許可權的申請 與 封裝

Android 6.0 以後最大的改變就是對於許可權的管理這一塊了,以前某個App 想使用什麼許可權 只要在 manifest 檔案裡面新增申請就可以了。 Android 6.0 以後不但要在manifest 裡面新增執行的時候還會彈出一個對話方塊讓使用

android 6.0許可權全面詳細分析和解決方案

原文: http://www.2cto.com/kf/201512/455888.html http://blog.csdn.net/yangqingqo/article/details/48371123 http://inthecheesefactory.com/blog

用URL 下載圖片(程式碼) (6.0許可權

首先我們知道要用到安卓讀寫許可權 只需要在AndroidManifest檔案中宣告即可,就像下面這樣: <uses-permission android:name="android.permission.INTERNET" />

Activity原始碼之Android 6.0許可權相關完全解析

我們都知道Android6.0以前許可權的申請非常簡單,只需要在mainfest宣告所需的許可權即可。而6.0以後,Android將許可權的管理進一步嚴格化,它要求使用者在使用某些敏感許可權時,必須在mainfest中先宣告之後再動態申請。在一定程度上約束了

android 6.0許可權動態申請

android M 的名字官方剛釋出不久,最終正式版即將來臨! android在不斷髮展,最近的更新 M 非常不同,一些主要的變化例如執行時許可權將有顛覆性影響。驚訝的是android社群鮮有談論這事兒,儘管這事很重要或許在不遠的將來會引發很嚴重的問題。 這是今天我寫

EasyPermissions解決Zxing掃一掃6.0許可權問題

無圖無真相,先來個真相: 最開始的時候,我不知道是哪個許可權,所以我就把Google6.0需要使用者手動開啟的許可權做了一個彙總: 我們找到這個方法,在這裡進行許可權的請求: @Override public

基於註解的6.0許可權動態請求框架——JPermission

目錄 一、 前言 二、支援的場景 三、如何接入 四、簡單使用 五、無上下文的類中如何使用 六、高階使用 一、前言 安卓6.0之後,一些敏感許可權需要進行動態請求,雖說編寫請求授權程式碼並不難,但是每次一需要許可權就需要在檢視中新增一段程式碼,嚴重影響程式碼美觀,同時也增加了一點點工作量。 於是,

Android——Android 6.0 許可權申請機制處理

Android 6.0帶來了新的許可權管理方式,預設情況下沒有任何應用有許可權去執行對其他應用、作業系統、使用者有不利影響的操作,這涉及到android 6.0的 Security Architecture(安全體系結構),也是Android安全體系結構的核心,

安卓6.0許可權申請詳解

安卓6.0的一大變化就是對於許可權的限制,首次安裝應用時會產生一個許可權請求列表,需要使用者手動逐個確認每個許可權,應用才能獲取該許可權。而在6.0之前預設開啟的,因此會產生一些應用會讀取使用者的一些隱私資訊,影響使用者體驗。本文根據實際專案開發經驗,簡述基於安