Руководство разработчика среды выполнения SDK,Руководство разработчика среды выполнения SDK

Предварительная

Читая документацию Privacy Sandbox для Android, используйте кнопку Developer Preview или Beta , чтобы выбрать версию программы, с которой вы работаете, поскольку инструкции могут отличаться.


Оставьте отзыв

Среда выполнения SDK позволяет запускать SDK в выделенной изолированной программной среде, отдельной от вызывающего приложения. SDK Runtime обеспечивает улучшенную защиту и гарантии сбора пользовательских данных. Это делается с помощью модифицированной среды выполнения, которая ограничивает права доступа к данным и набор разрешенных разрешений. Подробную информацию о среде выполнения SDK можно найти в проектном предложении .

Шаги на этой странице проведут вас через процесс создания SDK с поддержкой среды выполнения, который определяет веб-представление, которое можно удаленно преобразовать в вызывающее приложение.

Известные ограничения

Список текущих возможностей для среды выполнения SDK см. в примечаниях к выпуску.

Ожидается, что следующие ограничения будут исправлены в следующем основном выпуске платформы Android.

  • Рендеринг рекламы в режиме прокрутки. Например, RecyclerView работает неправильно.
    • Вы можете столкнуться с зависанием при изменении размера.
    • События сенсорной прокрутки пользователя не передаются в среду выполнения должным образом.
  • API хранилища

В 2023 году будет исправлена ​​следующая проблема:

  • API getAdId и getAppSetId пока не работают должным образом, поскольку их поддержка еще не активирована.

Прежде чем начать

Прежде чем приступить к работе, выполните следующие шаги:

  1. Настройте среду разработки для Privacy Sandbox на Android. Инструменты для поддержки среды выполнения SDK находятся в стадии активной разработки, поэтому для этого руководства вам потребуется использовать последнюю версию Canary Android Studio . Вы можете запускать эту версию Android Studio параллельно с другими используемыми вами версиями, поэтому сообщите нам, если это требование вас не устраивает.

  2. Либо установите образ системы на поддерживаемое устройство , либо настройте эмулятор , включающий поддержку Privacy Sandbox на Android.

Настройте свой проект в Android Studio

Чтобы опробовать SDK Runtime, используйте модель, аналогичную модели клиент-сервер . Основное отличие состоит в том, что приложения (клиент) и SDK («сервер») работают на одном устройстве.

  1. Добавьте модуль приложения в свой проект. Этот модуль служит клиентом, управляющим SDK.
  2. В модуле приложения включите SDK Runtime , объявите необходимые разрешения и настройте рекламные службы для конкретного API .
  3. Добавьте в свой проект один библиотечный модуль. Этот модуль содержит ваш код SDK.
  4. В вашем модуле SDK объявите необходимые разрешения. Вам не нужно настраивать рекламные службы для конкретного API в этом модуле.
  5. Удалите dependencies в файле build.gradle вашего библиотечного модуля, которые не использует ваш SDK. В большинстве случаев вы можете удалить все зависимости. Вы можете сделать это, создав новый каталог, имя которого соответствует вашему SDK.
  6. Вручную создайте новый модуль, используя тип com.android.privacy-sandbox-sdk . Он входит в состав кода SDK для создания APK, который можно развернуть на вашем устройстве. Вы можете сделать это, создав новый каталог, имя которого соответствует вашему SDK. Добавьте пустой файл build.gradle . Содержимое этого файла будет заполнено позже в этом руководстве.

  7. Добавьте следующий фрагмент в файл gradle.properties :

    android.experimental.privacysandboxsdk.enable=true
    
  8. Загрузите образ эмулятора Тирамису (уровень расширения 4) и создайте эмулятор с этим образом, включающий Play Store.

В зависимости от того, являетесь ли вы разработчиком SDK или разработчиком приложений, окончательная настройка может отличаться от той, которая описана в предыдущем абзаце.

Установите SDK на тестовое устройство аналогично тому, как вы устанавливаете приложение, используя Android Studio или Android Debug Bridge (ADB) .Чтобы помочь вам начать работу, мы создали примеры приложений на языках программирования Kotlin и Java, которые можно найти в этом репозитории GitHub . Файлы README и манифеста содержат комментарии, описывающие, что необходимо изменить для запуска примера в стабильных версиях Android Studio.

Подготовьте свой SDK

  1. Вручную создайте каталог уровня модуля. Это служит оболочкой вашего кода реализации для сборки APK SDK. В новом каталоге добавьте файл build.gradle и заполните его следующим фрагментом. Используйте уникальное имя для своего SDK с поддержкой среды выполнения (RE-SDK) и укажите версию. Включите свой библиотечный модуль в раздел 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. Создайте класс в своей библиотеке реализации, который будет служить точкой входа для вашего SDK. Имя класса должно сопоставляться со значением sdkProviderClassName и расширять SandboxedSdkProvider .

Точка входа для вашего SDK расширяет SandboxedSdkProvider . SandboxedSdkProvider содержит объект Context для вашего SDK, к которому вы можете получить доступ, вызвав getContext() . Доступ к этому контексту должен быть возможен только после вызова onLoadSdk() .

Чтобы ваше приложение SDK скомпилировалось, вам необходимо переопределить методы для управления жизненным циклом SDK:

onLoadSdk()

Загружает SDK в песочницу и уведомляет вызывающее приложение, когда SDK готов обрабатывать запросы, передавая свой интерфейс как объект IBinder , заключенный в новый объект SandboxedSdk . Руководство по связанным сервисам предоставляет различные способы предоставления IBinder . У вас есть возможность выбирать свой путь, но он должен быть одинаковым для SDK и вызывающего приложения.

Используя AIDL в качестве примера, вы должны определить файл AIDL для представления вашего IBinder , который будет использоваться приложением совместно:

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

Создает и настраивает представление для вашего объявления, инициализирует его так же, как и любое другое представление Android, и возвращает представление для удаленного отображения в окне заданной ширины и высоты в пикселях.

Следующий фрагмент кода демонстрирует, как переопределить эти методы:

Котлин

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

Ява

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

Тестирование видеоплееров в среде выполнения SDK

Помимо поддержки рекламных баннеров, Privacy Sandbox обеспечивает поддержку видеоплееров, работающих в среде выполнения SDK.

Процесс тестирования видеоплееров аналогичен тестированию баннерной рекламы. Измените метод getView() точки входа вашего SDK, чтобы включить видеоплеер в возвращаемый объект View . Проверьте все потоки видеопроигрывателя, которые, как вы ожидаете, будут поддерживаться Privacy Sandbox. Обратите внимание, что обмен данными между SDK и клиентским приложением о жизненном цикле видео выходит за рамки, поэтому для этой функции обратная связь пока не требуется.

Ваше тестирование и отзывы гарантируют, что среда выполнения SDK поддерживает все варианты использования предпочитаемого вами видеоплеера.

В следующем фрагменте кода показано, как вернуть простой просмотр видео, загружаемый по URL-адресу.

Котлин

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

Ява

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

Использование API хранилища в вашем SDK

SDK в среде выполнения SDK больше не могут получать доступ, читать или записывать во внутреннюю память приложения, и наоборот. Среде выполнения SDK будет выделена собственная внутренняя область хранения, которая гарантированно будет отделена от приложения.

SDK смогут получить доступ к этому отдельному внутреннему хранилищу с помощью API-интерфейсов хранилища файлов для объекта Context , возвращаемого SandboxedSdkProvider#getContext() . SDK могут использовать только внутреннее хранилище, поэтому будут работать только API внутреннего хранилища, такие как Context.getFilesDir() или Context.getCacheDir() . Дополнительные примеры см. в разделе Доступ из внутренней памяти .

Доступ к внешнему хранилищу из SDK Runtime не поддерживается. Вызов API для доступа к внешнему хранилищу либо выдаст исключение, либо вернет null . Несколько примеров:

  • Доступ к файлам с использованием Storage Access Framework приведет к возникновению SecurityException .
  • getExternalFilsDir() всегда будет возвращать null .

В Android 13 все SDK в среде выполнения SDK будут совместно использовать внутреннюю память, выделенную для среды выполнения SDK. Хранилище будет сохраняться до тех пор, пока клиентское приложение не будет удалено или пока не будут очищены данные клиентского приложения.

Для хранения необходимо использовать Context , возвращаемый SandboxedSdkProvider.getContext() . Использование API хранилища файлов в любом другом экземпляре объекта Context , например в контексте приложения, не гарантируется, что будет работать должным образом во всех ситуациях или в будущем.

Следующий фрагмент кода демонстрирует, как использовать хранилище в среде выполнения SDK:

Котлин

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

    

Ява

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

}

    

Хранилище для каждого SDK

В отдельном внутреннем хранилище для каждой среды выполнения SDK каждый SDK имеет собственный каталог хранения. Хранилище для каждого SDK — это логическое разделение внутреннего хранилища среды выполнения SDK, которое помогает учитывать объем хранилища, используемый каждым SDK.

В Android 13 только один API возвращает путь к хранилищу каждого SDK: Context#getDataDir() .

В Android 14 все API внутреннего хранилища объекта Context возвращают путь к хранилищу для каждого SDK. Возможно, вам придется включить эту функцию, выполнив следующую команду adb:

adb shell device_config put adservices sdksandbox_customized_sdk_context_enabled true

Получите доступ к рекламному идентификатору, предоставленному сервисами Google Play.

Если вашему SDK требуется доступ к рекламному идентификатору, предоставленному сервисами Google Play:

  • Объявите разрешение android.permission.ACCESS_ADSERVICES_AD_ID в манифесте SDK.
  • Используйте AdIdManager#getAdId() для асинхронного получения значения.

Получите доступ к идентификатору набора приложений, предоставленному сервисами Google Play.

Если вашему SDK требуется доступ к идентификатору набора приложений, предоставленному сервисами Google Play:

  • Используйте AppSetIdManager#getAppSetId() для асинхронного получения значения.

Обновите клиентские приложения

Чтобы вызвать SDK, работающий в среде выполнения SDK, внесите следующие изменения в вызывающее клиентское приложение:

  1. Добавьте разрешения INTERNET и ACCESS_NETWORK_STATE в манифест вашего приложения:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    
  2. В активности вашего приложения, включающей рекламу, объявите ссылку на SdkSandboxManager , логическое значение, чтобы узнать, загружен ли SDK, и объект SurfaceView для удаленного рендеринга:

    Котлин

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

    Ява

        private static final String SDK_NAME = "com.example.privacysandbox.provider";
    
        private SdkSandboxManager mSdkSandboxManager;
        private SurfaceView mClientView;
        private boolean mSdkLoaded = false;
    
  3. Проверьте, доступен ли на устройстве процесс выполнения SDK.

    1. Проверьте константу SdkSandboxState ( getSdkSandboxState() ). SDK_SANDBOX_STATE_ENABLED_PROCESS_ISOLATION означает, что среда выполнения SDK доступна.

    2. Убедитесь, что вызов loadSdk() прошел успешно. Это успешно, если исключений не возникает, а получателем является экземпляр SandboxedSdk .

      • Вызовите loadSdk() с переднего плана. Если он вызывается в фоновом режиме, будет выброшено SecurityException .

      • Проверьте OutcomeReceiver на наличие экземпляра SandboxedSdk , чтобы убедиться, что было создано LoadSdkException . Исключение указывает на то, что среда выполнения SDK может быть недоступна.

    Если вызов SdkSandboxState или loadSdk завершается неудачей, среда выполнения SDK недоступна, и вызов должен вернуться к существующему SDK.

  4. Определите класс обратного вызова, реализовав OutcomeReceiver для взаимодействия с SDK во время выполнения после его загрузки. В следующем примере клиент использует обратный вызов, чтобы дождаться успешной загрузки SDK, а затем пытается отобразить веб-представление из SDK. Обратные вызовы определяются позже на этом этапе.

    Котлин

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

    Ява

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

    Чтобы получить удаленное представление из SDK во время выполнения при вызове requestSurfacePackage() , реализуйте интерфейс OutcomeReceiver<Bundle, RequestSurfacePackageException> :

    Котлин

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

    Ява

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

    Закончив отображение представления, не забудьте освободить SurfacePackage , вызвав:

    surfacePackage.notifyDetachedFromWindow()
    
  5. В onCreate() инициализируйте SdkSandboxManager , необходимые обратные вызовы, а затем сделайте запрос на загрузку SDK:

    Котлин

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

    Ява

    @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. Чтобы обработать случай, когда процесс песочницы SDK неожиданно завершается, определите реализацию интерфейса SdkSandboxProcessDeathCallback :

    Котлин

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

    Ява

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

    Чтобы зарегистрировать этот обратный вызов для получения информации о завершении работы песочницы SDK, добавьте в любой момент следующую строку:

    Котлин

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

    Ява

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

    Поскольку состояние песочницы теряется при завершении ее процесса, представления, удаленно обработанные SDK, могут перестать работать корректно. Чтобы продолжить взаимодействие с SDK, эти представления необходимо загрузить еще раз, чтобы запустить новый процесс песочницы.

  7. Добавьте зависимость от вашего модуля SDK в build.gradle вашего клиентского приложения:

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

Тестируйте свои приложения

Чтобы запустить клиентское приложение, установите приложение SDK и клиентское приложение на тестовое устройство с помощью Android Studio или командной строки.

Развертывание через Android Studio

При развертывании через Android Studio выполните следующие шаги:

  1. Откройте проект Android Studio для своего клиентского приложения.
  2. Перейдите в «Выполнить» > «Изменить конфигурации» . Появится окно конфигурации запуска/отладки .
  3. В разделе «Параметры запуска» установите для параметра «Запуск» значение «Указанное действие» .
  4. Нажмите трехточечное меню рядом с пунктом «Действие» и выберите « Основное действие» для вашего клиента.
  5. Нажмите «Применить» , а затем «ОК» .
  6. Нажмите «Выполнить» . чтобы установить клиентское приложение и SDK на тестовое устройство.

Развертывание в командной строке

При развертывании с помощью командной строки выполните действия, указанные в следующем списке. В этом разделе предполагается, что имя вашего модуля приложения SDK — sdk-app , а имя вашего модуля клиентского приложения — client-app .

  1. В терминале командной строки создайте APK-файлы Privacy Sandbox SDK:

    ./gradlew :client-app:buildPrivacySandboxSdkApksForDebug
    

    Это выводит местоположение сгенерированных APK. Эти APK-файлы подписаны вашим локальным ключом отладки. Этот путь понадобится вам в следующей команде.

  2. Установите APK на свое устройство:

    adb install -t /path/to/your/standalone.apk
    
  3. В Android Studio нажмите «Выполнить» > «Изменить конфигурации» . Появится окно конфигурации запуска/отладки .

  4. В разделе «Параметры установки» установите «Развернуть в APK по умолчанию» .

  5. Нажмите «Применить» , а затем «ОК» .

  6. Нажмите «Выполнить» , чтобы установить пакет APK на тестовое устройство.

Отладка ваших приложений

Чтобы отладить клиентское приложение, нажмите кнопку «Отладка» . кнопка в Android Studio.

Чтобы отладить приложение SDK, выберите «Выполнить» > «Подключиться к процессу» , после чего появится всплывающий экран (показанный ниже). Установите флажок «Показать все процессы» . В появившемся списке найдите процесс с именем CLIENT_APP_PROCESS _sdk_sandbox . Выберите этот параметр и добавьте точки останова в код приложения SDK, чтобы начать отладку вашего SDK.

Процесс приложения SDK отображается в виде списка в нижней части диалогового окна.
Экран «Выбор процесса» , на котором можно выбрать приложение SDK для отладки.

Запускайте и останавливайте среду выполнения SDK из командной строки.

Чтобы запустить процесс выполнения SDK для вашего приложения, используйте следующую команду оболочки:

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

Аналогичным образом, чтобы остановить процесс выполнения SDK, выполните следующую команду:

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

Ограничения

Список разрабатываемых возможностей для среды выполнения SDK см. в примечаниях к выпуску .

Примеры кода

Репозиторий API среды выполнения SDK и сохранения конфиденциальности на GitHub содержит набор отдельных проектов Android Studio, которые помогут вам начать работу, включая примеры, демонстрирующие, как инициализировать и вызывать среду выполнения SDK.

Сообщайте об ошибках и проблемах

Ваш отзыв – важная часть Privacy Sandbox на Android! Сообщайте нам о любых обнаруженных проблемах или идеях по улучшению Privacy Sandbox на Android.

{% дословно %} {% дословно %} {% дословно %} {% дословно %}