React Native 下面Android 下的Deep link 配置

RN下面Android平台下的DeepLink 的配置与使用

简单来说就是 deeplink 的scheme 可以是任意值, weblink 只能是http/https, 这两种方式都需要用户选择是否使用app打开链接。
applink 的schema 与weblink 一样,唯一的差别就是,不需要用户选择,直接打开app.

Note:目前applink 的方式配置还没有成功。

遇到的坑

  1. 不要将定制化的sheme 与http(s) 配置到同一个Intent里面,以下面为例,如果你配置了,那么结果将会是mypayment://add 不起作用, mypayment://localhost/add 会起作用。实际上有效的link 组合将会是 schemehost 的全排列。但是,如果你的link 配置不正确,跳转还是不会正常工作。
  2. 对于host, port 非 applink 的模式,其实这两个值随便配,哪怕是假的都可以,就是用来占坑用的。
  3. 对于applink, 一直没有成功,安装文档都配置好了,就是不工作,还是走的deeplink, weblink 的模式。证书,autoVerify 等等都配置了,就是不工作。
  4. 还有一个问题,如果让用户选择某个App 来打开链接,如果用户选择永远用浏览器打开,那么以后都会用浏览器打开。调试的时候可以在 Android 手机上面的Settings-> Apps&Notifications->Advanced->default apps 里面清除。被坑了好久。
  5. 实际上applink 已经成功了只是验证的方式有问题,验证applink 只能使用 adb shell am start -W -a android.intent.action.VIEW -d "https://localhost/setting" com.payment, 不可以使用 uri-scheme来验证。

AndroidManifest.xml的配置

路径: android/app/src/main/AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.payment">
  <uses-permission android:name="android.permission.INTERNET" />
  <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize"
        android:exported="true">
      
       <!-- autoVerify 需要网页配置文件配合来达到浏览器打开app效果 -->
       <!-- 使用这个命令来验证 adb shell am start -W -a android.intent.action.VIEW -d "https://localhost/setting" com.payment -->
      <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" />

        <!-- 如果想使用applink 只能使用一直https -->
        <!-- https://localhost/.well-known/assetlinks.json 这个站点得有下面这个json 文件. -->
        <data android:scheme="https" android:host="localhost"/>
      </intent-filter>

      <!-- 可以使用这个命令 npx uri-scheme open "mypayment://setting" \\-\\-android` -->
      <!-- 这个命令也行 adb shell am start -W -a android.intent.action.VIEW -d "mypayment://setting" com.payment -->
      <intent-filter android:label="custom scheme name">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="mypayment"/>
      </intent-filter>

     
      <intent-filter>      
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>


      <!-- 下面这个配置项是用于配置路由,注意schema 那个data, -->
      <!-- 10.0.2.2 对应的是windows 机器,在android emulator中,我们的开发机器就是这个ip,相当于localhost -->
      <!-- 配置了三个路由 myPayment://10.0.2.2:8245/xxx -->
      <!-- https://10.0.2.2:8246/xxx -->
      <!-- http://10.0.2.2:8245/xxx -->
      <!-- !!!!!!!!!!!!!!!坚决不推荐使用这种方式,这种方式最多只能拿到weblink,!!!!!!!!!! -->
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- 不要采用注释掉的配置方法,否则一条也不会命中,实际上有效的link会是sheme 与host 的全排列  -->
        <!-- <data android:scheme="myPayment"/>
        <data android:scheme="https" android:host="10.0.2.2:8246"/>
        <data android:scheme="http" android:host="10.0.2.2:8245"/> -->


         <!-- 下面的配置是正确的 由于这个host 只是占位,不是applink, 所以不需要port, 对于实际的常见,我们一个intent-filter 只配置一个sheme,不要配多个 -->
        <data android:scheme="myPayment"/>
        <data android:scheme="https" />
        <data android:scheme="http" />
        <data android:host="localhost"/>
      </intent-filter>   
    </activity>
  </application>
</manifest>

由于开启了android:autoVerify="true",需要一个站点来提供app的签名认证,完整链接,

具体步骤如下:

  • keytool -list -v -keystore .\android\app\debug.keystore 产生app的签名,注意其中的SHA256这个hash。.\android\app\debug.keystore,这个路径是相对于项目目录而言的。这个里面有个坑,需要密码。密码是android,
  • copy 其中的 SHA256签名,放入assetlinks.json 文件中,内容如下;如果copy下面文件,记得删除注释。
[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.payment",  // 这个是你app的名字,android/app/build.gradle 中的defaultConfig, applicationId
    "sha256_cert_fingerprints":
    ["FA:C6:17:45:DC:09:03:78:6F:B9:ED:E6:2A:96:2B:39:9F:73:48:F0:BB:6F:89:9B:83:32:66:75:91:03:3B:9C"]  // 这个第一步中的SHA256
  }
}]
  • 建立一个web 站点 域名为https://localhost , 在https://localhost/.well-know/assetlinks.json 放置第二步的配置项。

定义linking 来响应接受上面配置的路由参数,完整链接

代码示例

const config = {
  screens: {
    approval_setting: 'setting',// key screen 名字,value: 我们需要的路由,例如: http://10.0.2.2:8245/setting 将对应approval_setting screen
    my_approvals: 'myapprovals',
    submit_invoice: 'invoice',
  }
};
const linking = {
  prefixes: ['myPayment://', 'https://localhost'],
  config,
};

function App(){
  return (
    <NavigationContainer linking={linking}>
        xxx
    </NavigationContainer>
  )
}

小插曲,我一开始直接在浏览器中输入url: https://localhost/setting,发现不起作用,实际上需要开发者工具,推荐 uri-scheme这个npm 包,
直接运行npx uri-scheme open "https://localhost/setting" --android就可以打开这个app.

验证deeplink 是否工作可以使用

  • npx uri-scheme open "https://localhost/setting" --android
  • adb shell am start -W -a android.intent.action.VIEW -d "https://localhost/setting" com.payment 推荐用这个来验证,也只有这个可以验证applink

link 的格式是 scheme://hostname/xxx

posted @ 2022-06-12 16:53  kongshu  阅读(387)  评论(0编辑  收藏  举报