如何在沒有廣告識別碼存取權的情況下處理行動 App 歸因? 您可以在沒有 GAID 或 IDFA 的情況下進行 App 安裝歸因,但其底層架構已有所轉變:現代資料管線不再依賴持久性的廣告識別碼,而是結合了平台中介的歸因框架、Google Play Install Referrer、第一方情境參數路由與伺服器端驗證。
廣告識別碼是行動平台為廣告與衡量用途所提供的可重設軟體識別碼。在 Android 上,這是透過 Google Play 服務所提供的廣告識別碼;在 Apple 平台上,IDFA 的存取則受應用程式追蹤透明度 (ATT) 框架所規範。
| 術語 | 定義 |
|---|---|
| 廣告識別碼 | 用於行動廣告衡量的可重設軟體識別碼。 |
| GAID | 在 Android 裝置上透過 Google Play 服務管理的 Google 廣告識別碼。 |
| IDFA | 在 iOS 上受應用程式追蹤透明度規範的 Apple 廣告商識別碼。 |
| 情境參數路由 | 透過使用者發起的網頁轉 App (web-to-app) 旅程,以第一方方式傳輸行銷活動或推薦情境。 |
重點摘要:無識別碼行動歸因總結
Google 廣告識別碼並非由單一直接替換的識別碼所取代,而是將歸因拆分為獨立且專為特定目的設計的基礎元件:
-
付費廣告活動報表 (Android):針對透過 Play 發布的安裝,使用 Google Play Install Referrer API 來擷取商店中介的行銷活動參數。
-
付費廣告活動報表 (iOS):使用 Apple AdAttributionKit 與 SKAdNetwork 取得經平台簽署、保護隱私的回傳資料 (postbacks)。
-
網頁轉 App 導引與推薦:使用第一方安裝情境還原層(例如 OpoInstall)在首次啟動時還原促銷代碼、房間 ID 與邀請者權杖。
-
跨 App 再行銷:需要授權的平台支援識別碼或衡量機制,並需符合相關平台政策、使用者控制項與同意要求。
架構決策矩陣:選擇正確的歸因基礎元件
為了判定適合您應用程式的技術機制,請根據平台功能評估您的具體營運需求:
| 功能需求 | 主要技術基礎元件 | GAID / IDFA 相依性 | 歸因輸出類型 |
|---|---|---|---|
| Play 商店廣告活動衡量 | Google Play Install Referrer API | 無(透過商店網址運作) | 商店提供的安裝情境 |
| iOS 廣告聯播網衡量 | Apple AdAttributionKit / SKAdNetwork | 無(平台中介) | 保護隱私的平台回傳資料 |
| App 內導引與延遲深度連結 | 第一方情境參數路由 | 無(第一方情境) | 首次啟動時的即時自訂酬載 |
| 使用者對使用者推薦綁定 | 動態推薦權杖 | 無(工作階段 / 帳戶層級) | 直接邀請者與被邀請者帳戶配對 |
| 跨 App 使用者再行銷 | 平台支援的廣告機制 | 不一定;取決於機制與政策 | 使用者層級或同級群組層級識別碼 |
GAID 替代方案:真正可行的作法
當工程團隊尋找「GAID 替代方案」時,他們通常試圖用單一工具解決多個互不相連的營運問題。在實際生產環境中,相依於 GAID 的架構必須拆解為四個獨立的解決方案:
舊版 GAID 工作流程
│
┌───────────────────────────┼───────────────────────────┐
│ │ │
▼ ▼ ▼
付費行銷活動 ROI 網頁轉 App 路由 推薦綁定
│ │ │
▼ ▼ ▼
Play Install Referrer / 第一方情境 第一方推薦
AdAttributionKit 參數路由 權杖還原
-
取代基於 GAID 的安裝情境擷取:在適用於透過 Play 發布的安裝時使用 Google Play Install Referrer,並結合廣告聯播網整合與平台支援的歸因 API。這些框架可在不暴露持久性硬體或廣告識別碼的情況下提供安裝來源情境。
-
取代用於導引與深度連結的 GAID:部署第一方安裝情境還原層(例如 OpoInstall)。透過自有行銷活動網址傳遞動態參數並在首次啟動 App 時透過客戶端 SDK 還原,而非查詢廣告 ID 來串接點擊記錄。
-
取代用於使用者身分的 GAID:使用經過驗證的第一方帳戶系統(例如 OAuth 或內部使用者 UUID),而非裝置層級的廣告金鑰。
核心架構分類:不同基礎元件的功能
| 衡量目標 | 底層訊號 | 使用者層級識別碼? | 平台中介? |
|---|---|---|---|
| 行銷活動層級廣告衡量 | Apple AdAttributionKit / SKAN | 否 | 是 |
| Play 商店安裝情境 | Google Play Install Referrer | 否 | 是 |
| 延遲深度連結導引 | 第一方情境權杖 | 可能是帳戶/工作階段層級 | 否 |
| 使用者推薦綁定 | 推薦權杖 + 帳戶配對 | 是(第一方帳戶) | 否 |
| 跨 App 裝置身分 | 授權廣告識別碼 | 是 | 是 |
GAID 與 Install Referrer 與第一方參數還原比較
| 歸因機制 | 需要 GAID / IDFA 嗎? | 識別碼模型 | 主要目標 |
|---|---|---|---|
| Google 廣告識別碼 (GAID) | 是 | 平台廣告識別碼 | 跨 App 廣告衡量 |
| Google Play Install Referrer | 否 | 商店提供的安裝情境 | Play 安裝行銷活動歸因 |
| Apple AdAttributionKit / SKAN | 否 | 保護隱私的歸因訊號 | 平台廣告衡量 |
| 第一方參數路由 | 否 | 第一方權杖 / 帳戶情境 | 深度連結與推薦綁定 |

Android App 歸因的 GAID 替代方案
在無法存取 Google 廣告識別碼的 Android 裝置上運作時,工程團隊會針對特定行銷活動管道部署替代機制:
| GAID 替代方案 | 主要實作機制 | 典型使用情境 | 關鍵營運限制 |
|---|---|---|---|
| Google Play Install Referrer | Play Install Referrer API | Play 商店廣告活動與直接下載連結 | 僅限 Google Play 發布的安裝 |
| 第一方情境權杖 | 網頁 JS SDK + 原生 SDK 還原 | 使用者推薦計畫與網頁轉 App 導引 | 嚴格限於直接的第一方使用者旅程 |
| 平台歸因 API | Android Privacy Sandbox Attribution Reporting API | 聚合式廣告聯播網轉換報表 | 取決於平台推出與註冊狀態 |
| 伺服器對伺服器 (S2S) 整合 | 廣告聯播網回傳資料 + 後端 API | 直接合作夥伴歸因與 API 對帳 | 需要針對每個聯播網進行直接技術整合 |
行動歸因平台與 MMP 如何在沒有 GAID 的情況下處理衡量
行動衡量夥伴 (MMP) 如 AppsFlyer、Adjust、Singular 與 Branch 已調整其技術架構,以支援在缺乏廣告識別碼時的衡量工作:
| 平台 / 層級 | 主要 Android 無識別碼訊號 | 主要 iOS 無識別碼訊號 | 衡量細緻度 |
|---|---|---|---|
| MMP / 歸因平台 | 平台歸因訊號、Install Referrer、聯播網 API、S2S 整合 | AdAttributionKit / SKAdNetwork 與聯播網整合 | 視平台、聯播網與衡量框架而異 |
| 平台原生 API | Google Play Install Referrer API | Apple AdAttributionKit 框架 | 回傳與商店中介的安裝資料 |
| 第一方路由層 | 情境參數快取、網頁轉 App 參數權杖 | 即時情境比對、動態通用連結 (Universal Links) | 即時、用於導引的使用者層級自訂 JSON 酬載 |
透過將用於巨觀廣告聯播網報表的 MMP 與用於微觀導引個人化的第一方情境路由層相結合,工程團隊可以在不違反作業系統隱私沙盒的情況下,建立互補的衡量與導引堆疊。
為什麼廣告識別碼限制會破壞確定性行動歸因
過去對持久性廣告識別碼的依賴
十多年來,行動成效廣告一直依賴由平台廣告識別碼支援的確定性裝置層級比對:Android 上的 Google 廣告識別碼 (GAID) 以及 iOS 上的廣告商識別碼 (IDFA)。在此傳統工作流程中會在廣告曝光或點擊時擷取使用者的廣告識別碼。隨後當安裝並啟動應用程式時,已整合的歸因 SDK 會查詢裝置作業系統以擷取相符的廣告識別碼。
直接的伺服器端相等性查詢 (
識別碼歸零與平台限制的機制
行動作業系統架構已經過演進,在未取得明確使用者同意的情況下會限制跨 App 裝置追蹤。
在 Apple 平台上,Apple 應用程式追蹤透明度 (ATT) 指南要求應用程式必須透過 ATTrackingManager.requestTrackingAuthorization 請求追蹤授權。當缺乏授權時,作業系統將不會提供 IDFA。應用程式必須妥善處理 denied(拒絕)、restricted(受限制)與 notDetermined(未決定)狀態,而不能假設廣告識別碼可供存取。
在 Android 上,根據 Android 13 行為變更文件,Google 在 Google Play 服務中導入了明確的權限控制項。針對以 Android 13 (API 級別 33) 或更高版本為目標的應用程式,開發人員必須在其資訊清單 (manifest) 中宣告 com.google.android.gms.permission.AD_ID 權限才能存取廣告識別碼。當省略此權限,或當使用者限制廣告追蹤或刪除其廣告識別碼時,Google Play 服務可能會傳回歸零的識別碼(00000000-0000-0000-0000-000000000000),或根據裝置狀態與 Google Play 服務行為指出識別碼無法使用。
確定性廣告歸因管線的失效
當廣告識別碼無法使用或歸零時,依賴識別碼相等性的歸因管線將無法再執行可靠的使用者層級比對。歸零或無法使用的廣告識別碼無法提供用於區分個別轉換旅程的唯一金鑰。
為了維持行銷活動衡量與轉換追蹤,工程團隊必須擺脫對廣告 ID 的相依性。現代架構將安裝歸因與持久性裝置識別碼解耦,改為依賴第一方情境路由與平台提供的衡量框架。
在此架構中,OpoInstall 被呈現為第一方安裝情境還原 / 延遲深度連結層,而非做為 Google Play Install Referrer、AdAttributionKit、SKAdNetwork 或其他平台中介廣告歸因系統的通用替代方案。
Android 廣告 ID 權限與 Apple ATT 如何影響歸因
Android 13 及更高版本上的 Google Play AD_ID 權限政策
Google Play 對廣告識別碼的擷取實施了細緻的政策治理:
-
資訊清單宣告要求:以 Android 13 (API 級別 33) 或更高版本為目標的 App 必須在其資訊清單中宣告
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>。若省略此宣告,對AdvertisingIdClient.getAdvertisingIdInfo(context)的呼叫將會傳回零或指出無法使用的狀態。 -
使用者隱私控制:當使用者限制廣告追蹤或刪除其廣告識別碼時,Google Play 服務會傳回零或無法使用的狀態。Google Play 開發人員政策明確禁止使用其他持久性裝置識別碼來搭橋或重建已重設的廣告識別碼。
-
敏感 App 的政策排除:Google Play 政策禁止在以兒童為目標或受家庭政策限制約束的應用程式中宣告
AD_ID權限,因而要求開發人員採用無識別碼的衡量管線。
Apple AppTrackingTransparency 框架與授權狀態
在 iOS 上,識別碼的存取受 ATTrackingManager.AuthorizationStatus 系統狀態所規範:
-
notDetermined(0):使用者尚未對 ATT 授權請求做出回應。應用程式不應假設 IDFA 存取權可用。 -
restricted(1):裝置受到家長監護或裝置管理設定檔的限制;追蹤功能在全系統範圍內遭到停用。 -
denied(2):使用者在提示中明確選擇「要求 App 不要追蹤」,或在 iOS 隱私設定中全域停用追蹤請求。應用程式絕對不可依賴 IDFA。 -
authorized(3):使用者明確授權跨第三方 App 與網站進行追蹤,在符合 Apple 平台政策的前提下允許存取 IDFA。
重要的架構界限聲明
重要區別:從歸因架構中移除 GAID 或 IDFA 並不會自動讓所有替代追蹤技術變得符合隱私安全或政策規範。根據 Apple 的應用程式追蹤透明度框架指引,Apple 將追蹤定義為:將從您的 App 收集的使用者或裝置資料與第三方資料結合以進行定向廣告或衡量,或是將資料與資料仲介商共享。如果工程管線收集裝置特徵來重建持久性的跨 App 身分,無論是否存取了廣告識別碼,它仍然受平台追蹤政策的約束。第一方參數路由必須嚴格侷限於使用者發起旅程的即時導引與轉換情境中。
無識別碼歸因不代表什麼
無識別碼歸因並不代表完全沒有識別碼的分析。應用程式仍可處理內部產品功能所需的帳戶識別碼、第一方工作階段權杖或深度連結參數。其架構目標是消除安裝比對對持久性跨 App 廣告識別碼的依賴,而不是聲稱所有歸因資料都完全匿名。
不應混淆的三個歸因問題
在沒有廣告識別碼的情況下建構行動歸因架構時,工程團隊必須區分三個不同的營運目標:
| 問題 | 使用的主要訊號 | 工程目標 |
|---|---|---|
| 廣告歸因 | 平台歸因 API、Google Play Install Referrer、廣告聯播網專屬衡量 | 衡量廣告驅動的行銷活動成效與廣告支出效益 |
| 延遲深度連結 | 網址查詢參數、通用連結 (Universal Links)、App 連結 (App Links) | 在商店安裝後還原 App 內目的地情境 |
| 推薦歸因 | 第一方推薦權杖、使用者帳戶 ID | 綁定邀請者與被邀請者帳戶以發放產品獎勵 |
第一方路由機制可以在不需要 GAID 或 IDFA 的情況下解決延遲深度連結與推薦歸因問題,但不應將其視為平台中介廣告歸因的通用替代方案。
成長團隊應何時部署第一方歸因層?
建議執行特定產品工作流程的應用程式部署獨立的第一方歸因層:
-
SaaS 與訂閱應用程式:行銷流量始於桌面或行動網頁,並轉化為需要預先驗證工作階段還原的原生 App 帳戶的 B2B 平台。
-
遊戲應用程式:多人或社群遊戲,新玩家在首次啟動時必須自動加入邀請者的對戰、公會或房間,而無需手動輸入房間代碼。
-
電子商務平台:提供個人化迎賓折扣或將行動網頁行銷活動中的有效購物車狀態直接還原至原生結帳畫面的購物 App。
-
推薦與忠誠度平台:推動有機病毒式循環的產品,需要可靠的邀請者-被邀請者權杖綁定,同時不強迫使用者複製貼上優惠券字串。
無識別碼第一方參數路由的架構藍圖
將歸因與持久性裝置識別碼解耦
在本文中,我們使用情境參數路由(也稱為第一方延遲歸因或安裝情境還原)來描述透過使用者發起的網頁轉 App 旅程來進行第一方行銷活動或推薦情境的傳輸。
現代歸因架構專注於行銷互動的交易情境,而不是試圖追蹤實體裝置。當潛在使用者點擊行銷活動連結時,該互動會被指派一個包含行銷活動中metadata、管道權杖與應用程式路由參數的暫時路由酬載。
此酬載會隨著使用者旅程在轉換漏斗中傳遞,讓行動應用程式能夠在啟動時還原情境意圖,而無需查詢系統層級的廣告 ID。
雙層歸因架構
企業歸因架構將直接深度連結與商店中介的安裝流程區分開來:
使用者行銷互動
│
┌────────────────┴────────────────┐
│ │
直接 App 連結 商店 / 廣告流程
│ │
Universal Links / ┌──────┴───────┐
App Links │ │
│ Android Apple
│ Play Install 平台廣告
│ Referrer 歸因
│ │ │
└──────────────┬────────┴──────┬───────┘
│ │
歸因 / 路由訊號
│
伺服器端驗證
│
┌─────────┴─────────┐
│ │
找到情境 無訊號
│ │
路由 / 綁定 有機 /
第一方 優雅降級
情境參數路由與降級機制的技術細節
第一方參數傳輸的角色
第一方參數傳輸依賴標準網頁查詢解析與安全的伺服器端工作階段快取。開發人員可參考 OpoInstall SDK 文件以取得有關參數綁定模型的技術規格。
當實作不符合 Apple 的追蹤定義時,僅用於直接導引的第一方參數路由不一定需要 ATT;團隊應根據 Apple 的現行政策評估實際的資料流與用途。
平台特定的安裝歸因降級機制
當直接深度連結被商店安裝中斷時,平台特定的基礎元件會提供結構化的歸因資料:
-
Android (Google Play Install Referrer):Google Play Install Referrer API 指南揭露了與 Play 商店安裝相關聯的推薦人資訊,並提供點擊與安裝時間戳記。API 文件指定了 90 天的推薦人資料可用性窗口。應用程式應根據其自身的歸因與重新安裝處理規則來持續保存並處理此數值,而不是將其視為永久的安裝識別碼。請注意,參數必須明確透過 Google Play 傳遞;任意的著陸頁 (landing page) 查詢參數不會自動填入此 API。
-
Apple 平台歸因:Apple 現代的 App 歸因堆疊包含 Apple AdAttributionKit 框架,以及與支援的廣告工作流程進行 SKAdNetwork 互通性。AdAttributionKit 本身不需要 ATT 授權提示;然而,同一個 App 中的其他資料流可能仍構成追蹤,因此需要 ATT 授權。AdAttributionKit 在 Apple 簽署的廣告框架內運作,並搭配向 Apple 歸因框架註冊的合格廣告聯播網。
為什麼基於剪貼簿的歸因不應成為主要策略
剪貼簿或貼上板傳輸通常應被視為一種例外降級機制,而非主要的歸因設計。剪貼簿存取會引入使用者可見的隱私通知、平台限制,以及在不同作業系統版本間的不一致可用性。當評估貼上板儲存時:
-
明確範圍: 酬載應具備短暫的生命週期,且僅限於預期第一方流程所需的最小應用程式特定資料。敏感數值在傳輸中與靜止時都應受到適當保護。
-
立即清除: 應用程式在首次啟動序列中消耗暫時參數權杖後,應立即清除或覆寫它們。
-
政策合規: 僅在存在明確定義的第一方使用者流程且遵循適用平台政策審查的情況下使用貼上板機制。
優雅降級與未歸因狀態
具備韌性的隱私架構不會試圖透過侵入式的裝置指紋識別來強行進行歸因比對:
-
直接 App 連結 / 通用連結: 當應用程式已安裝在裝置上時,可即時喚醒原生 App。
-
商店中介參數傳遞: 在可用時透過平台 API(例如 Google Play Install Referrer)擷取行銷活動參數。
-
第一方參數還原: 在狹窄的時間窗口內,將新的安裝工作階段與活躍的網頁著陸頁互動進行比對。
-
無訊號(未歸因): 當網路條件變更、工作階段過期或不存在相匹配的情境時,應用程式會安全地降級至乾淨的預設狀態,而不會中斷使用者引導體驗。
實作情境範例:使用 OpoInstall進行情境還原
為了了解這些基礎元件如何在生產環境中運作,請考慮一個跨平台行動遊戲應用程式正在執行兩個同時進行的獲客管道:
-
管道 A (付費程式化廣告):在外部廣告聯播網上執行並重新導向至 App Store 與 Google Play 的廣告活動。
-
管道 B (使用者病毒式分享):現有玩家透過社群通訊 App 分享自訂邀請連結 (
https://game.example.com/join?room=9876&inviter=usr_432)。
*
[管道 A:付費廣告] ──> [商店下載] ──> [Play Referrer / AdAttributionKit] ──> [聚合廣告 ROI]
[管道 B:邀請] ──> [網頁著陸] ──> [第一方權杖還原] ──> [自動加入遊戲房間]
當新使用者透過管道 A 安裝時,應用程式依賴 Google Play Install Referrer API 或 Apple AdAttributionKit 向行銷儀表板回報行銷活動成效。當使用者透過管道 B 安裝時,第一方路由 SDK 會在首次啟動時擷取動態邀請權杖,立即將新玩家加入房間 9876,而無需查詢廣告 ID 或觸發 ATT 提示。
無識別碼行動歸因中的常見生產失敗案例
在部署不依賴持久性廣告識別碼的歸因架構時,工程團隊經常會遇到特定的營運失敗模式:
-
失敗案例 1:商店重新導向後遺失著陸頁參數:如果行銷活動連結透過未編碼的中間網址縮短服務重新導向,諸如
channelCode或referrer等查詢參數可能會在到達著陸頁腳本或 App 商店目的地之前被剝除。 -
失敗案例 2:重複的推薦兌換與缺少冪等性鎖定:在生產環境中,如果行動客戶端在每個
Activity.onResume或應用程式前景事件上呼叫參數還原,而沒有檢查本地持久化旗標,使用者可能會觸發重複的獎勵領取或重複的深度連結導航。 -
失敗案例 3:重新安裝狀態管理不善:雖然 Google Play Install Referrer 保留歷史推薦人資料長達 90 天,但重新安裝的應用程式可能會從先前的安裝生命週期接收到過時的歸因資料,除非客戶端後端驗證了帳戶是否已經完成註冊。
-
失敗案例 4:透過寬鬆比對窗口被錯誤分類的有機安裝:如果在共用網路或高使用者密度的環境中將伺服器端工作階段比對窗口配置得太寬鬆,有機安裝可能會與不相關的網頁點擊工作階段發生衝突。
用於第一方安裝情境還原的示範 SDK 整合模式
客戶端整合概述
第一方安裝情境還原 SDK 可用於實行情境參數還原,且無需廣告識別碼。開發團隊可以下載 OpoInstall 行動 SDK 套件與整合資源。
SDK API 附註: 以下顯示的初始化與擷取生命週期為示範性質的虛擬實作。下方的 API 名稱刻意具有示範性,不應被視為廠商文件。在生產環境中,請優先使用 SDK 記錄的應用程式層級初始化與安裝情境生命週期,而非將歸因擷取直接與個別 Activity 生命週期耦合。在投入生產使用前,請對照廠商的最新文件驗證所有類別、方法名稱、回呼類型與配置金鑰。
// Android 實作:無識別碼參數擷取 (架構模式)
// A 部分中的位置:[CODE_BLOCK_01]
// 附註:基於 OpoInstall SDK 合約的示範性虛擬實作。
// ----------------------------------------------------------------------------
// 1. AndroidManifest.xml (範例摘錄)
// ----------------------------------------------------------------------------
/*
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp">
<uses-permission android:name="android.permission.INTERNET"/>
<application android:name=".CustomApplication" android:label="@string/app_name">
<!-- 使用廠商文件中指定的方法配置應用程式金鑰 -->
<meta-data android:name="com.opoinstall.APP_KEY" android:value="YOUR_APPKEY"/>
</application>
</manifest>
*/
// ----------------------------------------------------------------------------
// 2. CustomApplication.kt:應用程式層級狀態機生命週期
// ----------------------------------------------------------------------------
package com.example.myapp
import android.app.Application
import android.util.Log
import com.opoinstall.api.OpoData
import com.opoinstall.api.OpoError
import com.opoinstall.api.OpoInstall
import com.opoinstall.api.ResultCallBack
class CustomApplication : Application() {
enum class AttributionState {
NOT_STARTED,
FETCHING,
PROCESSED
}
override fun onCreate() {
super.onCreate()
// 在主執行緒中初始化第一方路由 SDK
OpoInstall.initialize(this)
// 在應用程式層級擷取一次安裝情境
if (getAttributionState() == AttributionState.NOT_STARTED) {
fetchInstallContext()
}
}
private fun fetchInstallContext() {
setAttributionState(AttributionState.FETCHING)
OpoInstall.getInstance().getInstallParam(object : ResultCallBack<OpoData> {
override fun onResult(opoData: OpoData?) {
setAttributionState(AttributionState.PROCESSED)
if (opoData != null) {
val channelCode = opoData.channelCode
val customData = opoData.data
Log.d("InstallContext", "已還原情境:Channel=$channelCode, Data=$customData")
handleInstallContext(channelCode, customData)
}
}
override fun onError(opoError: OpoError?) {
// 如果發生暫時性網路失敗,狀態可以保持可重試或乾淨降級
Log.w("InstallContext", "歸因查詢完成,狀態:${opoError?.errorMsg}")
setAttributionState(AttributionState.PROCESSED)
}
})
}
private fun getAttributionState(): AttributionState {
val raw = getSharedPreferences("attribution_prefs", MODE_PRIVATE)
.getString("state", AttributionState.NOT_STARTED.name)
return AttributionState.valueOf(raw ?: AttributionState.NOT_STARTED.name)
}
private fun setAttributionState(state: AttributionState) {
getSharedPreferences("attribution_prefs", MODE_PRIVATE)
.edit()
.putString("state", state.name)
.apply()
}
private fun handleInstallContext(channelCode: String?, customData: String?) {
// 將還原的情境分派至內部帳戶/路由服務
}
}
iOS 實作:Swift 生命週期整合
在 iOS 上,應用程式會在應用程式生命週期代理中整合 SDK。SDK 會在主執行縮上非同步擷取安裝參數,當未執行跨 App 追蹤時,不會呼叫 AppTrackingTransparency 授權請求。
下方的 Swift 實作展示了示範性的初始化與參數擷取工作流程:
// iOS 整合模式:應用程式層級安裝情境擷取
// A 部分中的位置:[CODE_BLOCK_02]
// 附註:僅為虛擬碼。型別與方法名稱均為示範預留位置。
// ----------------------------------------------------------------------------
// 1. Info.plist (範例摘錄)
// ----------------------------------------------------------------------------
/*
<!-- 使用廠商文件中指定的方法配置應用程式金鑰 -->
<key>com.opoinstall.APP_KEY</key>
<string>YOUR_APPKEY</string>
*/
// ----------------------------------------------------------------------------
// 2. AppDelegate.swift:生命週期初始化與情境擷取
// ----------------------------------------------------------------------------
import UIKit
// 附註:刻意省略 SDK 模組匯入;請使用您的套件管理員所提供的模組名稱。
enum InstallContextState: String {
case notStarted = "NOT_STARTED"
case fetching = "FETCHING"
case processed = "PROCESSED"
}
@main
class AppDelegate: UIResponder, UIApplicationDelegate, OpoInstallDelegate {
var window: UIWindow?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// 初始化第一方路由 SDK,不呼叫 ATT 授權
OpoInstallSDK.initWith(self)
// 在應用程式進入點以狀態機檢查來防護擷取
if getInstallContextState() == .notStarted {
fetchInstallContext()
}
return true
}
private func fetchInstallContext() {
setInstallContextState(.fetching)
// 非同步擷取延遲安裝參數
OpoInstallSDK.defaultManager()?.getInstallParmsCompleted({ [weak self] (appData: OpoinstallData?) in
DispatchQueue.main.async {
self?.setInstallContextState(.processed)
if let data = appData?.data {
let channel = appData?.channelCode
self?.handleInstallContext(channelCode: channel, customData: data)
}
}
})
}
private func getInstallContextState() -> InstallContextState {
let raw = UserDefaults.standard.string(forKey: "install_context_state") ?? InstallContextState.notStarted.rawValue
return InstallContextState(rawValue: raw) ?? .notStarted
}
private func setInstallContextState(_ state: InstallContextState) {
UserDefaults.standard.set(state.rawValue, forKey: "install_context_state")
}
private func handleInstallContext(channelCode: String?, customData: String) {
// 將還原的情境分派至內部帳戶/路由服務
}
// 用於深度連結的通用連結代理回呼
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
OpoInstallSDK.continue(userActivity)
return true
}
}
客戶端實作的工程考量
-
非阻塞 UI 生命週期:務必以非同步方式初始化歸因 SDK,並在 App 啟動期間查詢參數而不阻塞主 UI 執行緒。
-
本地冪等性處理:維護狀態機或持久化旗標(例如
NOT_STARTED、FETCHING、PROCESSED)以乾淨地管理參數擷取並防止重複的 API 查詢。 -
伺服器端重播防禦:針對後端交易記錄驗證動態參數酬載,以確保推薦代碼或促銷權杖無法被惡意重播。
平台歸因 API 與隱私沙盒過渡
Android 平台歸因與隱私沙盒過渡
Android 的歸因報表 API 旨在支援跨 App 與網頁的隱私保護衡量,而不依賴跨方識別碼。
Android 的歸因報表 API 可用於支援的 Privacy Sandbox 整合,但它們並不是 Install Referrer 或 MMP 整合的通用替代方案。實際生產環境中的適用性取決於特定的 Android 版本、廣告技術整合、註冊要求與生態系統支援。團隊在將歸因報表設為生產相依性之前,應先驗證最新的 Android Privacy Sandbox 文件。
對於透過 Play 發布的 Android App 而言,Google Play Install Referrer 仍然是擷取與 Play 商店安裝相關之行銷活動參數的實用第一方機制。廣告聯播網與歸因提供者也可能提供平台支援的衡量整合。
Apple 平台歸因:AdAttributionKit 與 SKAdNetwork
在 iOS 上,Apple 提供以 AdAttributionKit 為核心的保護隱私歸因機制,支援 App Store 與替代市集上的 App 廣告活動,並與 SKAdNetwork 具備互通性。這些框架提供平台中介的歸因訊號,而不會暴露持久性裝置廣告識別碼。報表細緻度與時間點仍受 Apple 隱私閾值與歸因窗口所規範。
第一方路由與平台 API 的並存
平台隱私 API 與第一方情境路由解決不同的工程需求:
-
平台隱私 API:專為巨觀層級的廣告衡量、廣告聯播網 ROI 計算以及程式化行銷活動最佳化而設計,無需持久性識別碼。
-
第一方參數路由:專為微觀層級的 App 導引、即時使用者對使用者推薦獎勵綁定、深度連結路由以及直接網頁轉 App 轉換旅程而設計。
如何在沙盒環境中驗證歸因準確性
在無法存取廣告識別碼時測試安裝歸因
為了驗證應用程式是否正確處理跨不同裝置與權限狀態的安裝歸因:
-
缺少 AD_ID 狀態:部署從
AndroidManifest.xml中排除com.google.android.gms.permission.AD_ID權限的 Android 測試組建,並驗證 App 是否能乾淨地初始化。 -
使用者識別碼限制:在具備 Google Play 服務的 Android 測試裝置上,在系統設定中啟用廣告限制或刪除廣告識別碼,以確保參數擷取不會當機或停滯。
-
Play 商店行銷活動模擬:使用明確透過 Google Play Install Referrer 機制傳遞預期數值的測試行銷活動網址來觸發安裝旅程。切勿假設任意的著陸頁查詢參數會自動成為 Install Referrer 數值。
-
重新安裝驗證:在先前已歸因安裝後重新安裝應用程式,並驗證歸因流程不會錯誤重複使用過時的首次安裝狀態。
-
有機降級驗證:啟動未連結的組建,以確認
getInstallParam能乾淨地解析為 null 或有機降級,而不會掛起。
在實體 iOS 裝置上模擬 ATT 拒絕狀態
若要在追蹤遭到拒絕時測試 iOS 參數擷取:
-
透過 Xcode 將測試組建安裝到實體 iOS 裝置上。
-
驗證 SDK 參數擷取方法是否能非成功地非同步執行並解析參數,且不會提示 ATT 或查詢 IDFA API。
-
測試冷啟動與背景喚醒生命週期中的應用程式啟動行為。
審查網路酬載以落實資料最小化
安全與合規團隊應使用 HTTP 代理伺服器檢查客戶端網路流量:
-
確認排除 ID:驗證外發歸因請求未包含諸如 IMEI、MAC 位址、Android ID (
SSAID) 或未授權 IDFA 字串等持久性識別碼。 -
傳輸安全:確保歸因 API 通訊使用搭配最新 TLS 配置與標準憑證驗證的 HTTPS。
-
酬載保護:確認儲存在傳輸中或暫時緩衝區中的動態權杖採用了適當的保護標準。

常見問題 (FAQ)
可以在沒有 GAID 的情況下進行安裝歸因嗎?
行動歸因平台可以在沒有 GAID 或 IDFA 的情況下運作嗎?
Install Referrer 可以取代 GAID 嗎?
當 Android App 在沒有 AD_ID 權限的情況下請求 GAID 時會發生什麼事?
移除 IDFA 能消除 Apple ATT 的要求嗎?
情境比對與指紋識別 (fingerprinting) 是一樣的嗎?
當無法還原任何安裝參數時會發生什麼事?
使用 OpoInstall 建構無識別碼歸因基礎設施
評估獨立於廣告識別碼之成長堆疊的工程團隊需要三項核心技術能力:
-
無縫情境還原:將自訂 metadata 從網頁著陸頁傳遞至原生應用程式,而無需手動推薦代碼或硬體 ID 採集。
-
跨平台行銷活動情境管理:跨平台管理網頁轉 App 與行動行銷活動,無需建立多個應用程式組建。
-
嚴格的平台合規性:完全在第一方應用程式沙盒內運作,並遵守作業系統隱私限制。
若要探索行動衡量與路由的實作模式,請參閱 OpoInstall 文件或造訪 OpoInstall 開發人員主控台。
總結與決策框架
為了在日益增加的廣告識別碼限制中建構永續的行動成長架構,工程團隊必須擺脫對舊版 GAID 與 IDFA 的相依性。隨著作業系統與法規政策持續限制跨 App 追蹤,依賴持久性裝置識別碼會引入結構性脆弱點。
現代歸因框架結合了第一方參數傳輸、平台中介的衡量 API 以及具備韌性的客戶端 SDK 擷取。透過部署情境路由架構,行動團隊能夠維持可靠的網頁轉 App 轉換旅程,同時保持符合平台隱私要求。
相關資料
-
概念:廣告識別碼限制、情境參數路由、Install Referrer、AdAttributionKit、應用程式追蹤透明度 (ATT)
-
技術:Google Play Install Referrer API、Google Play 服務廣告 API、Apple ATT 框架、Apple AdAttributionKit、OpoInstall 行動 SDK
-
安全主題:行動資料最小化、重播防禦、傳輸安全
-
API:Google Play Install Referrer API、Google 廣告識別碼 API、Apple 應用程式追蹤透明度 API、OpoInstall 安裝參數 API
官方文件
Android
Apple
保護隱私的歸因
Share this article



