App links intent filters in assetlinks.json not working on Android

前端 未结 12 1833
时光取名叫无心
时光取名叫无心 2020-12-02 17:12

My app defines the intent filters to handle URL\'s from my site defined by


  

        
相关标签:
12条回答
  • 2020-12-02 17:28

    For me, it was the fact that my assetlinks.json file was UTF-8 and contained a byte-order mark (BOM), which is a three-byte magic number at the head of the file that signals the encoding to a consuming program. The BOM is optional, and apparently the Google / Android tools do not like to see it. When it was present, Google's digital asset links verifier (URL below) gave me a "malformed JSON" error.

    If you're using Visual Studio, here's how to determine if you have the BOM in your file, and remove it if necessary:

    1. Right-click your assetlinks.json file.
    2. Choose "Open With..." from the context menu.
    3. Choose "Binary Editor" in the "Open With" dialog.
    4. Examine the file bytes. If the file starts with EF BB BF, that's the problem.
    5. Delete those characters (you can do this via either column) and save the file.
    6. Re-upload the file and test it using the Google tools (URLs below) and it should work properly for you.

    Here's the URL you can use to check your file (replace example.com with your actual URL):

    https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls

    0 讨论(0)
  • 2020-12-02 17:29

    For us it was Windows line endings!

    Testing with "https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://domain1:port&relation=delegate_permission/common.handle_all_urls" proved invaluable as it gave us an "Could not parse statement list (not valid JSON)" error which led us to the problem.

    TIP: It was good to use the 'Save File' button in the Android Studio App Links Assistant instead of copying and pasting as we did - that way it generates the file itself and is guaranteed not to have this issue.

    0 讨论(0)
  • 2020-12-02 17:29

    For me, don't change anything of assetlinks.json including trimming blanks and line-breaks.

    0 讨论(0)
  • 2020-12-02 17:35

    System app selection window in two cases

    1) User makes changes to settings related opening links by going to settings > apps > gear icon > opening links > select an app > open supported links > choose prompt every time.

    2)Default app is not set by user and auto verify is not enabled in one of the app links supported app

    I think in your case auto verify is enabled, so please check user settings.

    0 讨论(0)
  • 2020-12-02 17:36

    There are some common pitfalls which you should check twice (I don't say that you did it wrong. It is just a check list):

    1. Verify that the assetlinks.json is valid and stored accessible from https://example.com/.well-known/assetlinks.json to do that you need to visit https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site= https://example.com&relation=delegate_permission/common.handle_all_urls, there must be no errors.
    2. If you link multiple domains at once, check that all domains are setup correctly as in step 1.
    3. Make sure that those <intent-filters> which contain your <data> tags have the attribute android:autoVerify="true".
    4. Verify that you have the required <meta-data> tag in your <application> tag:

      <meta-data
          android:name="asset_statements"
          android:resource="@string/asset_statements"/>
      

      The content of the asset_statements string must be:

      <string name="asset_statements" translatable="false">[{\"include\": \"https://example.com/.well-known/assetlinks.json\"}]
      
    5. Use for debug also the release signing certificate (don't be scared you cannot upload it accidentally) use this in your build.gradle:

      buildTypes {
          release {
              minifyEnabled true
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
              signingConfig signingConfigs.release
          }
          debug {
              debuggable true
              signingConfig signingConfigs.release
          }
      }
      
    0 讨论(0)
  • 2020-12-02 17:37

    Looking at j__m comment, I found this.

    1. In AndroidManifest write so:

      <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" />
      
          <!-- Write <data> tags with one attribute, if you use several domains. -->
          <data android:scheme="https" />
          <data android:host="example.com" />
      </intent-filter>
      <!-- Other domains-->
      <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" />
          <data android:host="server.com" />
      </intent-filter>
      

    android:autoVerify="true" is needed for App Linking.

    1. Create assetlinks.json using Tools > App Links Assistant. Then press Open Digital Asset Links File Generator, enter domain, application id, select release signing config and press Generate Digital Asset Links File. Then you can save file or copy to clipboard.

    2. You can create several assetlinks.json files (for several applications) and join them into one JSON. To my mind it doesn't depend on Windows line endings (I used Notepad to concatenate JSONs). First time I auto-formatted it with Ctrl + Alt + L, and after uploading to domains App Link didn't work (probably because of later errors in AndroidManifest), so on the 2nd try I didn't format JSON. I created assetlinks.json for release and debug builds of the application.

    3. Upload assetlinks.json to https://example.com/.well-known/assetlinks.json. Check it with https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls. The file and the domain have some restrictions. In my case everything was simple, we didn't change settings.

    4. In your DeepLinkActivity you can parse URLs with regular expressions. Use JUnit to create tests. Call this method from onCreate():

      private fun processDeepLink() {
          if (intent?.data?.isHierarchical == true) {
              val data = intent?.dataString
              if (intent?.action == Intent.ACTION_VIEW && data != null) {
                  when {
                      REGEX.matches(data) -> // Get id and open some screen.
                      else -> // Either open MainActivity or skip this URL (open web browser instead).
                  }
                  finish()
              }
          }
      }
      
      companion object {
          val REGEX = "^https://example.com/some_request/(\\d+).*".toRegex()
      }
      

    Warning! If you open a web browser from the application, you will fall into a loop. When clicking a link to your domain in the application, a browser won't appear, but your application will be opened automatically! What a surprise! So, in processDeepLink you should check the URL and open MainActivity when URL matches one of your masks. Skip others. Now a user will see a dialog with a list of browsers and your application (like in Deep Link). This happens because your application also handles links to your domains, like a browser.

    You can also use WebView instead of a browser (not a good solution), open Chrome Custom Tabs or Chrome.

    1. Use device with Android 6 or later.

    2. If https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls returned no errors, build the application. Create an Email message, SMS, QR-code or another application with a link to your domain. Click it, and App Link will open your application or Deep Link will show a dialog to choose an application. If App Link didn't work, read later.

    3. In LogCat select No Filters and type IntentFilter into search box. There should be:

      I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:2 scheme:"https" hosts:"example.com" package:"com.my_package".
      I/IntentFilterIntentOp: Verification 0 complete. Success:true. Failed hosts:.
      

    Probably you will get:

    I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:0 scheme:"https" hosts:"example.com server.com" package:"com.my_package".
    I/IntentFilterIntentOp: Verification 0 complete. Success:false. Failed hosts:server.com.
    
    1. Later you will try to fix domains in the application, so sometimes you can launch for clean install:

      adb shell pm clear com.android.statementservice
      
    2. Start adb shell dumpsys package d and find your domains. There should be:

      Package Name: com.my_package
      Domains: example.com server.com
      Status:  always : 200000000
      

    But probably it will be:

    Package Name: com.my_package
    Domains: example.com server.com
    Status: ask
    

    See also https://chris.orr.me.uk/android-app-linking-how-it-works/. Strange, but in an emulator it wrote: always, while App Link didn't work.

    I also tried adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://example.com" to test App Link without a browser, but later it didn't work.

    1. If you have several domains, comment (or remove) other domains in AndroidManifest (retain only one domain, for example, "example.com"). Then click a URL https://example.com/something and check it uses App Link. In my case I checked release and debug builds of the application. While the debug build worked with App Link, release didn't (and sometimes vise versa). I used the solution of rekire:

      <meta-data
          android:name="asset_statements"
          android:resource="@string/asset_statements"/>
      

    and it helped for 2 domains, but later stopped, so I removed it. In the end I wrote in AndroidManifest <data> tags with one attribute as j__m said.

    Even if only one domain was failing, App Link was not working for other domains either. You can check domains one by one retaining only one domain each time in AndroidManifest.

    See also http://androidideas.com/handling-app-links-in-android/, https://willowtreeapps.com/ideas/a-better-user-experience-for-deep-linking-on-android, https://developer.android.com/training/app-links/verify-site-associations,

    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题