我是廣告,點擊一下吧!
標籤
#Flutter (11) 、 #PHP (8) 、 #Laravel (6) 、 #Mac (4) 、 #Dart (4) 、 #MySQL (4) 、 #VS Code (2) 、 #IDE (2) 、 #List (2) 、 #Android (2) 、 #Linux (2) 、 #Shell Script (2) 、 #addMonthNoOverflow (1) 、 #Deferred Join (1) 、 #subMonthNoOverflow (1) 、 #floorMonth (1) 、 #資安 (1) 、 #SVG (1) 、 #Directory Structure (1) 、 #SQL Injection (1) 、 #MySQL 效能 (1) 、 #subMonth (1) 、 #addMonth (1) 、 #Carbon (1) 、 #keytool (1) 、 #Play App Signing (1) 、 #copy (1) 、 #file_put_contents (1) 、 #file_get_contents (1) 、 #fwrite (1)Android 的 App Link 與 iOS 的 Universal Links 是可以讓手機點擊 HTTP URL Scheme (http:// or https://) 就直接開啟 APP 導向到指定頁面,也可在 APP 之間做轉跳。有別於 Deep Links 的 Custom Url Scheme 是可以避免跟其他 APP 命名衝突、或是發生使用者沒裝 APP 開啟後網頁一片白的窘境。
修改你的 AndroidManifest.xml
,將要開啟 APP 的 domain + path 放到 <activity>
之中。
android:scheme
:通常只要輸入 https,除非你特別要支援 http。android:host
:輸入你的 domain,如有測試環境也可一併加上,有 www 與沒 www 的算兩個 domain。android:pathPrefix
:因為不會是遇到網域底下所有頁面都要開啟 APP,這裡就是讓你輸入你要開啟的 path。<!-- App 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" />
<!-- /download -->
<data android:scheme="https" android:host="joymap.tw" android:pathPrefix="/download" />
<data android:scheme="https" android:host="www.joymap.tw" android:pathPrefix="/download" />
<!-- /member/news -->
<data android:scheme="https" android:host="joymap.tw" android:pathPrefix="/member/news" />
<data android:scheme="https" android:host="www.joymap.tw" android:pathPrefix="/member/news" />
<!-- /store -->
<data android:scheme="https" android:host="joymap.tw" android:pathPrefix="/store" />
<data android:scheme="https" android:host="www.joymap.tw" android:pathPrefix="/store" />
</intent-filter>
將以下 json 放至網站 /.well-known/assetlinks.json (例如 https://joymap.tw/.well-known/assetlinks.json)package_name
需修改成你的 package_name sha256_cert_fingerprints
也是修改為你的指紋
[
{
"relation":[
"delegate_permission/common.handle_all_urls"
],
"target":{
"namespace":"android_app",
"package_name":"com.toby.joymap",
"sha256_cert_fingerprints":[
"c1:06:01:09:6c:e1:89:78:38:87:73:9a:34:1d:07:fe:bf:1b:b8:a2:e7:49:6e:11:70:d9:fb:67:22:e0:da:22"
]
}
}
]
開啟你的 Xcode > Signing & Capabilities
> + Capability
> 搜尋 Associated Domains
雙擊開啟功能 > 填上你的 domain
將以下 json 放至網站 /.well-known/apple-app-site-association (例如 https://joymap.tw/.well-known/apple-app-site-association),注意檔名沒有 .json。
appID
格式為 {Team ID}.{Bundle Identifier}
paths
支援 *
、?
、NOT
{
"applinks": {
"apps": [],
"details": [
{
"appID": "RQ8UWKNDYA.com.toby.joymap",
"paths": ["/download", "/member/news/*", "/store/*"]
}
]
}
}
蘋果有 CDN,所以設定後需要數小時後才能動作,可以使用 https://app-site-association.cdn-apple.com/a/v1/{your_domain} 檢查是否已更新。
使用:https://pub.dev/packages/uni_links
新增 app_link.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:uni_links/uni_links.dart';
class AppLink {
static void handleIncomingLinks(BuildContext context) {
uriLinkStream.listen((Uri? uri) {
if (uri != null) {
try {
path(context, uri);
} catch (e) {
print(e);
}
}
}, onError: (Object err) {});
}
static Future handleInitialUri(BuildContext context) async {
try {
final uri = await getInitialUri();
if (uri != null) {
path(context, uri);
}
// ignore: empty_catches
} on FormatException {}
}
static Future<bool> path(BuildContext context, Uri? uri) async {
if (uri == null) return false;
try {
// 掃描支付 /download?store_id={store_id}
if (uri.path == '/download' && uri.queryParameters['store_id'] != null) {
_pay(context, uri);
return true;
}
// 最新消息 /member/news/{id}
if (uri.pathSegments.length == 3 && uri.pathSegments[0] == 'member' && uri.pathSegments[1] == 'news') {
_news(context, uri);
return true;
}
// 店家內頁 /store/{slug}
if (uri.pathSegments.length == 2 && uri.pathSegments[0] == 'store') {
_store(context, uri);
return true;
}
} catch (e) {
print(e);
}
return false;
}
static _pay(BuildContext context, Uri uri) async {
String storeId = uri.queryParameters['store_id'] ?? '';
// open pay page
}
static _news(BuildContext context, Uri uri) {
int id = int.parse(uri.pathSegments[2]);
// open news page
}
static _store(BuildContext context, Uri uri) {
String slug = uri.pathSegments[1];
// open store page
}
}
在你的起始 Widget State 加入
_appLinkInit() async {
AppLink.handleIncomingLinks(context);
await AppLink.handleInitialUri(context);
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_appLinkInit();
});
}
如果有安裝享樂地圖 APP 將會開啟至店家內頁,沒有的話會開啟網頁版。