Android Intent隱式啟動(dòng)通過scheme打開應(yīng)用

本文轉(zhuǎn)載自tickTick的BLOG扭勉,原始出處
本文通過完成一個(gè)實(shí)戰(zhàn)任務(wù)偏形,來掌握Android開發(fā)中隱式Intent的用法刁岸。
任務(wù):假設(shè)我們已經(jīng)實(shí)現(xiàn)了一個(gè)視頻播放器(PlayerActivity)耘子,我們希望能把它注冊(cè)到系統(tǒng)中果漾,當(dāng)用戶點(diǎn)擊本地視頻或者在線視頻時(shí),能啟動(dòng)這個(gè)視頻播放器谷誓。
(假設(shè)該類的全路徑為:com.jhuster.videoplayer.PlayerActivity)
1. 什么是隱式Intent?
Intent是Android中比較重要的組件吨凑,常用來啟動(dòng)一個(gè)新的Activity或者Service捍歪、廣播某個(gè)事件户辱,以及在Android組件之間傳遞數(shù)據(jù)。通過Intent來啟動(dòng)新的Activity或者Service通常有兩種方法糙臼,一種是顯示啟動(dòng)庐镐,另一種是隱式啟動(dòng)。
顯示啟動(dòng)就是在明確指出要啟動(dòng)的Activity或者Service的類或者包名变逃。例如:

Intent intent = new Intent(this, PlayerActivity.class);
startActivity(intent);
Intent intent =new Intent();
intent.setClass(this,PlayerActivity.class);
startActivity(intent);
Intent intent =new Intent();
intent.setClassName(“com.jhuster.videoplayer”,“com.jhuster.videoplayer.PlayerActivity”);
startActivity(intent);

隱式啟動(dòng)則是不明確指定啟動(dòng)哪個(gè)Activity或者Service必逆,而是通過設(shè)置Action、Data揽乱、Category名眉,讓系統(tǒng)來篩選出合適的目標(biāo)。
例如撥打電話:

Intent intent =new Intent(Intent.ACTION_DIAL,Uri.parse(“tel:021-80961111”));
startActivity(intent);

系統(tǒng)接收到隱式啟動(dòng)請(qǐng)求后凰棉,會(huì)根據(jù)系統(tǒng)中各個(gè)Activity在AndroidManifest.xml文件中聲明的<intent-filter>來比較和判斷是否匹配當(dāng)前的Intent請(qǐng)求的损拢。
因此,如果我們希望PlayerActivity能夠被系統(tǒng)隱式啟動(dòng)撒犀,則首先需要在AndroidManifest.xml文件中為該Activity添加<intent-filter>.
2. 為PlayerActivity添加<intent-filter>
<intent-filter>的標(biāo)簽有很多福压,這里只介紹和添加最基本且最常用的三個(gè)標(biāo)簽,分別是<action>或舞,<category>和<data>荆姆。
2.1 添加<action>
這個(gè)標(biāo)簽是必須添加的,可以自己定義映凳,也可以使用系統(tǒng)預(yù)定義的變量胞枕,Android系統(tǒng)默認(rèn)定義了很多action,具體可以查看SDK文檔魏宽,或者Google一下“android.intent.action.”腐泻。
這里,因?yàn)槲覀兊念愂怯脕怼安シ乓曨l”的队询,因此可以使用系統(tǒng)預(yù)定義的:android.intent.action.VIEW派桩,它表示需要啟動(dòng)某個(gè)Activity顯示指定的數(shù)據(jù)(包括圖片、視頻蚌斩、文檔等)铆惑。
添加了后的如下所示:

<activity android:name="com.jhuster.videoplayer.PlayerActivity">
  <intent-filter>
    <action android:name="android.intent.action.VIEW"/>
  </intent-filter>
</activity>

2.2 添加<category>
category代表類別,定義了Activity的類別送膳,Activity可以設(shè)置一個(gè)或者多個(gè)category標(biāo)簽员魏。常用的一般有3個(gè):DEFAULT,HOME叠聋,LAUNCHER

DEFAULT  默認(rèn)動(dòng)作
HOME     設(shè)置為本地桌面應(yīng)用
LAUNCHER 本APP的啟動(dòng)Activity

本應(yīng)用中我們使用DEFAULT類別即可撕阎,DEFAULT也是category最常用的選項(xiàng)。
添加了category后的如下所示:

<activity android:name="com.jhuster.videoplayer.PlayerActivity">
  <intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <categoryandroid:name="android.intent.category.DEFAULT"/>
  </intent-filter>
</activity>

2.3 添加<data>
data 代表數(shù)據(jù)源碌补,是<intent-filter>中最復(fù)雜的標(biāo)簽虏束,因?yàn)椴煌腁ctivity支持的數(shù)據(jù)來源和類型多種多樣棉饶,所以需要通過詳細(xì)的data標(biāo)簽信息來指明。

data 標(biāo)簽有很多屬性镇匀,包括:
android:host: 指定主機(jī)名照藻,例如:google.com
android:port:  制定主機(jī)端口,例如: 80
android:path:  指定URL的有效路徑值汗侵,例如: /index/examples
android:mimeType: 指定組件可以執(zhí)行的數(shù)據(jù)類型幸缕,例如:image/jpeg,video/*
android:scheme: 指定特定的模式晰韵,例如:content发乔,http

這里,假設(shè)我們的視頻播放器支持多種數(shù)據(jù)來源宫屠,包括:本地視頻文件列疗,本地媒體URL,網(wǎng)絡(luò)視頻流(HTTP浪蹂、RTMP抵栈、RTSP協(xié)議),另外坤次,假設(shè)我們的視頻播放器只支持mp4和3gpp兩種文件格式古劲。
那么,下面我們來添加兩種最常用<data>的標(biāo)簽缰猴,scheme和mimeType产艾,并且解釋每條標(biāo)簽對(duì)應(yīng)的是怎樣的一種數(shù)據(jù)來源或者數(shù)據(jù)格式。
(1)<data android:scheme="xxx"/>
這里的xxx可以是:file滑绒,content闷堡,網(wǎng)絡(luò)協(xié)議(HTTP,RTMP疑故、RTSP等)
本應(yīng)用中我們給PlayerActivity的中<Intent-filter>添加:

<data android:scheme="file"/>
<data android:scheme="content"/>
<data android:scheme="http"/>
<data android:scheme="rtsp"/>

添加了這樣幾條data標(biāo)簽項(xiàng)之后杠览,如果隱式Intent中的數(shù)據(jù)來源URL是以“file://”、“content://”纵势、“http://”踱阿、“rtsp://”開頭的URL資源,都會(huì)隱式地啟動(dòng)我們的PlayerActivity钦铁。
例如软舌,其他的Activity可以通過下面的方法來隱式啟動(dòng)我們的PlayerActivity.

Intent intent =new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.fromFile(new File("/sdcard/test.3gp")));
startActivity(intent);

Uri.fromFile這條語(yǔ)句會(huì)把指定的文件位置轉(zhuǎn)換為以“file://”開頭的Uri對(duì)象,如上述例子最終得到的URL為:“file:///sdcard/test.3gp”
同理牛曹,可以通過Uri.parse來轉(zhuǎn)換我們常見的網(wǎng)絡(luò)地址字符串為Uri對(duì)象佛点,例如:

Intent intent =new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://ticktick.blog.51cto.com/test.mp4"));
startActivity(intent);

(2)<data android:mimeType="xxx"/>
mimeType用來設(shè)置數(shù)據(jù)類型,例如圖像數(shù)據(jù)(image/png或者image/)躏仇,視頻數(shù)據(jù)(video/mp4或者video/)恋脚,如果使用*代表匹配所有的子類型腺办。
MIME TYPE是互聯(lián)網(wǎng)的一種標(biāo)記數(shù)據(jù)類型的標(biāo)準(zhǔn)焰手,現(xiàn)在已經(jīng)支持非常多的類型了糟描,這里我不一一列舉,大家可以在Google上搜索一下书妻。
本應(yīng)用中我們假設(shè)需要支持的是mp4和3gpp兩種類型船响,那么,我們可以添加這樣兩條 mimeType :

<data android:mimeType="video/3gpp"/>
<data android:mimeType="video/mp4"/>

那么躲履,其他的Activity就可以通過下面的方法來隱式啟動(dòng)我們的PlayerActivity. 注意见间,當(dāng)<intent-filter>已經(jīng)添加了mimeType之后,隱式Intent必須設(shè)置Type參數(shù)才能匹配到該Activity工猜,所以建議使用setDataAndType方法米诉,而不是單一的setData方法。

Intent intent =new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File("/sdcard/test.3gp")),"video/3gpp");
startActivity(intent);

當(dāng)然篷帅,這里的"video/3gpp"也可以寫成:"video/*"史侣,但這樣可能會(huì)匹配到一些不支持3gpp的播放器。

(3) 小結(jié)
添加了<data>標(biāo)簽后的如下所示:

<activity android:name="com.jhuster.videoplayer.PlayerActivity">
  <intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="file"/>
    <data android:scheme="content"/>
    <data android:scheme="http"/>
    <data android:scheme="rtsp"/>
    <data android:scheme="rtmp"/>
    <data android:mimeType="video/3gpp"/>
    <data android:mimeType="video/mp4"/>
  </intent-filter>
</activity>

3. 在PlayerActivity中獲取參數(shù)
通過上面的介紹魏身,我們已經(jīng)知道了怎樣添加<intent-filter>以及怎樣通過隱式Intent來調(diào)用我們的PlayerActivity惊橱,那么,下面我們還要了解如何在PlayerActivity中解析來自隱式Intent的參數(shù)箭昵。
其實(shí)税朴,Intent提供了很多方法可以Get相關(guān)的參數(shù)信息,例如:

public String getAction();
public Uri    getData();
public String getScheme();
public String getType();

上述方法分別可以獲取Intent的Action家制,Data Uri正林,Scheme和MimeType值。
對(duì)于“file://”開頭的Uri對(duì)象颤殴,我們可以通過Uri.getPath方法得到去除了“file://”前綴的具體文件地址觅廓。例如: “file:///sdcard/test.mp4”則可以轉(zhuǎn)換為實(shí)際的“/sdcard/test.mp4”。
對(duì)于網(wǎng)絡(luò)碼流诅病,例如:“http://”哪亿、“rtsp://”等開頭的Uri,則可以直接通過toString()方法轉(zhuǎn)換為實(shí)際地址的字符串贤笆。
而對(duì)于“content://”開頭的URI對(duì)象蝇棉,一般是從系統(tǒng)的媒體數(shù)據(jù)庫(kù)中檢索出來的結(jié)果,因此需要反向查找得到實(shí)際的文件地址芥永,這里提供一個(gè)函數(shù)進(jìn)行轉(zhuǎn)換篡殷。

public static String getVideoPath(Context context, Uri uri) {
  Uri videopathURI = uri;
  if(uri.getScheme().toString().compareTo("content") ==0) {
    Cursor cursor = context.getContentResolver().query(uri,null,null,null,null);
    if(cursor.moveToFirst()) {
      intcolumn_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
      videopathURI = Uri.parse(cursor.getString(column_index));
      return videopathURI.getPath();
    }
  }else if(uri.getScheme().compareTo("file") ==0) {
    return videopathURI.getPath();
  }
  return videopathURI.toString();
}

4. 總結(jié)
到這里算是把隱式Intent的重要知識(shí)點(diǎn)都講清楚了,本文轉(zhuǎn)載自tickTick的BLOG埋涧,原始出處板辽。謝謝奇瘦。
請(qǐng)務(wù)必保留此出處http://ticktick.blog.51cto.com/823160/1621957

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市劲弦,隨后出現(xiàn)的幾起案子耳标,更是在濱河造成了極大的恐慌,老刑警劉巖邑跪,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件次坡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡画畅,警方通過查閱死者的電腦和手機(jī)砸琅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轴踱,“玉大人症脂,你說我怎么就攤上這事∫В” “怎么了诱篷?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嘁傀。 經(jīng)常有香客問我兴蒸,道長(zhǎng),這世上最難降的妖魔是什么细办? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任橙凳,我火速辦了婚禮,結(jié)果婚禮上笑撞,老公的妹妹穿的比我還像新娘岛啸。我一直安慰自己,他們只是感情好茴肥,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布坚踩。 她就那樣靜靜地躺著,像睡著了一般瓤狐。 火紅的嫁衣襯著肌膚如雪瞬铸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天础锐,我揣著相機(jī)與錄音嗓节,去河邊找鬼。 笑死皆警,一個(gè)胖子當(dāng)著我的面吹牛拦宣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼鸵隧,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绸罗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起豆瘫,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤珊蟀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后靡羡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體系洛,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俊性,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年略步,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片定页。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡趟薄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出典徊,到底是詐尸還是另有隱情杭煎,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布卒落,位于F島的核電站羡铲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏儡毕。R本人自食惡果不足惜也切,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腰湾。 院中可真熱鬧雷恃,春花似錦、人聲如沸费坊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)附井。三九已至讨越,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間永毅,已是汗流浹背把跨。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卷雕,地道東北人节猿。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親滨嘱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子峰鄙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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