如何使用隱式 Intent

隱式 Intent 相比於顯式 Intent,隱式 Intent 則含蓄了許多,它並不明確指出我們想要啓動哪一個活動,而是指定了一系列更爲抽象的 action和category等信息,然後交由系統去分析這個 Intent,並幫我們找出合適的活動去啓動。

什麼叫做合適的活動呢?簡單來說就是可以響應我們這個隱式 Intent的活動,那麼目前SecondActivity 可以響應什麼樣的隱式 Intent 呢?額,現在好像還什麼都響應不了,不過很快就會有了。

使用隱式 Intent

通過在<activity>標籤下配置<intent-filter>的內容,可以指定當前活動能夠響應的 action 和 category,打開 AndroidManifest.xml,添加如下代碼:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="pub.weber.bym.activitytest.ACTION_START"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="com.example.activitytest.MY_CATEGORY"/>
    </intent-filter>
</activity>

<action>標籤中我們指明瞭當前活動可以響應 com.example.activitytest.ACTION_START這個 action,而<category>標籤則包含了一些附加信息,更精確地指明瞭當前的活動能夠響應的 Intent 中還可能帶有的 category。只有<action><category>中的內容同時能夠匹配上 Intent 中指定的 action 和 category 時,這個活動才能響應該 Intent。

修改 MainActivity 中按鈕的點擊事件,代碼如下所示:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent("pub.weber.bym.activitytest.ACTION_START");
        startActivity(intent);
    }
});

可以看到,我們使用了 Intent 的另一個構造函數,直接將 action 的字符串傳了進去,表明我們想要啓動能夠響應 com.example.activitytest.ACTION_START 這個 action 的活動。那前面不是說要<action><category>同時匹配上才能響應的嗎?怎麼沒看到哪裏有指定category 呢?這是因爲 android.intent.category.DEFAULT 是一種默認的 category,在調用startActivity()方法的時候會自動將這個 category 添加到 Intent 中。

重新運行程序,在 MainActivity 的界面點擊一下按鈕,你同樣成功啓動 SecondActivity了。不同的是,這次你是使用了隱式 Intent 的方式來啓動的,說明我們在<activity>標籤下配置的 action 和 category 的內容已經生效了!

每個 Intent 中只能指定一個 action,但卻能指定多個 category。目前我們的 Intent 中只有一個默認的 category,那麼現在再來增加一個吧。

修改 MainActivity 中按鈕的點擊事件,代碼如下所示:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent("pub.weber.bym.activitytest.ACTION_START");
        intent.addCategory("com.example.activitytest.MY_CATEGORY");
        startActivity(intent);
    }
});

可以調用 Intent 中的 addCategory()方法來添加一個 category,這裏我們指定了一個自定義的 category,值爲 com.example.activitytest.MY_CATEGORY

現在重新運行程序,在 MainActivity 的界面點擊一下按鈕,你會發現,程序崩潰了!

錯誤信息中提醒我們,沒有任何一個活動可以響應我們的 Intent,爲什麼呢?這是因爲我們剛剛在 Intent 中新增了一個 category,而 SecondActivity 的<intent-filter>標籤中並沒有聲明可以響應這個category,所以就出現了沒有任何活動可以響應該 Intent 的情況。現在我們在<intent-filter>中再添加一個 category 的聲明,如下所示:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="pub.weber.bym.activitytest.ACTION_START"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="com.example.activitytest.MY_CATEGORY"/>
    </intent-filter>
</activity>

再次重新運行程序,你就會發現一切都正常了。

更多隱式 Intent 的用法

使用隱式 Intent,我們不僅可以啓動自己程序內的活動,還可以啓動其他程序的活動,這使得 Android多個應用程序之間的功能共享成爲了可能。比如說你的應用程序中需要展示一個網頁,這時你沒有必要自己去實現一個瀏覽器(事實上也不太可能),而是隻需要調用系統的瀏覽器來打開這個網頁就行了。

修改 MainActivity 中按鈕點擊事件的代碼,如下所示:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("http://weber.pub/"));
        startActivity(intent);
    }
});

這裏我們首先指定了 Intent 的 action 是 Intent.ACTION_VIEW,這是一個 Android 系統內置的動作,其常量值爲 android.intent.action.VIEW。然後通過 Uri.parse()方法,將一個網址字符串解析成一個 Uri 對象,再調用 Intent的 setData()方法將這個 Uri 對象傳遞進去。

重新運行程序,在 MainActivity 界面點擊按鈕就可以看到打開了系統瀏覽器,如圖所示。

如何使用隱式 Intent

上述的代碼中,可能你會對 setData()部分感覺到陌生,這是我們前面沒有講到過的。這個方法其實並不複雜,它接收一個 Uri 對象,主要用於指定當前 Intent 正在操作的數據,而這些數據通常都是以字符串的形式傳入到 Uri.parse()方法中解析產生的。

與此對應,我們還可以在<intent-filter>標籤中再配置一個<data>標籤,用於更精確地指定當前活動能夠響應什麼類型的數據。<data>標籤中主要可以配置以下內容。

  • android:scheme
    用於指定數據的協議部分,如上例中的 http 部分。
  • android:host
    用於指定數據的主機名部分,如上例中的http://weber.pub/部分。
  • android:port
    用於指定數據的端口部分,一般緊隨在主機名之後。
  • android:path
    用於指定主機名和端口之後的部分,如一段網址中跟在域名之後的內容。
  • android:mimeType
    用於指定可以處理的數據類型,允許使用通配符的方式進行指定。

只有<data>標籤中指定的內容和 Intent 中攜帶的 Data完全一致時,當前活動才能夠響應該 Intent。不過一般在<data>標籤中都不會指定過多的內容,如上面瀏覽器示例中,其實只需要指定 android:scheme 爲 http,就可以響應所有的 http 協議的 Intent 了。

新建一個 activity_third.xml 佈局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Button
        android:id="@+id/button_3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 3"
        />
</LinearLayout>

然後新建活動 ThirdActivity 繼承自 Activity,代碼如下:

package pub.weber.bym.activitytest;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class ThirdActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_third);
    }
}

最後在 AndroidManifest.xml 中爲 ThirdActivity 進行註冊。

<activity android:name=".ThirdActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="http"/>
    </intent-filter>
</activity>

我們在 ThirdActivity 的 <intent-filter> 中 配 置 了 當 前 活 動 能 夠 響 應 的 action 是Intent.ACTION_VIEW 的常量值,而 category 則毫無疑問指定了默認的 category 值,另外在<data>標籤中我們通過android:scheme指定了數據的協議必須是 http協議,這樣 ThirdActivity應該就和瀏覽器一樣,能夠響應一個打開網頁的 Intent 了。讓我們運行一下程序試試吧,在FirstActivity 的界面點擊一下按鈕,結果如圖所示。

如何使用隱式 Intent

可以看到,系統自動彈出了一個列表,顯示了目前能夠響應這個 Intent 的所有程序。點擊 Browser 還會像之前一樣打開瀏覽器,並顯示weber的主頁,而如果點擊了 ActivityTest,則會啓動ThirdActivity。需要注意的是,雖然我們聲明瞭 ThirdActivity 是可以響應打開網頁的Intent 的,但實際上這個活動並沒有加載並顯示網頁的功能,所以在真正的項目中儘量不要去做這種有可能誤導用戶的行爲,不然會讓用戶對我們的應用產生負面的印象。

除了 http 協議外,我們還可以指定很多其他協議,比如 geo 表示顯示地理位置、tel 表示撥打電話。下面的代碼展示瞭如何在我們的程序中調用系統撥號界面。

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(Intent.ACTION_DIAL);
        intent.setData(Uri.parse("tel:10086"));
        startActivity(intent);
    }
});

首先指定了 Intent 的 action 是 Intent.ACTION_DIAL,這又是一個 Android 系統的內置動作。然後在 data部分指定了協議是 tel,號碼是 10086。重新運行一下程序,在 MainActivity 的界面點擊一下按鈕,結果如圖所示。

如何使用隱式 Intent

by web開發者 from http://weber.pub/

本文地址: http://weber.pub/安卓筆記6-如何使用隱式intent/293.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章