Intro
Quick Start
-
建構並執行應用程式 - Android Developers
若有建立 Android Emulator 則可以直接在 Android Studio 的 Running Devices 列表找到,實體手機則可以透過 USB 或 Wi-Fi 連結裝置以加入列表。使用連結的 Device 執行 Run 後該 Device 就會安裝 apk 並開啟執行
-
Build app for release
Build 出來的 apk 預設檔案目錄:app/build/outputs/apk/
WebView
Quick Start
快速在 onCreate 時就搭建好 WebView:
-
Add a WebView in onCreate()
包含在AndroidManifest.xml加入 INTERNET permission -
Handle page navigation
OverrideshouldOverrideUrlLoading()讓 WebView 可以支援 URL 的開啟方式。WebView.context.startActivity(Intent)用來支援 Intent 開啟 URL,可同時處理 App scheme launch 以及 HTTP URL 外開預設瀏覽器。onCreate -
MainActivity.kt:class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { ... val myWebView = WebView(this) myWebView.webViewClient = MyWebViewClient() myWebView.settings.javaScriptEnabled = true setContentView(myWebView) myWebView.loadUrl("https://webview.page") } }Override WebView client -
{custom}/{MyWebViewClient}.kt:class MyWebViewClient : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { if (Uri.parse(url).host == "www.webview-site.com") { // This is the loading web site, so do not override; let my WebView load the page return false } // Otherwise, launch another Activity that handles URLs including App scheme URL Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { view.context.startActivity(this) } return true } }
Deep Link
在 AndroidManifest.xml 中,透過新增 <intent-filter> 來定義 App 支援的 URL Scheme:
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:label="URL Scheme Setting">
<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 "example://gizmos” -->
<data android:scheme="example" android:host="gizmos" />
</intent-filter>
</activity>
Deep Link 也可以使用
https://協議,但因未經過官方驗證,當多個 App 都能處理該網域時,系統仍會彈出「開啟工具(app)」選擇選單。
App Link (Verified Links)
當你希望使用標準的 https 網址開啟 App,且不希望系統彈出「選擇開啟 App」的選單時,應使用 App Link。這是 Deep Link 的進階版,增加了「自動驗證」機制。
- Manifest 設定
在intent-filter中加入android:autoVerify="true",並指定你的官方網域
<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="[www.yourdomain.com](https://www.yourdomain.com)" />
<data android:scheme="http" />
</intent-filter>
- 銜接要點:伺服器驗證
與 Custom Scheme (Deep link) 不同,App Link 必須在你的 Web Server 放置驗證檔案,證明該網域與 App 的關聯性:
- 路徑:https://www.yourdomain.com/.well-known/assetlinks.json
- 目的:系統會在 App 安裝時檢查此檔案,驗證成功後,點擊該網域連結將會「直接跳轉」App,不再詢問使用者。
App Scheme 轉導「覆蓋/取代」問題總結
當 A App 透過 myapp:// 呼叫 B App,若發現 B 直接蓋在 A 的視窗內(多工界面只剩一個 app 視窗),通常是 Task Stack(任務棧) 管理不當。
🛠️ 解決方案:誰該負責?
要避免「覆蓋」現象,只要其中一方做好設定即可:
1. 呼叫者 (Caller App) 的責任
在發送 Intent 時,強制要求系統開啟新任務。
- 作法:加入
FLAG_ACTIVITY_NEW_TASK。 - 原理:告訴系統「把這個 URL 送到它目標去開」。
- 範例:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2. 目標 App (Target App) 的責任
在自己的設定檔中,聲明自己永遠要獨立開啟。
- 作法:在
AndroidManifest.xml設定android:launchMode。 - 推薦值:
singleTask或singleInstance。 - 原理:不論誰呼叫我,我都會強行建立/回到自己的 Task Stack。
- Sample:
<activity android:name=".MainActivity" android:label="@string/app_name" android:launchMode="singleTask"> <intent-filter> ...
📊 行為矩陣 (Priority Matrix)
| 呼叫者 (帶 Flag) | 目標 App (LaunchMode) | 結果 | 說明 |
|---|---|---|---|
| 有 NEW_TASK | 任意 (如 standard) | 正常 | 呼叫者強制要求獨立。 |
| 無 NEW_TASK | 有 singleTask | 正常 | 目標 App 自行要求獨立。 |
| 無 NEW_TASK | 無 (standard) | ❌ 覆蓋 | 雙方都沒堅持,系統會疊在一起。 |
💡 為什麼 Chrome 轉導 app 皆不會發生覆蓋?
因為 Chrome 內建已處理好 Flag。當你在 Chrome 點擊連結時,它發出的 Intent 預設就帶有「NEW_TASK」的指令,所以不會發生 Chrome 被目標 App 取代的情況。