Reputation: 417
I am trying to make App Links work on Android the whole day, using uni_links package, unsuccessfully.
When I open a link, the browser open it instead of launching the app.
You can see my full AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<!-- Permissions options for the `storage` group -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- Permissions options for the `camera` group -->
<uses-permission android:name="android.permission.CAMERA"/>
<!-- Permissions options for the `access notification policy` group -->
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
<application
android:label="example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- Deep links -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="example.com" />
</intent-filter>
</activity>
<!-- Apple Sign In: Set up the Sign in with Apple activity, such that it's callable from the browser-redirect -->
<activity
android:name="com.aboutyou.dart_packages.sign_in_with_apple.SignInWithAppleCallback"
android:exported="true"
>
<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="signinwithapple" />
<data android:path="callback" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
I replaced com.example.app
by my appID, and example.com
by my hostname. I also added assetlinks.json
to my backend, and the test on https://developers.google.com/digital-asset-links/tools/generator passed.
I created a simple function to check in main.dart
:
Future<void> initUniLinks() async {
// Platform messages may fail, so we use a try/catch PlatformException.
try {
final initialLink = await getInitialLink();
print('initialLink');
print(initialLink);
// Parse the link and warn the user, if it is not correct,
// but keep in mind it could be `null`.
// Attach a listener to the stream
_sub = linkStream.listen((String? link) {
// Parse the link and warn the user, if it is not correct
print(link);
}, onError: (err) {
// Handle exception by warning the user their action did not succeed
print('error');
print(err);
});
} on PlatformException catch (err) {
// return?
// Handle exception by warning the user their action did not succeed
print('error');
print(err);
}
}
Then I run the emulator, starts the app from VSCode. Here I can see the app calls /.well-known/assetlinks.json
and it returns the content of the file successfully.
Finally I test with the CLI:
adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://example.com/ping"
The link is directly opened with the browser instead of the app.
What am I missing or doing wrong?
Thank you for your help!
Upvotes: 6
Views: 8461
Reputation: 417
I finally got it to work. I had to add the fingerprint of the non-signed app (I think), in the assetlinks.json file. Will have to remember to change/remove it once deployed. In my case I use 2 different assetlinks, on 2 different hostnames so it won't be a problem.
I got the fingerprint when checking app links with the command:
adb shell pm get-app-links com.example.app
Let me know if I ever make a mistake or if there is another way to do this!
Upvotes: 11