Android動(dòng)態(tài)權(quán)限分析工具

審核對(duì)數(shù)據(jù)的訪問(wèn)

您可以通過(guò)執(zhí)行數(shù)據(jù)訪問(wèn)審核來(lái)了解您的應(yīng)用及其依賴(lài)項(xiàng)如何訪問(wèn)用戶(hù)的私密數(shù)據(jù)。此流程在搭載 Android 11(API 級(jí)別 30)及更高版本的設(shè)備上可用,可讓您更好地識(shí)別可能出現(xiàn)的意外數(shù)據(jù)訪問(wèn)攀甚。您的應(yīng)用可以注冊(cè) AppOpsManager.OnOpNotedCallback 實(shí)例,該實(shí)例可在每次發(fā)生以下任一事件時(shí)執(zhí)行相應(yīng)操作:

  • 應(yīng)用的代碼訪問(wèn)私密數(shù)據(jù)旦签。為了幫助您確定應(yīng)用的哪個(gè)邏輯部分調(diào)用了事件拾稳,您可以按歸因標(biāo)記審核數(shù)據(jù)訪問(wèn)
  • 依賴(lài)庫(kù)或 SDK 中的代碼訪問(wèn)私密數(shù)據(jù)参淹。

數(shù)據(jù)訪問(wèn)審核是在發(fā)生數(shù)據(jù)請(qǐng)求的線程上調(diào)用的醉锄。這意味著,如果應(yīng)用中的第三方 SDK 或庫(kù)調(diào)用訪問(wèn)私密數(shù)據(jù)的 API浙值,您的 OnOpNotedCallback 可以調(diào)用數(shù)據(jù)訪問(wèn)審核檢查有關(guān)該調(diào)用的信息榆鼠。通常,此回調(diào)對(duì)象可以通過(guò)查看應(yīng)用的當(dāng)前狀態(tài)(例如當(dāng)前線程的堆棧軌跡)以判斷調(diào)用是來(lái)自您的應(yīng)用還是來(lái)自 SDK亥鸠。

記錄數(shù)據(jù)訪問(wèn)

如需使用 AppOpsManager.OnOpNotedCallback 實(shí)例執(zhí)行數(shù)據(jù)訪問(wèn)審核妆够,請(qǐng)?jiān)谀蛩銓徍藬?shù)據(jù)訪問(wèn)的組件中實(shí)現(xiàn)回調(diào)邏輯,例如在某個(gè) Activity 的 onCreate() 方法中负蚊。

注意:如果您的應(yīng)用在多個(gè)組件(例如在前臺(tái)服務(wù)和后臺(tái)任務(wù))中訪問(wèn)數(shù)據(jù)神妹,請(qǐng)創(chuàng)建自定義子類(lèi) Application,并在子類(lèi)的 onCreate() 方法中定義 AppOpsManager.OnOpNotedCallback家妆。

以下代碼段定義了在單個(gè) Activity 中用于審核數(shù)據(jù)訪問(wèn)的 AppOpsManager.OnOpNotedCallback:

@Override
public void onCreate(@Nullable Bundle savedInstanceState,
        @Nullable PersistableBundle persistentState) {
    AppOpsManager.OnOpNotedCallback appOpsCallback =
            new AppOpsManager.OnOpNotedCallback() {
        private void logPrivateDataAccess(String opCode, String trace) {
            Log.i(MY_APP_TAG1

, "Private data accessed. " +
                    "Operation: $opCode\nStack Trace:\n$trace");
        }

        @Override
        public void onNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
            logPrivateDataAccess(syncNotedAppOp.getOp(),
                    Arrays.toString(new Throwable().getStackTrace()));
        }

        @Override
        public void onSelfNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
            logPrivateDataAccess(syncNotedAppOp.getOp(),
                    Arrays.toString(new Throwable().getStackTrace()));
        }

        @Override
        public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncNotedAppOp) {
            logPrivateDataAccess(asyncNotedAppOp.getOp(),
                    asyncNotedAppOp.getMessage());
        }
    };

    AppOpsManager appOpsManager = getSystemService(AppOpsManager.class);
    if (appOpsManager != null) {
        appOpsManager.setOnOpNotedCallback(getMainExecutor(), appOpsCallback);
    }
}

在特定情況下鸵荠,需要調(diào)用 onAsyncNoted()onSelfNoted() 方法:

  • 如果數(shù)據(jù)訪問(wèn)并非發(fā)生在應(yīng)用調(diào)用 API 期間,需要調(diào)用 onAsyncNoted()伤极。最常見(jiàn)的一個(gè)例子就是蛹找,在您的應(yīng)用注冊(cè)了監(jiān)聽(tīng)器后姨伤,每次調(diào)用該監(jiān)聽(tīng)器的回調(diào)時(shí)都會(huì)發(fā)生數(shù)據(jù)訪問(wèn)。

    傳遞到 onAsyncNoted() 中的 AsyncNotedOp 參數(shù)包含名為 getMessage() 的方法庸疾。此方法提供了有關(guān)數(shù)據(jù)訪問(wèn)的詳細(xì)信息乍楚。如果是位置信息回調(diào),該消息將包含監(jiān)聽(tīng)器的系統(tǒng)身份哈希值届慈。

  • 在極少數(shù)情況下徒溪,如果應(yīng)用將自身的 UID 傳遞到 noteOp(),需要調(diào)用 onSelfNoted()金顿。

按歸因標(biāo)記審核數(shù)據(jù)訪問(wèn)

您的應(yīng)用可能有幾種主要用例臊泌,例如允許用戶(hù)拍照并與聯(lián)系人分享這些照片。如果您開(kāi)發(fā)的是一款多用途應(yīng)用揍拆,可以在審核應(yīng)用的數(shù)據(jù)訪問(wèn)時(shí)對(duì)應(yīng)用的各部分使用歸因標(biāo)記渠概。在傳遞到 onNoted() 調(diào)用的對(duì)象中會(huì)返回 attributionTag 上下文。這可以幫助您更輕松地將數(shù)據(jù)訪問(wèn)回溯至代碼的邏輯部分嫂拴。

如需在應(yīng)用中定義歸因標(biāo)記播揪,請(qǐng)完成以下部分中的步驟。

創(chuàng)建歸因標(biāo)記

如果您在某個(gè) Activity 中訪問(wèn)數(shù)據(jù)(例如請(qǐng)求位置信息或訪問(wèn)用戶(hù)的聯(lián)系人列表)顷牌,請(qǐng)?jiān)谠?Activity 的 onCreate() 方法中調(diào)用 createAttributionContext()剪芍,并傳入您希望與應(yīng)用的一部分相關(guān)聯(lián)的歸因標(biāo)記。

以下代碼段展示了如何為應(yīng)用的“照片位置信息分享”部分創(chuàng)建歸因標(biāo)記:

public class SharePhotoLocationActivity extends AppCompatActivity {
    private Context attributionContext;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState,
            @Nullable PersistableBundle persistentState) {
        attributionContext = createAttributionContext("sharePhotos");
    }

    public void getLocation() {
        LocationManager locationManager =
                attributionContext.getSystemService(LocationManager.class);
        if (locationManager != null) {
            // Use "locationManager" to access device location information.
        }
    }
}

在訪問(wèn)日志中包含歸因標(biāo)記

更新您的 AppOpsManager.OnOpNotedCallback 回調(diào)窟蓝,以將您定義的歸因標(biāo)記的名稱(chēng)包含于應(yīng)用的日志中罪裹。

注意:如果歸因標(biāo)記的返回值為 null,意味著當(dāng)前的 Context 對(duì)象與您應(yīng)用的主要部分相關(guān)聯(lián)运挫。

以下代碼段展示了記錄歸因代碼的更新邏輯:

@Override
public void onCreate(@Nullable Bundle savedInstanceState,
        @Nullable PersistableBundle persistentState) {
    AppOpsManager.OnOpNotedCallback appOpsCallback =
            new AppOpsManager.OnOpNotedCallback() {
        private void logPrivateDataAccess(String opCode,
                String attributionTag, String trace) {
            Log.i("MY_APP_TAG", "Private data accessed. " +
                    "Operation: $opCode\n " +
                    "Attribution Tag:$attributionTag\nStack Trace:\n$trace");
        }

        @Override
        public void onNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
            logPrivateDataAccess(syncNotedAppOp.getOp(),
                    syncNotedAppOp.getAttributionTag(),
                    Arrays.toString(new Throwable().getStackTrace()));
        }

        @Override
        public void onSelfNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
            logPrivateDataAccess(syncNotedAppOp.getOp(),
                    syncNotedAppOp.getAttributionTag(),
                    Arrays.toString(new Throwable().getStackTrace()));
        }

        @Override
        public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncNotedAppOp) {
            logPrivateDataAccess(asyncNotedAppOp.getOp(),
                    asyncNotedAppOp.getAttributionTag(),
                    asyncNotedAppOp.getMessage());
        }
    };

    AppOpsManager appOpsManager = getSystemService(AppOpsManager.class);
    if (appOpsManager != null) {
        appOpsManager.setNotedAppOpsCollector(appOpsCollector);
    }
}


資料來(lái)源:https://developer.android.google.cn/guide/topics/data/audit-access#java

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末状共,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子谁帕,更是在濱河造成了極大的恐慌峡继,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匈挖,死亡現(xiàn)場(chǎng)離奇詭異碾牌,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)儡循,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)舶吗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人择膝,你說(shuō)我怎么就攤上這事誓琼。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵腹侣,是天一觀的道長(zhǎng)叔收。 經(jīng)常有香客問(wèn)我,道長(zhǎng)傲隶,這世上最難降的妖魔是什么饺律? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮伦籍,結(jié)果婚禮上蓝晒,老公的妹妹穿的比我還像新娘腮出。我一直安慰自己帖鸦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布胚嘲。 她就那樣靜靜地躺著作儿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪馋劈。 梳的紋絲不亂的頭發(fā)上攻锰,一...
    開(kāi)封第一講書(shū)人閱讀 49,792評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音妓雾,去河邊找鬼娶吞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛械姻,可吹牛的內(nèi)容都是我干的妒蛇。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼楷拳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼绣夺!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起欢揖,我...
    開(kāi)封第一講書(shū)人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤陶耍,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后她混,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體烈钞,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年坤按,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了毯欣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晋涣,死狀恐怖仪媒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤算吩,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布留凭,位于F島的核電站,受9級(jí)特大地震影響偎巢,放射性物質(zhì)發(fā)生泄漏蔼夜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一压昼、第九天 我趴在偏房一處隱蔽的房頂上張望求冷。 院中可真熱鬧,春花似錦窍霞、人聲如沸匠题。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)韭山。三九已至,卻和暖如春冷溃,著一層夾襖步出監(jiān)牢的瞬間钱磅,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工似枕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盖淡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓凿歼,卻偏偏與公主長(zhǎng)得像褪迟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子毅往,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容