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を特定