* getType()的调用:(以Android中的NotePad为例)
* 下面是一个隐式(implicit)Intent调用,这句代码存在于NotesList.java中,当插入一条记事时启用。
* startActivity(new Intent(Intent.ACTION_INSERT,getIntent().getData()));
* 那么它到底启动的是哪个Activity呢?*
* 其实这句话可以分解为:
* Intent intent = getIntent();
* intent.setAction(Intent.ACTION_INSERT);
* intent.setData(getIntent().getData() );
* startActivity(intent);
* 在NotesList.java中的onCreate()中有这么几句话:
* if (intent.getData() == null) {
intent.setData(NoteColumns.CONTENT_URI);
}
* 所以getIntent().getData() 就等于 NoteColumns.CONTENT_URI。 *
上面的intent.setData(getIntent().getData() )也就等于
intent.setData(NoteColumns.CONTENT_URI);
*
* 当startActivity(intent)时,intent要去AndroidManifest.xml中匹配,引用网上一段话:
* * intent到底发给哪个activity,须要进行三个匹配,一个是action,一个是category,一个是data。
* 理论上来说,若是intent不指定category,那么无论intent filter的内容是什么都应当是匹配的。
* 然则,若是是implicit intent,android默认给加上一个CATEGORY_DEFAULT,
* 若是intent filter中没有android.intent.category.DEFAULT这个category的话,匹配测试就会失败 * 。
* 所以,若是你的 activity支撑接管implicit intent的话就必然要在intent filter中参加android.intent.category.DEFAULT。*
* *
所以,implicit(隐式) intent调用需匹配三个元素:一个是action,一个是category,一个是data。
我们先来查找第一个元素category:<category android:name="android.intent.category.DEFAULT" />
* 在NotePad Manifest.xml中,含有 <category android:name="android.intent.category.DEFAULT" />
* 的Activity有NotesList、NoteEditor、TitleEditor、NotesLiveFolder 4个。
我们再通过intent.setAction(Intent.ACTION_INSERT)来匹配第二个元素action:
* 含有<action android:name="android.intent.action.INSERT" />则只有NoteEditor。
现在只有NoteEditor,那么我们要调用的Activity是NoteEditor吗?别忘了,还有一个data没有匹配
* 我们通过intent.setData(getIntent().getData() )来匹配第三个元素data:
* NoteEditor中的data为:
* <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
* 这个data中的mimeType就是通过ContentProvider中的getType(Uriuri)获取的。
* 而getType(Uriuri)中的uri就是intent.setData(NoteColumns.CONTENT_URI)中的NoteColumns.CONTENT_URI值。
* 看一下NotePadProvider中的getType(Uriuri)函数:
* @Override
public String getType(Uriuri) {
switch (sUriMatcher.match(uri)) {
case NOTES:
case LIVE_FOLDER_NOTES:
return NoteColumns.CONTENT_TYPE;
case NOTE_ID:
return NoteColumns.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " +uri);
}
}
再看一下sUriMatcher定义:
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);
可以发现sUriMatcher.match(uri)等同于sUriMatcher.match(NoteColumns.CONTENT_URI);
最后看下NoteColumns.CONTENT_URI这个值的定义:
* public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");
*
* 可以得出sUriMatcher.match(uri)匹配成功的返回码为NOTES,进而得出getType(Uriuri)中的
* 返回值为NoteColumns.CONTENT_TYPE;
*
* 看下NoteColumns.CONTENT_TYPE在NotePad.java中的定义:
* public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note";
* 哈哈,与我们要匹配的data值 <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
* 正好相等, 到此,NoteEditor中的
<intent-filter>
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>
皆匹配成功,
startActivity(new Intent(Intent.ACTION_INSERT,getIntent().getData()))启动的就是NoteEditor这个Activity.
*/
补充:
* 如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头
* 例如:要得到所有person记录的Uri为content://org.wp.provider.personprovider/person
* 那么返回的MIME类型字符串应该为:"vnd.android.cursor.dir/person"
* 如果要操作的数据属于单一数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头
* 例如:得到id为10的person记录,Uri为content://org.wp.provider.personprovider/person/10
* 那么返回的MIME类型字符串应该为:"vnd.android.cursor.item/person"
*