A medida que leas la documentación de Privacy Sandbox en Android, usa el botón Versión preliminar para desarrolladores o Beta para seleccionar la versión del programa con la que estás trabajando, ya que las instrucciones pueden variar.
El entorno de ejecución de SDK permite que los SDKs se ejecuten en una zona de pruebas dedicada independiente de la app que realiza la llamada. El entorno de ejecución de SDK proporciona mejores protecciones y garantías en cuanto a la recopilación de datos del usuario. Esto se hace a través de un entorno de ejecución modificado que limita los derechos de acceso a los datos y el conjunto de permisos permitidos. Obtén más información sobre el entorno de ejecución del SDK en la propuesta de diseño.
Los pasos que se indican en esta página te guiarán a través del proceso de creación de un SDK habilitado para el entorno de ejecución que define una vista basada en la Web que se puede renderizar, de forma remota, en una app que realiza la llamada.
Limitaciones conocidas
Si quieres ver una lista de las funciones en curso para el entorno de ejecución de SDK, consulta las notas de la versión.
Se espera que las siguientes limitaciones se corrijan en la próxima versión importante de la plataforma de Android.
- Renderización de anuncios dentro de una vista desplazable (por ejemplo,
RecyclerView
no funciona correctamente)- Es posible que experimentes bloqueos al cambiar el tamaño.
- Los eventos de desplazamiento táctil del usuario no se pasan correctamente al entorno de ejecución.
- API de Storage
- El almacenamiento por SDK no está disponible en Android 13.
El siguiente problema se corregirá en 2023:
- Las APIs de
getAdId
ygetAppSetId
aún no funcionan correctamente, ya que todavía se está trabajando en la compatibilidad.
Antes de comenzar
Antes de comenzar, completa los siguientes pasos:
Configura tu entorno de desarrollo para Privacy Sandbox en Android. Las herramientas para admitir el entorno de ejecución de SDK están en desarrollo activo, por lo que en esta guía deberás usar la versión Canary de Android Studio más reciente. Puedes ejecutar esta versión de Android Studio en paralelo a otras versiones que uses. Por lo tanto, coméntanos si este requisito no funciona en tu caso.
Instala una imagen del sistema en un dispositivo compatible o configura un emulador que incluya compatibilidad con Privacy Sandbox en Android.
Configura tu proyecto en Android Studio
Para probar el entorno de ejecución del SDK, usa un modelo similar al modelo cliente-servidor. La principal diferencia es que las apps (el cliente) y los SDKs (el "servidor") se ejecutan en el mismo dispositivo.
- Agrega un módulo de app a tu proyecto. Este módulo funciona como el cliente que controla el SDK.
- En el módulo de tu app, habilita el entorno de ejecución de SDK, declara los permisos necesarios y configura los servicios de anuncios específicos de la API.
- Agrega un módulo de biblioteca a tu proyecto. Este módulo contiene tu código del SDK.
- En el módulo del SDK, declara los permisos necesarios. No necesitas configurar servicios de anuncios específicos de APIs en este módulo.
- Quita el
dependencies
del archivobuild.gradle
del módulo de la biblioteca que no usa el SDK. En la mayoría de los casos, puedes quitar todas las dependencias. Puedes hacerlo creando un directorio nuevo cuyo nombre corresponda a tu SDK. Crea manualmente un módulo nuevo con el tipo
com.android.privacy-sandbox-sdk
. Este se incluye con el código del SDK para crear un APK que se pueda implementar en tu dispositivo. Puedes hacerlo creando un directorio nuevo cuyo nombre corresponda a tu SDK. Agrega un archivobuild.gradle
vacío. El contenido de este archivo se propagará más adelante en esta guía.Agrega el siguiente fragmento a tu archivo
gradle.properties
:android.experimental.privacysandboxsdk.enable=true
Descarga la imagen del emulador Tiramisu (nivel de extensión 4) y crea un emulador con esta imagen que incluya Play Store.
En función de si eres un desarrollador de SDKs o de apps, es posible que tengas una configuración final diferente a la que se describe en el párrafo anterior.
Instala el SDK en un dispositivo de prueba, de manera similar a como instalarías una app, con Android Studio o Android Debug Bridge (ADB). Para comenzar, creamos apps de ejemplo en los lenguajes de programación Kotlin y Java, que se pueden encontrar en este repositorio de GitHub. Los archivos de manifiesto y readme contienen comentarios que describen lo que se debe cambiar para ejecutar la muestra en versiones estables de Android Studio.
Prepara el SDK
Crea un directorio de nivel de módulo de forma manual. Esto sirve como el wrapper alrededor del código de implementación para compilar el APK del SDK. Agrega un archivo
build.gradle
en el directorio nuevo y propágalo con el siguiente fragmento. Usa un nombre único para el SDK habilitado para el entorno de ejecución y proporciona una versión. Incluye el módulo de biblioteca en la seccióndependencies
.plugins { id 'com.android.privacy-sandbox-sdk' } android { compileSdk 33 compileSdkExtension 4 minSdk 33 targetSdk 33 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>') }
Crea una clase en la biblioteca de implementación de modo que funcione como punto de entrada para el SDK. Se le debe asignar el valor de
sdkProviderClassName
al nombre y extenderSandboxedSdkProvider
.
El punto de entrada de tu SDK extiende SandboxedSdkProvider
. SandboxedSdkProvider
contiene un objeto Context
para tu SDK, al que puedes acceder si llamas a getContext()
. Solo se debe acceder a este contexto una vez que se invocó onLoadSdk()
.
Para que se compile tu app del SDK, debes anular métodos para controlar el ciclo de vida del SDK:
onLoadSdk()
Carga el SDK en la zona de pruebas y notifica a la app que realiza la llamada cuando este esté listo para controlar las solicitudes pasando su interfaz como un objeto
IBinder
que está unido a un nuevo objetoSandboxedSdk
. En la guía de servicios vinculados, se detallan diferentes formas de proporcionarIBinder
. Puedes elegir tu camino de manera flexible, pero debe ser coherente con el SDK y la app que realiza la llamada.Con AIDL como ejemplo, debes definir un archivo AIDL para presentar tu
IBinder
, que la app compartirá y usará:// ISdkInterface.aidl interface ISdkInterface { // the public functions to share with the App. int doSomthing(); }
getView()
Crea y configura la vista de tu anuncio, inicializa la vista de la misma manera que cualquier otra vista de Android y muestra la vista de modo que se renderice de forma remota en una ventana de un ancho y una altura determinados en píxeles.
En el siguiente fragmento de código, se muestra cómo anular estos métodos:
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. } } }
Cómo probar reproductores de video en el entorno de ejecución de SDK
Además de admitir anuncios de banner, Privacy Sandbox se compromete a admitir los reproductores de video que se ejecutan dentro del entorno de ejecución de SDK.
El flujo para probar reproductores de video es similar al de probar anuncios de banner. Cambia el método getView()
del punto de entrada de tu SDK para incluir un reproductor de video en el objeto View
que se muestra. Prueba todos los flujos del reproductor de video que esperas que sean compatibles con Privacy Sandbox. Ten en cuenta que la comunicación entre el SDK y la app cliente sobre el ciclo de vida del video está fuera del alcance, por lo que aún no se requieren comentarios para esta funcionalidad.
Tus pruebas y comentarios garantizarán que el entorno de ejecución de SDK sea compatible con todos los casos de uso de tu reproductor de video preferido.
En el siguiente fragmento de código, se demuestra cómo mostrar una vista de video simple que se carga desde una URL.
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; } }
Uso de las APIs de Storage en tu SDK
Los SDK en el entorno de ejecución del SDK ya no pueden acceder al almacenamiento interno de una app, ni viceversa, ni leer o escribir en él. Al entorno de ejecución de SDK se le asignará su propia área de almacenamiento interno, que será independiente de la app.
Los SDKs podrán acceder a este almacenamiento interno independiente con las APIs de almacenamiento de archivos en el objeto Context
que muestra SandboxedSdkProvider#getContext()
. Los SDKs solo pueden usar el almacenamiento interno, por lo que solo funcionarán las APIs de almacenamiento interno, como Context.getFilesDir()
o Context.getCacheDir()
. Puedes ver más ejemplos en Acceso desde el almacenamiento interno.
No se admite el acceso al almacenamiento externo desde el entorno de ejecución del SDK. Llamar a las APIs para que accedan al almacenamiento externo arrojará una excepción o mostrará null
. Varios ejemplos:
- El acceso a los archivos mediante el framework de acceso al almacenamiento arrojará una
SecurityException
. getExternalFilsDir()
siempre mostraránull
.
En Android 13, todos los SDKs en el entorno de ejecución de SDK compartirán el almacenamiento interno asignado para ese entorno. El almacenamiento se conservará hasta que se desinstale la app cliente o cuando se borren los datos de ella.
Debes usar el Context
que muestra SandboxedSdkProvider.getContext()
para el almacenamiento. El uso de la API de almacenamiento de archivos en cualquier otra instancia de objeto Context
, como el contexto de la aplicación, no se garantiza que funcione como se espera en todas las situaciones o en el futuro.
En el siguiente fragmento de código, se muestra el modo de uso del almacenamiento en el entorno de ejecución del SDK:
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); } } }
Almacenamiento por SDK
Dentro del almacenamiento interno independiente para cada entorno de ejecución de SDK, cada SDK tiene su propio directorio de almacenamiento. El almacenamiento por SDK es una separación lógica del almacenamiento interno del entorno de ejecución de SDK que ayuda a conocer la cantidad de almacenamiento que usa cada uno.
En Android 13, solo una API muestra una ruta de acceso al almacenamiento por SDK: Context#getDataDir()
.
En Android 14, todas las APIs de almacenamiento interno del objeto Context
muestran una ruta de almacenamiento para cada SDK. Es posible que debas habilitar esta función ejecutando el siguiente comando adb:
adb shell device_config put adservices sdksandbox_customized_sdk_context_enabled true
Accede al ID de publicidad que brindan los Servicios de Google Play
Si tu SDK necesita acceder al ID de publicidad que brindan los Servicios de Google Play, haz lo siguiente:
- Declara el permiso
android.permission.ACCESS_ADSERVICES_AD_ID
en el manifiesto del SDK. - Usa
AdIdManager#getAdId()
para recuperar el valor de forma asíncrona.
Accede al ID del conjunto de apps que brindan los Servicios de Google Play
Si tu SDK necesita acceder al ID del conjunto de apps que brindan los Servicios de Google Play, haz lo siguiente:
- Usa
AppSetIdManager#getAppSetId()
para recuperar el valor de forma asíncrona.
Actualiza las apps cliente
Para llamar a un SDK que se ejecuta en el entorno de ejecución de SDK, realiza los siguientes cambios en la app cliente que realiza la llamada:
Agrega los permisos
INTERNET
yACCESS_NETWORK_STATE
al manifiesto de tu app:<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
En la actividad de la app que incluye un anuncio, declara una referencia a
SdkSandboxManager
, un valor booleano para saber si se cargó el SDK, y a un objetoSurfaceView
para la renderización remota: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;
Comprueba si el proceso del entorno de ejecución del SDK está disponible en el dispositivo.
Verifica la constante
SdkSandboxState
(getSdkSandboxState()
).SDK_SANDBOX_STATE_ENABLED_PROCESS_ISOLATION
significa que el entorno de ejecución del SDK está disponible.Comprueba que la llamada a
loadSdk()
se haya realizado correctamente. Es exitosa si no se producen excepciones y el receptor es la instancia delSandboxedSdk
.Llama a
loadSdk()
desde el primer plano. Si se llama en segundo plano, se arroja unaSecurityException
.Verifica el
OutcomeReceiver
para ver una instancia deSandboxedSdk
a fin de comprobar si se arrojó unaLoadSdkException
. Una excepción indica que el entorno de ejecución del SDK puede no estar disponible.
Si la llamada a
loadSdk
o elSdkSandboxState
fallan, el entorno de ejecución del SDK no está disponible y la llamada debería recurrir al SDK existente.Para definir una clase de devolución de llamada, implementa
OutcomeReceiver
a fin de interactuar con el SDK en el entorno de ejecución después de que se haya cargado: En el siguiente ejemplo, el cliente usa una devolución de llamada para esperar hasta que el SDK se cargue de forma correcta y, luego, intenta renderizar una vista web desde el SDK. Las devoluciones de llamada se definen más adelante en este paso.Kotlin
private inner class LoadSdkOutcomeReceiverImpl private constructor() : OutcomeReceiver
{ 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
{ 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. } } Para recuperar una vista remota del SDK en el entorno de ejecución mientras llamas a
requestSurfacePackage()
, implementa la interfazOutcomeReceiver<Bundle, RequestSurfacePackageException>
:Kotlin
private inner class RequestSurfacePackageOutcomeReceiverImpl : OutcomeReceiver
{ 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
{ @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 } } Cuando termines de mostrar la vista, recuerda liberar a
SurfacePackage
con un llamado al siguiente comando:surfacePackage.notifyDetachedFromWindow()
En
onCreate()
, inicializaSdkSandboxManager
, las devoluciones de llamada necesarias y, luego, realiza una solicitud para cargar el SDK: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); }
A fin de manejar el caso cuando el proceso de la zona de pruebas del SDK finaliza de forma inesperada, define una implementación para la interfaz
SdkSandboxProcessDeathCallback
: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); } }
Para registrar esta devolución de llamada para recibir información sobre cuándo se cerró la zona de pruebas del SDK, agrega la siguiente línea en cualquier momento:
Kotlin
mSdkSandboxManager.addSdkSandboxProcessDeathCallback({ obj: Runnable -> obj.run() }, SdkSandboxLifecycleCallbackImpl())
Java
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, new SdkSandboxLifecycleCallbackImpl());
Debido a que el estado de la zona de pruebas se pierde cuando finaliza su proceso, es posible que las vistas que haya renderizado el SDK de forma remota ya no funcionen correctamente. Para seguir interactuando con los SDKs, se deben volver a cargar estas vistas para que se inicie un nuevo proceso de zona de pruebas.
Agrega una dependencia en el módulo del SDK al
build.gradle
de tu app cliente:dependencies { ... implementation project(':<your-sdk-module>') ... }
Prueba tus apps
Para ejecutar tu app cliente, instala la app del SDK y la app cliente en tu dispositivo de prueba mediante Android Studio o la línea de comandos.
Cómo implementar mediante Android Studio
Cuando realices implementaciones mediante Android Studio, sigue estos pasos:
- Abre el proyecto de Android Studio de tu app cliente.
- Ve a Run > Edit Configurations. Aparecerá la ventana Run/Debug Configuration.
- En Launch Options, establece Launch en Specified Activity.
- Haz clic en el menú de tres puntos junto a Activity y selecciona Main Activity para tu cliente.
- Haz clic en Apply y, luego, en OK.
- Haz clic en Run
para instalar la app cliente y el SDK en tu dispositivo de prueba.
Cómo implementar mediante la línea de comandos
Cuando realices implementaciones con la línea de comandos, completa los pasos de la siguiente lista.
En esta sección, se supone que el nombre del módulo de tu app del SDK es sdk-app
y que el nombre del módulo de tu app cliente es client-app
.
Compila los APK del SDK de Privacy Sandbox desde la terminal de la línea de comandos:
./gradlew :client-app:buildPrivacySandboxSdkApksForDebug
Esto genera la ubicación para los APKs generados. Estos APKs están firmados con tu clave de depuración local. Necesitarás esta ruta de acceso en el siguiente comando.
Instala el APK en tu dispositivo:
adb install -t /path/to/your/standalone.apk
En Android Studio, haz clic en Run > Edit Configurations. Aparecerá la ventana Run/Debug Configuration.
En Installation Options, configura Deploy como Default APK.
Haz clic en Apply y, luego, en OK.
Haz clic en Run para instalar el paquete de APK en el dispositivo de prueba.
Depura tus apps
Para depurar la app cliente, haz clic en el botón Debug en Android Studio.
Para depurar la app del SDK, ve a Run > Attach to Process, que muestra una pantalla emergente (figura 1). Marca la casilla Show all processes. En la lista que aparece, busca un proceso con el nombre CLIENT_APP_PROCESS_sdk_sandbox
. Selecciona esta opción y agrega puntos de interrupción en el código de la app del SDK para comenzar a depurar tu SDK.

Inicia y detén el entorno de ejecución del SDK desde la línea de comandos
Para iniciar el proceso del entorno de ejecución del SDK de tu app, usa el siguiente comando shell:
adb shell cmd sdk_sandbox start [--user <USER_ID> | current] <CLIENT_APP_PACKAGE>
Del mismo modo, para detener el proceso del entorno de ejecución del SDK, ejecuta este comando:
adb shell cmd sdk_sandbox stop [--user <USER_ID> | current] <CLIENT_APP_PACKAGE>
Limitaciones
A fin de obtener una lista de las funciones en curso para el entorno de ejecución del SDK, consulta las notas de la versión.
Muestras de código
El repositorio de APIs del entorno de ejecución y la protección de la privacidad del SDK en GitHub contiene un conjunto de proyectos individuales de Android Studio que te ayudarán a comenzar, incluidos ejemplos que muestran cómo inicializar y llamar al entorno de ejecución del SDK.Informa errores y problemas
Tus comentarios son una parte fundamental de Privacy Sandbox en Android. Avísanos si tienes problemas o ideas para mejorar Privacy Sandbox en Android.
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Entorno de ejecución de SDK
- Notas de la versión
- Guía para desarrolladores de la API de Protected Audience en Android