Beim Lesen der Privacy Sandbox für Android Dokumentation auswählen, klicken Sie auf die Schaltfläche Vorschau für Entwickler oder Beta, um Programmversion, mit der Sie arbeiten, da die Anleitung variieren kann.
Mit der SDK Runtime können SDKs in einer dedizierten Sandbox ausgeführt werden, die von der über die Anruf-App. Die SDK-Laufzeit bietet erweiterte Absicherungen und Garantien zur Erhebung von Nutzerdaten. Dies erfolgt durch eine modifizierte Ausführung Umgebung, in der die Datenzugriffsrechte und die Anzahl der zulässigen Berechtigungen eingeschränkt sind. Weitere Informationen zur SDK-Laufzeit finden Sie im Entwurfsvorschlag.
Auf dieser Seite wird Schritt für Schritt erklärt, wie Sie ein laufzeitfähiges SDK, das eine webbasierte Ansicht definiert, die remote gerendert werden kann in eine Anruf-App umwandeln.
Bekannte Einschränkungen
Eine Liste der laufenden Funktionen für die SDK-Laufzeit finden Sie im Release Notizen.
Die folgenden Einschränkungen werden voraussichtlich in der nächsten großen Android-Version Plattformrelease.
- Anzeigen-Rendering in einer scrollbaren Ansicht Zum Beispiel enthält
RecyclerView
keine ordnungsgemäß funktioniert.- Möglicherweise treten Verzögerungen bei der Größenänderung auf.
- Die Ereignisse vom Typ „Scrollen beim Berühren“ werden nicht korrekt an die Laufzeit übergeben.
- Storage-API
<ph type="x-smartling-placeholder">
- </ph>
- Speicherplatz pro SDK ist unter Android 13 nicht verfügbar.
Das folgende Problem wird 2023 behoben:
- Die
getAdId
undgetAppSetId
API funktionieren noch nicht richtig, da sie da diese noch nicht aktiviert wurden.
Hinweis
Führen Sie zuerst die folgenden Schritte aus:
Richten Sie Ihre Entwicklungsumgebung für die Privacy Sandbox für Android ein. Die Tools zur Unterstützung der SDK-Laufzeit befinden sich in der aktiven Entwicklung. müssen Sie die neueste Canary-Version von Android Studio verfügbar. Du kannst diese Version von Android Studio parallel zu anderen Versionen, die du verwendest. Bitte teile uns mit, wenn diese Anforderung nicht für Sie funktioniert.
Installieren Sie entweder ein System-Image auf einem unterstützten Gerät oder richten Sie ein Emulator, der die Privacy Sandbox für Android unterstützt.
Projekt in Android Studio einrichten
Um die SDK-Laufzeit zu testen, verwenden Sie ein Modell, das dem Client-Server-Modell. Der Hauptunterschied besteht darin, dass Apps (die und SDKs (der „Server“) auf demselben Gerät ausgeführt werden.
- Fügen Sie Ihrem Projekt ein App-Modul hinzu. Dieses Modul dient als Kundschaft, für das SDK verantwortlich.
- Aktivieren Sie in Ihrem App-Modul die SDK-Laufzeit, deklarieren Sie die erforderlichen Berechtigungen und API-spezifische Werbedienste konfigurieren
- Fügen Sie Ihrem Projekt ein Bibliotheksmodul hinzu. Dieses Modul enthält deinen SDK-Code.
- Deklariere in deinem SDK-Modul die erforderlichen Berechtigungen. Sie müssen nicht API-spezifische Anzeigendienste konfigurieren.
- Entfernen Sie
dependencies
in derbuild.gradle
-Datei Ihres Bibliotheksmoduls, die Ihr SDK nicht verwendet. In den meisten Fällen können Sie alle Abhängigkeiten entfernen. Ich Erstellen Sie dazu ein neues Verzeichnis, dessen Name Ihrem SDK entspricht. Neues Modul mit der
com.android.privacy-sandbox-sdk
manuell erstellen Typ. Diese wird zusammen mit dem SDK-Code bereitgestellt, um ein APK zu erstellen, das die auf Ihrem Gerät bereitgestellt sind. Erstellen Sie dazu ein neues Verzeichnis, der Ihrem SDK entspricht. Fügen Sie eine leerebuild.gradle
-Datei hinzu. Inhalt dieser Datei werden später in diesem Leitfaden dargestellt.Fügen Sie der Datei
gradle.properties
das folgende Snippet hinzu:android.experimental.privacysandboxsdk.enable=true
Laden Sie das Emulator-Image für TiramisuPrivacySandbox herunter und erstellen Sie ein mit diesem Image, das den Play Store enthält.
Je nachdem, ob Sie SDK- oder App-Entwickler sind, von der im vorherigen Abschnitt beschriebenen Einrichtung abweichen.
Installieren Sie das SDK auf einem Testgerät, ähnlich wie bei der Installation einer App, mit entweder Android Studio oder Android Debug Bridge (ADB). Um Ihnen den Einstieg zu erleichtern, haben wir Beispiel-Apps in Kotlin und Java erstellt. Programmiersprachen, die Sie in diesem GitHub-Repository. Die README- und Manifest-Dateien enthalten Kommentare, in denen beschrieben wird, was geändert werden muss, um das Beispiel in stabilen Versionen auszuführen von Android Studio.
SDK vorbereiten
Erstellen Sie manuell ein Verzeichnis auf Modulebene. Dies dient als Wrapper um Implementierungscode, um das SDK-APK zu erstellen. Fügen Sie im neuen Verzeichnis
build.gradle
-Datei und füllen Sie sie mit dem folgenden Snippet. Verwenden Sie eine eindeutige Name für Ihr laufzeitfähiges SDK (RE-SDK) und geben Sie eine Version an. Einschließen dein Bibliotheksmodul im Abschnittdependencies
an.plugins { id 'com.android.privacy-sandbox-sdk' } android { compileSdkPreview 'TiramisuPrivacySandbox' minSdkPreview 'TiramisuPrivacySandbox' namespace = "com.example.example-sdk" bundle { packageName = "com.example.privacysandbox.provider" sdkProviderClassName = "com.example.sdk_implementation.SdkProviderImpl" setVersion(1, 0, 0) } } dependencies { include project(':<your-library-here>') }
Erstellen Sie in Ihrer Implementierungsbibliothek eine Klasse, die als Einstiegspunkt für Ihres SDKs. Der Name der Klasse sollte dem Wert von entsprechen.
sdkProviderClassName
und erweitern SieSandboxedSdkProvider
.
Der Einstiegspunkt für Ihr SDK ist die Erweiterung SandboxedSdkProvider
. Die
SandboxedSdkProvider
enthält ein Context
-Objekt für Ihr SDK, das Sie
Zugriff erhalten, indem du getContext()
aufrufst. Auf diesen Kontext darf nur einmal zugegriffen werden
onLoadSdk()
wurde aufgerufen.
Damit deine SDK-App kompiliert werden kann, musst du Methoden zur Verarbeitung des SDK überschreiben Lebenszyklus:
onLoadSdk()
Lädt das SDK in die Sandbox und benachrichtigt die aufrufende App, wenn das SDK zur Verarbeitung von Anfragen bereit ist, indem die zugehörige Schnittstelle als
IBinder
-Objekt übergeben wird das in ein neuesSandboxedSdk
-Objekt eingebettet ist. Die Leitfaden für gebundene Dienste bietet verschiedene Möglichkeiten,IBinder
bereitzustellen. Ich Sie können flexibel wählen, aber sie müssen für das SDK einheitlich sein. und die Anruf-App.Am Beispiel von AIDL sollten Sie eine AIDL-Datei definieren, die Deine
IBinder
, die von der App geteilt und verwendet wird:// ISdkInterface.aidl interface ISdkInterface { // the public functions to share with the App. int doSomething(); }
getView()
Erstellt die Ansicht für Ihre Anzeige und richtet sie ein. Die Initialisierung der Ansicht erfolgt auf dieselbe Weise. wie jede andere Android-Ansicht und gibt die Ansicht für das Remote-Rendering in einem Fenster mit einer vorgegebenen Breite und Höhe in Pixeln.
Das folgende Code-Snippet zeigt, wie diese Methoden überschrieben werden:
Kotlin
class SdkProviderImpl : SandboxedSdkProvider() { override fun onLoadSdk(params: Bundle?): SandboxedSdk { // Returns a SandboxedSdk, passed back to the client. The IBinder used // to create the SandboxedSdk object is used by the app to call into the // SDK. return SandboxedSdk(SdkInterfaceProxy()) } override fun getView(windowContext: Context, bundle: Bundle, width: Int, height: Int): View { val webView = WebView(windowContext) val layoutParams = LinearLayout.LayoutParams(width, height) webView.setLayoutParams(layoutParams) webView.loadUrl("https://developer.android.com/privacy-sandbox") return webView } private class SdkInterfaceProxy : ISdkInterface.Stub() { fun doSomething() { // Implementation of the API. } } }
Java
public class SdkProviderImpl extends SandboxedSdkProvider { @Override public SandboxedSdk onLoadSdk(Bundle params) { // Returns a SandboxedSdk, passed back to the client. The IBinder used // to create the SandboxedSdk object is used by the app to call into the // SDK. return new SandboxedSdk(new SdkInterfaceProxy()); } @Override public View getView(Context windowContext, Bundle bundle, int width, int height) { WebView webView = new WebView(windowContext); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(width, height); webView.setLayoutParams(layoutParams); webView.loadUrl("https://developer.android.com/privacy-sandbox"); return webView; } private static class SdkInterfaceProxy extends ISdkInterface.Stub { @Override public void doSomething() { // Implementation of the API. } } }
SDKSandboxController
SdkSandboxController
ist ein kontextbasierter Systemdienst-Wrapper, der verfügbar ist
bis hin zu SDKs. Dies kann von SDKs unter Verwendung des Kontexts abgerufen werden, der von
SandboxedSdkProvider#getContext()
und Aufruf
context.getSystemService(SdkSandboxController.class)
dazu. Die
hat der Verantwortliche APIs, über die SDKs mit dem
Privacy Sandbox
Die meisten APIs im Controller lösen Ausnahmen aus, wenn SandboxedSdkContext
nicht
Kontext, in dem der Zugriff erfolgte. Wir planen, den Dienst-Wrapper für alle
anderen Kontexten. SdkSandboxController
ist für SDK-Anbieter vorgesehen.
und wird nicht für die Verwendung durch App-Entwickler empfohlen.
SDK-zu-SDK-Kommunikation
SDKs in der Laufzeit sollten in der Lage sein, miteinander zu kommunizieren, Vermittlung und zugehörige Anwendungsfälle. Das hier beschriebene Toolset bietet um mit SDKs zu arbeiten, die anderen SDKs im Sandbox ausführen. Diese SDK Runtime-Implementierung ist ein erster Schritt, damit das SDK SDK-Kommunikation. Möglicherweise sind noch nicht alle Anwendungsfälle für die Vermittlung in der Privacy Sandbox
Die getSandboxedSdks()
API in der SdkSandboxController
stellt ein
SandboxedSdk
-Klasse für alle geladenen SDKs in der Privacy Sandbox. Die
Das Objekt SandboxedSdk
enthält Details zum SDK sowie ein sdkInterface
für
mit ihr kommunizieren können.
SDKs in der Privacy Sandbox müssen Code-Snippets wie den um mit anderen SDKs zu kommunizieren. Angenommen, dieser Code wurde geschrieben, um „SDK1“ zu aktivieren bis mit SDK2 kommunizieren können. Beide werden von der App im Sandbox
SdkSandboxController controller = mSdkContext
.getSystemService(SdkSandboxController.class);
List<SandboxedSdk> sandboxedSdks = controller.getSandboxedSdks();
SandboxedSdk sdk2 = sandboxedSdks.stream().filter( // The SDK it wants to
// connect to, based on SDK name or SharedLibraryInfo.
try {
IBinder binder = sdk2.getInterface();
ISdkApi sdkApi = ISdkApi.Stub.asInterface(binder);
// Call API on SDK2
message = sdkApi.getMessage();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
Im obigen Beispiel fügt SDK1 die AIDL-Bibliothek von SDK2 als Abhängigkeit hinzu. Dieses Client-SDK enthält den von AIDL generierten Binder-Code. Beide SDKs sollten um diese AIDL-Bibliothek zu exportieren. Das ist gleichbedeutend mit dem, was Apps tun sollen, kommunizieren sie in der Privacy Sandbox mit SDKs.
Eine automatisch generierte Methode zur gemeinsamen Nutzung von Schnittstellen zwischen SDKs wird unterstützt. in zukünftigen Updates.
SDKs in der Laufzeit müssen möglicherweise mit App-Abhängigkeiten und Anzeigen-SDKs kommunizieren die noch nicht laufzeitfähig sind.
Die registerAppOwnedSdkSandboxInterface()
API in SdkSandboxManager
bietet
eine Möglichkeit für nicht laufzeitfähige SDKs, ihre Schnittstellen mit
auf der Plattform. Die getAppOwnedSdkSandboxInterfaces()
API in
SdkSandboxController
stellt die AppOwnedSdkSandboxInterface
für alle
registrierte, statisch verknüpfte SDKs.
Das folgende Beispiel zeigt, wie Schnittstellen registriert werden, damit sie verfügbar für laufzeitfähige SDK-Kommunikation:
// Register AppOwnedSdkSandboxInterface
mSdkSandboxManager.registerAppOwnedSdkSandboxInterface(
new AppOwnedSdkSandboxInterface(
APP_OWNED_SDK_NAME, (long) APP_OWNED_SDK_VERSION, new AppOwnedSdkApi())
);
Dieses Beispiel zeigt, wie Sie die Kommunikation mit laufzeitfähige SDKs:
// Get AppOwnedSdkSandboxInterface
List<AppOwnedSdkSandboxInterface> appOwnedSdks = mSdkContext
.getSystemService(SdkSandboxController.class)
.getAppOwnedSdkSandboxInterfaces();
AppOwnedSdkSandboxInterface appOwnedSdk = appOwnedSdks.stream()
.filter(s -> s.getName().contains(APP_OWNED_SDK_NAME))
.findAny()
.get();
IAppOwnedSdkApi appOwnedSdkApi =
IAppOwnedSdkApi.Stub.asInterface(appOwnedSdk.getInterface());
message = appOwnedSdkApi.getMessage();
Da Anzeigen-SDKs, die nicht laufzeitaktiviert sind, möglicherweise nicht empfehlen wir die Erstellung eines SDK für Vermittler, das die Registrierung und beinhaltet Partner- oder App-SDKs als direkte Abhängigkeiten. Dieses Vermittler-SDK stellt die Kommunikation zwischen SDKs und Abhängigkeiten her, die nicht laufzeitfähigen Vermittler, der als Adapter agiert, und den laufzeitfähigen Vermittler.
Unterstützte Aktivitäten
Laufzeitfähige SDKs können ihrer Manifestdatei kein Aktivitäts-Tag hinzufügen und
beginnen ihre eigenen Aktivitäten. Auf das Activity
-Objekt wird Zugriff gewährt.
Durch Registrieren eines SdkSandboxActivityHandler
und Starten der Sandbox-Aktivität:
1. SdkSandboxActivityHandler registrieren
Registrieren Sie eine Instanz von SdkSandboxActivityHandler
mit
SdkSandboxController#registerSdkSandboxActivityHandler(SandboxedActivityHandler)
Die API registriert dieses Objekt und gibt ein IBinder
-Objekt zurück, das identifiziert
Die übergebenen SdkSandboxActivityHandler
.
public interface SdkSandboxActivityHandler {
void onActivityCreated(Activity activity);
}
Die API registriert dieses Objekt und gibt ein IBinder
-Objekt zurück, das identifiziert
Die übergebenen SdkSandboxActivityHandler
.
2. Sandbox-Aktivität starten
Das SDK übergibt das zurückgegebene Token, um das registrierte
SdkSandboxActivityHandler
für die Client-App Die Client-App ruft dann
SdkSandboxManager#startSdkSandboxActivity(Activity, Binder)
, übergibt ein
Aktivität zum Starten der Sandbox und ein Token, das die registrierte
SdkSandboxActivityHandler
Mit diesem Schritt wird eine neue Plattformaktivität gestartet, die in derselben SDK-Laufzeit ausgeführt wird wie das anfragende SDK.
Wenn die Aktivität beginnt, wird das SDK über einen Aufruf an
SdkSandboxActivityHandler#onActivityCreated(Activity)
als Teil des
Activity#OnCreate(Bundle)
-Ausführung.
Wenn der Aufrufer beispielsweise auf das Activity
-Objekt zugreifen kann, hat er die Möglichkeit,
contentView
pro Aufruf durch Aufrufen von Activity#setContentView(View)
Verwenden Sie zum Registrieren von Lebenszyklus-Callbacks die
Activity#registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks)
Um OnBackInvokedCallback
bei der bestandenen Aktivität zu registrieren, verwenden Sie
Activity#getOnBackInvokedDispatcher().registerOnBackInvokedCallback(Int,
OnBackInvokedCallback)
.
Videoplayer in der SDK-Laufzeit testen
Mit der Privacy Sandbox werden nicht nur Banneranzeigen unterstützt, sondern auch Videoplayer, die in der SDK-Laufzeit ausgeführt werden, werden unterstützt.
Der Ablauf beim Testen von Videoplayern ähnelt dem Testen von Banneranzeigen. Ändern Sie die
getView()
-Methode des SDK-Einstiegspunkts, um einen Videoplayer in den
hat ein View
-Objekt zurückgegeben. Teste alle Videoplayer-Abläufe, die du erwarten würdest
die von der Privacy Sandbox unterstützt werden. Die Kommunikation zwischen SDK und
die Client-App über den Lebenszyklus des Videos
außerhalb des Projektumfangs,
ist für diese Funktion noch kein Feedback erforderlich.
Deine Tests und dein Feedback sorgen dafür, dass die SDK-Laufzeit alle Anwendungsfälle für Ihren bevorzugten Videoplayer.
Das folgende Code-Snippet zeigt, wie eine einfache Videoansicht zurückgegeben wird, die über eine URL geladen wird.
Kotlin
class SdkProviderImpl : SandboxedSdkProvider() { override fun getView(windowContext: Context, bundle: Bundle, width: Int, height: Int): View { val videoView = VideoView(windowContext) val layoutParams = LinearLayout.LayoutParams(width, height) videoView.setLayoutParams(layoutParams) videoView.setVideoURI(Uri.parse("https://test.website/video.mp4")) videoView.setOnPreparedListener { mp -> mp.start() } return videoView } }
Java
public class SdkProviderImpl extends SandboxedSdkProvider { @Override public View getView(Context windowContext, Bundle bundle, int width, int height) { VideoView videoView = new VideoView(windowContext); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(width, height); videoView.setLayoutParams(layoutParams); videoView.setVideoURI(Uri.parse("https://test.website/video.mp4")); videoView.setOnPreparedListener(mp -> { mp.start(); }); return videoView; } }
Storage APIs im SDK verwenden
SDKs in der SDK Runtime können nicht mehr auf die internen Speicher und umgekehrt. Der SDK-Laufzeit wird ein eigener interner Speicherbereich zugewiesen, der unabhängig von der App.
SDKs können über die Datei auf diesen separaten internen Speicher zugreifen
für das Objekt Context
, das vom
SandboxedSdkProvider#getContext()
. SDKs können nur den internen Speicher nutzen.
internen Speicher-APIs wie Context.getFilesDir()
oder
Context.getCacheDir()
funktioniert. Weitere Beispiele finden Sie unter
Zugriff aus dem internen Speicher.
Der Zugriff auf externen Speicher über die SDK-Laufzeit wird nicht unterstützt. APIs aufrufen, um
auf externen Speicher zugreifen, wird entweder eine Ausnahme auslösen oder null
zurückgeben. Mehrere
Beispiele:
- Beim Zugriff auf Dateien mit dem Storage Access Framework wird eine Fehlermeldung ausgegeben.
SecurityException
getExternalFilsDir()
gibt immernull
zurück.
In Android 13 teilen sich alle SDKs in der SDK Runtime den internen Speicher. für die SDK-Laufzeit zugewiesen. Der Speicher bleibt bestehen, bis die Client-App deinstalliert oder wenn Client-App-Daten bereinigt werden.
Sie müssen die von SandboxedSdkProvider.getContext()
zurückgegebene Context
verwenden für
Speicherplatz. Verwendung der File Storage API auf einer anderen Context
-Objektinstanz, z. B.
im Kontext der Anwendung funktioniert, kann nicht in allen Situationen erwartungsgemäß funktionieren.
oder in der Zukunft liegen.
Das folgende Code-Snippet zeigt, wie Speicher in der SDK-Laufzeit verwendet wird:
Kotlin
private static class SdkInterfaceStorage extends ISdkInterface.Stub { override fun doSomething() { val filename = "myfile" val fileContents = "content" try { getContext().openFileOutput(filename, Context.MODE_PRIVATE).use { it.write(fileContents.toByteArray()) } catch (e: Exception) { throw RuntimeException(e) } } } }
Java
private static class SdkInterfaceStorage extends ISdkInterface.Stub { @Override public void doSomething() { final filename = "myFile"; final String fileContents = "content"; try (FileOutputStream fos = getContext().openFileOutput(filename, Context.MODE_PRIVATE)) { fos.write(fileContents.toByteArray()); } catch (Exception e) { throw new RuntimeException(e); } } }
Speicherplatz pro SDK
Innerhalb des separaten internen Speichers für jede SDK-Laufzeit hat jedes SDK eine eigene Speicherverzeichnis. Der Speicher pro SDK ist eine logische Trennung der internen Speicher, mit dem der von den jeweiligen SDKs verwendete Speicherplatz berücksichtigt wird.
In Android 13 gibt nur eine API einen Pfad zum Speicherplatz pro SDK zurück:
Context#getDataDir()
Unter Android 14 geben alle internen Speicher-APIs für das Objekt Context
den Fehlercode zurück:
Speicherpfad für jedes SDK. Möglicherweise müssen Sie diese Funktion aktivieren, indem Sie den
folgenden ADB-Befehl:
adb shell device_config put adservices sdksandbox_customized_sdk_context_enabled true
SharedPreferences
des Clients wird gelesen
Client-Apps können festlegen, dass ein Satz von Schlüsseln aus ihrer SharedPreferences
für sie freigegeben wird
SdkSandbox
. SDKs können die aus der Client-App synchronisierten Daten lesen, indem sie
SdkSanboxController#getClientSharedPreferences()
-API. Das SharedPreferences
der von dieser API zurückgegebenen Daten dienen nur dem Lesen. Sie sollten nicht in dieses Feld schreiben.
Auf die von den Google Play-Diensten bereitgestellte Werbe-ID zugreifen
Wenn Ihr SDK Zugriff auf die von den Google Play-Diensten bereitgestellte Werbe-ID benötigt:
- Deklariere die Berechtigung
android.permission.ACCESS_ADSERVICES_AD_ID
im SDK-Manifest. - Verwenden Sie
AdIdManager#getAdId()
, um den Wert asynchron abzurufen.
Auf die von den Google Play-Diensten bereitgestellte App-Set-ID zugreifen
Wenn Ihr SDK Zugriff auf die von den Google Play-Diensten bereitgestellte App-Set-ID benötigt:
- Verwenden Sie
AppSetIdManager#getAppSetId()
, um den Wert asynchron abzurufen.
Client-Apps aktualisieren
Um ein SDK aufzurufen, das in der SDK-Laufzeit ausgeführt wird, musst du Folgendes tun: Änderungen an der aufrufenden Client-App:
Fügen Sie die Berechtigungen
INTERNET
undACCESS_NETWORK_STATE
hinzu: in das Manifest Ihrer App einfügen:<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Deklarieren Sie in der App-Aktivität, die eine Anzeige enthält, einen Verweis auf die
SdkSandboxManager
, ein boolescher Wert, mit dem angegeben wird, ob das SDK geladen ist, und EinSurfaceView
-Objekt für Remote-Rendering:Kotlin
private lateinit var mSdkSandboxManager: SdkSandboxManager private lateinit var mClientView: SurfaceView private var mSdkLoaded = false companion object { private const val SDK_NAME = "com.example.privacysandbox.provider" }
Java
private static final String SDK_NAME = "com.example.privacysandbox.provider"; private SdkSandboxManager mSdkSandboxManager; private SurfaceView mClientView; private boolean mSdkLoaded = false;
Prüfen Sie, ob der SDK-Laufzeitprozess auf dem Gerät verfügbar ist.
Prüfen Sie die
SdkSandboxState
-Konstante (getSdkSandboxState()
).SDK_SANDBOX_STATE_ENABLED_PROCESS_ISOLATION
bedeutet, dass die SDK-Laufzeit verfügbar.Prüfe, ob der Aufruf von
loadSdk()
erfolgreich war. Es ist erfolgreich, wenn werden keine Ausnahmen ausgelöst und der Empfänger ist die Instanz derSandboxedSdk
loadSdk()
im Vordergrund aufrufen. Wird sie über das im Hintergrund wird einSecurityException
ausgelöst.Im
OutcomeReceiver
nach einer Instanz vonSandboxedSdk
suchen um zu prüfen, ob eineLoadSdkException
ausgelöst wurde. Eine Ausnahme bedeutet, ist die SDK-Laufzeit möglicherweise nicht verfügbar.
Wenn der
SdkSandboxState
- oderloadSdk
-Aufruf fehlschlägt, wird die SDK-Laufzeit nicht und der Aufruf sollte auf das vorhandene SDK zurückgreifen.Callback-Klasse durch Implementieren von
OutcomeReceiver
für die Interaktion definieren mit dem SDK in der Laufzeit, nachdem es geladen wurde. Im Folgenden Beispiel: Der Client wartet mithilfe eines Callbacks, bis das SDK geladen wurde. und versucht dann, mit dem SDK eine Webansicht zu rendern. Die Callbacks werden später in diesem Schritt definiert.Kotlin
private inner class LoadSdkOutcomeReceiverImpl private constructor() : OutcomeReceiver<SandboxedSdk?, LoadSdkException?> { override fun onResult(sandboxedSdk: SandboxedSdk) { mSdkLoaded = true val binder: IBinder = sandboxedSdk.getInterface() if (!binderInterface.isPresent()) { // SDK is not loaded anymore. return } val sdkInterface: ISdkInterface = ISdkInterface.Stub.asInterface(binder) sdkInterface.doSomething() Handler(Looper.getMainLooper()).post { val bundle = Bundle() bundle.putInt(SdkSandboxManager.EXTRA_WIDTH_IN_PIXELS, mClientView.getWidth()) bundle.putInt(SdkSandboxManager.EXTRA_HEIGHT_IN_PIXELS, mClientView.getHeight()) bundle.putInt(SdkSandboxManager.EXTRA_DISPLAY_ID, display!!.displayId) bundle.putInt(SdkSandboxManager.EXTRA_HOST_TOKEN, mClientView.getHostToken()) mSdkSandboxManager!!.requestSurfacePackage( SDK_NAME, bundle, { obj: Runnable -> obj.run() }, RequestSurfacePackageOutcomeReceiverImpl()) } } override fun onError(error: LoadSdkException) { // Log or show error. } }
Java
import static android.app.sdksandbox.SdkSandboxManager.EXTRA_DISPLAY_ID; import static android.app.sdksandbox.SdkSandboxManager.EXTRA_HEIGHT_IN_PIXELS; import static android.app.sdksandbox.SdkSandboxManager.EXTRA_HOST_TOKEN; import static android.app.sdksandbox.SdkSandboxManager.EXTRA_WIDTH_IN_PIXELS; private class LoadSdkOutcomeReceiverImpl implements OutcomeReceiver<LoadSdkResponse, LoadSdkException> { private LoadSdkOutcomeReceiverImpl() {} @Override public void onResult(@NonNull SandboxedSdk sandboxedSdk) { mSdkLoaded = true; IBinder binder = sandboxedSdk.getInterface(); if (!binderInterface.isPresent()) { // SDK is not loaded anymore. return; } ISdkInterface sdkInterface = ISdkInterface.Stub.asInterface(binder); sdkInterface.doSomething(); new Handler(Looper.getMainLooper()).post(() -> { Bundle bundle = new Bundle(); bundle.putInt(EXTRA_WIDTH_IN_PIXELS, mClientView.getWidth()); bundle.putInt(EXTRA_HEIGHT_IN_PIXELS, mClientView.getHeight()); bundle.putInt(EXTRA_DISPLAY_ID, getDisplay().getDisplayId()); bundle.putInt(EXTRA_HOST_TOKEN, mClientView.getHostToken()); mSdkSandboxManager.requestSurfacePackage( SDK_NAME, bundle, Runnable::run, new RequestSurfacePackageOutcomeReceiverImpl()); }); } @Override public void onError(@NonNull LoadSdkException error) { // Log or show error. } }
Um beim Aufruf einer Remote-Ansicht vom SDK in der Laufzeit eine Remote-Ansicht zurückzugeben
requestSurfacePackage()
implementieren Sie dieOutcomeReceiver<Bundle, RequestSurfacePackageException>
-Schnittstelle:Kotlin
private inner class RequestSurfacePackageOutcomeReceiverImpl : OutcomeReceiver<Bundle, RequestSurfacePackageException> { fun onResult(@NonNull result: Bundle) { Handler(Looper.getMainLooper()) .post { val surfacePackage: SurfacePackage = result.getParcelable( EXTRA_SURFACE_PACKAGE, SurfacePackage::class.java) mRenderedView.setChildSurfacePackage(surfacePackage) mRenderedView.setVisibility(View.VISIBLE) } } fun onError(@NonNull error: RequestSurfacePackageException?) { // Error handling } }
Java
import static android.app.sdksandbox.SdkSandboxManager.EXTRA_SURFACE_PACKAGE; private class RequestSurfacePackageOutcomeReceiverImpl implements OutcomeReceiver<Bundle, RequestSurfacePackageException> { @Override public void onResult(@NonNull Bundle result) { new Handler(Looper.getMainLooper()) .post( () -> { SurfacePackage surfacePackage = result.getParcelable( EXTRA_SURFACE_PACKAGE, SurfacePackage.class); mRenderedView.setChildSurfacePackage(surfacePackage); mRenderedView.setVisibility(View.VISIBLE); }); } @Override public void onError(@NonNull RequestSurfacePackageException error) { // Error handling } }
Wenn Sie fertig sind, denken Sie daran,
SurfacePackage
durch folgenden Aufruf wieder freizugeben:surfacePackage.notifyDetachedFromWindow()
Initialisieren Sie in
onCreate()
dieSdkSandboxManager
, die erforderlichen Callbacks. und dann eine Anfrage zum Laden des SDK stellen:Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mSdkSandboxManager = applicationContext.getSystemService( SdkSandboxManager::class.java ) mClientView = findViewById(R.id.rendered_view) mClientView.setZOrderOnTop(true) val loadSdkCallback = LoadSdkCallbackImpl() mSdkSandboxManager.loadSdk( SDK_NAME, Bundle(), { obj: Runnable -> obj.run() }, loadSdkCallback ) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSdkSandboxManager = getApplicationContext().getSystemService( SdkSandboxManager.class); mClientView = findViewById(R.id.rendered_view); mClientView.setZOrderOnTop(true); LoadSdkCallbackImpl loadSdkCallback = new LoadSdkCallbackImpl(); mSdkSandboxManager.loadSdk( SDK_NAME, new Bundle(), Runnable::run, loadSdkCallback); }
Die App kann bestimmte Schlüssel der Standard-
SharedPreferences
freigeben mit der Sandbox. Dazu kann erSdkSandboxManager#addSyncedSharedPreferencesKeys(Set<String>keys)
-Methode auf einer beliebigen Instanz desSdkSandbox
-Managers. Sobald die App eine BenachrichtigungSdkSandboxManager
, welche Schlüssel synchronisiert werden sollen,SdkSandboxManager
wird synchronisiert können die Werte dieser Schlüssel in die Sandbox und in die SDKs eingelesen werden.SdkSandboxController#getClientSharedPreferences
. Weitere Informationen finden Sie unter Weitere Informationen finden Sie unter Freigegebene Einstellungen des Clients lesen. Informationen.Der Schlüsselsatz, der synchronisiert wird, bleibt bei einem Neustart der App und bei den Daten nicht erhalten die mit der Sandbox synchronisiert wird, beim Neustart der Sandbox gelöscht. Daher ist es wichtig, Die App initiiert die Synchronisierung durch Aufrufen von
addSyncedSharedPreferencesKeys
alle wenn die App gestartet wird.Du kannst den Schlüsselsatz, der synchronisiert wird, ändern, indem du folgenden Befehl aufrufst:
SdkSandboxManager#removeSyncedSharedPreferencesKeys(Set<String>keys)
bis Schlüssel entfernen. Wenn Sie den aktuell synchronisierten Schlüsselsatz sehen möchten, verwenden SieSdkSandboxManager#getSyncedSharedPreferencesKeys()
Wir empfehlen, den Schlüsselsatz so klein wie möglich zu halten und ihn nur zu verwenden, wenn notwendig ist. Wenn Sie Informationen zu allgemeinen Zwecken an SDKs weitergeben möchten, kommuniziere bitte über die
SandboxedSdk
-Schnittstelle direkt mit dem SDK. A Ein mögliches Szenario für die Verwendung dieser APIs wäre, wenn die App eine Consent Management Platform (CMP) SDK verwenden, werden SDKs in der Sandbox die Daten, die CMP SDK standardmäßig speichert,SharedPreferences
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { … // At some point, initiate the set of keys for synchronization with sandbox mSdkSandboxManager.addSyncedSharedPreferencesKeys(Set.of("foo", "bar")); }
Java
@Override protected void onCreate(Bundle savedInstanceState) { … // At some point, initiate the set of keys for synchronization with sandbox mSdkSandboxManager.addSyncedSharedPreferencesKeys(Set.of("foo", "bar")); }
Um den Fall zu bewältigen, dass der SDK-Sandbox-Prozess unerwartet beendet wird, Definiere eine Implementierung für die
SdkSandboxProcessDeathCallback
-Schnittstelle:Kotlin
private inner class SdkSandboxLifecycleCallbackImpl() : SdkSandboxProcessDeathCallback { override fun onSdkSandboxDied() { // The SDK runtime process has terminated. To bring back up the // sandbox and continue using SDKs, load the SDKs again. val loadSdkCallback = LoadSdkOutcomeReceiverImpl() mSdkSandboxManager.loadSdk( SDK_NAME, Bundle(), { obj: Runnable -> obj.run() }, loadSdkCallback) } }
Java
private class SdkSandboxLifecycleCallbackImpl implements SdkSandboxProcessDeathCallback { @Override public void onSdkSandboxDied() { // The SDK runtime process has terminated. To bring back up // the sandbox and continue using SDKs, load the SDKs again. LoadSdkOutcomeReceiverImpl loadSdkCallback = new LoadSdkOutcomeReceiverImpl(); mSdkSandboxManager.loadSdk( SDK_NAME, new Bundle(), Runnable::run, loadSdkCallback); } }
Zum Registrieren dieses Callbacks, um Informationen darüber zu erhalten, wann die SDK-Sandbox beendet wurde, können Sie jederzeit folgende Zeile hinzufügen:
Kotlin
mSdkSandboxManager.addSdkSandboxProcessDeathCallback({ obj: Runnable -> obj.run() }, SdkSandboxLifecycleCallbackImpl())
Java
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, new SdkSandboxLifecycleCallbackImpl());
Da der Status der Sandbox beim Beenden des Prozesses verloren geht, werden Ansichten die vom SDK remote gerendert wurden, funktionieren möglicherweise nicht mehr richtig. Damit Sie weiterhin mit SDKs interagieren können, müssen diese Ansichten neu geladen werden. wird ein neuer Sandbox-Prozess gestartet.
Fügen Sie den Abhängigkeiten Ihrer Client-App eine Abhängigkeit von Ihrem SDK-Modul hinzu.
build.gradle
:dependencies { ... implementation project(':<your-sdk-module>') ... }
Apps testen
Installieren Sie zum Ausführen der Client-App die SDK-App und die Client-App auf Ihrem Testgerät entweder über Android Studio oder über die Befehlszeile.
Über Android Studio bereitstellen
Führen Sie bei der Bereitstellung über Android Studio die folgenden Schritte aus:
- Öffnen Sie das Android Studio-Projekt für Ihre Client-App.
- Wählen Sie Ausführen > Konfigurationen bearbeiten. Das Fenster Run/Debug Configuration (Konfiguration ausführen/Fehlerbehebung) angezeigt wird.
- Legen Sie unter Startoptionen für Start die Option Angegebene Aktivität fest.
- Klicken Sie auf das Dreipunkt-Menü neben „Aktivität“ und wählen Sie die Hauptaktivität aus. für Ihre Kundschaft.
- Klicken Sie auf Übernehmen und dann auf OK.
- Klicken Sie auf Ausführen.
um die Client-App und das SDK auf dem Testgerät zu installieren.
Über die Befehlszeile bereitstellen
Führen Sie bei der Bereitstellung über die Befehlszeile die Schritte in der folgenden Liste aus.
In diesem Abschnitt wird davon ausgegangen, dass der Name des SDK-App-Moduls sdk-app
ist und dass
Der Name des Client-App-Moduls lautet client-app
.
Erstellen Sie über ein Befehlszeilenterminal die Privacy Sandbox SDK-APKs:
./gradlew :client-app:buildPrivacySandboxSdkApksForDebug
Dadurch wird der Speicherort für die generierten APKs ausgegeben. Diese APKs sind signiert mit Ihren lokalen Schlüssel zur Fehlerbehebung. Sie benötigen diesen Pfad im nächsten Befehl.
Installieren Sie das APK auf Ihrem Gerät:
adb install -t /path/to/your/standalone.apk
Klicken Sie in Android Studio auf Run > Konfigurationen bearbeiten. Die Funktion Run/Debug (Ausführen/Fehlerbehebung) Konfiguration angezeigt.
Setzen Sie unter Installation Options (Installationsoptionen) die Option Deploy (Bereitstellen) auf Default APK (Standard-APK).
Klicken Sie auf Übernehmen und dann auf OK.
Klicken Sie auf Ausführen, um das APK-Bundle auf Ihrem Testgerät zu installieren.
Fehler in Apps beheben
Wenn Sie Fehler in der Client-App beheben möchten, klicken Sie auf den Link Fehler beheben.
Schaltfläche in Android Studio.
Rufen Sie zum Debuggen der SDK-App Ausführen > Attach to Process (An Prozess anfügen) aus, in dem ein Pop-up eingeblendet wird.
(siehe unten). Klicken Sie das Kästchen Alle Prozesse anzeigen an. In der Liste, die
suchen, suchen Sie nach einem Prozess namens CLIENT_APP_PROCESS_sdk_sandbox
. Wählen Sie diese Option aus und fügen Sie Haltepunkte im Code der SDK-App hinzu, um
und beginnen Sie mit der Fehlerbehebung.
![Der SDK-App-Prozess wird unten in einer Listenansicht angezeigt
des Dialogfelds](https://developers.google.cn/static/privacy-sandbox/assets/images/android/debug-sdk-app.png?authuser=9&hl=de)
SDK-Laufzeit über die Befehlszeile starten und beenden
Verwenden Sie den folgenden Shell-Befehl, um den SDK-Laufzeitprozess für Ihre App zu starten:
adb shell cmd sdk_sandbox start [--user <USER_ID> | current] <CLIENT_APP_PACKAGE>
Führen Sie auf ähnliche Weise den folgenden Befehl aus, um den SDK-Laufzeitprozess zu beenden:
adb shell cmd sdk_sandbox stop [--user <USER_ID> | current] <CLIENT_APP_PACKAGE>
Prüfen, welche SDKs derzeit geladen sind
Sie können prüfen, welche SDKs derzeit geladen sind, indem Sie den
getSandboxedSdks
-Funktion im
SdkSandboxManager
Beschränkungen
Eine Liste der laufenden Funktionen für die SDK-Laufzeit finden Sie in der Versionshinweise.
Codebeispiele
Die SDK-Laufzeit und datenschutzfreundliches API-Repository auf GitHub enthält eine Reihe einzelner Android Studio-Projekte, mit denen Sie einschließlich Beispielen, die zeigen, wie das SDK initialisiert und Laufzeit:Fehler und Probleme melden
Ihr Feedback ist ein wichtiger Teil der Privacy Sandbox für Android. Teilen Sie uns Ihre Meinung mit. alle Probleme, die Sie gefunden haben, oder Ideen zur Verbesserung der Privacy Sandbox für Android.
Persönliche Empfehlungen
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- SDK-Laufzeit
- Versionshinweise
- Entwicklerleitfaden für die Protected Audience API auf Android-Geräten