Android 跨應(yīng)用調(diào)用組件與Uid機制

引言:本篇文章主要說明四大組件與Application間調(diào)用的一些條件注意點膳凝,包括Activity火的、Service等組件能夠被外界訪問的條件等。關(guān)于四大組件特別是Service对雪、ContentProvider和BroadcastReceiver需要注意的地方,可以查看本人另一篇文章:查漏補缺(三):重溫Service米绕、BoardcastReceiver和ContentProvider瑟捣。至于為什么沒有細講Activity,因為看過Activity生命周期以及其啟動方式的讀者對于Activity已經(jīng)比較熟悉了栅干,這里重點是講講一些細節(jié)上的東西迈套。

一、問題描述

  1. 在開發(fā)一個App過程中碱鳞,activityA通過Intent啟動activityB桑李,有顯式啟動和隱式啟動兩種方式,而官方的文檔中說startActivity可能會報NotFoundException,表示被start的Activity不存在贵白。因此率拒,我們很容易忽略另一個可能的Exception,Permission Denial禁荒。
  2. 開發(fā)多個App時俏橘,想要讓AppB去調(diào)用AppA中的Activity(如:startActivity()方式),也許你什么Exception都不會得到圈浇,也可能會直接Force Close掉寥掐。

二呻拌、問題原因

因為Start Activity時费奸,代碼是有去檢驗permission的。

如下情況蚕脏,可以成功startActivity而不會得到permission denial

  1. 同一個application下
  2. Uid相同
  3. permission匹配
  4. 目標Activity的屬性Android:exported=”true”
  5. 目標Activity具有相應(yīng)的IntentFilter褐隆,存在Action動作或其他過濾器并且沒有設(shè)置exported=false
  6. 啟動者的Pid是一個系統(tǒng)服務(wù)(System Server)的Pid【也就是系統(tǒng)服務(wù)前來調(diào)用普通App的Activity等】
  7. 啟動者的Uid是一個System Uid(Android規(guī)定android.system.uid=1000污它,具有該Uid的application,我們稱之為獲得Root權(quán)限)

如果上述調(diào)節(jié)庶弃,滿足一條衫贬,一般即可(與其他幾條不發(fā)生強制設(shè)置沖突),否則歇攻,將會得到Permission Denial的Exception而導致Force Close固惯。

三、Uid機制

我們知道缴守,Pid表示<u>進程ID</u>葬毫,Uid表示<u>用戶ID</u>,只是Android和計算機不一樣屡穗,計算機每個用戶都具有一個Uid贴捡,哪個用戶start的程序,這個程序的Uid就是那個那個用戶村砂,而Android中每個程序都有一個Uid烂斋,默認情況下,Android會給每個程序分配一個<u>普通級別互不相同的Uid</u>础废,如果用互相調(diào)用汛骂,只能是Uid相同才行,這就使得共享數(shù)據(jù)具有了一定安全性色迂,每個軟件之間是不能隨意獲得數(shù)據(jù)的香缺。而同一個application只有一個Uid,所以application下的Activity之間不存在訪問權(quán)限的問題歇僧。

讓你的App將它里面含有的某些activity图张、service锋拖、provider等的數(shù)據(jù)進行共享

  • 法一:完全暴露。這就是android:exported=”true”的作用祸轮,而一旦設(shè)置了intentFilter之后兽埃,exported就默認被設(shè)置為true了,除非再強制設(shè)為false适袜。當然柄错,對那些沒有intentFilter的程序體,它的exported屬性默認仍然是false苦酱,也就不能共享出去售貌。

  • 法二:權(quán)限提示暴露。這就是為什么經(jīng)常要設(shè)置<uses-permission name="xxxxx"/>的原因疫萤,如果人家設(shè)置了android:permission=”xxx.xxx.xx”那么颂跨,你就必須在你的App的AndroidManifast.xml中uses-permission xxx.xxx.xx才能訪問人家的東西〕度模【下面以自定義權(quán)限的用法來作為示例恒削,而關(guān)于系統(tǒng)權(quán)限大全,可以查看本人的另一篇文章:Android字典(一) -- permission權(quán)限說明尾序〉龇幔】

    • <permission>格式
<!--自定義權(quán)限格式-->
<permission android:description="string resource"  //權(quán)限描述(描述權(quán)限)
          android:icon="drawable resource"  //權(quán)限圖標(描述權(quán)限)
          android:label="string resource"  ///權(quán)限標簽(描述權(quán)限)
          android:name="string"  //權(quán)限名稱(描述權(quán)限)
          android:permissionGroup="string"
         //權(quán)限組。此屬性是可選的每币,被用于協(xié)助系統(tǒng)向用戶顯示權(quán)限携丁,一般會像(`android:permissionGroup="android.permission-group.SYSTEM_TOOLS" `)這個一樣設(shè)置為標準系統(tǒng)組,很少自定義脯爪,最好使用已經(jīng)定義的则北,使用起來也方便。
          android:protectionLevel=["normal" | "dangerous" | "signature" | "signatureOrSystem"]
         //權(quán)限級別痕慢。必須聲明,用于告訴系統(tǒng)當前應(yīng)用進行訪問控制涌矢,例如對于:如網(wǎng)絡(luò)訪問(需付費)以及獲取聯(lián)系人(涉及隱私)等掖举。
         //normal:低風險權(quán)限,只要申請了就可以使用(在AndroidManifest.xml中添加<uses-permission>標簽)娜庇,安裝時不需要用戶確認塔次;
         //dangerous:高風險權(quán)限,安裝時需要用戶的確認才可使用名秀;
         //signature:只有當申請權(quán)限的應(yīng)用程序的數(shù)字簽名與聲明此權(quán)限的應(yīng)用程序的數(shù)字簽名相同時(如果是申請系統(tǒng)權(quán)限励负,則需要與系統(tǒng)簽名相同),才能將權(quán)限授給它匕得;
         //signatureOrSystem:簽名相同继榆,或者申請權(quán)限的應(yīng)用為系統(tǒng)應(yīng)用(在system image中)巾表。
/>
* 用法步驟:
  首先在App中的androidManifast.xml文件中`<application>`標簽內(nèi)部定義了自己的`<permission>`,然后在`<application>`標簽之外使用`<uses-permission>`來聲明需要的權(quán)限略吨,再讓自己的`<activity>`或者`<receiver>`等組件添加上`android:permission="你剛剛自定義的權(quán)限名稱"`來使你的組件擁有被調(diào)用時檢測對方App有沒有相應(yīng)權(quán)限的能力集币。
  • 法三:私有暴露。使用sharedUserId翠忠。在Android里面每個app都有一個唯一的linux user ID鞠苟,則這樣權(quán)限就被設(shè)置成該應(yīng)用程序的文件只對該用戶可見,只對該應(yīng)用程序自身可見秽之,而我們可以使他們對其他的應(yīng)用程序可見当娱,這會使我們用到SharedUserId,也就是讓兩個apk使用相同的userID考榨,這樣它們就可以看到對方的文件跨细。為了節(jié)省資源,具有相同ID的apk也可以在相同的linux進程中進行(注意董虱,并不是一定要在一個進程里面運行)扼鞋,共享一個虛擬機。
    ??假如說一個公司做了兩個產(chǎn)品愤诱,只想這兩個產(chǎn)品之間可互相調(diào)用云头,那么這個時候就必須使用shareUserID將兩個軟件的Uid強制設(shè)置為一樣的。這種情況下必須使用具有該公司簽名的簽名文檔才能淫半,如果使用一個系統(tǒng)自帶軟件的ShareUID溃槐,例如Contact,那么無須第三方簽名科吭。
    • 一般用法步驟:
      1. 第一個應(yīng)用程序為的menifest文件代碼如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.abc.serviceID"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="com.abc.share">
//.......
2. 第二個應(yīng)用程序的menifest文件代碼如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.abc.clientID"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="com.abc.share">

      3. 假設(shè)我們從package=“com.abc.clientID”的程序獲取package="com.abc.serviceID"的程序的context:
      ```
Context context=this.createPackageContext("com.abc.serviceID",Context.CONTEXT_IGNORE_SECURITY);
      ```


#### Uid機制的意義在于:應(yīng)用程序獲得系統(tǒng)權(quán)限 

   ?如果一個activity是由system process跑出來的昏滴,那么它就可以橫行霸道,任意權(quán)限对人,只是你無法開發(fā)一個第三方application具有系統(tǒng)的Pid(系統(tǒng)Pid不固定)谣殊,但是你<u>完全可以開發(fā)一個具有系統(tǒng)Uid的程序,對系統(tǒng)中的所有程序任意訪問牺弄,只需在AndroidManifest.xml中聲明shareUserId為`android.uid.system`即可姻几,生成的文件也必須經(jīng)過高權(quán)限簽名才行,一般不具備這種審核條件的application势告,google不會提供給你這樣的簽名文件蛇捌。當然你是在編譯自己的系統(tǒng)的話,想把它作成系統(tǒng)軟件程序咱台,只需在Android.mk中聲明Certificate:platform則可以了络拌,既采用系統(tǒng)簽名。</u>這個系統(tǒng)Uid的獲得過程回溺,我們把它叫做獲得Root權(quán)限的過程春贸。所以很多第三方系統(tǒng)管理軟件就是有Root權(quán)限的軟件混萝,因為他需要對系統(tǒng)有任意訪問的權(quán)限。那么它的Root簽名則需要和編譯的系統(tǒng)一致祥诽,例如官方的系統(tǒng)得用官方的簽名文件譬圣,CM的系統(tǒng)就得用CM的簽名文件。至于Android.mk文件以及相關(guān)配置等雄坪,可以參考下http://dengzhangtao.iteye.com/blog/1750782 厘熟,http://blog.sina.com.cn/s/blog_628cc2b70101dcai.html

#### 拓展:Android整個permission機制
?AndroidManifest.xml里面的sharedUserID能夠讓不同的apk運行在同一個進程里,分享里面的數(shù)據(jù)维哈,比如Contacts等绳姨,當然這個sharedUserID可以設(shè)置成“android.uid.system”就可以運行在系統(tǒng)進程中,有權(quán)修改系統(tǒng)數(shù)據(jù)阔挠。
?但僅僅有著一個sharedUserID并不能夠保證你的apk一定能運行成功飘庄,怎么辦?簽名啊购撼。如果你有Android的源碼就比較方便了跪削,直接把Android.mk里面的LOCAL_CERTIFICATE 賦值為platform就行了。然后mm編輯迂求,就能安裝了碾盐。因為在安裝的時候,PackageManager會檢查揩局,如果sharedUserId是system的毫玖,它會看這個apk的簽名是不是system.crt,如果不是凌盯,會報出permission deny的error付枫。而把LOCAL_CERTIFICATE改成platform就等于給APK簽名。
?進而可以通過這個問題研究一下整個Android permission的機制驰怎。系統(tǒng)的安全機制通過給每個用戶分配單獨的uid和gid來實現(xiàn)阐滩,Android系統(tǒng)中pid代表進程ID,這個是有系統(tǒng)在程序運行時分配的县忌,這一點可以防止地址空間的數(shù)據(jù)共享叶眉,增強內(nèi)存空間的安全性。對于外部則用到了uid進行封鎖芹枷。
?系統(tǒng)會給于用戶進程單獨的uid,當然系統(tǒng)也是要運行進程的莲趣,比如System鸳慈,Radio,藍牙喧伞,IO設(shè)備走芋。系統(tǒng)中的init.rc文件會詳細定義這些文件的權(quán)限绩郎。Android中對uid的定義是Root最高,其次是system翁逞,最低的是app肋杖。這是基于Linux系統(tǒng)的結(jié)果。
?那么在APP里挖函,要對一些進程進行訪問状植,或者接受Broadcast,或者啟動Activity怨喘、Service都是需要權(quán)限的津畸,不能說你的app什么都能做,這也是需要在manifest file中設(shè)置的必怜。
?比如在startActivity時肉拓,如果你start自己apk里的activity,它們會在同一個application下梳庆,那么自然也就使用一個uid暖途,start過程自然沒有什么問題。如果你需要start別人寫的Activity或者service膏执,都需要用到同一個shareUserId才行驻售,因為在ActivityManagerService要啟動activity的之前,會首先檢查uid胧后,用checkPermission方法芋浮,透過binder獲得pid和uid,檢查你activity的binder的權(quán)限壳快,如果你有權(quán)限則已纸巷,沒權(quán)限的話就會拋出security exception。至于broadcast眶痰,檢查則更為嚴格瘤旨,會雙向的檢查發(fā)出者和接受者的權(quán)限。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末竖伯,一起剝皮案震驚了整個濱河市存哲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌七婴,老刑警劉巖祟偷,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異打厘,居然都是意外死亡修肠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門户盯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嵌施,“玉大人饲化,你說我怎么就攤上這事÷鹕耍” “怎么了吃靠?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長足淆。 經(jīng)常有香客問我巢块,道長,這世上最難降的妖魔是什么缸浦? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任夕冲,我火速辦了婚禮,結(jié)果婚禮上裂逐,老公的妹妹穿的比我還像新娘歹鱼。我一直安慰自己,他們只是感情好卜高,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布弥姻。 她就那樣靜靜地躺著,像睡著了一般掺涛。 火紅的嫁衣襯著肌膚如雪庭敦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天薪缆,我揣著相機與錄音秧廉,去河邊找鬼。 笑死拣帽,一個胖子當著我的面吹牛疼电,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播减拭,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蔽豺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拧粪?” 一聲冷哼從身側(cè)響起修陡,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎可霎,沒想到半個月后魄鸦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡癣朗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年号杏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡盾致,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荣暮,到底是詐尸還是另有隱情庭惜,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布穗酥,位于F島的核電站护赊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏砾跃。R本人自食惡果不足惜骏啰,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抽高。 院中可真熱鬧判耕,春花似錦、人聲如沸翘骂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碳竟。三九已至草丧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莹桅,已是汗流浹背昌执。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诈泼,地道東北人懂拾。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像厂汗,于是被迫代替她去往敵國和親委粉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

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