漫聊android適配動態權限機制

	近期利用工作空閒之際,學習了些新的知識,爲了更好的消化他們,我覺得把他們寫出來能更好的幫我理解知識,也希望我的知識總結能方便大家學習,共同探討和交流

   我先談點兒題外話,要說做android開發遇到最麻煩無語的事兒,我個人認爲是“給手機做適配”。由於android的開源性的特點,還有近年來非常火熱的“互聯網思維之個性化私人定製”。現在的android手機系統越來越多樣化,比方說我最喜歡的小米的MIUI,還有魅族、華爲、三星以及樂視等手機廠商都有自己的深度定製android系統。這樣做有很多好處,例如可以快速佔領市場,有優點就一定有缺點,這是萬物的規律,android也不例外,例如系統碎片化嚴重導致手機越用越用越卡(由於本文是技術類文章,這方面內容在本片文章不是重點,我這裏簡略)。我這裏順帶提一下開發上的坑吧,由於現在手機系統定製化嚴重,有些android原有的功能直接就被手機廠商修改了,這就會出現同一段代碼在AB手機上運行正常,但在C手機上直接運行崩潰。遇到這個情況開發人員內心有一萬頭羊駝飄過。導致開發一個APP不得不在各大手機上調試適配,工作任務量一下漲了很多(真羨慕IOS沒這個問題啊)適配上的坑很多,由於我開發閱歷有限,看到的坑不多,等以後閱歷多後,會考慮寫篇文章好好聊聊那些坑的事兒。

爲了能改善這一糟糕的局面,Google決定開始優化Android系統,於是在2015年的Google I/O大會上,Google公司推出了Android 6.0系統。這個6.0系統特點有很多,其中有一點很值得用戶關注,那就是“更加安全”,手機系統的敏感權限(例如讀寫SD卡、短信、拍照等)由之前的自動打開權限變成由用戶自己手動決定是否需要打開。

好了,現在先問各位三個問題。1android爲什麼要改變老的權限管理機制?2、可以不適配嗎?3、可以不借助第三方庫嗎?

先來回答第一個問題。因爲爲了保護用戶的隱私安全!之前我聽同事告訴我說,在這一特性沒出來之前,有些軟件公司爲了謀取金錢利益,在用戶不知情的情況下打開攝像頭偷拍用戶,然後進行敲詐勒索。呵,這流氓軟件想想都覺的可怕,可真會鑽谷歌的空子,好還谷歌及時發現把這個漏洞補上了。回答第二個問題,我以親身經歷告訴你,不能!如果不適配android動態權限,其結果就是若用戶要使用功能的相關權限沒有打開,你直接就使用的話,APP一定會直接崩潰!!!回答第三個問題,可以。其實動態權限適配實現起來並不困難,完全沒必要去用第三方庫去做。因此接下來我就來實現android動態權限的適配。

在編寫代碼之前,我們要明白哪些權限需要動態申請,哪些不需要。Google將權限分爲兩類,一類是Normal Permissions,這類權限一般不涉及用戶隱私,是不需要用戶進行授權的,比如手機震動、訪問網絡等;另一類是Dangerous Permission,一般是涉及到用戶隱私的,需要用戶進行授權,比如讀取sdcard、訪問通訊錄等。

Normal Permissions如下

Dangerous Permissions:



就這些內容吧。由於使用申請權限這些事兒基本都在Activity和Fragment裏。爲了使用方便,減少代碼冗餘。我們可以把這塊邏輯封裝放到我們自定義的BaseActivity和BaseFragment中,這樣只要我們只需要繼承他們就可以直接使用了。當然也可將這些邏輯放到自己封裝的Utils工具類中,兩種方案都可以的。這裏我使用的是第一種方案。

使用之前,1、先要判斷是否有指定的權限

public boolean hasPermission(String... permissions) {

        for (String permisson : permissions) {
            if (ContextCompat.checkSelfPermission(getActivity(), permisson)
                != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }
使用String... permissions方便多個權限的判斷,檢查權限可以使用ContextCompat.checkSelfPermission(),ContextCompat類是Context下屬的一個類,裏面有很多和文件相關的方法。PERMISSION_GRANTED表示允許授權。
接下來如果用戶沒有打開相關權限.2、那就要申請權限了

public void requestPermission(int code, String... permissions) {

        if (Build.VERSION.SDK_INT >= 23) {
            requestPermissions(permissions, code);
        }
    }
權限動態申請是在android6.0以後的事,所以這裏要判斷一下。
既然申請了權限,3、接下來要處理權限申請回調了

 @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case Constant.HARDWEAR_CAMERA_CODE: // 打開相機權限
                if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    doOpenCamera();
                }
                break;
            case Constant.WRITE_READ_EXTERNAL_CODE: // 讀寫SD卡權限
                if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    doWriteSDCard();
                }
                break;
        }
    }

這裏我們在申請權限時,要填寫一個請求碼,方便後面回調時識別是申請的哪個權限,而這些請求碼可以放在自定義的Constant類中,例如

/**
     * 權限常量相關
     */
    public static final int WRITE_READ_EXTERNAL_CODE = 0x01;
    public static final String[] WRITE_READ_EXTERNAL_PERMISSION = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE};

    public static final int HARDWEAR_CAMERA_CODE = 0x02;
    public static final String[] HARDWEAR_CAMERA_PERMISSION = new String[]{Manifest.permission.CAMERA};
最後就是使用。使用也很方便,例如在使用相機時。
case R.id.card_view:
                if (hasPermission(Constant.HARDWEAR_CAMERA_PERMISSION)) {
                    doOpenCamera();
                } else {
                    requestPermission(Constant.HARDWEAR_CAMERA_CODE, Constant.HARDWEAR_CAMERA_PERMISSION);
                }
                break;

doOpenCamera()方法可以在BaseFragment中,至於裏面的方法實現,可以在自己的Activity去做。例如
 @Override
    public void doOpenCamera() {
        Intent intent = new Intent(mContext, CaptureActivity.class);
        startActivityForResult(intent, REQUEST_QRCODE);
    }

或許有人會說在BaseFragment中寫這麼多空方法不好,太冗餘了。其實也不算太嚴重,因爲危險權限就9個,平時用的話連一半都不到,所以不用擔心。

以上就是我的個人實現。如有不對,請各位大神指正,謝謝




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章