Panduan developer Runtime SDK

Saat Anda membaca dokumentasi Privacy Sandbox di Android, gunakan tombol Pratinjau Developer atau Beta untuk memilih versi program yang sedang Anda gunakan, karena petunjuknya dapat bervariasi.


Berikan masukan

Runtime SDK memungkinkan SDK berjalan di sandbox khusus yang terpisah dari aplikasi pemanggil. Runtime SDK memberikan peningkatan pengamanan dan jaminan seputar pengumpulan data pengguna. Hal ini dilakukan melalui lingkungan eksekusi yang dimodifikasi, yang membatasi hak akses data dan serangkaian izin yang diperbolehkan. Pelajari lebih lanjut Runtime SDK di proposal desain.

Langkah-langkah di halaman ini akan memandu Anda dalam proses pembuatan SDK yang mendukung runtime yang menentukan tampilan berbasis web yang dapat dirender dari jarak jauh ke aplikasi panggilan.

Batasan umum

Untuk daftar kemampuan yang sedang berlangsung untuk Runtime SDK, lihat catatan rilis.

Batasan berikut diperkirakan akan diperbaiki dalam rilis platform Android utama berikutnya.

  • Rendering iklan dalam tampilan yang dapat di-scroll. Misalnya, RecyclerView tidak berfungsi dengan baik.
    • Anda mungkin mengalami jank saat mengubah ukuran.
    • Peristiwa scroll sentuh pengguna tidak diteruskan ke runtime dengan benar.
  • Storage API

Masalah berikut akan diperbaiki pada 2023:

  • API getAdId dan getAppSetId belum berfungsi dengan baik karena dukungan untuk API ini belum diaktifkan.

Sebelum memulai

Sebelum memulai, selesaikan langkah-langkah berikut:

  1. Menyiapkan lingkungan pengembangan Anda untuk Privacy Sandbox di Android. Alat untuk mendukung Runtime SDK sedang dalam pengembangan aktif sehingga panduan ini akan mengharuskan Anda menggunakan Android Studio versi Canary terbaru. Anda dapat menjalankan versi Android Studio ini secara paralel dengan versi lain yang Anda gunakan. Jadi, beri tahu kami jika persyaratan ini tidak berhasil untuk Anda.

  2. Instal image sistem ke perangkat yang didukung atau siapkan emulator yang menyertakan dukungan untuk Privacy Sandbox di Android.

Menyiapkan project di Android Studio

Untuk mencoba Runtime SDK, gunakan model yang mirip dengan model klien-server. Perbedaan utamanya adalah aplikasi (klien) dan SDK ("server") berjalan di perangkat yang sama.

  1. Tambahkan modul aplikasi ke project Anda. Modul ini berfungsi sebagai klien yang mendorong SDK.
  2. Dalam modul aplikasi, aktifkan Runtime SDK, deklarasikan izin yang diperlukan, dan konfigurasi layanan iklan khusus API.
  3. Tambahkan satu modul library ke project Anda. Modul ini berisi kode SDK Anda.
  4. Dalam modul SDK, deklarasikan izin yang diperlukan. Anda tidak perlu mengonfigurasi layanan iklan khusus API dalam modul ini.
  5. Hapus dependencies di file build.gradle modul library yang tidak digunakan SDK Anda. Dalam sebagian besar kasus, Anda dapat menghapus semua dependensi. Anda dapat melakukannya dengan membuat direktori baru yang namanya sesuai dengan SDK Anda.
  6. Buat modul baru menggunakan jenis com.android.privacy-sandbox-sdk secara manual. Modul ini disertakan dengan kode SDK untuk membuat APK yang dapat di-deploy ke perangkat. Anda dapat melakukannya dengan membuat direktori baru yang namanya sesuai dengan SDK Anda. Tambahkan file build.gradle kosong. Konten file ini akan diisi nanti dalam panduan ini.

  7. Tambahkan cuplikan berikut ke file gradle.properties Anda:

    android.experimental.privacysandboxsdk.enable=true
    

  8. Download image emulator Tiramisu (Ekstensi Level 4), lalu buat emulator dengan image ini yang menyertakan Play Store.

Bergantung pada apakah Anda seorang developer SDK atau developer aplikasi, Anda mungkin memiliki penyiapan akhir yang berbeda dari yang dijelaskan dalam paragraf sebelumnya.

Instal SDK ke perangkat pengujian, sama dengan cara Anda menginstal aplikasi, menggunakan Android Studio atau Android Debug Bridge (ADB). Untuk membantu Anda memulai, kami telah membuat aplikasi contoh dalam bahasa pemrograman Kotlin dan Java yang dapat ditemukan di repositori GitHub ini. File README dan manifes memiliki komentar yang menjelaskan apa yang harus diubah untuk menjalankan contoh dalam versi stabil Android Studio.

Menyiapkan SDK

  1. Buat direktori level modul secara manual. Direktori ini berfungsi sebagai wrapper terkait kode penerapan Anda untuk mem-build APK SDK. Di direktori baru, tambahkan file build.gradle dan isi dengan cuplikan berikut. Gunakan nama unik untuk SDK yang mendukung runtime (RE-SDK), dan berikan versi. Sertakan modul library Anda di bagian 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. Buat class di library penerapan Anda sebagai titik entri untuk SDK Anda. Nama class harus dipetakan ke nilai sdkProviderClassName dan memperluas SandboxedSdkProvider.

Titik entri untuk SDK Anda memperluas SandboxedSdkProvider. SandboxedSdkProvider berisi objek Context untuk SDK Anda, yang dapat diakses dengan memanggil getContext(). Konteks ini hanya boleh diakses setelah onLoadSdk() dipanggil.

Agar aplikasi SDK dapat dikompilasi, Anda perlu mengganti metode untuk menangani siklus proses SDK:

onLoadSdk()

Memuat SDK di sandbox, dan memberi tahu aplikasi panggilan saat SDK siap menangani permintaan dengan meneruskan antarmukanya sebagai objek IBinder yang digabungkan di dalam objek SandboxedSdk baru. Panduan layanan terikat menyediakan berbagai cara untuk menyediakan IBinder. Anda memiliki fleksibilitas untuk memilih cara, tetapi harus konsisten untuk SDK dan aplikasi panggilan.

Dengan menggunakan AIDL sebagai contoh, Anda harus menentukan file AIDL untuk menampilkan IBinder yang akan dibagikan dan digunakan oleh aplikasi:

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

Membuat dan menyiapkan tampilan untuk iklan Anda, melakukan inisialisasi tampilan dengan cara yang sama seperti tampilan Android lainnya, dan menampilkan tampilan yang akan dirender dari jarak jauh di jendela dengan lebar dan tinggi yang ditentukan dalam piksel.

Cuplikan kode berikut menunjukkan cara mengganti metode ini:

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

Menguji pemutar video di Runtime SDK

Selain mendukung iklan banner, Privacy Sandbox berkomitmen untuk mendukung pemutar video yang berjalan di dalam Runtime SDK.

Alur untuk menguji pemutar video mirip dengan menguji iklan banner. Ubah metode getView() titik entri SDK Anda untuk menyertakan pemutar video dalam objek View yang ditampilkan. Uji semua alur pemutar video yang Anda harapkan akan didukung oleh Privacy Sandbox. Perlu diketahui bahwa komunikasi antara SDK dan aplikasi klien tentang siklus proses video saat ini berada di luar cakupan, sehingga masukan belum diperlukan untuk fungsi ini.

Pengujian dan masukan Anda akan memastikan bahwa Runtime SDK mendukung semua kasus penggunaan pemutar video pilihan Anda.

Cuplikan kode berikut menunjukkan cara menampilkan tampilan video sederhana yang dimuat dari 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;
        }
    }

Menggunakan storage API di SDK Anda

SDK di Runtime SDK tidak dapat lagi mengakses, membaca, atau menulis di penyimpanan internal aplikasi, dan sebaliknya. Runtime SDK akan diberi alokasi area penyimpanan internalnya sendiri, yang dijamin terpisah dari aplikasi.

SDK akan dapat mengakses penyimpanan internal terpisah ini menggunakan API penyimpanan file pada objek Context yang ditampilkan oleh SandboxedSdkProvider#getContext(). SDK hanya dapat menggunakan penyimpanan internal sehingga hanya API penyimpanan internal, seperti Context.getFilesDir() atau Context.getCacheDir() yang akan berfungsi. Lihat contoh lainnya di Mengakses dari penyimpanan internal.

Akses ke penyimpanan eksternal dari Runtime SDK tidak didukung. Memanggil API untuk mengakses penyimpanan eksternal akan menampilkan pengecualian atau menampilkan null. Beberapa contoh:

Di Android 13, semua SDK di Runtime SDK akan membagikan penyimpanan internal yang dialokasikan untuk Runtime SDK. Penyimpanan akan dipertahankan sampai aplikasi klien di-uninstal, atau saat data aplikasi klien dihapus.

Anda harus menggunakan Context yang ditampilkan oleh SandboxedSdkProvider.getContext() untuk penyimpanan. Menggunakan API penyimpanan file pada instance objek Context lainnya, seperti konteks aplikasi, tidak dijamin akan berfungsi seperti yang diharapkan dalam semua situasi atau di masa mendatang.

Cuplikan kode berikut menunjukkan cara menggunakan penyimpanan di Runtime 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);
        }
    }

}

    

Penyimpanan per SDK

Dalam penyimpanan internal terpisah untuk setiap Runtime SDK, setiap SDK memiliki direktori penyimpanannya sendiri. Penyimpanan per SDK adalah pemisahan logis penyimpanan internal Runtime SDK yang membantu memperhitungkan jumlah penyimpanan yang digunakan setiap SDK.

Di Android 13, hanya satu API yang menampilkan jalur ke penyimpanan per SDK: Context#getDataDir().

Di Android 14, semua API penyimpanan internal pada objek Context menampilkan jalur penyimpanan untuk setiap SDK. Anda mungkin perlu mengaktifkan fitur ini dengan menjalankan perintah adb berikut:

adb shell device_config put adservices sdksandbox_customized_sdk_context_enabled true

Mengakses ID iklan yang disediakan oleh layanan Google Play

Jika SDK Anda memerlukan akses ke ID iklan yang disediakan oleh layanan Google Play:

  • Deklarasikan izin android.permission.ACCESS_ADSERVICES_AD_ID dalam manifes SDK.
  • Gunakan AdIdManager#getAdId() untuk mengambil nilai secara asinkron.

Mengakses ID kumpulan aplikasi yang disediakan oleh layanan Google Play

Jika SDK Anda memerlukan akses ke ID kumpulan aplikasi yang disediakan oleh layanan Google Play:

  • Gunakan AppSetIdManager#getAppSetId() untuk mengambil nilai secara asinkron.

Mengupdate aplikasi klien

Untuk memanggil SDK yang berjalan di Runtime SDK, terapkan perubahan berikut pada aplikasi klien yang melakukan panggilan:

  1. Tambahkan izin INTERNET dan ACCESS_NETWORK_STATE ke manifes aplikasi Anda:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    
  2. Dalam aktivitas aplikasi Anda yang menyertakan iklan, deklarasikan referensi ke SdkSandboxManager, boolean untuk mengetahui apakah SDK telah dimuat, dan objek SurfaceView untuk rendering jarak jauh:

    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. Periksa apakah proses Runtime SDK tersedia di perangkat.

    1. Periksa konstanta SdkSandboxState (getSdkSandboxState()). SDK_SANDBOX_STATE_ENABLED_PROCESS_ISOLATION berarti Runtime SDK tersedia.

    2. Pastikan bahwa panggilan loadSdk() berhasil. Panggilan berhasil jika tidak ada pengecualian yang ditampilkan, dan penerima merupakan instance dari SandboxedSdk.

      • Panggil loadSdk() dari latar depan. Jika dipanggil dari latar belakang, SecurityException akan ditampilkan.

      • Periksa OutcomeReceiver untuk melihat instance SandboxedSdk guna memverifikasi apakah LoadSdkException ditampilkan. Pengecualian menunjukkan Runtime SDK mungkin tidak tersedia.

    Jika panggilan SdkSandboxState atau loadSdk gagal, Runtime SDK tidak tersedia dan panggilan harus dialihkan ke SDK yang ada.

  4. Tentukan class callback dengan menerapkan OutcomeReceiver untuk berinteraksi dengan SDK dalam runtime setelah dimuat. Pada contoh berikut, klien menggunakan callback untuk menunggu hingga SDK berhasil dimuat, lalu berupaya merender tampilan web dari SDK. Callback akan ditentukan nanti dalam langkah ini.

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

    Untuk mendapatkan kembali tampilan jarak jauh dari SDK dalam runtime saat memanggil requestSurfacePackage(), implementasikan antarmuka 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
            }
        }
    

    Setelah selesai menunjukkan tampilan, jangan lupa merilis SurfacePackage dengan memanggil:

    surfacePackage.notifyDetachedFromWindow()
    
  5. Di onCreate(), lakukan inisialisasi SdkSandboxManager, callback yang diperlukan, lalu buat permintaan untuk memuat 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. Untuk menangani kasus saat proses sandbox SDK tiba-tiba berhenti, tentukan implementasi untuk antarmuka 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);
              }
          }
    

    Untuk mendaftarkan callback ini guna menerima informasi tentang kapan sandbox SDK telah dihentikan, tambahkan baris berikut kapan saja:

    Kotlin

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

    Java

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

    Karena status sandbox hilang saat prosesnya dihentikan, tampilan yang telah dirender dari jarak jauh mungkin tidak lagi berfungsi dengan benar. Agar dapat terus berinteraksi dengan SDK, tampilan ini harus dimuat lagi sehingga proses sandbox baru dimulai.

  7. Tambahkan dependensi pada modul SDK ke build.gradle aplikasi klien Anda:

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

Menguji aplikasi Anda

Untuk menjalankan aplikasi klien, instal aplikasi SDK dan aplikasi klien ke perangkat pengujian Anda menggunakan Android Studio atau command line.

Men-deploy melalui Android Studio

Saat men-deploy melalui Android Studio, selesaikan langkah-langkah berikut:

  1. Buka project Android Studio untuk aplikasi klien Anda.
  2. Buka Run > Edit Configurations. Jendela Run/Debug Configuration akan muncul.
  3. Di bagian Launch Options, tetapkan Launch ke Specified Activity.
  4. Klik menu tiga titik di samping Activity dan pilih Main Activity untuk klien Anda.
  5. Klik Apply, lalu OK.
  6. Klik Run untuk menginstal aplikasi klien dan SDK di perangkat pengujian Anda.

Men-deploy pada command line

Saat men-deploy menggunakan command line, selesaikan langkah-langkah dalam daftar berikut. Bagian ini mengasumsikan bahwa nama modul aplikasi SDK Anda adalah sdk-app dan nama modul aplikasi klien Anda adalah client-app.

  1. Dari terminal command line, buat APK SDK Privacy Sandbox:

    ./gradlew :client-app:buildPrivacySandboxSdkApksForDebug
    

    Tindakan ini menghasilkan lokasi untuk APK yang dibuat. APK ini ditandatangani dengan kunci debug lokal Anda. Anda memerlukan jalur ini di perintah berikutnya.

  2. Instal APK di perangkat Anda:

    adb install -t /path/to/your/standalone.apk
    
  3. Di Android Studio, klik Run > Edit Configurations. Jendela Run/Debug Configuration akan muncul.

  4. Di bagian Installation Options, setel Deploy ke Default APK.

  5. Klik Apply, lalu OK.

  6. Klik Run untuk menginstal paket APK di perangkat pengujian Anda.

Men-debug aplikasi Anda

Untuk men-debug aplikasi klien, klik tombol Debug di Android Studio.

Untuk men-debug aplikasi SDK, buka Run > Attach to Process, yang menampilkan layar pop-up (ditampilkan di bawah). Centang kotak Tampilkan semua proses. Dalam daftar yang muncul, cari proses yang disebut CLIENT_APP_PROCESS_sdk_sandbox. Pilih opsi ini dan tambahkan titik henti sementara di kode aplikasi SDK untuk mulai men-debug SDK Anda.

Proses aplikasi SDK muncul dalam tampilan daftar di dekat bagian bawah
  dialog
Layar Choose process, tempat Anda dapat memilih aplikasi SDK untuk di-debug.

Memulai dan menghentikan runtime SDK dari command line

Untuk memulai proses runtime SDK untuk aplikasi Anda, gunakan perintah shell berikut:

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

Demikian pula, untuk menghentikan proses runtime SDK, jalankan perintah ini:

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

Batasan

Untuk daftar kemampuan yang sedang berlangsung untuk Runtime SDK, lihat catatan rilis.

Contoh kode

Halaman Repositori Privacy Preserving API dan Runtime SDK di GitHub berisi kumpulan masing-masing project Android Studio untuk membantu Anda memulai, termasuk contoh yang menunjukkan cara menginisialisasi dan memanggil Runtime SDK.

Melaporkan bug dan masalah

Masukan Anda adalah bagian penting dari Privacy Sandbox di Android. Beri tahu kami jika Anda menemukan masalah atau memiliki ide untuk meningkatkan kualitas Privacy Sandbox di Android.