在这里可以参考Android Sample中自带的Notepad程序。当然也有网友早就对这个例子进行过讲解。可以参考http://www.cyqdata.com/android/article-detail-37654。
当自己创建日志后,在NotesList中会显示出来。当点击这个ListView中的某一个item时,响应的代码为:
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), id);
Log.e(TAG," onListItemClick() called,noteUri = " + noteUri);
String action = getIntent().getAction();
if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
// The caller is waiting for us to return a note selected by
// the user. The have clicked on one, so return it now.
setResult(RESULT_OK, new Intent().setData(noteUri));
} else {
// Launch activity to view/edit the currently selected item
startActivity(new Intent(Intent.ACTION_EDIT, noteUri));
}
}
其中,代码startActivity(new Intent(Intent.ACTION_EDIT, noteUri));就是启动一个隐式的Activity。此时,Android系统就出来接管这个隐式的Intent,它会根据intent-filter来匹配将要启动的组件。显然,此时的Intent中的action 为:android.intent.action.EDIT。此时,从AndroidManifest.xml文件中进行分析,发现文件中有两个组件intent-filter中均包含<action android:name="android.intent.action.EDIT" />,
<activity android:name="NotesList"
android:label="@string/title_notes_list">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>
... ... ... ...
</activity>
<activity android:name="NoteEditor"
android:theme="@android:style/Theme.Light"
android:configChanges="keyboardHidden|orientation">
<!-- This filter says that we can view or edit the data of
a single note -->
<intent-filter android:label="@string/resolve_edit">
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="com.android.notes.action.EDIT_NOTE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
</intent-filter>
... ... ... ...
</activity>
为神马NotesList组件中的intent-filter也包涵 一个<action android:name="android.intent.action.EDIT" />?估计是Google的程序员在copy代码时,出现的差错。这个action本没有作用。
那么NoteEditor组件是如何正确的被启动的呢??
在上一篇博文里面谈到,在通过和intent-filter比较来解析隐式Intent请求时,Android将以下三个因素作为选择的参考标准。 Action,Data,Category。当Action和Category一致时,只能从Date来进行区分咯!
于是,intent-filter中的<data android:mimeType="vnd.android.cursor.item/vnd.google.note" />和 <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />开始浮出水面了。这两个date是神马区别呢?
在NotesList.java中的代码,添加Log信息。
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), id);
Log.e(TAG," onListItemClick() called,noteUri = " + noteUri);
... ... ... ...
打印的Log信息如下:
NotesList(4103): onListItemClick() called,noteUri = content://com.example.notepad.provider.NotePad/notes/2
Android系统获取到这个Intent后,去掉开始的content:标识和后面的资源路径(/notes)以及资源ID(2)得到com.google.provider.NotePad,然后就加载这个content provider。紧接着,就开始通过NotePadProvider.java中的getType(Uri),返回数据的MIME类型,其返回值为 vnd.android.cursor.item/vnd.google.note,这个就与组件NoteEditor匹配上了。