actionとUriで指定したIntentからどのようにActivityを特定しているか?
連絡先を表示したい場合
こうすると
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("content://contacts/people")));
ちゃんとDialtactsContactsEntryActivityがcmpに指定される。
12-08 20:22:51.547: INFO/ActivityManager(60): Starting activity: Intent { act=android.intent.action.VIEW dat=content://contacts/people cmp=com.android.contacts/.DialtactsContactsEntryActivity }
NotePadの場合
NotePadではこのコードが
// getData()の戻り値はUri.parse("content://com.google.provider.NotePad/notes") Uri uri = ContentUris.withAppendedId(getIntent().getData(), id); //(中略) startActivity(new Intent(Intent.ACTION_EDIT, uri)); } }
NoteEditorがcmpに指定される。
12-08 20:33:19.347: INFO/ActivityManager(60): Starting activity: Intent { act=android.intent.action.EDIT dat=content://com.google.provider.NotePad/notes/1 cmp=com.example.android.notepad/.NoteEditor }
ActivityManagerはどうやってDialtactsContactsEntryActivityやNoteEditorを特定しているのだろうか?
Android Developersによると
action: android.intent.action.VIEW
data: content://com.google.provider.NotePad/notes/ID
Asks the activity to display the content of the note identified by ID. (For details on how content: URIs specify individual members of a group, see Content Providers.)
というわけでContent Providerが面倒を見てくれていたようです。
Content Providers | Android Developers
NotePadProvider#getType(Uri)
static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES); sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID); //(略) } @Override public String getType(Uri uri) { switch (sUriMatcher.match(uri)) { case NOTES: return Notes.CONTENT_TYPE; case NOTE_ID: return Notes.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException("Unknown URI " + uri); } }
If you are handling a new data type, you must define a new MIME type to return in your implementation of ContentProvider.getType(). The type depends in part on whether or not the content: URI submitted to getType() limits the request to a specific record. There's one form of the MIME type for a single record and another for multiple records. Use the Uri methods to help determine what is being requested. Here is the general format for each type:
For a single record: vnd.android.cursor.item/vnd.yourcompanyname.contenttype
For example, a request for train record 122, like this URI,
content://com.example.transportationprovider/trains/122
might return this MIME type:
vnd.android.cursor.item/vnd.example.rail
For multiple records: vnd.android.cursor.dir/vnd.yourcompanyname.contenttype
For example, a request for all train records, like the following URI,
content://com.example.transportationprovider/trains
might return this MIME type:
vnd.android.cursor.dir/vnd.example.rail
Intents and Intent Filters | Android Developers
actionとuriからActivityを特定するまでの流れ
actionとuriを指定して、Activity#startActivity(Intent)する
↓
uriのauthorityからContentProviderを特定
↓
ContentProvider#getType(Uri)で、authorityより後のパスに対応するmimeTypeを取得
↓
actionとmimeTypeの組み合わせからintent-filterによりActivityを特定
NotePadの場合の具体例
new Intent(Intent.ACTION_EDIT, Uri.parse("content://com.google.provider.NotePad/notes/1"));
↓
authority"com.google.provider.NotePad"から、providerのNotePadProviderを特定
↓
pathの"/notes/1"からmimeType"vnd.android.cursor.item/vnd.google.note"を取得
↓
action.VIEWとvnd.google.noteのintent-filterを持つActivityのNoteEditorを特定