Intent的屬性及Intent-filter配置——Data、Type屬性與intent-filter配置


     Data屬性通常用於向Action屬性提供操作的數據,Data屬性接受一個Uri對象,一個Uri對象通常通過如下形式的字符串來表示:

     content://com.android.contacts/contacts/1

     tel:123

     Uri字符串總滿足如下格式:

     scheme://host:port/path

     例如上面給出content://com.android.contacts/contacts/1,其中content是scheme部分,com.android.contacts是host部分,port部分被省略了,/contacts/1 是path部分。

     Type屬性用於指定該Data所指定Uri對應的MIME類型,這種MIME類型可以是任何自定義的MIME類型,只要符合abc/xyz格式的字符串即可。

     Data屬性與Type屬性的關系比較微妙,這兩個屬性會相互覆蓋,例如:

  • 如果為Intent先設置Data屬性,后設置Type屬性,那么Type屬性將會覆蓋Data屬性。
  • 如果為Intent先設置Type屬性,后設置Data屬性,那么Data屬性將會覆蓋Type屬性。
  • 如果希望Intent既有Data屬性,也有Type屬性,應該調用Intent的setDataAndType()方法。  

    下面的示例演示了Intent的Data與Type屬性互相覆蓋的情形,該示例的界面布局文件很簡單,只定義了三個按鈕,並為三個按鈕綁定了事件監聽器。

    下面是該實例的Activity代碼。

    

package com.example.studyintent;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class DataTypeOverride extends Activity {

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

    public void overrideType(View source)
    {
        Intent intent=new Intent();
        //先為Intent設置Type屬性
        intent.setType("abc/xyz"); //再為Intent設置Data屬性,覆蓋Type屬性
        intent.setData(Uri.parse("lee://www.fkjava.org:8888/test"));
        Toast.makeText(this, intent.toString(),Toast.LENGTH_LONG).show();
    }
    
    public void overrideData(View source)
    {
        Intent intent=new Intent();
        //先為Intent設置Data屬性
        intent.setData(Uri.parse("lee://www.fkjava.org:8888/mypath")); //再為Intent設置Type屬性,覆蓋Data屬性
        intent.setType("abc/xyz");
        Toast.makeText(this, intent.toString(),Toast.LENGTH_LONG).show();
    }
    
    public void dataAndType(View source)
    {
        Intent intent=new Intent();
        //同時設置Intent的Data、Type屬性
        intent.setDataAndType(Uri.parse("lee://www.fkjava.org:8888/mypath"), "abc/xyz");
        Toast.makeText(this, intent.toString(), Toast.LENGTH_LONG).show();
    }
    
    
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.data_type_override, menu);
        return true;
    }

}

      上面的三個事件監聽方法分別為Intent設置了Data、Type屬性,第一個事件監聽方法先設置Type屬性,再設置Data屬性,這將導致Data屬性覆蓋Type屬性,單擊按鈕激發該事件監聽方法,將可以看到如圖5.6所示的Toast輸出。

      

從圖5.6可以看出,此時的Intent只有Data屬性,Type屬性被覆蓋了。

上面的示例中第二個事件監聽方法先設置了Data屬性、再設置了Type屬性,這將導致Type屬性覆蓋Data屬性,單擊按鈕激發該事件監聽方法,將可以看到如圖5.7所示輸出。

 

上面的示例中第三個事件監聽方法同時設置了Data、Type屬性、這樣該Intent才會同時具有Data、Type屬性。

   在AndroidManifest.xml文件中為組件聲明Data、Type屬性都通過<data.../>元素,<data.../>元素的格式如下:

  

<data android:mimeType=""
android:scheme=""
android:host=""
android:port=""
android:path=""
android:pathPrefix=""
android:pathPattern=""/>

    上面<data.../>元素支持如下屬性。

  • mimeType:用於聲明該組件所能匹配的Intent的Type屬性。
  • scheme:用於聲明該組件所能匹配的Intent的Data屬性的scheme部分。
  • host:用於聲明該組件所能匹配的Intent的Data屬性的host部分。
  • port:用於聲明該組件所能匹配的Intent的Data屬性的port部分。
  • path:用於聲明該組件所能匹配的Intentde Data屬性的path部分。
  • pathPrefix:用於聲明該組件所能匹配的Intent的Data屬性的path前綴。
  • pathPattern:用於聲明該組件所能匹配的Intent的的Data屬性的path字符串模板。 

    Intent的Type屬性也用於指定該Intent的要求,必須對應組件中<intent-filter.../>元素中<data.../>子元素的mineType屬性與此相同,才能啟動該組件。

    Data屬性的“匹配”過程有些差別,它會先檢查<intent-filter.../>里的<data.../>子元素然后:

  • 如果目標組件的Data子元素只指定了android:scheme屬性,那么只要Intent的Data屬性的scheme部分與android:scheme屬性值相同,即可啟動該組件。
  • 如果目標組件的<data.../>子元素只指定了android:scheme、android:host屬性,那么只要Intent的Data屬性的scheme、host部分與android:scheme、android:host屬性值相同,即可啟動該組件。
  • 如果目標組件的<data.../>子元素指定了android:scheme、android:host、android:port屬性,那么要求Intent的Data屬性的scheme、host、port部分與android:scheme、android:host、android:host屬性值相同,即可啟動該組件。 
  • 如果目標組件的<data.../>子元素只指定了android:scheme、android:host、android:path屬性,那么只要求Intent的Data屬性的scheme、host、port部分與android:scheme、android:host、android:path屬性值相同,即可啟動該組件。
  • 如果目標組件的<data.../>子元素指定了android:scheme、android:host、android:port、android:path屬性,那么就要求Intent的Data屬性scheme、host、port、path部分依次與android:scheme、android:host、android:port、android:path屬性值相同,才可啟動該組價。

     下面的示例測試了Intent的Data屬性與<data.../>元素配置的關系,該示例依次配置了如下5個Activity。

 <activity
            android:name="com.example.studyintent.SchemeActivity"
            android:icon="@drawable/ic_scheme"
            android:label="指定scheme的Activity" >
            <intent-filter>
                <action android:name="xx" />

                <category android:name="android.intent.category.DEFAULT" />
                <!-- 只要Intent的Data屬性的scheme是lee,即可啟動該Activity -->
                <data android:scheme="lee" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.studyintent.SchemeHostPortActivity"
            android:icon="@drawable/ic_host"
            android:label="指定scheme、host、port的Activity" >
            <intent-filter>
                <action android:name="xx" />

                <category android:name="android.intent.category.DEFAULT" />
                <!-- 只要Intent的Data屬性和scheme是lee,且host是www.fkjava.orgport是8888即可啟動該Activity -->
               <data android:host="www.fkjava.org" android:port="8888" android:scheme="lee" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.studyintent.SchemeHostPathActivity"
            android:icon="@drawable/ic_sp"
            android:label="指定scheme、host、path的Activity" >
            <intent-filter>
                <action android:name="xx" />

                <category android:name="android.intent.category.DEFAULT" />
                <!--
                      只要Intent的Data屬性的scheme是lee,且host是www.fkjava.org path是/maypath,
                        即可啟動該Activity




                -->
               <data android:host="www.fkjava.org" android:path="/mypath" android:scheme="lee" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.studyintent.SchemeHostPortPathActivity"
            android:icon="@drawable/ic_path"
            android:label="指定scheme、host、port、path的Activity" >
            <intent-filter>
                <action android:name="xx" />

                <category android:name="android.intent.category.DEFAULT" />
                <!--
                 需要Intent的Data屬性的scheme是lee,且host是www.fkjava.org  port是8888,
                 且path是/mypath,才可啟動該Activity




                -->
               <data android:host="www.fkjava.org" android:path="/mypath" android:port="8888" android:scheme="lee" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.studyintent.SchemeHostPortPathTypeActivity"
            android:icon="@drawable/ic_type"
            android:label="指定scheme、host、port、path、type的Activity" >
            <intent-filter>
                <action android:name="xx" />

                <category android:name="android.intent.category.DEFAULT" />
                <!--
                 需要Intent的Data屬性的scheme是lee,且host是www.fkjava.org port是8888,
                 且path是/mypath 且type是abc/xyz,才可啟動該Activity




                -->
               <data android:host="www.fkjava.org" android:mimeType="abc/xyz" android:path="/mypath" android:port="8888" android:scheme="lee" />
            </intent-filter>
        </activity>

 上面的配置文件中配置了5個Activity,這個5個Activity的實現類都非常簡單,它們都僅在界面上顯示一個TextView,並不顯示其他內容。關於這5個Activity的<data.../>子元素配置的說明如下:

  • 第一個Activity:只要Intent的Data屬性的scheme是lee,即可啟動該Activity。
  • 第二個Activity:只要Intent的Data屬性的scheme是lee,且host是www.fkjava.org、port是8888,即可啟動該Activity。
  • 第三個Activiyt:只要Intent的Data屬性的scheme是lee,且host是www.fkjava.org、path是/mypath,即可啟動該Activiyt。
  • 第四個Activiyt:需要Intent的Data屬性的scheme是lee,且host是www.fkjava.org、port是8888、且path是/mypath,才可啟動該Activity。
  • 第五個Activity:需要Intent的Data屬性的scheme是lee,且host是www.fkjava.org、port是8888、且path是/mypaht,且type是abc/xyz,才可啟動該Activity。

     下面是啟動第一個Activity的方法:

 

  public void scheme(View source)
    {
        Intent intent=new Intent();
        //只設置Intent的Data屬性
        intent.setData(Uri.parse("lee://www.crazyit.org:1234:test"));
        startActivity(intent);
    }

由於上面的Data屬性,只有scheme為lee,也就是只有1個Activity符合條件,因此通過該方法啟動Activity時,將可以看到如圖5.8所示的Activity。

     下面是第二個啟動Activity的方法:

public void schemeHostPort(View source)
    {
        Intent intent=new Intent();
        //只設置Intent的Data屬性
        intent.setData(Uri.parse("lee://www.fkjava.org:8888/test"));
        startActivity(intent);
    }

由於上面的Intent的Data屬性,只有scheme為lee,也就是有第一個Activity符合條件;且該Intent的Data屬性的host為www.fkjava.org、port為8888,因此第二個Activity也符合條件。通過該方法啟動Activity時將可看到啟動5.9所示的選擇Activity的界面。

下面是第3個啟動Activity的方法:

public void schemeHostPath(View source)
    {
        Intent intent=new Intent();
        //只設置Intent的Data屬性
        intent.setData(Uri.parse("lee://www.fkjava.org:1234/mypath"));
        startActivity(intent);
    }

 由於上面Intent的Data屬性,只有scheme為lee,也就是有第一個Activity符合條件;且該Intent的Data屬性的host為www.fkjava.org、path為/mypath,因此第三個Activity也符合條件。通過該方法啟動Activity時,即可看到啟動如圖5.10所示的選擇Activity的界面。

下面是第4個啟動Activity的方法。

public void schemeHostPortPath(View source)
    {
        Intent intent=new Intent();
        //只設置Intent的Data屬性
        intent.setData(Uri.parse("lee://www.fkjava.org:8888/mypath"));
        startActivity(intent);
    }

由於上面Intent的Data屬性,只有scheme為lee,也就只有第一個Activity符合條件;且該Intent的Data屬性為的host為www.fkjava.org、port為8888,因此第二個Activity也符合條件;且該Intent的Data屬性的host為www.fkjava.org、path為/mypath,因此第三個Activity也符合條件;且該Intent的Data屬性的host為www.fkjava.org、port為8888、path為/mypath,因此第四個Activity也符合條件。通過該方法啟動Activity時,將可看到啟動如圖5.11所示的選擇Activity的界面。

    下面是第5個啟動Activity的方法:

public void schemeHostPortPathType(View source)
    {
        Intent intent=new Intent();
        //同時設置Intent的Data、Type屬性
        intent.setDataAndType(Uri.parse("lee://www.fkjava.org:8888/mypath"), "abc/xyz");
        startActivity(intent);
        
    }

上面的Intent不僅指定了Data屬性,也指定了Type屬性,此時符合條件的只有第五個Activity,通過該方法啟動Activity時,將可看到啟動如圖5.12所示的Activity。


免責聲明!

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



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