設定
如要導入 Topics API,您必須先設定開發環境。請按照下列步驟進行設定:
請使用最新的 Android Privacy Sandbox SDK,取得最新版本的隱私權保護 API。
在資訊清單中新增以下內容:
權限:加入
ACCESS_ADSERVICES_TOPICS
權限,允許應用程式存取 Topics API:<uses-permission android:name="android.permission.ACCESS_ADSERVICES_TOPICS" />
廣告服務設定:在資訊清單的
<application>
元素中參照廣告服務設定檔。<property android:name="android.adservices.AD_SERVICES_CONFIG" android:resource="@xml/ad_services_config" />
指定資訊清單所參照的廣告服務 XML 資源,例如
res/xml/ad_services_config.xml
。使用allowAllToAccess
屬性授予所有 SDK 的存取權,或allowSdksToAccess
屬性授予個別 SDK 的存取權。進一步瞭解廣告服務權限和 SDK 存取權控管。<ad-services-config> <topics allowAllToAccess="true"/> </ad-services-config>
透過 Privacy Sandbox 註冊廣告技術,即可在 SDK 中呼叫 Topics API。如要在本機測試,您可以使用下列指令停用主題註冊檢查:
adb shell setprop debug.adservices.disable_topics_enrollment_check true
啟用 Topics API 存取權。根據預設,Topics API 會停用。您必須使用 ADB 指令啟用這項功能:
adb shell device_config put adservices ppapi_app_signature_allow_list \"\*\"
adb shell setprop debug.adservices.disable_topics_enrollment_check true
要求一組主題
Topics API 的主要功能位於 TopicsManager
物件中的 getTopics()
方法中,如以下範例所示:
Kotlin
fun getTopics(
getTopicsRequest: GetTopicsRequest,
executor: Executor,
callback: OutcomeReceiver<GetTopicsResponse, Exception>
) { }
Java
public void getTopics (@NonNull GetTopicsRequest getTopicsRequest,
@NonNull Executor executor,
@NonNull OutcomeReceiver<GetTopicsResponse, Exception> callback)
如要使用這個方法,請初始化 TopicsManager
物件,以及接收主題資料所必需的參數。GetTopicsRequest
會傳送必要資訊來擷取 Topics API 資料,包括用來表示呼叫端是否做為觀測器的旗標。不做為觀測器時,getTopics
呼叫會傳回上個週期的主題,但不會影響下一個週期的主題資料。而 OutcomeReceiver
回呼會以非同步的方式處理結果。例如:
Kotlin
private fun topicGetter() {
val mContext = baseContext
val mTopicsManager = mContext.getSystemService(TopicsManager::class.java)
val mExecutor: Executor = Executors.newCachedThreadPool()
val shouldRecordObservation = false
val mTopicsRequestBuilder: GetTopicsRequest.Builder = GetTopicsRequest.Builder()
mTopicsRequestBuilder.setAdsSdkName(baseContext.packageName)
mTopicsRequestBuilder.setShouldRecordObservation(shouldRecordObservation)
mTopicsManager.getTopics(mTopicsRequestBuilder.build(), mExecutor,
mCallback as OutcomeReceiver<GetTopicsResponse, Exception>)
}
private var mCallback: OutcomeReceiver<GetTopicsResponse, java.lang.Exception> =
object : OutcomeReceiver<GetTopicsResponse, java.lang.Exception> {
override fun onResult(result: GetTopicsResponse) {
// handle successful result
val topicsResult = result.topics
for (i in topicsResult.indices) {
Log.i("Topic", topicsResult[i].getTopicId().toString())
}
if (topicsResult.size == 0) {
Log.i("Topic", "Returned Empty")
}
}
override fun onError(error: java.lang.Exception) {
// handle error
Log.i("Topic", "Error, did not return successfully")
}
}
Java
public void TopicGetter() {
@NonNull Context mContext = getBaseContext();
TopicsManager mTopicsManager = mContext.getSystemService(TopicsManager.class);
Executor mExecutor = Executors.newCachedThreadPool();
boolean shouldRecordObservation = false;
GetTopicsRequest.Builder mTopicsRequestBuilder = new GetTopicsRequest.Builder();
mTopicsRequestBuilder.setAdsSdkName(getBaseContext().getPackageName());
mTopicsRequestBuilder.setShouldRecordObservation(shouldRecordObservation);
mTopicsManager.getTopics(mTopicsRequestBuilder.build(), mExecutor, mCallback);
}
OutcomeReceiver mCallback = new OutcomeReceiver<GetTopicsResponse, Exception>() {
@Override
public void onResult(@NonNull GetTopicsResponse result) {
//Handle Successful Result
List<Topic> topicsResult = result.getTopics();
for (int i = 0; i < topicsResult.size(); i++) {
Log.i("Topic", topicsResult.get(i).getTopicId().toString());
}
if (topicsResult.size() == 0) {
Log.i("Topic", "Returned Empty");
}
}
@Override
public void onError(@NonNull Exception error) {
// Handle error
Log.i("Topic", "Experienced an error, and did not return successfully");
}
};
設定完成後,您可以呼叫 getTopics()
方法,取得 GetTopicsResponse
做為結果:
Kotlin
mTopicsManager.getTopics(mTopicsRequestBuilder.build(), mExecutor,
mCallback as OutcomeReceiver<GetTopicsResponse, java.lang.Exception>)
Java
mTopicsManager.getTopics(mTopicsRequestBuilder.build(), mExecutor, mCallback);
這個叫用會提供包含 ID 值的 Topics 物件清單,這些值會對應至開放原始碼分類中與使用者相關的主題,或對應至相關的錯誤。主題會類似於下列範例:
/Internet & Telecom/Text & Instant Messaging
如需可能傳回的主題清單,請參閱分類相關資訊。這套分類是開放原始碼,因此您可以使用本頁頂端的意見回饋按鈕提出建議,指出需要的變更。
測試
Topics API 會根據應用程式的使用情況提供相關的最新主題。這個早期版本可讓您預覽 API 的行為,我們會在日後版本中不斷改進主題的品質。
為獲得完整體驗,建議使用包含多個應用程式的測試環境,並可在其中呼叫 getTopics()
瞭解主題的選用情形。GitHub 上的 SDK 執行階段和隱私權保護 API 存放區包含一組可幫助您入門的 Android Studio 專案,其中包括一些示範如何初始化及呼叫 Topics API 的範例。
主題計算會在週期結束時進行。在預設情況下,每個週期都是 7 天,但您可以修改時間間隔,以便快速取得結果。此 Android Debug Bridge 殼層指令會將週期的長度縮短為 5 分鐘:
adb shell device_config put adservices topics_epoch_job_period_ms 300000
您可以使用 get
確認 topics_epoch_job_period_ms
值:
adb shell device_config get adservices topics_epoch_job_period_ms
如要手動觸發週期運算,請執行下列指令:
adb shell cmd jobscheduler run -f com.google.android.adservices.api 2
除了使用範例應用程式之外,您也可以使用這個 Colab 針對主題分類器測試不同的應用程式資訊組合。此外,這個 Colab 還可用於查看應用程式呼叫 getTopics
後可能取得的結果類型。
加密詳細資料
隨著加密功能的推出,對 GetTopics()
的呼叫現在會產生包含 EncryptedTopic
物件清單的回應。解密這些結果後,物件會採用與先前 Topic
物件相同的 JSON 格式。
Topics API 支援 HPKE (混合式公開金鑰加密) 的一次性實作。我們預期已註冊的呼叫端會在註冊期間提供的公開加密網址端點上主控 32 位元公開金鑰。這些金鑰應採用 Base64 編碼。
EncryptedTopic
物件有三個欄位。您可以使用公開金鑰的對應私密金鑰,取得傳回主題的清單。
為了進行開發作業,您可以停用註冊檢查功能,測試 Topics API 加密功能。這會強制 API 使用測試公開金鑰來加密回應。您可以使用對應的私密金鑰解密已加密的主題。
限制
如需 Topics API 處於開發階段的功能清單,請參閱「版本資訊」。
回報錯誤和問題
您的意見回饋對 Android 版 Privacy Sandbox 至關重要。如果您發現任何問題,或希望對 Android 版 Privacy Sandbox 提出改進意見,請告訴我們。
後續步驟
控制選項和資訊公開
Android 版 Topics 總覽
另請參閱
請參閱我們的資源,進一步瞭解 Android 上的 Topics API。
- 或是觀看 Topics 的範例應用程式、合作影片及逐步操作說明影片。
- 瞭解使用者和開發人員如何「控管」 API。
- 歡迎查看支援資源,提出問題、互動及分享意見回饋。