Data属性通常用于向Action属性提供操作的数据。Data属性接受一个Uri对象,一个Uri对象通常通过如下形式的字符串来表示:
content://com.android.contacts/contacts/1
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()方法。
接下来演示一下覆盖的情况:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
overrideType();
overrideData();
dataAndType();
}
private void overrideType(){
Intent intent = new Intent();
intent.setType("abc/xyz");
intent.setData(Uri.parse("content://com.android.contacts/test"));
Log.e("overrideType",intent.toString());
}
private void overrideData(){
Intent intent = new Intent();
intent.setData(Uri.parse("content://com.android.contacts/test"));
intent.setType("abc/xyz");
Log.e("overrideData",intent.toString());
}
private void dataAndType(){
Intent intent = new Intent();
intent.setDataAndType(Uri.parse("content://com.android.contacts/test"),"abc/xyz");
Log.e("dataAndType",intent.toString());
}
}
运行结果如下:
06-30 09:42:46.260 14239-14239/com.mystudy.kibi.networktype E/overrideType: Intent { dat=content://com.android.contacts/test }
06-30 09:42:46.260 14239-14239/com.mystudy.kibi.networktype E/overrideData: Intent { typ=abc/xyz }
06-30 09:42:46.261 14239-14239/com.mystudy.kibi.networktype E/dataAndType: Intent { dat=content://com.android.contacts/test typ=abc/xyz }
在AndroidManifest.xml文件中为组件声明Data、Type属性都通过< data …/>元素,< data …/>元素格式如下所示:
<intent-filter>
<data android:mimeType=""
android:scheme=""
android:host=""
android:port=""
android:path=""
android:pathPrefix=""
android:pathPattern=""/>
</intent-filter>
- mimeType:用于声明该组件所能配置的Intent的Type属性。
- scheme:用于声明该组件所能配置的Intent的Type属性的scheme部分。
- host:用于声明该组件所能配置的Intent的Type属性的host部分。
- port:用于声明该组件所能配置的Intent的Type属性的port部分。
- path:用于声明该组件所能配置的Intent的Type属性的path部分。
- pathPrefix:用于声明该组件所能配置的Intent的Type属性的path前缀。
- pathPattern:用于声明该组件所能配置的Intent的Type属性的path字符串模版。
Intent的Type属性也用于指定该Intent的要求,必须对应组件中的< intent-filter …/>元素中< data …/>子元素的mimeType属性与此相同,才能启动该组件。
Intent的Data属性则留有差异,程序员为Intent指定Data属性时,Data的属性的Uri对象实际上可分为scheme、host、port和path部分,此时并不要求被启动组件的< intent-filter …/>中< data …/>子元素的android:scheme、android:host、android:port、android:path完全满足。
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:port属性值相同,即可启动该组件。
如果< data …/>子元素只有android:port属性没有指定android:host属性,那么android:port属性将不会起作用。如果目标组件的< data …/>子元素只指定了android:scheme、android:host、android:path属性,那么只要Intent的Data属性的scheme、host、path部分与android:scheme、android:host、android:path属性值相同,即可启动该组件。
如果< data …/>子元素只有android:path属性没有指定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属性值相同,即可启动该组件。
注意:配置Activity的< intent-filter …/>元素时,< action …/>子元素的name属性是随意指定的,这是必需的。如果希望< data …/>子元素能正常起作用,至少要配置一个< action …/>子元素,但该子元素的android:name属性值可以是任意的字符串。