Android 意圖(Intent)和過濾器(Filter)

2023-05-09 11:12 更新

Android 意圖(Intent)和過濾器(Filter)

Android意圖是一個(gè)要執(zhí)行的操作的抽象描述。它可以通過 startActivity 來啟動(dòng)一個(gè)活動(dòng),broadcastIntent 來發(fā)送廣播到任何對(duì)它感興趣的廣播接受器組件,startService(Intent) 或者bindService(Intent, ServiceConnection, int) 來與后臺(tái)服務(wù)通訊。

意圖本身(一個(gè) Intent 對(duì)象)是一個(gè)被動(dòng)的數(shù)據(jù)結(jié)構(gòu),保存著要執(zhí)行操作的抽象描述。

例如,你有一個(gè)活動(dòng),需要打開郵件客戶端并通過 Android 設(shè)備來發(fā)送郵件。為了這個(gè)目的,你的活動(dòng)需要發(fā)送一個(gè)帶有合適選擇器的 ACTION_SEND 到 Android 意圖處理者。指定的選擇器給定合適的界面來讓用戶決定如何發(fā)送他的郵件數(shù)據(jù)。

Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
email.putExtra(Intent.EXTRA_EMAIL, recipients);
email.putExtra(Intent.EXTRA_SUBJECT, subject.getText().toString());
email.putExtra(Intent.EXTRA_TEXT, body.getText().toString());
startActivity(Intent.createChooser(email, "Choose an email client from..."));

上面的語法調(diào)用 startActivity 方法來開啟郵件活動(dòng),代碼運(yùn)行結(jié)果看起來像這樣:

例如,你有一個(gè)活動(dòng),需要在 Android 設(shè)備上通過瀏覽器打開一個(gè)URL。為了這個(gè)目的,你的活動(dòng)發(fā)送 ACTION_WEB_SEARCH 意圖到 Android 意圖處理器來在瀏覽器中打開給定的 URL 。意圖處理器通過解析一系列活動(dòng),并選擇最適合你的意圖的一個(gè)活動(dòng),在這個(gè)例子中,是 Web 瀏覽器活動(dòng)。意圖處理器傳遞你的網(wǎng)頁地址到 Web 瀏覽器,并打開 Web 瀏覽器活動(dòng)。

String q = "http://www.uprogrammer.cn";
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH );
intent.putExtra(SearchManager.QUERY, q);
startActivity(intent);

上面的例子將在Android搜索引擎上查找"www.uprogrammer.cn",并在一個(gè)活動(dòng)上給出關(guān)鍵詞的結(jié)果。

對(duì)于每一個(gè)組件-活動(dòng),服務(wù),廣播接收器都有獨(dú)立的機(jī)制來傳遞意圖。

序號(hào) 方法和描述
1 Context.startActivity():意圖傳遞給該方法,用于啟動(dòng)一個(gè)新的活動(dòng)或者讓已存在的活動(dòng)做一些新的事情。
2 Context.startService():意圖傳遞給該方法,將初始化一個(gè)服務(wù),或者新的信息到一個(gè)持續(xù)存在的服務(wù)。
3 Context.sendBroadcast():意圖傳遞給該方法,信息將傳遞到所有對(duì)此感興趣的廣播接收器。

意圖對(duì)象

意圖對(duì)象是一包的信息,用于組件接收到的意圖就像 Android 系統(tǒng)接受到的信息。

意圖對(duì)象包括如下的組件,具體取決于要通信或者執(zhí)行什么。

動(dòng)作(Action)

這是意圖對(duì)象中必須的部分,被表現(xiàn)為一個(gè)字符串。在廣播的意圖中,動(dòng)作一旦發(fā)生,將會(huì)被報(bào)告。動(dòng)作將很大程度上決定意圖的其他部分如何被組織。Intent 類定義了一系列動(dòng)作常量對(duì)應(yīng)不同的意圖。這里是一份Android意圖標(biāo)準(zhǔn)動(dòng)作列表。

意圖對(duì)象中的動(dòng)作可以通過 setAction() 方法來設(shè)置,通過 getAction() 方法來讀取。

數(shù)據(jù)(Data)

添加數(shù)據(jù)規(guī)格到意圖過濾器。這個(gè)規(guī)格可以只是一個(gè)數(shù)據(jù)類型(如元類型屬性),一條 URI ,或者同時(shí)包括數(shù)據(jù)類型和 URI 。 URI 則由不同部分的屬性來指定。

這些指定 URL 格式的屬性是可選的,但是也相互獨(dú)立 -

  • 如果意圖過濾器沒有指定模式,所有其他的 URI 屬性將被忽略。
  • 如果沒有為過濾器指定主機(jī),端口屬性和所有路徑屬性將被忽略。

setData() 方法只能以 URI 來指定數(shù)據(jù),setType() 只能以元類型指定數(shù)據(jù),setDataAndType() 可以同時(shí)指定 URI 和元類型。URI 通過 getData() 讀取,類型通過 getType() 讀取。

以下是動(dòng)作/數(shù)據(jù)組的一些實(shí)例 -

序號(hào) 動(dòng)作/數(shù)據(jù)組和描述
1 ACTION_VIEW content://contacts/people/1:顯示ID為1的用戶的信息。
2 ACTION_DIAL content://contacts/people/1:顯示電話撥號(hào)器,并填充用戶1的數(shù)據(jù)。
3 ACTION_VIEW tel:123:顯示電話撥號(hào)器,并填充給定的號(hào)碼。
4 ACTION_DIAL tel:123:顯示電話撥號(hào)器,并填充給定的號(hào)碼。
5 ACTION_EDIT content://contacts/people/1:編輯ID為1的用戶信息。
6 ACTION_VIEW content://contacts/people/:顯示用戶列表,以便查看。
7 ACTION_SET_WALLPAPER:顯示選擇壁紙?jiān)O(shè)置。
8 ACTION_SYNC:同步數(shù)據(jù),默認(rèn)的值為:android.intent.action.SYNC
9 ACTION_SYSTEM_TUTORIAL:開啟平臺(tái)定義的教程(默認(rèn)教程或者啟動(dòng)教程)
10 ACTION_TIMEZONE_CHANGED:當(dāng)時(shí)區(qū)被改變時(shí)通知
11 ACTION_UNINSTALL_PACKAGE:運(yùn)行默認(rèn)的卸載器

類別

類別是意圖中可選的部分,是一個(gè)字符串,包含該類型組件需要處理的意圖的附加信息。addCategory() 方法為意圖對(duì)象添加類別,removeCategory() 方法刪除之前添加的類別,getCategories() 獲取所有被設(shè)置到意圖對(duì)象中的類別。這里是Android意圖標(biāo)準(zhǔn)類別列表。

可以查看下面章節(jié)中的意圖過濾器來了解我們?nèi)绾问褂妙悇e來通過對(duì)應(yīng)的意圖選擇合適的活動(dòng)。

附加數(shù)據(jù)

這是傳遞給需要處理意圖的組件的以鍵值對(duì)描述的附加信息。通過 putExtras() 方法設(shè)置,getExtras() 方法讀取。這里是Android意圖標(biāo)準(zhǔn)附加數(shù)據(jù)列表。

標(biāo)記

這些標(biāo)記是意圖的可選部分,說明Android系統(tǒng)如何來啟動(dòng)活動(dòng),啟動(dòng)后如何處理等。

序號(hào) 標(biāo)記和說明
1 FLAG_ACTIVITY_CLEAR_TASK :如果在意圖中設(shè)置,并通過 Context.startActivity 傳遞,這個(gè)標(biāo)記將導(dǎo)致與該活動(dòng)相關(guān)聯(lián)的所有已存在的任務(wù)在活動(dòng)啟動(dòng)前被清空?;顒?dòng)將成為一個(gè)空任務(wù)的根,所有舊的活動(dòng)被結(jié)束。該標(biāo)記可以與 FLAG_ACTIVITY_NEW_TASK 結(jié)合使用。
2 FLAG_ACTIVITY_CLEAR_TOP :如果設(shè)置該標(biāo)記,活動(dòng)將在當(dāng)前運(yùn)行的任務(wù)中被啟動(dòng)。這并不會(huì)啟動(dòng)一個(gè)新的活動(dòng)實(shí)例,所有的在它之上的活動(dòng)被關(guān)閉,這個(gè)意圖作為一個(gè)新的意圖被傳遞到已有的(目前在頂部的)活動(dòng)。
3 FLAG_ACTIVITY_NEW_TASK :這個(gè)標(biāo)記一般用于使得活動(dòng)用于"啟動(dòng)器"風(fēng)格的行為:為用戶提供一個(gè)可以獨(dú)立完成運(yùn)行的數(shù)據(jù),并啟動(dòng)完整兒獨(dú)立的活動(dòng)。

組件名稱

組件名稱對(duì)象是一個(gè)可選的域,代表活動(dòng)、服務(wù)或者廣播接收器類。如果設(shè)置,則意圖對(duì)象被傳遞到實(shí)現(xiàn)設(shè)計(jì)好的類的實(shí)例,否則,Android 使用其他意圖中的其他信息來定位一個(gè)合適的目標(biāo)。組件名稱通過 setComponent(),setClass()或者 setClassName() 來設(shè)置,通過 getComponent() 獲取。


意圖的類型

Android 支持兩種類型的意圖。


顯式意圖

顯式意圖用于連接應(yīng)用程序的內(nèi)部世界,假設(shè)你需要連接一個(gè)活動(dòng)到另外一個(gè)活動(dòng),我們可以通過顯示意圖,下圖顯示通過點(diǎn)擊按鈕連接第一個(gè)活動(dòng)到第二個(gè)活動(dòng)。


這些意圖通過名稱指定目標(biāo)組件,一般用于應(yīng)用程序內(nèi)部信息 - 比如一個(gè)活動(dòng)啟動(dòng)一個(gè)下屬活動(dòng)或者啟動(dòng)一個(gè)兄弟活動(dòng)。舉個(gè)例子:

// 通過指定類名的顯式意圖
Intent i = new Intent(FirstActivity.this, SecondAcitivity.class);

// 啟動(dòng)目標(biāo)活動(dòng)
startActivity(i);

隱式意圖

這些意圖沒有為目標(biāo)命名,組件名稱的域?yàn)榭?。隱式意圖經(jīng)常用于激活其他應(yīng)用程序的組件。舉個(gè)例子:

Intent read1=new Intent();
read1.setAction(android.content.Intent.ACTION_VIEW);
read1.setData(ContactsContract.Contacts.CONTENT_URI);
startActivity(read1);

上面的代碼將給出如下結(jié)果:


目標(biāo)組件接收到意圖,可以使用getExtras()方法來獲取由源組件發(fā)送的附加數(shù)據(jù)。例如:

// 在代碼中的合適位置獲取包對(duì)象
Bundle extras = getIntent().getExtras();

// 通過鍵解壓數(shù)據(jù)
String value1 = extras.getString("Key1");
String value2 = extras.getString("Key2");

實(shí)例

下面的實(shí)例演示使用 Android 意圖來啟動(dòng)各種 Android 內(nèi)置應(yīng)用程序的功能。

步驟 描述
1 使用 Android Studio IDE 創(chuàng)建 Android 應(yīng)用程序,并命名為Intent filter,包名為 cn.uprogrammer.intentfilter。當(dāng)創(chuàng)建項(xiàng)目時(shí),確保目標(biāo) SDK 和用最新版本的 Android SDK 進(jìn)行編譯使用高級(jí)的API。
2 修改src/cn.uprogrammer.intentfilter/MainActivity.java文件,并添加代碼定義兩個(gè)監(jiān)聽器來對(duì)應(yīng)兩個(gè)按鈕"啟動(dòng)瀏覽器"和"啟動(dòng)電話"
3 修改res/layout/activity_main.xml布局文件,在線性布局中添加3個(gè)按鈕。
4 啟動(dòng)Android模擬器來運(yùn)行應(yīng)用程序,并驗(yàn)證應(yīng)用程序所做改變的結(jié)果。

以下是src/cn.uprogrammer.intentfilter/MainActivity.java文件的內(nèi)容:

package cn.uprogrammer.intentfilter;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;


public class MainActivity extends ActionBarActivity {
    Button b1,b2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        b1=(Button)findViewById(R.id.button);
        b1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://www.uprogrammer.cn"));
                startActivity(i);
            }
        });

        b2=(Button)findViewById(R.id.button2);
        b2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(android.content.Intent.ACTION_VIEW,Uri.parse("tel:9510300000"));
                startActivity(i);
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.

        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

下面是res/layout/activity_main.xml文件的內(nèi)容:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="意圖實(shí)例"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="www.uprogrammer.cn"
        android:textColor="#ff87ff09"
        android:textSize="30dp"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true" />

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageButton"
        android:src="@drawable/ic_launcher"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText"
        android:layout_below="@+id/imageButton"
        android:layout_alignRight="@+id/imageButton"
        android:layout_alignEnd="@+id/imageButton" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="啟動(dòng)瀏覽器"
        android:id="@+id/button"
        android:layout_alignTop="@+id/editText"
        android:layout_alignRight="@+id/textView1"
        android:layout_alignEnd="@+id/textView1"
        android:layout_alignLeft="@+id/imageButton"
        android:layout_alignStart="@+id/imageButton" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="啟動(dòng)電話"
        android:id="@+id/button2"
        android:layout_below="@+id/button"
        android:layout_alignLeft="@+id/button"
        android:layout_alignStart="@+id/button"
        android:layout_alignRight="@+id/textView2"
        android:layout_alignEnd="@+id/textView2" />
</RelativeLayout>

下面是res/values/strings/xml的內(nèi)容,定義了兩個(gè)新的常量。

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="app_name">Intent filter</string>
   <string name="action_settings">Settings</string>
</resources>

下面是默認(rèn)的AndroidManifest.xml的內(nèi)容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.uprogrammer.intentfilter"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="22" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Base.Theme.AppCompat" >

        <activity
            android:name="cn.uprogrammer.intentfilter.MainActivity"
            android:label="@string/app_name" >

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>

    </application>
</manifest>

讓我們運(yùn)行剛剛修改的 Intent filter 應(yīng)用程序。我假設(shè)你已經(jīng)在安裝環(huán)境時(shí)創(chuàng)建了 AVD。打開你的項(xiàng)目中的活動(dòng)文件,點(diǎn)擊工具欄中的 圖標(biāo)來在 Android Studio 中運(yùn)行應(yīng)用程序。Android Studio 在 AVD 上安裝應(yīng)用程序并啟動(dòng)它。如果一切順利,將在模擬器窗口上顯示如下:


現(xiàn)在點(diǎn)擊"啟動(dòng)瀏覽器"按鈕,這將根據(jù)配置啟動(dòng)一個(gè)瀏覽器,并且顯示http://www.uprogrammer.cn如下:


類似的方式,你可以點(diǎn)擊"啟動(dòng)電話"按鈕來打開電話界面,這將允許你撥打已經(jīng)給定的電話號(hào)碼。


意圖過濾器

你已經(jīng)看到如何使用意圖來調(diào)用另外的活動(dòng)。 Android 操作系統(tǒng)使用過濾器來指定一系列活動(dòng)、服務(wù)和廣播接收器處理意圖,需要借助于意圖所指定的動(dòng)作、類別、數(shù)據(jù)模式。在 manifest 文件中使用 <intent-filter> 元素在活動(dòng),服務(wù)和廣播接收器中列出對(duì)應(yīng)的動(dòng)作,類別和數(shù)據(jù)類型。

下面的實(shí)例展示AndroidManifest.xml文件的一部分,指定一個(gè)活動(dòng)cn.uprogrammer.intentfilter.CustomActivity可以通過設(shè)置的動(dòng)作,類別及數(shù)據(jù)來調(diào)用:

<activity android:name=".CustomActivity"
   android:label="@string/app_name">

   <intent-filter>
      <action android:name="android.intent.action.VIEW" />
      <action android:name="com.example.MyApplication.LAUNCH" />
      <category android:name="android.intent.category.DEFAULT" />
      <data android:scheme="http" />
   </intent-filter>

</activity>

當(dāng)活動(dòng)被上面的過濾器所定義,其他活動(dòng)就可以通過下面的方式來調(diào)用這個(gè)活動(dòng)。使用 android.intent.action.VIEW,使用 cn.uprogrammer.intentfilter.LAUNCH 動(dòng)作,并提供android.intent.category.DEFAULT類別。

元素指定要被調(diào)用的活動(dòng)所期望的數(shù)據(jù)類型。上面的實(shí)例中,自定義活動(dòng)期望的數(shù)據(jù)由"http://"開頭。

有這樣的情況,通過過濾器,意圖將被傳遞到多個(gè)的活動(dòng)或者服務(wù),用戶將被詢問啟動(dòng)哪個(gè)組件。如果沒有找到目標(biāo)組件,將發(fā)生一個(gè)異常。

在調(diào)用活動(dòng)之前,有一系列的 Android 檢查測(cè)試:

  • 過濾器 <intent-filter> 需要列出一個(gè)或者多個(gè)的動(dòng)作,不能為空;過濾器至少包含一個(gè) 元素,否則將阻塞所有的意圖。如果多個(gè)動(dòng)作被提到,Android 在調(diào)用活動(dòng)前嘗試匹配其中提到的一個(gè)動(dòng)作。
  • 過濾器 <intent-filter> 可能列出0個(gè),1個(gè)或者多個(gè)類別。如果沒有類別被提到,Android 通過這個(gè)測(cè)試,如果有多個(gè)類別被提及,意圖通過類型測(cè)試,每個(gè)意圖對(duì)象的分類必須匹配過濾器中的一個(gè)分類。
  • 每個(gè) 元素可以指定一個(gè) URI 和一個(gè)數(shù)據(jù)類型(元媒體類型)。這里有獨(dú)立的屬性,如 URI 中的每個(gè)部分:模式,主機(jī),端口和路徑。意圖包含有 URI 和類型,只有它的類型匹配了過濾器中列出的某個(gè)類型,則通過數(shù)據(jù)類型部分的測(cè)試。

實(shí)例

下面的實(shí)例是上面實(shí)例的一些修改。這里我們將看到如果一個(gè)意圖調(diào)用定義的兩個(gè)活動(dòng),Android 如何來解決沖突;如何使用過濾器來調(diào)用自定義活動(dòng);如果沒有為意圖定義合適的活動(dòng),則會(huì)出現(xiàn)異常。

步驟 說明
1 使用Android Studio IDE創(chuàng)建Android應(yīng)用程序,并命名為Intent filter,包名為cn.uprogrammer.intentfilter。當(dāng)創(chuàng)建項(xiàng)目時(shí),確保目標(biāo) SDK 和用最新版本的 Android SDK 進(jìn)行編譯使用高級(jí)的API。
2 修改 src/cn.uprogrammer.intentfilter/MainActivity.java 文件,添加代碼來定義三個(gè)監(jiān)聽器來對(duì)應(yīng)布局文件中定義的三個(gè)按鈕。
3 添加 src/cn.uprogrammer.intentfilter/CustomActivity.java 文件來包含一個(gè)活動(dòng),可以被不同的意圖調(diào)用。
4 修改 res/layout/activity_main.xml 文件在線性布局中添加三個(gè)按鈕。
5 添加 res/lauout/custom_view.xml 布局文件,添加簡(jiǎn)單地 來顯示通過 intent 傳遞的數(shù)據(jù)。
6 修改 AndroidManifest.xml 文件,添加 <intent-filter> 定義意圖的規(guī)則來調(diào)用自定義活動(dòng)。
7 啟動(dòng) Android 模擬器來運(yùn)行應(yīng)用程序,并驗(yàn)證應(yīng)用程序所做改變的結(jié)果。

以下是src/cn.uprogrammer.intentfilter/MainActivity.java的內(nèi)容:

package cn.uprogrammer.intentfilter;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;


public class MainActivity extends ActionBarActivity {
    Button b1,b2,b3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        b1=(Button)findViewById(R.id.button);

        b1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent(android.content.Intent.ACTION_VIEW,Uri.parse("http://www.uprogrammer.cn"));
                startActivity(i);
            }
        });

        b2=(Button)findViewById(R.id.button2);
        b2.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent("cn.uprogrammer.intentfilter.LAUNCH",Uri.parse("http://www.uprogrammer.cn"));
                startActivity(i);
            }
        });

        b3=(Button)findViewById(R.id.button3);
        b3.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent("cn.uprogrammer.intentfilter.LAUNCH",Uri.parse("https://www.uprogrammer.cn"));
                startActivity(i);
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.

        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

下面是src/cn.uprogrammer.intentfilter/CustomActivity.java的內(nèi)容:

package cn.uprogrammer.intentfilter;

import android.app.Activity;
        import android.net.Uri;
        import android.os.Bundle;
        import android.widget.TextView;

public class CustomActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_view);
        TextView label = (TextView) findViewById(R.id.show_data);
        Uri url = getIntent().getData();
        label.setText(url.toString());
    }
}

下面是res/layout/activity_main.xml 的內(nèi)容:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="意圖實(shí)例"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="www.uprogrammer.cn"
        android:textColor="#ff87ff09"
        android:textSize="30dp"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true" />

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageButton"
        android:src="@drawable/ic_launcher"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText"
        android:layout_below="@+id/imageButton"
        android:layout_alignRight="@+id/imageButton"
        android:layout_alignEnd="@+id/imageButton" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="通過View動(dòng)作啟動(dòng)瀏覽器"
        android:id="@+id/button"
        android:layout_alignTop="@+id/editText"
        android:layout_alignRight="@+id/textView1"
        android:layout_alignEnd="@+id/textView1"
        android:layout_alignLeft="@+id/imageButton"
        android:layout_alignStart="@+id/imageButton" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="通過Launch動(dòng)作啟動(dòng)瀏覽器"
        android:id="@+id/button2"
        android:layout_below="@+id/button"
        android:layout_alignLeft="@+id/button"
        android:layout_alignStart="@+id/button"
        android:layout_alignRight="@+id/textView2"
        android:layout_alignEnd="@+id/textView2" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="異常情況"
        android:id="@+id/button3"
        android:layout_below="@+id/button2"
        android:layout_alignLeft="@+id/button2"
        android:layout_alignStart="@+id/button2"
        android:layout_alignRight="@+id/textView2"
        android:layout_alignEnd="@+id/textView2" />

</RelativeLayout>

下面是res/layout/custom_view.xml文件的內(nèi)容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent">

   <TextView android:id="@+id/show_data"
      android:layout_width="fill_parent"
      android:layout_height="400dp"/>

</LinearLayout>

下面是res/values/strings.xml文件的內(nèi)容:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="app_name">My Application</string>
   <string name="action_settings">Settings</string>
</resources>

下面是AndroidManifest.xml文件的內(nèi)容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.uprogrammer.intentfilter"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="22" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Base.Theme.AppCompat" >

        <activity
            android:name="cn.uprogrammer.intentfilter.MainActivity"
            android:label="@string/app_name" >

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>

        <activity android:name="cn.uprogrammer.intentfilter.CustomActivity"
            android:label="@string/app_name">

        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <action android:name="cn.uprogrammer.intentfilter.LAUNCH" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="http" />
        </intent-filter>

        </activity>

    </application>
</manifest>

讓我們運(yùn)行剛剛修改的 Intent filter 應(yīng)用程序。我假設(shè)你已經(jīng)在安裝環(huán)境時(shí)創(chuàng)建了 AVD 。打開你的項(xiàng)目中的活動(dòng)文件,點(diǎn)擊工具欄中的圖標(biāo)來在 Android Studio 中運(yùn)行應(yīng)用程序。 Android Studio 在 AVD 上安裝應(yīng)用程序并啟動(dòng)它。如果一切順利,將在模擬器窗口上顯示如下:


點(diǎn)擊第一個(gè)按鈕"使用View動(dòng)作啟動(dòng)瀏覽器"。這里我們定義我們自定義的活動(dòng)包含"android.intent.action.VIEW",并且 Android 系統(tǒng)已經(jīng)定義了默認(rèn)的活動(dòng)來對(duì)應(yīng)VIEW動(dòng)作來啟動(dòng)Web瀏覽器,因此 Android 顯示下面的選項(xiàng)來選擇你想要啟動(dòng)的活動(dòng):

如果你選擇瀏覽器, Android 將啟動(dòng) Web 瀏覽器,并打開 www.uprogrammer.cn 網(wǎng)站。如果你選擇 IntentDemo選項(xiàng),Android 將啟動(dòng) CustomActivity,該活動(dòng)什么都沒有做,僅僅是捕獲并在TextView中顯示傳遞的數(shù)據(jù)。


現(xiàn)在,通過返回按鈕返回并點(diǎn)擊"通過Launch動(dòng)作啟動(dòng)瀏覽器"按鈕,這里 Android 應(yīng)用過濾器來選擇定義的活動(dòng),并簡(jiǎn)單啟動(dòng)自定義活動(dòng)。

再次使用返回按鈕返回,并點(diǎn)擊"異常條件"按鈕,這里Android嘗試找到一個(gè)由意圖給定的有效的過濾器,但沒有找到一個(gè)定義的有效的活動(dòng)。因?yàn)槲覀兪褂?https 代替 http 的數(shù)據(jù),并給定了正確的動(dòng)作,一次 Android 產(chǎn)生了一個(gè)異常。如下:



以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)