Guida per gli sviluppatori di SDK Runtime

Mentre leggi la documentazione di Privacy Sandbox su Android, utilizza il pulsante Anteprima per sviluppatori o Beta per selezionare la versione del programma che stai utilizzando, poiché le istruzioni possono variare.


Inviare feedback

SDK Runtime consente l'esecuzione degli SDK in una sandbox dedicata, separata dall'app chiamante. SDK Runtime fornisce salvaguardie e garanzie avanzate per la raccolta dei dati utente. Ciò avviene attraverso un ambiente di esecuzione modificato che limita i diritti di accesso ai dati e l'insieme di autorizzazioni consentite. Scopri di più su SDK Runtime nella proposta di progettazione.

I passaggi in questa pagina illustrano la procedura di creazione di un SDK abilitato per runtime che definisce una vista basata sul web di cui è possibile eseguire il rendering da remoto in un'app per chiamate.

Limitazioni note

Per un elenco delle funzionalità in corso per SDK Runtime, visualizza le note di rilascio.

Le seguenti limitazioni dovrebbero essere risolte nella prossima release principale della piattaforma Android.

  • Rendering dell'annuncio in una visualizzazione scorrevole. Ad esempio, RecyclerView non funziona correttamente.
    • Potresti riscontrare rallentamenti al momento del ridimensionamento.
    • Gli eventi di scorrimento al tocco dell'utente non vengono trasmessi correttamente al runtime.
  • API Storage

Il seguente problema verrà risolto nel 2023:

  • Le API getAdId e getAppSetId non funzionano ancora correttamente perché il relativo supporto non è ancora stato attivato.

Prima di iniziare

Prima di iniziare, completa i seguenti passaggi:

  1. Configura il tuo ambiente di sviluppo per Privacy Sandbox su Android. Gli strumenti per il supporto di SDK Runtime sono in fase di sviluppo attivo, pertanto questa guida richiede l'utilizzo dell'ultima versione canary di Android Studio. Puoi eseguire questa versione di Android Studio in parallelo ad altre versioni che utilizzi, quindi contattaci se questo requisito non funziona per te.

  2. Installa un'immagine di sistema su un dispositivo supportato o configura un emulatore che includa il supporto di Privacy Sandbox su Android.

Configurare il progetto in Android Studio

Per provare SDK Runtime, utilizza un modello simile al modello client-server. La differenza principale è che le app (il client) e gli SDK (il "server") vengono eseguiti sullo stesso dispositivo.

  1. Aggiungi un modulo dell'app al tuo progetto. Questo modulo funge da client che gestisce l'SDK.
  2. Nel modulo dell'app, attiva SDK Runtime, dichiara le autorizzazioni necessarie e configura i servizi pubblicitari specifici per l'API.
  3. Aggiungi un modulo della libreria al tuo progetto. Questo modulo contiene il tuo codice SDK.
  4. Nel modulo SDK, dichiara le autorizzazioni necessarie. In questo modulo non è necessario configurare i servizi pubblicitari specifici dell'API.
  5. Rimuovi dependencies dal file build.gradle del modulo della libreria che non utilizza il tuo SDK. Nella maggior parte dei casi, puoi rimuovere tutte le dipendenze. Puoi farlo creando una nuova directory il cui nome corrisponde a quello del tuo SDK.
  6. Crea manualmente un nuovo modulo utilizzando il tipo com.android.privacy-sandbox-sdk. Questo codice viene fornito insieme al codice SDK per creare un APK che può essere implementato sul tuo dispositivo. Puoi farlo creando una nuova directory il cui nome corrisponde al tuo SDK. Aggiungi un file build.gradle vuoto. I contenuti di questo file verranno completati più avanti in questa guida.

  7. Aggiungi il seguente snippet al tuo file gradle.properties:

    android.experimental.privacysandboxsdk.enable=true
    

  8. Scarica l'immagine dell'emulatore Tiramis (livello 4) e crea un emulatore con questa immagine che includa il Play Store.

A seconda che tu sia uno sviluppatore di SDK o di app, potresti avere una configurazione finale diversa da quella descritta nel paragrafo precedente.

Installa l'SDK su un dispositivo di test, utilizzando Android Studio o Android Debug Bridge (ADB) in modo simile a come installeresti un'app. Per aiutarti a iniziare, abbiamo creato app di esempio nei linguaggi di programmazione Kotlin e Java, che puoi trovare in questo repository di GitHub. Il file README e il file manifest contengono commenti che descrivono cosa deve essere modificato per eseguire l'esempio nelle versioni stabili di Android Studio.

Prepara l'SDK

  1. Crea manualmente una directory a livello di modulo. Questo serve da wrapper intorno al codice di implementazione per creare l'APK dell'SDK. Nella nuova directory, aggiungi un file build.gradle e compilalo con il seguente snippet. Utilizza un nome univoco per il tuo SDK (RE-SDK) abilitato per il runtime e fornisci una versione. Includi il modulo della tua libreria nella sezione dependencies.

    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>')
    }
    
  2. Crea una classe nella libreria di implementazione da utilizzare come punto di ingresso per l'SDK. Il nome della classe deve essere mappato al valore di sdkProviderClassName ed estendere SandboxedSdkProvider.

Il punto di ingresso per il tuo SDK estende SandboxedSdkProvider. SandboxedSdkProvider contiene un oggetto Context per il tuo SDK, a cui puoi accedere chiamando getContext(). È possibile accedere a questo contesto solo dopo aver richiamato onLoadSdk().

Per completare la compilazione dell'app SDK, devi eseguire l'override dei metodi per gestire il ciclo di vita dell'SDK:

onLoadSdk()

Carica l'SDK nella sandbox e avvisa l'app chiamante quando è pronto a gestire le richieste passando la propria interfaccia come un oggetto IBinder aggregato all'interno di un nuovo oggetto SandboxedSdk. La guida ai servizi associati offre diversi modi per fornire IBinder. Puoi scegliere la modalità che preferisci, ma deve essere coerente per l'SDK e l'app per le chiamate.

Utilizzando AIDL come esempio, dovresti definire un file AIDL per presentare IBinder, che sarà condiviso e utilizzato dall'app:

// ISdkInterface.aidl
interface ISdkInterface {
    // the public functions to share with the App.
    int doSomething();
}
getView()

Crea e imposta la visualizzazione per l'annuncio, inizializzala come qualsiasi altra visualizzazione Android e restituisce la visualizzazione da eseguire in remoto in una finestra con una determinata larghezza e altezza in pixel.

Lo snippet di codice riportato di seguito mostra come eseguire l'override di questi metodi:

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.
        }
    }
}

Testare i video player in SDK Runtime

Oltre a supportare gli annunci banner, Privacy Sandbox si impegna a supportare i video player in esecuzione all'interno di SDK Runtime.

La procedura per testare i video player è simile a quella per gli annunci banner. Modifica il metodo getView() del punto di ingresso dell'SDK per includere un video player nell'oggetto View restituito. Testa tutti i flussi del video player che ti aspetti siano supportati da Privacy Sandbox. Tieni presente che la comunicazione tra l'SDK e l'app client sul ciclo di vita del video non rientra nell'ambito, quindi il feedback non è ancora necessario per questa funzionalità.

I tuoi test e feedback garantiranno che SDK Runtime supporti tutti i casi d'uso del tuo video player preferito.

Il seguente snippet di codice mostra come restituire una visualizzazione di video semplice che venga caricata da un 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;
        }
    }

Utilizzo delle API di archiviazione nell'SDK

Gli SDK in SDK Runtime non possono più accedere, leggere o scrivere nella archiviazione interna di un'app e viceversa. A SDK Runtime verrà allocata una propria area di archiviazione interna, che sarà garantita come separata dall'app.

Gli SDK potranno accedere a questa archiviazione interna separata utilizzando le API per l'archiviazione dei file nell'oggetto Context restituito da SandboxedSdkProvider#getContext(). Gli SDK possono utilizzare solo l'archiviazione interna, pertanto funzioneranno solo le API di archiviazione interna, come Context.getFilesDir() o Context.getCacheDir(). Guarda altri esempi in Accesso dallo spazio di archiviazione interno.

L'accesso all'unità di archiviazione esterna da SDK Runtime non è supportato. La chiamata alle API per accedere all'unità di archiviazione esterna genererà un'eccezione o restituirà null. Alcuni esempi:

In Android 13, tutti gli SDK in SDK Runtime condivideranno la memoria interna allocata per SDK Runtime. Lo spazio di archiviazione rimarrà mantenuto fino alla disinstallazione dell'app client o fino alla pulizia dei dati dell'app client.

Devi utilizzare il valore Context restituito da SandboxedSdkProvider.getContext() per l'archiviazione. L'utilizzo dell'API di archiviazione file su qualsiasi altra istanza di oggetto Context, come il contesto dell'applicazione, non garantisce il funzionamento previsto in tutte le situazioni o in futuro.

Il seguente snippet di codice mostra come utilizzare lo spazio di archiviazione in SDK Runtime:

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);
        }
    }

}

    

Spazio di archiviazione per SDK

All'interno della memoria interna separata per ogni SDK Runtime, ogni SDK dispone della propria directory di archiviazione. L'archiviazione per SDK è una segregazione logica della memoria interna di SDK Runtime che aiuta a tenere conto della quantità di spazio di archiviazione utilizzata da ogni SDK.

In Android 13, solo un'API restituisce un percorso di archiviazione per SDK: Context#getDataDir().

In Android 14, tutte le API di archiviazione interna nell'oggetto Context restituiscono un percorso di archiviazione per ogni SDK. Potrebbe essere necessario abilitare questa funzionalità eseguendo il seguente comando adb:

adb shell device_config put adservices sdksandbox_customized_sdk_context_enabled true

Accedi all'ID pubblicità fornito da Google Play Services

Se il tuo SDK deve accedere all'ID pubblicità fornito da Google Play Services:

  • Dichiara l'autorizzazione android.permission.ACCESS_ADSERVICES_AD_ID nel manifest dell'SDK.
  • Utilizza AdIdManager#getAdId() per recuperare il valore in modo asincrono.

Accedere all'ID set di app fornito da Google Play Services

Se il tuo SDK deve accedere all'ID set di app fornito da Google Play Services:

  • Utilizza AppSetIdManager#getAppSetId() per recuperare il valore in modo asincrono.

Aggiorna le app client

Per chiamare un SDK in esecuzione in SDK Runtime, apporta le seguenti modifiche all'app client chiamante:

  1. Aggiungi le autorizzazioni INTERNET e ACCESS_NETWORK_STATE al file manifest dell'app:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    
  2. Nell'attività della tua app che include un annuncio, dichiara un riferimento a SdkSandboxManager, un valore booleano per sapere se l'SDK è stato caricato e un oggetto SurfaceView per il rendering remoto:

    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;
    
  3. Controlla se il processo di SDK Runtime è disponibile sul dispositivo.

    1. Controlla la costante SdkSandboxState (getSdkSandboxState()). SDK_SANDBOX_STATE_ENABLED_PROCESS_ISOLATION indica che il runtime SDK è disponibile.

    2. Verifica che la chiamata al numero loadSdk() sia riuscita. L'operazione ha esito positivo se non vengono generate eccezioni e il destinatario è l'istanza di SandboxedSdk.

      • Chiama loadSdk() dal primo piano. Se viene chiamato dallo sfondo, viene generato un valore SecurityException.

      • Controlla il OutcomeReceiver per un'istanza di SandboxedSdk per verificare se è stato generato un LoadSdkException. Un'eccezione indica che SDK Runtime potrebbe non essere disponibile.

    Se la chiamata SdkSandboxState o loadSdk ha esito negativo, SDK Runtime non è disponibile e la chiamata dovrebbe ricorrere all'SDK esistente.

  4. Definisci una classe di callback implementando OutcomeReceiver per interagire con l'SDK nel runtime dopo che è stato caricato. Nell'esempio seguente, il client utilizza un callback per attendere che l'SDK venga caricato correttamente, quindi tenta di eseguire il rendering di una visualizzazione web dall'SDK. I callback vengono definiti più avanti in questo passaggio.

    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.
            }
        }
    

    Per ottenere una visualizzazione remota dall'SDK nel runtime durante la chiamata a requestSurfacePackage(), implementa l'interfaccia OutcomeReceiver<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
            }
        }
    

    Quando hai finito di mostrare la visualizzazione, ricordati di rilasciare SurfacePackage chiamando:

    surfacePackage.notifyDetachedFromWindow()
    
  5. In onCreate(), inizializza SdkSandboxManager, i callback necessari, quindi una richiesta per caricare l'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);
    }
    
  6. Per gestire il caso in cui il processo sandbox dell'SDK termina in modo imprevisto, definisci un'implementazione per l'interfaccia 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);
              }
          }
    

    Per registrare questo callback e ricevere informazioni sul termine della sandbox dell'SDK, aggiungi la seguente riga in qualsiasi momento:

    Kotlin

        mSdkSandboxManager.addSdkSandboxProcessDeathCallback({ obj: Runnable -> obj.run() },
                SdkSandboxLifecycleCallbackImpl())
    

    Java

        mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run,
                new SdkSandboxLifecycleCallbackImpl());
    

    Poiché lo stato della sandbox va perso al termine del processo, le viste di cui l'SDK ha eseguito il rendering in remoto potrebbero non funzionare più correttamente. Per continuare a interagire con gli SDK, è necessario caricare di nuovo queste viste per avviare un nuovo processo sandbox.

  7. Aggiungi una dipendenza al modulo SDK a build.gradle dell'app client:

    dependencies {
        ...
        implementation project(':<your-sdk-module>')
        ...
    }

Testare le app

Per eseguire l'app client, installa l'app SDK e l'app client sul dispositivo di test utilizzando Android Studio o la riga di comando.

Implementazione tramite Android Studio

Quando esegui il deployment tramite Android Studio, completa i seguenti passaggi:

  1. Apri il progetto Android Studio per l'app client.
  2. Vai a Esegui > Modifica configurazioni. Viene visualizzata la finestra Esegui/configura il debug.
  3. Sotto Opzioni di avvio, imposta Avvia su Attività specificata.
  4. Fai clic sul menu con tre puntini accanto ad Attività e seleziona l'Attività principale per il tuo cliente.
  5. Fai clic su Applica, quindi su OK.
  6. Fai clic su Esegui per installare l'app client e l'SDK sul tuo dispositivo di test.

Esegui il deployment dalla riga di comando

Quando esegui il deployment utilizzando la riga di comando, completa i passaggi nell'elenco seguente. Questa sezione presuppone che il nome del modulo dell'app SDK sia sdk-app e che il nome del modulo dell'app client sia client-app.

  1. Da un terminale a riga di comando, crea gli APK dell'SDK Privacy Sandbox:

    ./gradlew :client-app:buildPrivacySandboxSdkApksForDebug
    

    Verrà restituita la posizione per gli APK generati. Questi APK sono firmati con la chiave di debug locale. Questo percorso è necessario nel comando successivo.

  2. Installa l'APK sul dispositivo:

    adb install -t /path/to/your/standalone.apk
    
  3. In Android Studio, fai clic su Esegui > Modifica configurazioni. Viene visualizzata la finestra Configurazione esecuzione/debug.

  4. In Opzioni di installazione, imposta Esegui il deployment su APK predefinito.

  5. Fai clic su Applica, quindi su OK.

  6. Fai clic su Esegui per installare il pacchetto APK sul dispositivo di test.

Esegui il debug delle tue app

Per eseguire il debug dell'app client, fai clic sul pulsante Debug in Android Studio.

Per eseguire il debug dell'app SDK, vai a Esegui > Allega a processo; viene visualizzata una schermata popup (mostrata di seguito). Seleziona la casella Mostra tutti i processi. Nell'elenco visualizzato, cerca un processo chiamato CLIENT_APP_PROCESS_sdk_sandbox. Seleziona questa opzione e aggiungi punti di interruzione nel codice dell'app SDK per iniziare il debug dell'SDK.

Il processo dell&#39;app SDK viene visualizzato in una visualizzazione elenco nella parte inferiore della finestra di dialogo
La schermata Scegli processo, in cui puoi selezionare l'app SDK di cui eseguire il debug.

Avvia e interrompi il runtime dell'SDK dalla riga di comando

Per avviare il processo di runtime dell'SDK per la tua app, utilizza il seguente comando shell:

adb shell cmd sdk_sandbox start [--user <USER_ID> | current] <CLIENT_APP_PACKAGE>

Analogamente, per interrompere il processo di runtime dell'SDK, esegui questo comando:

adb shell cmd sdk_sandbox stop [--user <USER_ID> | current] <CLIENT_APP_PACKAGE>

Limitazioni

Per un elenco delle funzionalità in corso per SDK Runtime, consulta le note di rilascio.

Esempi di codice

Il repository di API SDK Runtime e Privacy Conserveing su GitHub contiene un set di singoli progetti Android Studio per aiutarti a iniziare, inclusi esempi che mostrano come inizializzare e chiamare l'SDK Runtime.

Segnala bug e problemi

Il tuo feedback è una parte fondamentale di Privacy Sandbox su Android. Comunicaci eventuali problemi riscontrati o idee per migliorare Privacy Sandbox su Android.