Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android筆記五.深入理解Intent和IntentFilters(一)

Android筆記五.深入理解Intent和IntentFilters(一)

編輯:關於Android編程

深入理解Intent和IntentFiler(一) Jiangdg_VIP http://blog.csdn.net/u012637501 為了比較深刻的理解並靈活使用Intent,我計劃將這部分的學習分為兩步:一是深入理解Intent基本概念以及其類;二是,通過實例來闡述如何靈活使用Intent來啟動一個組件以及實現組件之間的傳遞數據。 一、什麼是Intent,有什麼作用? Android的應用程序包括三大組件:Activity、Service、BroadcastReceiver,為了方便不同組件之間的交流通信,應用程序就采用了一種統一的方式啟動組件及傳遞數據,即使用Intent。 Intent封裝了Android應用程序需要啟動某個組件的"意圖",Intent類的對象是組件間的通信載體,一個Intent對象就是一組信息,其包含接收Intent組件所關心的信息(如action 和 Data)和Android 系統關心的信息(如Category等)。也就是說,發送"意圖"的組件通過Intent對象所包含的內容,來啟動指定的(即Component屬性)或通過篩選(即Action&Category屬性)的某(些)組件,然後實施相應的動作(即Action屬性)並傳遞相應的數據(即Data屬性)以便完成相應的動作。 二、Intent是如何實現組件間相互調用? 1.Intent實現 \ 上圖請求一個Activity組件的簡單的實現流程圖,算是用的最多的Intent解析實例。 首先,發出"意圖"的組件,通過調用Context.startActivity(intent)開始啟動組件:發出"意圖"的組件傳入已經構好的Intent對象(為一組信息,它決定了是否能夠成功的啟動另一個組件); 然後,調用"動作"實際的執行著Instrumentation對象,它是整個應用激活的Activity管理者,集中負責應用內所有Activity的運行。它有一個隱藏的方法execStartActivity方法,就是負責根據Intent啟動Activity。該方法去掉一些細節,它做得最重要的事情,就是將此調用,通過RPC的方式,傳遞到ActivityManagerService。 最後,ActivityManagerService會將這些關鍵信息遞交給另一個服務PackageManagerService,此服務掌握整個軟件包及其各組件的信息,它會將傳遞過來的Intent,與已知的所有Intent Filters進行匹配(如果帶有Component信息,就不用比了)。如果找到了,就把相關Component的信息通知回AcitivityManagerService,在這裡,會完成啟動Activity這個很多細節的事情。 2.Intent匹配 到底發出"意圖"的組件是如何找到所需的組件呢?在這裡,Intent Filters就開始起作用了,Intent Filters定義在AndroidMainFest.xml文件中,每一個Activity都會有一個元素,它包含了、等子元素。當我們的intent對象沒有包含Component信息時,這種"意圖"被稱之為隱形"意圖"。也就是說,"意圖"沒有指明具體要啟動哪個組件以及完成什麼樣的動作。這時我們就需要通過Intent Filters中的子元素進行信息匹配,從而確定當前包含Intent Filters屬性的Activity是不是我們要啟動的那個(些)組件。即發送"意圖"組件配置好intent對象,被啟動組件實現Intent Filters屬性,最後,發送組件會根據被啟動組件AndroidMainFest.xml中的信息來確定它是不是目標組件。 \ 三、Intent對象詳解 Intent類的對象是組件間的通信載體,利用Intent對象我們可以很方便的實現不同組件之間的通信。一個Intent對象就是一組信息,這些信息都是通過其Component、Action、CategZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcnmhokRhdGGhokV4dHJhus1GbGFn1eI31tbK9NDUzOXP1rXEoaNJbnRlbnS0+rHtwctBbmRyb2lk06bTw7XExvS2rw=="意圖",Android應用將會根據Intent來啟動指定組件,至於到底啟動哪個組件,則取決於Intent的屬性。 1.Action屬性 Action屬性為一個普通的字符串,它代表了該Intent對象要完成一個什麼樣的"動作"。當我們為Intent對象指明了一個action時,被啟動的組件就會依照這個動作的指示表現出相應的行為,比如查看、撥打、編輯等,需要注意的是一個組件(如Activity)只能有一個action。我們可以方便自己的應用程序組件之間的通信,自定義action的(字符串)創建新的動作;也可以直接使用Intent類中的靜態成員變量,比如ACTION_VIEW,ACTION_PICK,它們是Android中為action屬性預定義的一批action變量。 在設置Intent對象Action屬性時,有兩種:
(1)自定義字符串
public final String CUSTOME_ACTION="intent.action.CUSTOME_JIANG";//字符串可以任意
Intent intent=new Intent();
intent.setAction(ActionAttr.CUSTOME_ACTION); //注意:ActionAttr為我們創建的類,也可以使用this.CUSTOME_ACTION
(2)使用系統預定action常量
Intent intent=new Intent();
intent.setAction(Intent.ACTION_CALL);    //其中ACTION_CALL為Intent類的靜態成員變量,可以類直接調用
                                        //對應字符串"android.intent.action.CALL"
2.Data屬性 Action屬性為Intent對象描述了一個"動作",那麼Data屬性就為Intent對象的Action屬性提供了操作的數據。這裡需要注意的是,Data屬性只接受一個Uri對象,一個Uri對象通常通過如下形式的字符串來表示: Uri字符串格式:scheme://host:port/path 舉例: content://com.android.contacts/contacts/1或tel://18819463209 在設置Intent對象Data屬性時可以這樣:
Intent intent=new Intent();
String data="content://com.android.contacts/contacts/1";
Uri uri=Uri.parse(data);//將字符串轉換為Uri
intent.setData(uri);
或者
Intent intent=new Intent();
intent.setData(Uri.parse("content://com.android.contacts/contacts/1"));

博主筆記1:action屬性和data屬性為Intent所傳遞信息的主要部分,action/data屬性舉例: ACTION_VIEW content://contacts/people/1 -- 傳遞的信息: 顯示 號碼為1的人相關信息 ACTION_DIAL content://contacts/people/1 -- 傳遞的信息:給編號為1的人 打 電話 ACTION_VIEW tel:123 -- 傳遞的信息:將號碼123 顯示 ACTION_DIAL tel:123 --傳遞的信息: 撥打 號碼123 ACTION_EDIT content://contacts/people/1 -- 傳遞的信息: 編輯編號為1的聯系人 ACTION_VIEW content://contacts/people/ -- 傳遞的信息:列出顯示所有聯系人.如果希望在查看某個聯系人,需要定義一個新的intent並且屬性設置為{ ACTION_VIEW content://contacts/N } 傳遞到一個新的Activity。 總結:action屬性、data屬性是intent的主要屬性。
3.Catagory屬性 通過Action,配合Data或Type屬性可以准確的表達出一個完整的意圖了。但為了使的"意圖"更加精確,我們也給意圖添加一些約束,這個約束由"意圖"的Catagory屬性實現。一個意圖只能指定一個action屬性,但是可以添加一個或多個Catagory屬性。Category屬性可以自定義字符串實現,但為了方便不同應用之間的通信還可以設置系統預定義的Category常量。調用方法addCategory 用來為Intent 添加一個Category,方法removeCategory 用來移除一個Category;getCategories方法返回已定義的Category。 在設置Intent對象Categoty屬性時可以這樣:
(1)自定義字符串
public final String CUSTOME_CATEGORY="intent.action.CUSTOME_CATEGORY";//字符串可以任意
Intent intent=new Intent();
intent.addCategory(ActionAttr.CUSTOME_CATEGORY); 
(2)使用系統預定action、category常量
    以下代碼實現當點擊某個按鈕時,通過Intent對象實現返回HOME桌面。
Intent intent=new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);//返回Home桌面 

博主筆記2:一般來說Action屬性和Category屬性都是同時使用的。在Android中,所有應用主Activity(就是單獨啟動時候,第一個運行的那個Activity...),都需要能夠接受一個Category為 CATEGORY_LAUNCHER,Action為ACTION_Main的意圖。對於發出"意圖"的組件,我們可以通過setAction()、addCategory()方法為"意圖"添加action屬性或者同時添加Action、Category屬性;對於接收"意圖"的組件,在AndroidManifest.xm文件中,我們可以這樣設置: //默認Action //默認Category //默認Category 注釋:發出"意圖"的Activity將Category為 CATEGORY_LAUNCHER,Action為ACTION_Main,接收"意圖"的Activity須設置一個默認的Category屬性CATEGORY_DEFAULT,這裡不能將其設置為CATEGORY_LAUNCHER否者會報錯。另外,如果我們使用了系統預定義的action常量,則需要在AndroidManifest.xm文件中添加相應的權限,這方面的內容我們將在第二部分講到。
4.Type屬性 Type屬性用於指定該Data所指定Uri對應的MIME類型,這種類型可以是任何自定義的MIME類型,只要符合abc/xyz格式的字符串即可。這裡需要注意的是,Type屬性和Data屬性一般會出現相互覆蓋的情況,如果希望Intent既有Data屬性也有Type屬性,必須通過setDataAndType()方法來實現。對於Type屬性的理解,我記得有篇博文是這樣作比方的:說了Data,就必須要提Type,很多時候,會有人誤解,覺著Data和Type的差別,就猶如泡妞和泡馬子之間的差別一樣,微乎其微。但其實不然,Type信息,是用MIME來表示的,比如text/plain,這樣的東西。說到這裡,兩者差別就很清晰了,Data就是門牌號,指明了具體的位置,具體問題具體分析,而type,則是強調物以類聚,解決一批量的問題。實際的例子是這樣的,比如,從某個應用撥打一個電話,會發起的是action為ACTION_DIAL且data為tel:xxx這樣的Intent,對應的人類語言就是撥打xxx的電話,很具象。而如果使用type,就寬泛了許多,比如浏覽器收到一個未知的MIME類型的數據(比如一個視頻...),就會放出這樣的Intent,求系統的其他應用來幫助,表達成自然語言應該就是:查看pdf類文檔,這樣的。
博主筆記3:MIME類型? MIME(Multipurpose Internet Mail Extensions)多用途互聯網郵件擴展類型就是設定某種擴展名的文件用一種應用程序來打開的方式類型,當該擴展名文件被訪問的時候,浏覽器會自動使用指定應用程序來打開。多用於指定一些客戶端自定義的文件名,以及一些媒體文件打開方式。最早的HTTP協議中,並沒有附加的數據類型信息,所有傳送的數據都被客戶程序解釋為超文本標記語言HTML 文檔,而為了支持多媒體數據類型,HTTP協議中就使用了附加在文檔之前的MIME數據類型信息來標識數據類型。MIME意為多功能Internet郵件擴展,它設計的最初目的是為了在發送電子郵件時附加多媒體數據,讓郵件客戶程序能根據其類型進行處理。然而當它被HTTP協議支持之後,它的意義就更為顯著了。它使得HTTP傳輸的不僅是普通的文本,而變得豐富多彩。每個MIME類型由兩部分組成,前面是數據的大類別,例如聲音audio、圖象image等,後面定義具體的種類。 常見的MIME類型(通用型): 超文本標記語言文本 .html text/html xml文檔 .xml text/xml XHTML文檔 .xhtml application/xhtml+xml 普通文本 .txt text/plain RTF文本 .rtf application/rtf PDF文檔 .pdf application/pdf Microsoft Word文件 .word application/msword PNG圖像 .png image/png GIF圖形 .gif image/gif JPEG圖形 .jpeg,.jpg image/jpeg au聲音文件 .au audio/basic MIDI音樂文件 mid,.midi audio/midi,audio/x-midi RealAudio音樂文件 .ra, .ram audio/x-pn-realaudio MPEG文件 .mpg,.mpeg video/mpeg AVI文件 .avi video/x-msvideo GZIP文件 .gz application/x-gzip TAR文件 .tar application/x-tar 任意的二進制數據 application/octet-stream
5.Ertras屬性 通過上面的這些項,識別問題,基本完美解決了,剩下一個重要的問題,就是傳參。Extras是用來做這個事情的,它是一個Bundle 類的對象,有一組可序列化的key/value對組成。每一個Action都會有與之對應的key和value類型約定,發起Intent的時候,需要按照要求把Data不能表示的額外參數放入Extras中。 6.Flags屬性 能識別,有輸入,整個Intent基本就完整了,但還有一些附件的指令,需要放在Flags中帶過去。顧名思義,Flags是一個整形數,有一些列的標志 位構成,這些標志,是用來指明運行模式的。比如,你期望這個意圖的執行者,和你運行在兩個完全不同的任務中(或說進程也無妨吧...),就需要設置FLAG_ACTIVITY_NEW_TASK 的標志位。 7.Component屬性 通常來說,"意圖"可分為顯示intent和隱式intent。Intent Filters它是用來描述一個Activity或 Serveice等組件,我們通過在組件AndroidManifest.xml中元素中添加等屬性,以滿足期望能夠響應怎麼樣的Intent,這種沒有指明要啟動組件名方式就稱之為隱式intent。當然,我們也可以使"意圖"實現啟動指定的組件,即稱之為顯示intent,主要通過Component屬性來實現。Intent的Component屬性需要接受一個ComponentName對象,這個對實現將要啟動指定組件的類名、類所在的包名綁定在intent上。
ComponentName comp=new ComponentName(ComponentAttr.this,SecondaryActivity.class); 
Intent intent=new Intent();
intent.setComponent( comp);//設置intent的Component屬性,指定"意圖"要啟動組件的包和類名
注釋:第一句用於創建一個ComponentName對象,來指定包名和類型-這就可以唯一地確定一個組件類。
四、Intent相關類 1.Activity類 這裡我們只需學習使用Intent啟動Activity組件將要用的的方法 void startActivity(Intent intent) 作用:啟動Activity,具體啟動哪個Activity和怎麼樣啟動由intent屬性決定 void startActivityForResult(Intent intent, int requestCode) 作用:啟動Activity,並返回一個結果。當被啟動的Activity退出時,會調用 onActivityResult() 方法並向其傳入一個 requestCode參數,這個 requestCode參數為非負數(>0),作用是標志是哪個Activity組件發出的"意圖",需要注意的是如果 requestCode小於0時,這個方法的只能用於啟動一個Activity而不能返回值了。另外,Intent的action屬性設為能夠返回一個結果,如果設置為 Intent.ACTION_MAIN or Intent.ACTION_VIEW,也是不能獲取結果的。 待寫:另外還有如何啟動Service、BroadcastReceiver組件的方法,這以後學到了再說吧。 2.Intent類 (1)構造函數
Intent():創建一個空的構造函數 Intent(Intent o) :拷貝構造函數
Intent(String action) :創建一個具有acion屬性的意圖對象
Intent(String action, Uri uri):創建一個帶action屬性的意圖,接受一個Uri對象
Intent(Context packageContext, Class cls):創建一個已經指定組件的意圖
Intent(String action, Uri uri, Context packageContext, Class cls) 為一個指定的組件創建一個帶action和data屬性的意圖 (2)常用方法
Intent addCategory(String category) Add a new category to the intent. Intent addFlags(int flags) Add additional flags to the intent (or with existing flags value). String getAction() Retrieve the general action to be performed, such as ACTION_VIEW. Set getCategories() Return the set of all categories in the intent. ComponentName getComponent() Retrieve the concrete component associated with the intent. Uri getData() Retrieve data this intent is operating on. Bundle getExtras() Retrieves a map of extended data from the intent. int getFlags() Retrieve any special flags associated with this intent. static Intent getIntent(String uri) This method was deprecated in API level 4. Use parseUri(String, int) instead. String getPackage() Retrieve the application package name this Intent is limited to. String getScheme() Return the scheme portion of the intent's data. Intent getSelector() Return the specific selector associated with this Intent. Rect getSourceBounds() Get the bounds of the sender of this intent, in screen coordinates. String getType() Retrieve any explicit MIME type included in the intent. boolean hasCategory(String category) Check if a category exists in the intent. boolean hasExtra(String name) Returns true if an extra value is associated with the given name. static Intent makeMainActivity(ComponentName mainActivity) Create an intent to launch the main (root) activity of a task. static Intent makeMainSelectorActivity(String selectorAction, String selectorCategory) Make an Intent for the main activity of an application, without specifying a specific activity to run but giving a selector to find the activity. static Intent parseIntent(Resources resources, XmlPullParser parser, AttributeSet attrs) Parses(解析) the "intent" element (and its children) from XML and instantiates an Intent object. static Intent parseUri(String uri, int flags) Create an intent from a URI. Intent putExtra(String name, int value) Add extended data to the intent. Intent putExtra(String name, CharSequence value) Add extended data to the intent. Intent setAction(String action) Set the general action to be performed. Intent setClass(Context packageContext, Class cls) Convenience for calling setComponent(ComponentName) with the name returned by a Class object. Intent setClassName(Context packageContext, String className) Convenience for calling setComponent(ComponentName) with an explicit class name. Intent setClassName(String packageName, String className) Convenience for calling setComponent(ComponentName) with an explicit application package name and class name. Intent setComponent(ComponentName component) (Usually optional) Explicitly set the component to handle the intent. Intent setData(Uri data) Set the data this intent is operating on. Intent setFlags(int flags) Set special flags controlling how this intent is handled. Intent setPackage(String packageName) (Usually optional) Set an explicit application package name that limits the components this Intent will resolve to. void setSourceBounds(Rect r) Set the bounds of the sender of this intent, in screen coordinates. Intent setType(String type) Set an explicit MIME data type. String toString() Returns a string containing a concise(簡潔), human-readable (可讀)description of this object. String toUri(int flags) Convert this Intent into a String holding a URI representation of it. (3)類靜態成員變量 即ACTION、CAYEGORY常量等,由Intent或其對象調用設置intent屬性 a.標准Activity Actions 以下actions常量,用於Intent定義用來操作各種Activity,通常使用 startActivity(Intent)方法實現。
  • ACTION_MAIN //傳遞返回到主Activity動作
  • ACTION_VIEW //傳遞顯示動作
  • ACTION_ATTACH_DATA
  • ACTION_EDIT //傳遞編輯動作
  • ACTION_PICK
  • ACTION_CHOOSER //傳遞選擇動作
  • ACTION_GET_CONTENT
  • ACTION_DIAL
  • ACTION_CALL
  • ACTION_SEND
  • ACTION_SENDTO
  • ACTION_ANSWER //傳遞接聽電話動作
  • ACTION_INSERT
  • ACTION_DELETE
  • ACTION_RUN
  • ACTION_SYNC
  • ACTION_PICK_ACTIVITY
  • ACTION_SEARCH
  • ACTION_WEB_SEARCH
  • ACTION_FACTORY_TEST b.標准Broadcast Actions 以下"意圖"的action屬性常量,用於接收廣播,通常使用 registerReceiver(BroadcastReceiver, IntentFilter)方法或者在AndroidManifest.xml 文件中定義了屬性的Activity。
    • ACTION_TIME_TICK
    • ACTION_TIME_CHANGED
    • ACTION_TIMEZONE_CHANGED
    • ACTION_BOOT_COMPLETED
    • ACTION_PACKAGE_ADDED
    • ACTION_PACKAGE_CHANGED
    • ACTION_PACKAGE_REMOVED
    • ACTION_PACKAGE_RESTARTED
    • ACTION_PACKAGE_DATA_CLEARED
    • ACTION_UID_REMOVED
    • ACTION_BATTERY_CHANGED
    • ACTION_POWER_CONNECTED
    • ACTION_POWER_DISCONNECTED
    • ACTION_SHUTDOWN c.標准Categories常量 為Action增加額外的附加類別信息,通常使用addCategory (String category)方法。
      • CATEGORY_DEFAULT
      • CATEGORY_BROWSABLE
      • CATEGORY_TAB
      • CATEGORY_ALTERNATIVE
      • CATEGORY_SELECTED_ALTERNATIVE
      • CATEGORY_LAUNCHER
      • CATEGORY_INFO
      • CATEGORY_HOME
      • CATEGORY_PREFERENCE
      • CATEGORY_TEST
      • CATEGORY_CAR_DOCK
      • CATEGORY_DESK_DOCK
      • CATEGORY_LE_DESK_DOCK
      • CATEGORY_HE_DESK_DOCK
      • CATEGORY_CAR_MODE
      • CATEGORY_APP_MARKET d.標准Extra Data常量 通過putExtra(String, Bundle)方法實現。
        • EXTRA_ALARM_COUNT
        • EXTRA_BCC
        • EXTRA_CC
        • EXTRA_CHANGED_COMPONENT_NAME
        • EXTRA_DATA_REMOVED
        • EXTRA_DOCK_STATE
        • EXTRA_DOCK_STATE_HE_DESK
        • EXTRA_DOCK_STATE_LE_DESK
        • EXTRA_DOCK_STATE_CAR
        • EXTRA_DOCK_STATE_DESK
        • EXTRA_DOCK_STATE_UNDOCKED
        • EXTRA_DONT_KILL_APP
        • EXTRA_EMAIL
        • EXTRA_INITIAL_INTENTS
        • EXTRA_INTENT
        • EXTRA_KEY_EVENT
        • EXTRA_ORIGINATING_URI
        • EXTRA_PHONE_NUMBER
        • EXTRA_REFERRER
        • EXTRA_REMOTE_INTENT_TOKEN
        • EXTRA_REPLACING
        • EXTRA_SHORTCUT_ICON
        • EXTRA_SHORTCUT_ICON_RESOURCE
        • EXTRA_SHORTCUT_INTENT
        • EXTRA_STREAM
        • EXTRA_SHORTCUT_NAME
        • EXTRA_SUBJECT
        • EXTRA_TEMPLATE
        • EXTRA_TEXT
        • EXTRA_TITLE
        • EXTRA_UID e.Flags 通過 setFlags(int) 和addFlags(int)設置intent的flags屬性。
          • getFlags()
          • addFlags(int)
          • FLAG_GRANT_READ_URI_PERMISSION
          • FLAG_GRANT_WRITE_URI_PERMISSION
          • FLAG_GRANT_PERSISTABLE_URI_PERMISSION
          • FLAG_GRANT_PREFIX_URI_PERMISSION
          • FLAG_DEBUG_LOG_RESOLUTION
          • FLAG_FROM_BACKGROUND
          • FLAG_ACTIVITY_BROUGHT_TO_FRONT
          • FLAG_ACTIVITY_CLEAR_TASK
          • FLAG_ACTIVITY_CLEAR_TOP
          • FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
          • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
          • FLAG_ACTIVITY_FORWARD_RESULT
          • FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
          • FLAG_ACTIVITY_MULTIPLE_TASK
          • FLAG_ACTIVITY_NEW_DOCUMENT
          • FLAG_ACTIVITY_NEW_TASK
          • FLAG_ACTIVITY_NO_ANIMATION
          • FLAG_ACTIVITY_NO_HISTORY
          • FLAG_ACTIVITY_NO_USER_ACTION
          • FLAG_ACTIVITY_PREVIOUS_IS_TOP
          • FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
          • FLAG_ACTIVITY_REORDER_TO_FRONT
          • FLAG_ACTIVITY_SINGLE_TOP
          • FLAG_ACTIVITY_TASK_ON_HOME
          • FLAG_RECEIVER_REGISTERED_ONLY 參考:http://developer.android.com/reference/android/net/Uri.html
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved