AppOpsManager權限檢測適配

導語

android碎片化相信是每一個android開發(fā)者的痛丑搔。機型適配也是難以繞過去的坎厦瓢。這其中Android動態(tài)權限檢測適配,相信對于很多開發(fā)者來說啤月,都是被按在地上摩擦摩擦煮仇。本文就針對Android權限動態(tài)檢測提出一種解決方案。

一谎仲、Android權限介紹

談起Android權限機制浙垫,很多人都會想到Google在Android 6.0 提出運行時權限管理機制(Android Runtime Permission)。針對運行時權限管理機制在這里我們不做過多描述郑诺。相信對于大多數(shù)開發(fā)者而言夹姥,真正的痛點在于建立在6.0之前的權限機制的權限檢測。之所以被認為是痛點辙诞,我們會在之后給大家介紹辙售。不同于Android Runtime Permission,6.0之前的權限機制飞涂,所申請只需要在AndroidManifest.xml列舉出來旦部,這無疑給惡意軟件提供了可趁之機。

二较店、動態(tài)權限檢測

針對權限檢測志鹃,我們根據(jù)權限機制的不同,劃分為以下兩類:
(1) targetSdkVersion >= 23
當設備處于6.0或6.0以上時采用的運行時權限機制泽西,權限檢測變得很簡單曹铃,只需要調用ContextCompat::checkSelfPermission(),瀟瀟灑灑一行代碼即可檢測對應的權限是否被賦予,簡直不要太簡單捧杉。
(2) tagetSdkVersion <23
當設備是6.0以下系統(tǒng)時陕见,使用的老的權限機制。不像大家想象的味抖,應用所需要的權限只需要在清單文件里面列出就可以一勞永逸评甜。如果真有這么簡單,那恐怕連一點裝逼的空間都沒有啦仔涩。事實上忍坷,android設備提供應用權限開關,達到用戶控制整個應用的權限的賦予。對于應用本身而言佩研,應用的很多功能是建立在擁有某一或者某些權限的基礎上柑肴。一旦用戶收回某一功能的具體權限,對于該功能來說無疑是一種災難旬薯。開發(fā)者建立了良好的容災機制那么只是會使某一功能異常晰骑,影響用戶體驗,然而對于那些沒有
建立起好的容災處理的代碼而言绊序,嚴重的可能導致應用閃退硕舆。到了線上飄紅的地步,領導請喝茶恐怕是跑不了骤公。
針對建立在老的權限機制基礎上的動態(tài)權限檢測的方案抚官,很多人第一時間就會想到我們是否可以像6.0以上設備一樣使用ContextCompat::checkSelfPermission()。對此我們特地做了測試阶捆,然而在我們測試過程發(fā)現(xiàn)只有清單文件里面申明了該權限耗式,那么不管用戶是否關閉或者開啟這一權限對應的開關,該方法都會返回true趁猴。這無疑宣告了該方案的根本無法滿足我們的需求刊咳。為了弄明白該方法為何會出現(xiàn)這一情況,我們從源碼入手儡司,去驗證對應的邏輯娱挨。

ActivityCompat::requestPermissions()

在圖中可以看到ActivityCompat::requestPermissions()方法體里面會對當前api版本中做判斷,當api<23時捕犬,會調用PackageManager.checkPermission(),為了進一步了解我們接著去看PackageManager.checkPermission()方法體內有什么邏輯跷坝。

PackageManager.checkPermission()

從圖上框出的文字中可以了解到判斷權限是否賦予是去判斷對應的package是否含有該權限,換句更容易理解的話來說就是如果該權限在清單文件中聲明了碉碉,即代表該權限被賦予柴钻。由此綜合前面的代碼片段來看當api<23時,使用ContextCompat::checkSelfPermission()是無法滿足我們的需求垢粮。
那么除了使用ContextCompat::checkSelfPermission()還有什么辦法可以滿足我們的代碼需求贴届。這里我們就不得不提起我們要介紹給大家的解決方案——AppOpsManager。

三蜡吧、權限檢測解決方案——AppOpsManager

AppOpsManager究竟是什么呢毫蚓?Google在Android開發(fā)者手冊對AppPosManager的描述為

API for interacting with "application operation" tracking.

這玩意說白了就是應用程序操作管理。AppOpsManager是在api 19引入昔善,即Android 4.3元潘。


checkOp-String

checkOp-Int

通過查看Android開發(fā)者手冊,以及查看AppOpsManager的源碼我們會發(fā)現(xiàn)checkOp()的多態(tài)方法君仆,其中checkOp(String op,int uid,String packageName)主要在api>23可以使用翩概,而checkOp(int op,int uid,String packageName)則沒有這一限制牲距。既然有了思路,那么就來介紹一下AppOpsManager針對權限控制應該主要那些東西钥庇。查看AppOpsManager的文檔牍鞠,你會看到這樣一段文字:

This API is not generally intended for third party application developers; most features are only available to system applications.

這么一段文字扯了啥呢,其實主要表達的是AppOpsManager在設計之初并不是面向開發(fā)者上沐。這一點其實在這個類的很多地方就體現(xiàn)出來了,同時也是我們需要注意的楞艾。在這個類中参咙,有很多權限對應的常量被隱藏起來,如下圖所示:


ConstantValueHide

與此同時硫眯,checkOp(int op,int uid,String packageName)蕴侧,這個方法本身也是hide,也就說我們無法通過AppOpsManager這個類正常調用該方法两入,以及訪問該屬性净宵。走到這一步,然后再告訴大家裹纳,這個方法也走不通的話择葡,我估計拍磚的肯定不少。那么處理這一問題剃氧,對于我們來說敏储,這個時候當然少不了反射。你敢隱藏朋鞍,只要你存在已添,我都要把你挖出來。以下為相關的代碼片段:

private boolean isPermissionGranted(String permissionCode) {
    try {
        Object object = getSystemService(Context.APP_OPS_SERVICE);
        if (object == null) {
            return false;
        }
        Class localClass = object.getClass();
        Class[] arrayOfClass = new Class[3];
        arrayOfClass[0] = Integer.TYPE;
        arrayOfClass[1] = Integer.TYPE;
        arrayOfClass[2] = String.class;
        Method method = localClass.getMethod("checkOp", arrayOfClass);

        if (method == null) {
            return false;
        }
        Object[] arrayOfObject = new Object[3];
        arrayOfObject[0] = Integer.valueOf(permissionCode);
        arrayOfObject[1] = Integer.valueOf(Binder.getCallingUid());
        arrayOfObject[2] = getPackageName();
        int m = ((Integer) method.invoke(object, arrayOfObject)).intValue();
        return m == AppOpsManager.MODE_ALLOWED;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

結語

權限動態(tài)檢測有多種解決方案滥酥,AppOpsManager只是其中一種維護成本相對較少的方案更舞。其中在做權限動態(tài)檢測時,看到了大家提供了很多針對某一權限的腦洞極大的方案坎吻,不得不感慨這得被虐了死去活來才能得出的經(jīng)驗教訓缆蝉。同時有部分反應AppOpsManager這一解決方案在某些機型上依舊不能適配的問題,只能表示,


MMP

最后瘦真,AppOpsManager這個類還有潛在的彩蛋返奉,通過這個工具可以打造一些裝逼利器山橄,大家有興趣可以去挖掘侍咱。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市名眉,隨后出現(xiàn)的幾起案子弦讽,更是在濱河造成了極大的恐慌污尉,老刑警劉巖膀哲,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異被碗,居然都是意外死亡某宪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門锐朴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兴喂,“玉大人,你說我怎么就攤上這事焚志∫旅裕” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵酱酬,是天一觀的道長壶谒。 經(jīng)常有香客問我,道長膳沽,這世上最難降的妖魔是什么汗菜? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮挑社,結果婚禮上陨界,老公的妹妹穿的比我還像新娘。我一直安慰自己痛阻,他們只是感情好普碎,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著录平,像睡著了一般麻车。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斗这,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天动猬,我揣著相機與錄音,去河邊找鬼表箭。 笑死赁咙,一個胖子當著我的面吹牛,可吹牛的內容都是我干的免钻。 我是一名探鬼主播彼水,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼极舔!你這毒婦竟也來了凤覆?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拆魏,失蹤者是張志新(化名)和其女友劉穎盯桦,沒想到半個月后慈俯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡拥峦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年贴膘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片略号。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡刑峡,死狀恐怖,靈堂內的尸體忽然破棺而出玄柠,到底是詐尸還是另有隱情突梦,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布随闪,位于F島的核電站阳似,受9級特大地震影響骚勘,放射性物質發(fā)生泄漏铐伴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一俏讹、第九天 我趴在偏房一處隱蔽的房頂上張望当宴。 院中可真熱鬧,春花似錦泽疆、人聲如沸户矢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梯浪。三九已至,卻和暖如春瓢娜,著一層夾襖步出監(jiān)牢的瞬間挂洛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工眠砾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留虏劲,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓褒颈,卻偏偏與公主長得像柒巫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子谷丸,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理堡掏,服務發(fā)現(xiàn),斷路器刨疼,智...
    卡卡羅2017閱讀 134,660評論 18 139
  • 開頭不得不吐槽下:簡書的markdown編輯器居然不支持目錄索引,非常的坑. 安卓權限概覽安卓的安全和權限架構 安...
    人海中一只羊閱讀 6,922評論 1 17
  • 淅淅瀝瀝的小雨布疼,越下越大摊趾。躺在床上,靜靜的聽游两,雨點兒專為我準備的獨奏砾层。我在想,...
    西北土錘閱讀 487評論 0 0
  • “泰”,好宝踪∏仍悖看卦畫,上輕下重瘩燥,外松內緊秕重。 正本清源,小往大來厉膀,事情就會越來越好溶耘。這叫原應如此。本卦爻辭和“否”卦相...
    童年的流星閱讀 1,288評論 4 4