Android 之UID and PID
轉(zhuǎn)自http://www.cnblogs.com/awkflf11/articles/5232275.html
在開(kāi)發(fā)中遇到這樣一個(gè)問(wèn)題:
安裝任意第三方的一個(gè)apk,恢復(fù)出廠設(shè)置,再次安裝相同的apk,提示安裝失敗,通過(guò)打印LOG發(fā)現(xiàn),安裝失敗的錯(cuò)誤反回值是24,public static final int INSTALL_FAILED_UID_CHANGED = -24 ; 進(jìn)一步跟蹤發(fā)現(xiàn),在恢復(fù)出廠設(shè)置后/data/data目錄下的第三方應(yīng)用的文件夾還在,手動(dòng)刪除此文件后再次安裝就會(huì)成功,按正常邏輯恢復(fù)出廠設(shè)置后應(yīng)該清除系統(tǒng)所有數(shù)據(jù)文件(包括第三方應(yīng)用的一切都被清除才對(duì))。
問(wèn)題原因:恢復(fù)出廠設(shè)置后改變了之前安裝第三方應(yīng)用的UID,導(dǎo)致安裝失敗
疑問(wèn)就出來(lái)了,Android中的UID是什么?每個(gè)應(yīng)用的UIDD是否相同?UID是如何生成的?
所以就在網(wǎng)上找了找,以下信息解決了我的疑惑:
我們經(jīng)常在一個(gè)activity中去start另一個(gè)activity,或者與另一個(gè)acitivity的結(jié)果進(jìn)行交互(startActivityForResult)。但有沒(méi)有想過(guò)可能會(huì)出現(xiàn)的permission問(wèn)題呢?如果你遇到了permission denial的Exception,那么你需要讀讀這篇文章啦。
我們?cè)谕粋€(gè)application內(nèi)部,可以隨意的startActivity from Activity A to Activity B,而官方的文檔中說(shuō)startActivity可能會(huì)報(bào)NotFoundException,表示被start的Activity不存在。因此,我們很容易忽略另一個(gè)可能的Exception,Permission Denial。
當(dāng)我們?cè)诓煌腶pplication中,如application A中的Activity去start一個(gè)application B中的Activity,也許你什么Exception都不會(huì)得到,也可能會(huì)直接Force Close掉。因?yàn)樵賁tart Activity時(shí),代碼是有去檢驗(yàn)permission的。
如下情況,可以成功startActivity而不會(huì)得到permission denial
1、同一個(gè)application下
2、Uid相同
3、permission匹配
4、目標(biāo)Activity的屬性Android:exported=”true”
5、目標(biāo)Activity具有相應(yīng)的IntentFilter,存在Action動(dòng)作或其他過(guò)濾器并且沒(méi)有設(shè)置exported=false
6、啟動(dòng)者的Pid是一個(gè)System Server的Pid
7、啟動(dòng)者的Uid是一個(gè)System Uid(Android規(guī)定android.system.uid=1000,具有該Uid的application,我們稱之為獲得Root權(quán)限)
如果上述調(diào)節(jié),滿足一條,一般即可(與其他幾條不發(fā)生強(qiáng)制設(shè)置沖突),否則,將會(huì)得到Permission Denial的Exception而導(dǎo)致Force Close。
現(xiàn)在,我來(lái)解釋一下Uid機(jī)制
眾所周知,Pid是進(jìn)程ID,Uid是用戶ID,只是Android和計(jì)算機(jī)不一樣,計(jì)算機(jī)每個(gè)用戶都具有一個(gè)Uid,哪個(gè)用戶start的程序,這個(gè)程序的Uid就是那個(gè)那個(gè)用戶,而Android中每個(gè)程序都有一個(gè)Uid,默認(rèn)情況下,Android會(huì)給每個(gè)程序分配一個(gè)普通級(jí)別互不相同的 Uid,如果用互相調(diào)用,只能是Uid相同才行,這就使得共享數(shù)據(jù)具有了一定安全性,每個(gè)軟件之間是不能隨意獲得數(shù)據(jù)的。而同一個(gè)application 只有一個(gè)Uid,所以application下的Activity之間不存在訪問(wèn)權(quán)限的問(wèn)題。
如果你需要做一個(gè)application,將某些服務(wù)service,provider或者activity等的數(shù)據(jù),共享出來(lái)怎么辦,三個(gè)辦法。
1、完全暴露,這就是android:exported=”true”的作用,而一旦設(shè)置了intentFilter之后,exported就默認(rèn)被設(shè)置為true了,除非再?gòu)?qiáng)制設(shè)為false。當(dāng)然,對(duì)那些沒(méi)有intentFilter的程序體,它的exported屬性默認(rèn)仍然是false,也就不能共享出去。
2、權(quán)限提示暴露,這就是為什么經(jīng)常要設(shè)置usePermission的原因,如果人家設(shè)置了 android:permission=”xxx.xxx.xx”那么,你就必須在你的application的Manufest中 usepermission xxx.xxx.xx才能訪問(wèn)人家的東西。
3、私有暴露,假如說(shuō)一個(gè)公司做了兩個(gè)產(chǎn)品,只想這兩個(gè)產(chǎn)品之間可互相調(diào)用,那么這個(gè)時(shí)候就必須使用shareUserID將兩個(gè)軟件的Uid強(qiáng)制設(shè)置為一樣的。這種情況下必須使用具有該公司簽名的簽名文檔才能,如果使用一個(gè)系統(tǒng)自帶軟件的ShareUID,例如Contact,那么無(wú)須第三方簽名。
這種方式保護(hù)了第三方軟件公司的利益于數(shù)據(jù)安全。
當(dāng)然如果一個(gè)activity是又system process跑出來(lái)的,那么它就可以橫行霸道,任意權(quán)限,只是你無(wú)法開(kāi)發(fā)一個(gè)第三方application具有系統(tǒng)的Pid(系統(tǒng)Pid不固定),但是你完全可以開(kāi)發(fā)一個(gè)具有系統(tǒng)Uid的程序,對(duì)系統(tǒng)中的所有程序任意訪問(wèn),只需再M(fèi)anufest中聲明shareUserId為 android.system.uid即可,生成的文件也必須經(jīng)過(guò)高權(quán)限簽名才行,一般不具備這種審核條件的application,google不會(huì)提供給你這樣的簽名文件。當(dāng)然你是在編譯自己的系統(tǒng)的話,想把它作成系統(tǒng)軟件程序,只需在Android.mk中聲明 Certificate:platform則可以了,既采用系統(tǒng)簽名。這個(gè)系統(tǒng)Uid的獲得過(guò)程,我們把它叫做獲得Root權(quán)限的過(guò)程。所以很多第三方系統(tǒng)管理軟件就是有Root權(quán)限的軟件,因?yàn)樗枰獙?duì)系統(tǒng)有任意訪問(wèn)的權(quán)限。那么它的Root簽名則需要和編譯的系統(tǒng)一致,例如官方的系統(tǒng)得用官方的簽名文件,CM的系統(tǒng)就得用CM的簽名文件。
再附上Android中安裝應(yīng)用失敗的25種原因:
????已經(jīng)安裝。
????public static final int INSTALL_FAILED_ALREADY_EXISTS = -1 ;
????APK文件是無(wú)效的。
????public static final int INSTALL_FAILED_INVALID_APK = -2 ;
????所傳遞的URI是無(wú)效的。
????public static final int INSTALL_FAILED_INVALID_URI = -3 ;
????設(shè)備沒(méi)有足夠的存儲(chǔ)空間來(lái)安裝應(yīng)用程序。
????public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4 ;
????包已經(jīng)具有相同名稱的安裝。
????public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5 ;
????請(qǐng)求共享的用戶不存在。
????public static final int INSTALL_FAILED_NO_SHARED_USER = -6 ;
????與先前安裝的軟件包同名,但有不同的簽名。
????public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7 ;
????對(duì)已經(jīng)安裝了共享用戶的設(shè)備,不具有匹配的簽名。
????public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8 ;
????新包裝采用的共享庫(kù),無(wú)法使用。
????public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9 ;
????新包裝采用的是共享庫(kù),無(wú)法使用。
????public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10 ;
????優(yōu)化并驗(yàn)證它的dex文件的新包失敗,是因?yàn)闆](méi)有足夠的存儲(chǔ)空間或驗(yàn)證失敗。
????public static final int INSTALL_FAILED_DEXOPT = -11 ;
????因?yàn)楫?dāng)前的SDK版本低于程序包所需要的。
????public static final int INSTALL_FAILED_OLDER_SDK = -12 ;
????新包失敗,因?yàn)樗伺c已經(jīng)安裝在系統(tǒng)中內(nèi)容提供者(Content Provider)同等的授權(quán)。
????public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13 ;
????新包失敗,因?yàn)楫?dāng)前的SDK版本比新
????public static final int INSTALL_FAILED_NEWER_SDK = -14 ;
????新包失敗,因?yàn)樗呀?jīng)指定,它是一個(gè)測(cè)試,只
????public static final int INSTALL_FAILED_TEST_ONLY = -15 ;
????如果要安裝的軟件包包含本地代碼,但沒(méi)有一樣是與設(shè)備的CPU_ABI兼容。
????public static final int INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16 ;
????如果新的包使用功能不可用。
????public static final int INSTALL_FAILED_MISSING_FEATURE = -17 ;
????一個(gè)安全容器裝載點(diǎn)不能在外部媒體訪問(wèn)。
????public static final int INSTALL_FAILED_CONTAINER_ERROR = -18 ;
????新的軟件包無(wú)法安裝在指定的安裝位置。
????public static final int INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19 ;
????新的軟件包無(wú)法安裝在指定的安裝位置,因?yàn)槊襟w不可用。
????public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20 ;
????新的軟件包無(wú)法安裝,因?yàn)轵?yàn)證超時(shí)。
????public static final int INSTALL_FAILED_VERIFICATION_TIMEOUT = -21 ;
????新的軟件包無(wú)法安裝,因?yàn)轵?yàn)證沒(méi)有成功。
????public static final int INSTALL_FAILED_VERIFICATION_FAILURE = -22 ;
????調(diào)用程序預(yù)期調(diào)用的包裝改變了。
????public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23 ;
????新的包被分配一個(gè)不同的UID比它先前的。
????public static final int INSTALL_FAILED_UID_CHANGED = -24 ;
????新包具有比目前安裝的軟件包的較舊版本的代碼。
????public static final int INSTALL_FAILED_VERSION_DOWNGRADE = -25 ;
轉(zhuǎn)載于:https://www.cnblogs.com/xiayexingkong/p/6769313.html
總結(jié)
以上是生活随笔為你收集整理的Android 之UID and PID的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: tensorflow 的 Batch N
- 下一篇: Android NDK 编译选项设置[z