Flutter Scheme 使用(瀏覽器開啟App,App內開啟另一個App)

Tecode發表於2020-06-10

?專案地址

URL Scheme的作用

iOS Scheme介紹

我們都知道蘋果手機中的APP都有一個沙盒,APP就是一個資訊孤島,相互是不可以進行通訊的。但是iOS的APP可以註冊自己的URL Scheme,URL Scheme是為方便app之間互相呼叫而設計的。我們可以通過系統的OpenURL來開啟該app,並可以傳遞一些引數。

例如:你在Safari裡輸入www.alipay.com,就可以直接開啟你的支付寶app,前提是你的手機裝了支付寶。如果你沒有裝支付寶,應該顯示的是支付寶下載介面,點選會跳到AppStore的支付寶下載介面。

URL Scheme必須能唯一標識一個APP,如果你設定的URL Scheme與別的APP的URL Scheme衝突時,你的APP不一定會被啟動起來。因為當你的APP在安裝的時候,系統裡面已經註冊了你的URL Scheme。

一般情況下,是會呼叫先安裝的app。但是iOS的系統app的URL Scheme肯定是最高的。所以我們定義URL Scheme的時候,儘量避開系統app已經定義過的URL Scheme。

Android Scheme介紹

android中的scheme是一種頁面內跳轉協議;

通過定義自己的scheme協議,可以非常方便跳轉app中的各個頁面;

通過scheme協議,伺服器可以定製化告訴App跳轉到APP內部頁面。

使用uni_links

1 、pubspec.yaml檔案新增依賴

dependencies:
  uni_links: 0.4.0
複製程式碼

2 、安裝

flutter pub get

Running "flutter pub get" in dynamic_theme...                       5.8s
Process finished with exit code 0
複製程式碼

3、Dart程式碼中使用外掛

import 'package:uni_links/uni_links.dart';
複製程式碼

Android 配置

⚠️注意:Scheme 命名不支援dynamic_themeiOS中測試了一下無法開啟,改成了全小寫dynamictheme

android/app/src/main/AndroidManifest.xml

新增以下程式碼檢視完整程式碼

<!-- Deep Links -->
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <!-- Accepts URIs that begin with YOUR_SCHEME://YOUR_HOST -->
    <data
          android:scheme="[YOUR_SCHEME]"
          android:host="[YOUR_HOST]" />
</intent-filter>
複製程式碼

例子:

<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="dynamictheme"/>
  <data 
        android:host="detail"
        android:scheme="dynamictheme"/>
</intent-filter>
複製程式碼

iOS 配置

開啟Xcode->Info->URL Types設定URL Scheme

新增完也直接反應到配置檔案info.plist中了,當然你要是覺得自己很厲害,也可以直接在info.plist新增。

iOS 配置

ios/Runner/Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
<!-- 其它配置 -->
	<array>
		<dict>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>dynamictheme</string>
			</array>
		</dict>
	</array>
...
<!-- 其它配置 -->
</dict>
</plist>

複製程式碼

Dart 程式碼

不同狀態下實現頁面跳轉

Future<void> initPlatformStateForStringUniLinks() async {
    String initialLink;
    // App未開啟的狀態在這個地方捕獲scheme
    try {
      initialLink = await getInitialLink();
      print('initial link: $initialLink');
      if (initialLink != null) {
        print('initialLink--$initialLink');
        //  跳轉到指定頁面
        schemeJump(context, initialLink);
      }
    } on PlatformException {
      initialLink = 'Failed to get initial link.';
    } on FormatException {
      initialLink = 'Failed to parse the initial link as Uri.';
    }
    // App開啟的狀態監聽scheme
    _sub = getLinksStream().listen((String link) {
      if (!mounted || link == null) return;
      print('link--$link');
    //  跳轉到指定頁面
      schemeJump(context, link);
    }, onError: (Object err) {
      if (!mounted) return;
    });
}
複製程式碼

解析Scheme跳轉頁面

我配置的schemedynamictheme://使用的是Deep Link,你也可以配置成http://www.xx.comhttps://www.xx.com這種是App Links

final Uri _jumpUri = Uri.parse(schemeUrl.replaceFirst(
    'dynamictheme://',
    'http://path/',
  ));
  switch (_jumpUri.path) {
    case '/detail':
      Navigator.of(context).pushNamed(
        Detail.routeName,
        arguments: Detail(value: _jumpUri.queryParameters['name'] ?? '詳情'),
      );
      break;
    default:
      break;
}
複製程式碼

Scheme 測試地址

測試前需要先安裝APK(目前只有安卓APK可以下載,iOS需要自己拉程式碼打包)。

<a href="dynamictheme://"> 開啟App(dynamictheme://) </a>
<a href="dynamictheme://detail"> 開啟App跳轉到詳情頁面 </a>
<a href="dynamictheme://detail?name=flutter"> 開啟App跳轉到詳情頁面帶上引數 </a>
複製程式碼

iOS 效果預覽

未開啟App(開啟以後跳轉)

Flutter Scheme 使用(瀏覽器開啟App,App內開啟另一個App)

已開啟App(監聽Scheme)

Flutter Scheme 使用(瀏覽器開啟App,App內開啟另一個App)

Android 效果預覽

未開啟App(開啟以後跳轉)

Flutter Scheme 使用(瀏覽器開啟App,App內開啟另一個App)

已開啟App(監聽Scheme)

Flutter Scheme 使用(瀏覽器開啟App,App內開啟另一個App)

相關文章