Android6.0權限管理

Android6.0權限管理

Android6.0棉花糖發(fā)布也快一年了,一直沒有時間去做相應的權限處理,最近有點時間宠进,系統(tǒng)的研究了一下屏箍,并在自己的app中增加了權限管理。
從此app再也不能在安裝時胸哥,就獲取想要的權限了涯竟,系統(tǒng)安全更進一步,這個絕對是個喜訊啊~~~
雖然這樣會給開發(fā)增加很多工作量,但是作為一個有節(jié)操庐船、有理想的程序員银酬,我們是要鼎力配合的

普通權限---不需做特殊處理

Android 6.0并不是要求所有的權限都要申請,需要得到用戶同意才能使用筐钟,很多權限系統(tǒng)是默認放給我們的揩瞪,比如INTERNET NETWORK等。一下是所有普通權限:

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT

這些權限只需要在AndroidManifest的聲明即可篓冲,app在使用時李破,不需做特殊處理而且用戶也不能取消這些權限。

危險權限---使用時需做處理

危險權限有這些:

permgroup.png
這些權限在使用在使用時壹将,一定要首先獲取用戶授權喷屋,否則直接使用,說不定會遇上什么bug~~

好在這樣的權限并不是很多瞭恰,系統(tǒng)采用了權限組屯曹,只要獲得組中任何一個權限,同組中的權限都會相應的獲得惊畏,這樣也省了不少事情恶耽。

讓我們的app支持這個新特性吧

首先,我們要把 targetSdkVersion compileSdkVersion都改成23.

android{
 compileSdkVersion 23
    defaultConfig {
        ...
        targetSdkVersion 23
        ...
}

由于不明白整個思路應該怎么做颜启,首先分析一下微信的權限流程是怎么做的

微信權限處理

啟動app偷俭,在閃屏頁顯示
 - 存儲空間權限。拒絕不能打開微信   
 - 電話權限缰盏。拒絕不能打開微信
 - 位置權限涌萤。拒絕不能打開微信

進入app:
 - 發(fā)照片時,申請照片權限
 - 發(fā)語音時口猜,申請麥克風權限

用戶每次點擊拒絕负溪,都彈出自定義對話框,提示用戶設置權限

實現思路

  • 先弄清楚自己app中需要哪些“危險”權限济炎,以及這些權限在哪里使用
  • 想清楚申請權限的時機川抡,有沒有哪些權限被拒絕app就無法使用
  • 寫出整個授權流程
  • 在BaseActivity里寫請求權限的方法
  • 針對每個點寫相應的處理

具體實現

  • BasePermissionsActivity中實現相關的權限申請操作
    private int permissionRequestCode = 88;
    private PermissionCallback permissionRunnable ;
    /**
     * 權限申請對應的提示語
     */
    private static final String CAMERA_TIP="請在設置-應用-AppName-權限中開啟相機權限,以正常使用拍照功能";
    private static final String RECORD_TIP="請在設置-應用-AppName-權限中開啟麥克風權限须尚,以正常使用語音功能";
    private static final String LOCATION_TIP="請在設置-應用-AppName-權限中開啟位置信息權限崖堤,以正常使用位置功能";
    private static final String STORAGE_TIP="請在設置-應用-AppName-權限中開啟存儲空間權限,以正常使用天天投功能";
    private static final String CONTACTS_TIP="請在設置-應用-AppName-權限中開啟通訊錄權限耐床,以正常使用人脈功能";
    private static final String PHONE_TIP="AppName使用電話權限確定本機設備ID密幔,以保證賬號登錄的安全性。AppName不會撥打其他號碼或者終止通話撩轰。\n" +
            "請在設置-應用-AppName-權限中開啟電話權限胯甩,以正常登錄AppName";
    public interface PermissionCallback{
        void hasPermission();
        void noPermission();
    }

    /**
     * Android M運行時權限請求封裝
     * @param runnable 請求權限回調
     * @param permissions 請求的權限(數組類型)昧廷,直接從Manifest中讀取相應的值,eg:android.permission.WRITE_CONTACTS
     */
    public void performCodeWithPermission(PermissionCallback runnable,@NonNull String... permissions){
        if (permissions == null || permissions.length == 0) {
            return;
        }

        this.permissionRunnable = runnable;
        /**
         * 如果Android SDK低于23或者已經獲得權限蜡豹,則直接執(zhí)行對應方法
         */
        if((Build.VERSION.SDK_INT < Build.VERSION_CODES.M) || checkPermissionGranted(permissions)){
            if(permissionRunnable!=null){
                permissionRunnable.hasPermission();
                permissionRunnable = null;
            }
        }else{
            requestPermission(permissionRequestCode,permissions);
        }

    }
    private boolean checkPermissionGranted(String[] permissions){
        boolean flag = true;
        for(String p:permissions){
            if(ActivityCompat.checkSelfPermission(this, p) != PackageManager.PERMISSION_GRANTED){
                flag = false;
                break;
            }
        }
        return flag;
    }
    private void requestPermission(final int requestCode,final String[] permissions){
        ActivityCompat.requestPermissions(BasePermissionsActivity.this, permissions, requestCode);
    }

    /**
     * 申請權限后的回調麸粮,即處理結果
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        if(requestCode == permissionRequestCode){
            if(verifyPermissions(grantResults)){
                if(permissionRunnable!=null) {
                    permissionRunnable.hasPermission();
                    permissionRunnable = null;
                }
            } else {
                /**
                 * 一般一次只請求一個權限,所以只取permissions中的第一個
                 */
                String tip = "";
                if (permissions != null && permissions.length > 0) {
                    if (permissions[0].equals("android.permission.READ_EXTERNAL_STORAGE")||permissions[0].equals("android.permission.WRITE_EXTERNAL_STORAGE\n")) {
                        tip = STORAGE_TIP;
                    }
                    if (permissions[0].equals("android.permission.CAMERA")) {
                        tip = CAMERA_TIP;
                    }
                    if (permissions[0].equals("android.permission.READ_CONTACTS")) {
                        tip = CONTACTS_TIP;
                    }
                    if (permissions[0].equals("android.permission.READ_PHONE_STATE")) {
                        tip = PHONE_TIP;
                    }
                    if (permissions[0].equals("android.permission.ACCESS_FINE_LOCATION")||permissions[0].equals("android.permission.ACCESS_COARSE_LOCATION")) {
                        tip = LOCATION_TIP;
                    }
                    if (permissions[0].equals("android.permission.RECORD_AUDIO")) {
                        tip = RECORD_TIP;
                    }
                }
                new AlertDialog.Builder(mContext)
                        .setTitle("權限申請")
                        .setMessage(tip)
                        .setPositiveButton("去設置", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Intent intent=new Intent(Settings.ACTION_APPLICATION_SETTINGS);
                                startActivity(intent);
                            }
                        })
                        .setNegativeButton("取消",null)
                        .show();
                if(permissionRunnable!=null) {
                    permissionRunnable.noPermission();
                    permissionRunnable = null;
                }
            }
        }else{
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }

    }
    public boolean verifyPermissions(int[] grantResults) {
        if(grantResults.length < 1){
            return false;
        }

        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

請求相機的例子:

//判斷是否獲取這個權限
 if(ActivityCompat.checkSelfPermission(mContext, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
             performCodeWithPermission(new PermissionCallback() {
                    @Override
                    public void hasPermission() {
                    //獲得權限后镜廉,做相應處理
                    }

                    @Override
                    public void noPermission() {
                      //未獲得權限弄诲,做相應處理

                    }
                }, Manifest.permission.CAMERA);
  }

到此,權限管理基本上就可以基于這些處理了娇唯,不過具體問題還得具體考慮

特別注意

  • 如果沒有做好相關的權限處理齐遵,一定不能把targetSdkVersion設為23
  • 上面這種寫在BasePermissionsActivity的方法,僅適合是Activity中使用,如果是在自定義view中需要申請的話塔插,可以使用EventBus通知其所屬的Activity進行權限申請

最后說一下梗摇,加上運行時權限確實不是個“小工程",很多地方可能都要重構想许,改之前建議還是想清楚再動手伶授。
希望這篇文章對大家有用,寫的不好流纹,請多指正糜烹。

參考鏈接:
http://www.reibang.com/p/d3a998ec04ad

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市漱凝,隨后出現的幾起案子疮蹦,更是在濱河造成了極大的恐慌,老刑警劉巖茸炒,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愕乎,死亡現場離奇詭異,居然都是意外死亡壁公,警方通過查閱死者的電腦和手機感论,發(fā)現死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贮尖,“玉大人笛粘,你說我怎么就攤上這事∈酰” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵润努,是天一觀的道長关斜。 經常有香客問我,道長铺浇,這世上最難降的妖魔是什么痢畜? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上丁稀,老公的妹妹穿的比我還像新娘吼拥。我一直安慰自己,他們只是感情好线衫,可當我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布凿可。 她就那樣靜靜地躺著,像睡著了一般授账。 火紅的嫁衣襯著肌膚如雪枯跑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天白热,我揣著相機與錄音敛助,去河邊找鬼。 笑死屋确,一個胖子當著我的面吹牛纳击,可吹牛的內容都是我干的。 我是一名探鬼主播攻臀,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼焕数,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茵烈?” 一聲冷哼從身側響起百匆,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呜投,沒想到半個月后加匈,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡仑荐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年雕拼,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粘招。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡啥寇,死狀恐怖,靈堂內的尸體忽然破棺而出洒扎,到底是詐尸還是另有隱情辑甜,我是刑警寧澤,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布袍冷,位于F島的核電站磷醋,受9級特大地震影響,放射性物質發(fā)生泄漏胡诗。R本人自食惡果不足惜邓线,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一淌友、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骇陈,春花似錦震庭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至匪蝙,卻和暖如春主籍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逛球。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工千元, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颤绕。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓幸海,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奥务。 傳聞我的和親對象是個殘疾皇子物独,可洞房花燭夜當晚...
    茶點故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內容