We have successfuly integrated AppAuth into our application but suddenly ran into a couple of problems with deep links.
We are using custom URI scheme for AppAuth. These are all the relevant parts:
build.gradle
manifestPlaceholders = [
'appAuthRedirectScheme': 'com.example'
]
manifest
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="com.example://redirect" />
</intent-filter>
</activity>
This part works fine for the login flow. However, we are using some other deep links and redirects and couple of other activites have intent filters like this:
<intent-filter android:label="Futurity">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="com.example" android:host="login"/>
</intent-filter>
When we click a button on our webpage with custom uri com.example://login, we are prompted to select between two instances of our application - one of the activities picked by this uri is AppAuth, as I discovered (if I change the scheme to com.example2://redirect), then everything works fine in terms of app selection but it feels unnecessary to have a separete scheme just for AppAuth.
Is this a bug or am I missing something fundamental? Thank you very much for the answer and I am happy to provide more details if needed.
This is expected. For more information you can take a look at:
https://developer.android.com/guide/components/intents-filters.html#Resolution
So how would you recommend implementing the deep links, so that user is prompted to select only one instance of the application @tikurahul ? Because the other one leads to the AppAuth redirect and won't handle the other deep link.
You can have AppAuth use the custom scheme you are already using. Rather than using RedirectUriActivity which in turn starts AuthorizationManagementActivity you can just use your deep link activity to redirect to AuthorizationManagementActivity when you know its an authorization response.
Read this for more info.
By default, the intent filter defined by AppAuth for RedirectUriReceiverActivity captures all URIs that match the scheme defined in the placeholder (see here). So, this is overlapping with your own filter. You can fix this by defining a different intent filter for RedirectUriReceiverActivity, overriding the one that the library provides:
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity"
tools:node="replace">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="com.example"
android:path="redirect" />
</intent-filter>
</activity>
This would mean that AppAuth would only capture com.example:/redirect, and therefore should not capture your com.example://host link.
Thank you, Ian.
This solution works with a small tweak: the correct intent filter uses <data android:scheme="com.example" android:host="redirect" />.
So if I understand it correctly, the trick is to use tools:node="replace" to override the default filter.
I am closing this issue now.
How do I fix it if i am using the library?
I dont think this fix is available in the latest version
i got error " At least one host must be specified" when setting
``
<data
android:scheme="com.example"
android:path="redirect" />
```
Most helpful comment
By default, the intent filter defined by AppAuth for RedirectUriReceiverActivity captures all URIs that match the scheme defined in the placeholder (see here). So, this is overlapping with your own filter. You can fix this by defining a different intent filter for RedirectUriReceiverActivity, overriding the one that the library provides:
This would mean that AppAuth would only capture
com.example:/redirect, and therefore should not capture yourcom.example://hostlink.