简体   繁体   中英

Flutter - App links does not work on Android

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!

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM