Android端權(quán)限隱私的合規(guī)化處理實戰(zhàn)記錄
是什么
對客戶端而言,權(quán)限隱私可分為權(quán)限和隱私兩個大的方面。
- 權(quán)限為用戶通過app內(nèi)彈窗設(shè)置或者手機設(shè)置內(nèi)對應(yīng)app的權(quán)限設(shè)置方式給予對應(yīng)app相應(yīng)的權(quán)限,如電話權(quán)限,定位權(quán)限,相機權(quán)限等,本文主要集中介紹隱私相關(guān)的權(quán)限部分。
- 隱私為app使用過程中與用戶個人相關(guān)的個人信息,如所在位置,Mac地址,設(shè)備id等。就Android端而言,多數(shù)隱私信息需要對應(yīng)授權(quán)后才能獲取,但目前仍存在部分隱私信息無需授權(quán)就可以拿到的。
為什么
- 大眾隱私意識覺醒,權(quán)限隱私安全性差會直接導(dǎo)致用戶不愿使用;
- 日趨嚴格的權(quán)限治理和隱私安全治理,工信部和市場的嚴格管控;
- 客戶端作為與用戶最直接的交互信息收集入口,有義務(wù)合規(guī)化的收集和使用用戶信息。
具體實踐
一.Android各版本對權(quán)限的適配處理
1.1 早期的注冊權(quán)限
Android6.0(SDK版本為23)之前的版本,安裝App頁面會列出當(dāng)前app所注冊的所有權(quán)限,無同意與否按鈕,只有安裝和取消,開發(fā)App時只需要在清單文件中注冊所需的對應(yīng)權(quán)限即可:
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.CAMERA" />
1.2 動態(tài)權(quán)限授予
Android自6.0(SDK版本為23)開始,將權(quán)限分為普通權(quán)限,危險權(quán)限,特殊權(quán)限。而其中的危險權(quán)限需要在調(diào)用某些系統(tǒng)方法之前需要用戶手動授予對應(yīng)權(quán)限,包括PHONE,LOCATION,STORAGE等多個權(quán)限組。如果在沒授權(quán)的情況下直接調(diào)用相關(guān)方法,就會拋出,應(yīng)用也隨之崩潰。報錯信息類似下方這種:
java.lang.SecurityException: getDeviceId: has android.permission.READ_PHONE_STATE.
而要解決以上的報錯問題,可以自行封裝權(quán)限處理類工具,也可使用一些開源的權(quán)限工具進行處理。核心代碼都逃不過:
//判斷某個權(quán)限是否已經(jīng)被同意 ContextCompat.checkSelfPermission(context, perm) == PackageManager.PERMISSION_GRANTED) //請求某個權(quán)限,調(diào)用后會彈出權(quán)限系統(tǒng)彈窗 ActivityCompat.requestPermissions((Activity) object, perms, requestCode);
注:如果用戶拒絕權(quán)限且不讓再次顯示系統(tǒng)權(quán)限授權(quán)彈窗的話,最好是提供端內(nèi)可點擊進入手機系統(tǒng)的權(quán)限設(shè)置頁面以讓用戶可以選擇開啟對應(yīng)權(quán)限。
1.3 READ_PHONE_STATE權(quán)限的變化
1.3.1 演變
- READ_PHONE_STATE權(quán)限是允許訪問電話狀態(tài)權(quán)限,此權(quán)限主要集中在TelephonyManager類中,控制對imei,deviceId,Meid,SimSerialNumber等id和其他手機狀態(tài)的獲取。而多數(shù)app都會單獨引用或者組合引用這些字段作為設(shè)備唯一碼來標識用戶設(shè)備,進而服務(wù)端進行數(shù)據(jù)分析,下發(fā)等操作。在6.0之前只需注冊后就可以使用。
- 在Android6.0之后,READ_PHONE_STATE權(quán)限變?yōu)槲kU權(quán)限,需要用戶主動授權(quán)后方可使用,故部分App處理的操作為必須授權(quán)該權(quán)限后才允許使用App,不授權(quán)的話就退出應(yīng)用。這顯然不是一個很好的解決方式,但在過渡階段還是能有一定效果的??梢灶A(yù)留出時間重新定義在未授權(quán)情況下如何標識特定設(shè)備。
- 在適配Android10.0之后,READ_PHONE_STATE權(quán)限直接被取消掉了,換成了系統(tǒng)權(quán)限READ_PRIVILEGED_PHONE_STATE,此權(quán)限只能在系統(tǒng)App中才可以被使用。而如果代碼處理上仍使用READ_PHONE_STATE權(quán)限進行授權(quán)的話,手機上不會再彈出同樣的權(quán)限授予彈窗了,此時如果仍調(diào)用getDeviceId方法,會直接拋出SecurityException。源碼上的可以體現(xiàn)在對應(yīng)方法的注解上:
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceId() @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getImei()
1.3.2 適配處理
清單文件中設(shè)定使用READ_PHONE_STATE權(quán)限最高為28,即Android10以上的設(shè)備不進行該權(quán)限的獲取。
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
android:maxSdkVersion="28"/>
- 在調(diào)用getDeviceId,getImei等方法之前增加當(dāng)前設(shè)備Android版本的判斷Build.VERSION.SDK_INT < Build.VERSION_CODES.Q,能有效避免調(diào)用這些方法導(dǎo)致的崩潰問題。
- 由于Android10.0以上手機獲取不到這些id,對國內(nèi)廣告的精準推送也都產(chǎn)生了一定的影響,故各大產(chǎn)商聯(lián)盟推出了OAID的標識,本意是用于廣告精準推送,但目前也不失作為客戶端App唯一標識的一種選擇。具體獲取方式參考聯(lián)盟的集成文檔即可。
1.4 存儲分區(qū)的處理
自Android10.0之后,Google開始采用存儲分區(qū),主要目的是改變現(xiàn)有App胡亂使用手機存儲導(dǎo)致垃圾和其他安全問題。適配 Android11 后強制使用存儲分區(qū)。具體分區(qū)如下,擴展的外部存儲是無權(quán)限進行讀取的。而其他私有存儲會在App卸載后清理掉:

具體部分代碼改動如下:
1.拍照存儲路徑:
Environment.getExternalStorageDirectory().getAbsolutePath()修改為getExternalFilesDir(Environment.DIRECTORY_DCIM);
2.原本的存儲路徑 /storage/emulated/0 改為 /storage/emulated/0/Android/data
具體調(diào)用的修改為:
Environment.getExternalStorageDirectory()改為context.getExternalFilesDir() ;
3.如果App在sdcard中有重要存儲,可以在適配android10.0的過渡階段將之前的數(shù)據(jù)復(fù)制出來到新的存儲分區(qū)中。
二.隱私信息合規(guī)化處理
上半部分較為粗略的過了一下權(quán)限相關(guān)的部分改動和對應(yīng)修改,接下來說一說隱私信息的合規(guī)化處理。當(dāng)然,權(quán)限作為隱私處理的前提,如果權(quán)限都沒有合理的修改完畢,那隱私處理合規(guī)化更談不上了,畢竟很多隱私是依賴于權(quán)限的。
2.1 隱私信息獲取告知的直接化和透明化
- 在首次打開App時,需要在進行初始化之前就向用戶展示用戶協(xié)議與隱私保護彈窗或頁面,只有用戶在同意之后才能進入App進行使用。而對于手機號、MAC地址、IMEI、所在位置信息、手機存儲權(quán)限、相冊訪問權(quán)限,手機流量使用等敏感信息需要讓用戶在第一屏就能夠看到。并且提供用戶協(xié)議和隱私政策鏈接,能讓用戶點擊后查看具體詳細的條款。設(shè)計完成后要讓法務(wù)進行確認,是否符合。
- 在處理1.2中的動態(tài)權(quán)限時,需要在系統(tǒng)彈窗中或者之前說明需要用戶授予該權(quán)限的原因。如:獲取定位權(quán)限之前需要告知用戶該權(quán)限是為了獲取定位信息,然后精準推送相關(guān)內(nèi)容。獲取相機權(quán)限是為了要使用攝像頭進行拍照。
- 在進入App操作三步以內(nèi)能看到法律條款和隱私政策入口,正常處理方式會在App的設(shè)置頁內(nèi)加上對應(yīng)入口。同時在注冊登錄頁面,需要明顯展示出法律條款和隱私條款入口,且需要默認不勾選,需要用戶主動同意后才能進行賬號注冊和登錄。如下圖:

- 分發(fā)廣告的App需要注意處理廣告下載邏輯,在用戶點擊后需要展示所下載App的信息,所需的權(quán)限和隱私條款,讓用戶清楚的知道下載的App是否是自己想要的,且不允許自動下載。這樣能很好的解決用戶無意識的在手機上下載了很多無用App,這對很多老年人使用手機很有幫助。
2.2 隱私信息獲取和傳輸?shù)陌踩?br />
- 避免頻繁的調(diào)用系統(tǒng)方法獲取隱私信息,可以在單次啟動App調(diào)用該獲取數(shù)據(jù)后使用全局變量進行緩存,之后每次使用時直接調(diào)用全局變量使用就行,不必每次都調(diào)用系統(tǒng)方法。包括getDeviceId,getMacAddress等。
- 諸如imei,mac,定位的經(jīng)緯度等敏感信息,需要避免多次在網(wǎng)絡(luò)中傳輸,可以處理為單獨接口收集相關(guān)信息一次后保存在服務(wù)端即可,無需每次傳輸;另外需要避免以明文的方式在數(shù)據(jù)接口中傳輸。像imei可以通過MD5加密算法進行加密處理,并不會影響用戶的區(qū)分;
- 由于READ_PHONE_STATE權(quán)限升級為了系統(tǒng)權(quán)限READ_PRIVILEGED_PHONE_STATE,部分通過native方式(C代碼)直接調(diào)用imei等信息時也會報錯或者為空。建議這部分盡量使用java方式調(diào)用,如果有變動可以明顯的感知到錯誤并修改,不至于需要重新修改C代碼,然后又進行jni編譯。
2.3 部分隱私Api調(diào)用的嚴格化
- 在未授權(quán)的情況下,需要保證App中與該權(quán)限無關(guān)聯(lián)的功能可以正常使用。所以就不能簡單的處理為1.3.1中提到的不給權(quán)限就不讓使用App的方案了。
- Android端目前尚存在部分無需動態(tài)授權(quán)就可以獲取的隱私,如用戶手機上的應(yīng)用安裝列表。此信息可用于分析用戶喜好,如小說類產(chǎn)品還是視頻類產(chǎn)品;也可以用于分析用戶某些App還未安裝,便于推送廣告的拉新。但目前國內(nèi)市場已經(jīng)開始治理,如果存在獲取手機內(nèi)應(yīng)用列表的情況,會進行下架處理或者不予上架。
- 目前工信部和各應(yīng)用市場對App上架要求嚴格,使用第三方檢測工具可以很細致的檢測出App中存在哪些不合理的系統(tǒng)方法調(diào)用,比如:在未同意協(xié)議與隱私之前就進行了網(wǎng)絡(luò)請求;在未同意協(xié)議與隱私之前獲取了Mac地址;在未獲取定位權(quán)限的情況下就獲取了手機的基站信息。
三.遇到的一些問題和坑
這里總結(jié)部分在開發(fā)過程中遇到的一些隱蔽小點,希望能幫助到大家。
- 早期的騰訊X5內(nèi)核會在隱私協(xié)議展示時就會獲取mac地址,如下圖??蓢L試更新到新的版本繼續(xù)查看。由于我方對X5內(nèi)核需求不高,所以直接進行了刪除清理。

- 集成開源庫或者第三方sdk的初始化均需要處理為同意隱私之后再進行,大多數(shù)sdk在初始化時都會調(diào)用相關(guān)無需授權(quán)的api方法。如語音相關(guān)的訊飛sdk會在初始化的時候調(diào)用MAC地址信息。
- 部分統(tǒng)計庫如umeng,talkingdata sdk需要升級到新版本的接入方式。老版本的talkingdata sdk在尚未授定位權(quán)限時進行初始化仍會調(diào)用手機基站信息api(屬于定位)。
- 自有代碼邏輯中相關(guān)隱私信息的獲取和賦值,也都要放到隱私同意之后去進行,故在用戶協(xié)議和隱私同意之前盡量少的進行代碼邏輯處理。
總結(jié)
權(quán)限隱私的發(fā)展趨勢只會越來越嚴格和規(guī)范。在日常的客戶端開發(fā)當(dāng)中,我們就需要時刻持有隱私安全的意識,讓自己站在用戶的角度上合理的保證隱私安全。并緊跟隱私安全的發(fā)展,提前布局。這樣才能不至于臨時出問題后手忙腳亂的去處理。
到此這篇關(guān)于Android端權(quán)限隱私合規(guī)化處理的文章就介紹到這了,更多相關(guān)Android端權(quán)限隱私合規(guī)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android利用SpannableString實現(xiàn)格式化微博內(nèi)容
這篇文章主要介紹了Android利用SpannableString實現(xiàn)格式化微博內(nèi)容的相關(guān)資料,文中介紹的非常詳細,對大家具有一定的參考借鑒價值,需要的朋友們下面來一起看看吧。2017-03-03
Android橫豎屏切換及其對應(yīng)布局加載問題詳解
這篇文章主要為大家詳細介紹了Android橫豎屏切換及其對應(yīng)布局加載問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
Android自定義View實現(xiàn)微信支付密碼輸入框
這篇文章主要為大家詳細介紹了Android自定義View實現(xiàn)微信支付密碼輸入框,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-06-06
Android開發(fā)之獲取LayoutInflater對象的方法總結(jié)
這篇文章主要介紹了Android開發(fā)之獲取LayoutInflater對象的方法,結(jié)合實例形式總結(jié)分析了Android獲取LayoutInflater對象的常用技巧,需要的朋友可以參考下2016-02-02
關(guān)于Android Device Monitor 無法打開問題
大家好,本篇文章主要講的是關(guān)于Android Device Monitor 無法打開問題,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-01-01

