Android AAR + Intent Filter: clarification

2019-08-15 06:34发布

问题:

Based on this documentation available at Android NFC doc:

If a tag contains an AAR, the tag dispatch system dispatches in the following manner:

  1. Try to start an Activity using an intent filter as normal. If the Activity that matches the intent also matches the AAR, start the Activity.

  2. If the Activity that filters for the intent does not match the AAR, if multiple Activities can handle the intent, or if no Activity handles the intent, start the application specified by the AAR.

  3. If no application can start with the AAR, go to Google Play to download the application based on the AAR.

From those lines I understand that if I specify an intent filter for an activity A and the received NDEF message matches the filter of A, A will be started even if the NDEF message contains the AAR record of the app that A belongs to.

In my case A starts only if there is no AAR record. As soon as I add the AAR record, the activity A is not started: when the NDEF message is detected, the main activity of the app indicated in the AAR is launched.

What do they mean with "if the Activity [...] also matches the AAR"?

Is there anyone who can provide a hint?

回答1:

1.) Try to start an Activity using an intent filter as normal. If the Activity that matches the intent also matches the AAR, start the Activity.

This means that activity A has an NDEF_DISCOVERED intent filter that matches the datatype of the first NDEF record of the NDEF message on the tag and that the AAR matches the application package name that activity A belongs to.

2.) If the Activity that filters for the intent does not match the AAR, if multiple Activities can handle the intent, or if no Activity handles the intent, start the application specified by the AAR.

This means that there is

  • an activity A with an NDEF_DISCOVERED intent filter that does not match the datatype of the first NDEF record of the NDEF message on the tag and that the AAR matches the application package name that activity A belongs to,
  • an activity A and an activity B that both have an NDEF_DISCOVERED intent filter that matches the datatype of the first NDEF record of the NDEF message on the tag and that the AAR matches the application package name that activities A and B belong to, or
  • no activity of the app matching the AAR has an NDEF_DISCOVERED intent filter.

In that case, the app that has a package name that matches the one in the AAR is started by sending intent action MAIN with category LAUNCHER for the first activity in your app that has such an intent filter. Hence, the app is "started" as if the launcher icon for that activity was clicked.

3.) If no application can start with the AAR, go to Google Play to download the application based on the AAR.

This means that if there is no app with a package name that matches the one in the AAR, then Play Store is opened.


So, for instance, if you have the NDEF message

+------------------------------+----------------------+
| URI: http://www.example.com/ | AAR: com.example.app |
+------------------------------+----------------------+

then you would need an application with the package name com.example.app that has one activity with an intent filter like

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http" android:host="www.example.com" android:pathPrefix="/" />
</intent-filter>

Scenario 1 (match for activity A):

<manifest package="com.example.app" ... >
    <uses-permission android:name="android.permission.NFC" />
    <application ...>
        <activity android:name="MAIN" ...>
            <intent-filter>
                <action android:name="android.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="A" ...>
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="http" android:host="www.example.com" android:pathPrefix="/" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Scenario 2a (no match for activity A, MAIN is launched):

<manifest package="com.example.app" ... >
    <uses-permission android:name="android.permission.NFC" />
    <application ...>
        <activity android:name="MAIN" ...>
            <intent-filter>
                <action android:name="android.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="A" ...>
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Scenario 2b (match for activities A and B, MAIN is launched):

<manifest package="com.example.app" ... >
    <uses-permission android:name="android.permission.NFC" />
    <application ...>
        <activity android:name="MAIN" ...>
            <intent-filter>
                <action android:name="android.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="A" ...>
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="http" android:host="www.example.com" android:pathPrefix="/" />
            </intent-filter>
        </activity>
        <activity android:name="B" ...>
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="http" android:host="www.example.com" android:pathPrefix="/" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Scenario 2c (no NDEF_DISCOVERED intent filter, MAIN is launched):

<manifest package="com.example.app" ... >
    <uses-permission android:name="android.permission.NFC" />
    <application ...>
        <activity android:name="MAIN" ...>
            <intent-filter>
                <action android:name="android.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>