Intent學習


1.Intent是什么


Android中提供了Intent機制來協助應用間的交互與通訊,Intent負責對
應用中一次操作的動作、動作涉及數據、附加數據進行描述,Android則
根據此Intent的描述,負責找到對應的組件,將 Intent傳遞給調用的組
件,並完成組件的調用。
Intent不僅可用於應用程序之間,也可用於應用程序內部的Activity/Service
之間的交互。因此,Intent在這里起着一個中介的作用,專門提供組
件互相調用的相關信息,實現調用者與被調用者之間的解耦。

2.Intent定義的內容


在Android參考文檔中,對Intent的定義是執行某操作的一個抽象描述。

(1)Action,也就是要執行的動作
(2)Data,也就是執行動作要操作的數據
(3)type(數據類型)
(4)category(類別)
(5) component(組件)
(6) extras(附加信息)

2.1)執行的動作(action)


動作(action)的一個簡要描述,如VIEW_ACTION(查看)、EDIT_ACTION
(修改)等,Android為我們定義了一套標准動作。

系統定義的動作(action)
ACTION_CALL    activity    Initiate a phone call.
ACTION_EDIT    activity    Display data for the user to edit.
ACTION_MAIN    activity    Start up as the initial activity of a task, with no data input and no returned output.
ACTION_SYNC    activity    Synchronize data on a server with data on the mobile device.
ACTION_BATTERY_LOW    broadcast receiver    A warning that the battery is low.
ACTION_HEADSET_PLUG    broadcast receiver    A headset has been plugged into the device, or unplugged from it.
ACTION_SCREEN_ON    broadcast receiver    The screen has been turned on.
ACTION_TIMEZONE_CHANGED    broadcast receiver    The setting for the time zone has changed.

2.2)執行動作要操作的數據(data)


Android中采用指向數據的一個URI來表示,
如在聯系人應用中,一個指向某聯系人的URI可能為:content://contacts/1。

這種URI表示,通過 ContentURI這個類來描述,具體可以參考android.net.ContentURI類的文檔。

以聯系人應用為例,以下是一些action / data對,及其它們要表達的意圖

VIEW_ACTION content://contacts/1-- 顯示標識符為"1"的聯系人的詳細信息
EDIT_ACTION content://contacts/1-- 編輯標識符為"1"的聯系人的詳細信息
VIEW_ACTION content://contacts/-- 顯示所有聯系人的列表
PICK_ACTION content://contacts/-- 顯示所有聯系人的列表,並且允許用戶在列表中選擇一個聯系人,然后把這個聯系人返回給父activity。

--------------------code-----------------
action為Intent.ACTION_VIEW,data為ContactsContract.Contacts.CONTENT_URI
查看聯系人列表

Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("content://com.android.contacts/contacts"));
//Intent intent = new Intent(Intent.ACTION_VIEW,ContactsContract.Contacts.CONTENT_URI);


startActivity(intent);
查看某一個聯系人

Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("content://com.android.contacts/contacts/190"));
//Intent intent = new Intent(Intent.ACTION_VIEW,ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, 190));

startActivity(intent);
編輯某一個聯系人

Intent intent = new Intent(Intent.ACTION_EDIT,Uri.parse("content://com.android.contacts/contacts/190"));
//Intent intent = new Intent(Intent.ACTION_EDIT,ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, 190));


startActivity(intent);
注意:不能編輯一個聯系人列表。

Intent intent = new Intent(Intent.ACTION_EDIT,Uri.parse("content://com.android.contacts/contacts"));//錯


顯示聯系人列表,並選擇一個,然后獲取該聯系人信息;

Intent intent = new Intent(Intent.ACTION_PICK,ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, 100);
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == 100){
            if(resultCode == RESULT_OK){
                Uri uri = data.getData();
                Cursor cursor = getContentResolver().query(uri, null, null, null, null);
                if(cursor.moveToFirst()){
                    String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                    System.out.println(name);
                }
                cursor.close();
            }
        }
    }


-----------------------code-------------------------------

Uri uri = data.getData();
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if(cursor.moveToFirst()){
    String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
    nameet.setText(name);
    String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
    
    Cursor c2 = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+id, null, null);
    c2.moveToFirst();
    String phone = c2.getString(c2.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
    phoneet.setText(phone);
    
    c2.close();
    cursor.close();
}

 

2.3)category 類別


category(類別)是被執行動作的附加信息。

 

2.4)type(數據類型)


type(數據類型),顯式指定Intent的數據類型(MIME)。一般Intent
的數據類型能夠根據數據本身進行判定,
但是通過設置這個屬性,可以強制采用顯式指定的類型而不再進行推導。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file:///mnt/sdcard/a.pdf"),"application/pdf");
startActivity(intent);


2.5)component(組件)


component(組件),指定Intent的的目標組件的類名稱。
通常 Android會根據Intent 中包含的其它屬性的信息
,比如action、data/type、category進行查找,最終找到一個
與之匹配的目標組件。
但是,如果 component這個屬性有指定的話,將直接
使用它指定的組件,而不再執行上述查找過程。
指定了這個屬性以后,Intent的其它所有屬性都是可選的。

Intent intent = new Intent();
ComponentName component = 
        new ComponentName(getApplicationContext(), SecondActivity.class);
intent.setComponent(component);
startActivity(intent);

 

2.6)extras(附加信息)


extras(附加信息),是其它所有附加信息的集合。使用extras可以為
組件提供擴展信息,比如,如果要執行“發送電子郵件”這個動作,可以
將電子郵件的標題、正文等保存在extras里,傳給電子郵件發送組件。

 

3.Android如何解析Intent


在應用中,我們可以以兩種形式來使用Intent:

直接Intent:

指定了component屬性的Intent(調用setComponent
(ComponentName)或者setClass(Context, Class)來指定)。
通過指定具體的組件類,通知應用啟動對應的組件。
間接Intent:沒有指定comonent屬性的Intent。這些Intent需要
包含足夠的信息,這樣系統才能根據這些信息,在所有的可用組件
中,確定滿足此Intent的組件。

間接Intent


Intent解析機制主要是通過查找已注冊在AndroidManifest.xml中
的所有IntentFilter及其中定義的Intent,最終找到匹配的Intent。

IntentFilter意圖篩選器
IntentFilter用來描述Activity能夠做些什么事情。
應用程序的組件為了告訴Android自己能響應、處理哪些隱式Intent
請求,可以聲明一個甚至多個Intent Filter。每個Intent Filter描
述該組件所能響應Intent請求的能力——組件希望接收什么類型的請求
行為,什么類型的請求數據。

間接Intent匹配


隱式Intent(Explicit Intents)和Intent Filter(Implicit Intents)
進行比較時的三要素是Intent的動作、數據以及類別。(隱式Intent:指的是在
Intent intent = new Intent()時的java代碼,而Intent filter是在androidmanifest.xml
文件中定義的。)
實際上,一個隱式Intent請求要能夠傳遞給目標組件,必要通過這三個方
面的 檢查。如果任何一方面不匹配,Android都不會將該隱式Intent傳遞
給目標組件。接下來我們講解這三方面檢查的具體規則。

隱式啟動:

Intent intent = new Intent();
intent.setAction("com.anjoyo.myfirsttest");
startActivity(intent);

intent-filter配置:

<activity android:name=".intentfilter.TestActivity">
    <intent-filter >
        <action android:name="com.anjoyo.myfirsttest"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

補充

1.作為一個程序為桌面程序

 

<activity
    android:name=".intent.MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.HOME"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>
<category android:name="android.intent.category.HOME"/>回到桌面

<category android:name="android.intent.category.LAUNCHER"/>作為應用的入口

2.隱式Intent(Explicit Intents)和Intent Filter(Implicit Intents)


進行比較時的三要素是Intent的動作、數據以及類別。
實際上,一個隱式Intent請求要能夠傳遞給目標組件,必要通過這三個方面
的 檢查。如果任何一方面不匹配,Android都不會將該隱式Intent傳遞給目
標組件。接下來我們講解這三方面檢查的具體規則。
1).動作測試
<intent-filter>元素中可以包括子元素<action>,比如:

<intent-filter>
    <action android:name=”com.example.project.SHOW_CURRENT” />
    <action android:name=”com.example.project.SHOW_RECENT” />
    <action android:name=”com.example.project.SHOW_PENDING” />
</intent-filter>

一條<intent-filter>元素至少應該包含一個<action>,否則任何Intent
請求都不能和 該<intent-filter>匹配。
如果隱式啟動一個Activity,那么還需要在<intent-filter>中加入
 

<category android:name="android.intent.category.DEFAULT"/>

例子:

<activity android:name="xxx"> 
    <intent-filter >
        <action android:name="com.anjoyo.mysecond"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
    <intent-filter >
        <action android:name="com.anjoyo.mysecond2"/>
        <action android:name="com.anjoyo.mysecond3"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

action匹配規則:找到一個與隱式Intent的Action定義相同的Intent filter.

2).類別測試
<intent-filter>元素可以包含<category>子元素,比如:

<intent-filter>
    <category android:name=”android.Intent.Category.DEFAULT” />
    <category android:name=”android.Intent.Category.BROWSABLE” />
</intent-filter>

只有當Intent請求中所有的Category與組件中某一個IntentFilter的
<category>完全匹配時,才會讓該Intent請求通過測試,IntentFilter
中多余的<category>聲明並不會導致匹配失敗。

3).數據在<intent-filter>中的描述如下:

<intent-filter>
    <data android:type=”video/mpeg” android:scheme=”http” . . . />
    <data android:type=”audio/mpeg” android:scheme=”http” . . . />
</intent-filter>

<data>元素指定了希望接受的Intent請求的數據URI和數據類型,
URI被分成三部分來進行匹配:scheme、authority和path。
其中,用setData()設定的Intent請求的URI數據類型和scheme必須
與IntentFilter中所指定的一致。若IntentFilter中還指定了
authority或path,它們也需要相匹配才會通過測試。

如:http://www.baidu.com  http就是schema
tel:1390023232  tel就是schema
file:///mnt/sdcard/Picture/xx.jpg file就是schema

例子:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:123343"));
startActivity(intent);
<activity 
    android:name=".intent.ForthActivity">
    <intent-filter>
        <action android:name="android.intent.action.CALL"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="tel"/>
    </intent-filter>
</activity>


3.
1).向下一個Activity傳遞數據(使用Bundle和Intent.putExtras)

Intent it = new Intent(Activity.Main.this, Activity2.class); 
Bundle bundle=new Bundle(); 
bundle.putString("name", "This is from MainActivity!"); 
it.putExtras(bundle); 
startActivity(it);


對於數據的獲取可以采用:

Bundle bundle=getIntent().getExtras(); 
String name=bundle.getString("name");

2).向上一個Activity返回結果
(使用setResult,針對startActivityForResult(it,REQUEST_CODE)啟動的Activity)
   

Intent intent=getIntent(); 
    Bundle bundle2=new Bundle(); 
    bundle2.putString("name", "This is from ShowMsg!"); 
    intent.putExtras(bundle2); 
    setResult(RESULT_OK, intent);

    
回調上一個Activity的結果處理函數(onActivityResult)

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==REQUEST_CODE)
{ 
if(resultCode==RESULT_CANCELED) 
    setTitle("cancle"); 
else if (resultCode==RESULT_OK) 
{ 
    String temp=null; 
    Bundle (); 
    if(bundle!=null) 
        bundle=data.getExtras
    temp=bundle.getString("name"); 
    setTitle(temp); 
} } }

簡單例子:
1,調用web瀏覽器

Uri myBlogUri = Uri.parse(http://www.cmd100.com); 
 intent = new Intent(Intent.ACTION_VIEW, myBlogUri);

  2,地圖

Uri mapUri = Uri.parse("geo:38.899533,-77.036476"); 
 intent = new Intent(Intent.ACTION_VIEW, mapUri);

  3,調撥打電話界面

Uri telUri = Uri.parse("tel:10086"); 
 intent = new Intent(Intent.ACTION_DIAL, telUri);


4,直接撥打電話

Uri callUri = Uri.parse("tel:10086"); 
 intent = new Intent(Intent.ACTION_CALL, callUri);

  5,卸載

Uri uninstallUri = Uri.fromParts("package", "xxx", null); 
 intent = new Intent(Intent.ACTION_DELETE, uninstallUri);


6,安裝

Uri installUri = Uri.fromParts("package", "xxx", null); 
 intent = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);


7,播放

Uri playUri = Uri.parse("file:///sdcard/download/everything.mp3"); 
 intent = new Intent(Intent.ACTION_VIEW, playUri);


8,發郵件

Uri emailUri = Uri.parse("mailto:xx@xxx.com"); 
 intent = new Intent(Intent.ACTION_SENDTO, emailUri);

  9,發郵件

intent = new Intent(Intent.ACTION_SEND); 
 String[] tos = { "xx@xxx.com" }; 
 String[] ccs = { "xx@xxx.com" }; 
 intent.putExtra(Intent.EXTRA_EMAIL, tos); 
 intent.putExtra(Intent.EXTRA_CC, ccs);
 intent.putExtra(Intent.EXTRA_TEXT, "body"); 
 intent.putExtra(Intent.EXTRA_SUBJECT, "subject"); 
 intent.setType("message/rfc882"); 
 Intent.createChooser(intent, "Choose Email Client");


10,發短信

Uri smsUri = Uri.parse("tel:10086"); 
 intent = new Intent(Intent.ACTION_VIEW, smsUri); 
 intent.putExtra("sms_body", "hello~"); 
 intent.setType("vnd.android-dir/mms-sms");


11,直接發郵件

Uri smsToUri = Uri.parse("smsto://10086"); 
 intent = new Intent(Intent.ACTION_SENDTO, smsToUri); 
 intent.putExtra("sms_body", "hello");


12,發彩信

Uri mmsUri = Uri.parse("content://media/external/images/media/23");
 intent = new Intent(Intent.ACTION_SEND); 
 intent.putExtra("sms_body", "hello"); 
 intent.putExtra(Intent.EXTRA_STREAM, mmsUri); 
 intent.setType("image/png");


用獲取到的Intent直接調用startActivity(intent)就可以了。
==================================================================


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM