คู่มือนักพัฒนาซอฟต์แวร์รันไทม์ SDK

ขณะที่คุณอ่าน Privacy Sandbox ใน Android ให้ใช้ปุ่มแสดงตัวอย่างสำหรับนักพัฒนาซอฟต์แวร์ หรือปุ่มเบต้าเพื่อเลือก เวอร์ชันของโปรแกรมที่คุณใช้งานอยู่ เนื่องจากวิธีการอาจแตกต่างกันไป


แสดงความคิดเห็น

รันไทม์ของ SDK ทำให้ SDK สามารถทำงานในแซนด์บ็อกซ์เฉพาะที่แยกต่างหากจาก แอปการโทร รันไทม์ของ SDK ให้การป้องกันและการรับประกันที่ดียิ่งขึ้น เกี่ยวกับการรวบรวมข้อมูลผู้ใช้ ซึ่งทำได้โดยผ่านการดำเนินการที่แก้ไขแล้ว สภาพแวดล้อมที่จำกัดสิทธิ์การเข้าถึงข้อมูลและชุดสิทธิ์ที่อนุญาต ดูข้อมูลเพิ่มเติมเกี่ยวกับรันไทม์ของ SDK ในข้อเสนอการออกแบบ

ขั้นตอนในหน้านี้จะแนะนำคุณตลอดขั้นตอนการสร้าง SDK ที่เปิดใช้รันไทม์ซึ่งกำหนดมุมมองบนเว็บที่แสดงผลจากระยะไกลได้ ลงในแอปการโทร

ข้อจำกัดที่ทราบ

ดูรายการความสามารถที่กำลังดำเนินการอยู่สำหรับรันไทม์ของ SDK ได้ที่รุ่น หมายเหตุ

ข้อจำกัดต่อไปนี้คาดว่าจะได้รับการแก้ไขใน Android เวอร์ชันหลักเวอร์ชันถัดไป การเปิดตัวแพลตฟอร์ม

  • การแสดงโฆษณาภายในมุมมองที่เลื่อนได้ ตัวอย่างเช่น RecyclerView ไม่ ทำงานได้อย่างถูกต้อง
    • คุณอาจพบปัญหาการกระตุกเมื่อปรับขนาด
    • เหตุการณ์การเลื่อนการแตะของผู้ใช้ไม่ส่งผ่านไปยังรันไทม์อย่างถูกต้อง
  • API พื้นที่เก็บข้อมูล

ปัญหาต่อไปนี้จะได้รับการแก้ไขในปี 2023

  • API getAdId และ getAppSetId ยังทำงานผิดปกติเนื่องจากรองรับ ที่ยังไม่ได้เปิดใช้งาน

ก่อนเริ่มต้น

ก่อนที่จะเริ่มต้น ให้ทำตามขั้นตอนต่อไปนี้

  1. ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์สำหรับ Privacy Sandbox ใน Android เครื่องมือเพื่อสนับสนุนรันไทม์ของ SDK อยู่ในระหว่างการพัฒนาอย่างต่อเนื่อง ด้วยเหตุนี้ คุณจะต้องใช้Android เวอร์ชัน Canary รุ่นล่าสุด Studio คุณสามารถเรียกใช้ Android Studio เวอร์ชันนี้พร้อมกันได้ เวอร์ชันที่คุณใช้ ดังนั้นโปรดแจ้งให้เราทราบ หากข้อกำหนดนี้ไม่มีผลกับ ที่ทำงานให้คุณ

  2. ติดตั้งอิมเมจระบบในอุปกรณ์ที่รองรับหรือตั้งค่า โปรแกรมจำลองที่มีการรองรับ Privacy Sandbox ใน Android

ตั้งค่าโปรเจ็กต์ใน Android Studio

หากต้องการลองใช้รันไทม์ของ SDK ให้ใช้โมเดลที่คล้ายกับ แบบไคลเอ็นต์-เซิร์ฟเวอร์ ความแตกต่างที่สำคัญคือแอป ( ไคลเอ็นต์) และ SDK ("เซิร์ฟเวอร์") ทำงานในอุปกรณ์เดียวกัน

  1. เพิ่มโมดูลแอปลงในโปรเจ็กต์ โมดูลนี้ทำหน้าที่เป็นไคลเอ็นต์ที่ ทำหน้าที่ขับเคลื่อน SDK
  2. ในโมดูลแอป ให้เปิดใช้รันไทม์ของ SDK ประกาศสิทธิ์ที่จำเป็น และ กำหนดค่าบริการโฆษณาเฉพาะ API
  3. เพิ่มโมดูลไลบรารี 1 รายการในโปรเจ็กต์ โมดูลนี้มีโค้ด SDK ของคุณ
  4. ในโมดูล SDK ให้ประกาศสิทธิ์ที่จำเป็น คุณไม่จำเป็นต้อง กำหนดค่าบริการโฆษณาเฉพาะ API ในโมดูลนี้
  5. นำ dependencies ในไฟล์ build.gradle ของโมดูลคลังที่ SDK ของคุณไม่ใช้ ในกรณีส่วนใหญ่ คุณจะนำทรัพยากร Dependency ออกทั้งหมดได้ คุณ โดยการสร้างไดเรกทอรีใหม่ที่มีชื่อที่สอดคล้องกับ SDK ของคุณ
  6. สร้างโมดูลใหม่ด้วยตนเองโดยใช้ com.android.privacy-sandbox-sdk ประเภท ซึ่งจะมาพร้อมกับโค้ด SDK สำหรับสร้าง APK ที่สามารถ กับอุปกรณ์ของคุณ คุณสามารถทำได้โดยการสร้างไดเรกทอรีใหม่ที่มี สอดคล้องกับ SDK ของคุณ เพิ่มไฟล์ build.gradle ที่ว่างเปล่า เนื้อหา ของไฟล์นี้จะปรากฏในส่วนหลังของคู่มือนี้

  7. เพิ่มข้อมูลโค้ดต่อไปนี้ลงในไฟล์ gradle.properties

    android.experimental.privacysandboxsdk.enable=true
    
  8. ดาวน์โหลดอิมเมจโปรแกรมจำลอง TiramisuPrivacySandbox และสร้าง โปรแกรมจำลองที่มีรูปภาพนี้ รวมถึง Play Store

ขึ้นอยู่กับว่าคุณเป็นนักพัฒนา SDK หรือนักพัฒนาแอป คุณอาจมี การตั้งค่าขั้นสุดท้ายแตกต่างจากการตั้งค่าที่อธิบายในย่อหน้าก่อนหน้านี้

ติดตั้ง SDK ในอุปกรณ์ทดสอบ ในทำนองเดียวกับวิธีติดตั้งแอปโดยใช้ Android Studio หรือ Android Debug Bridge (ADB) เราได้สร้างแอปตัวอย่างใน Kotlin และ Java เพื่อช่วยคุณเริ่มต้นใช้งาน ในภาษาโปรแกรม ซึ่งสามารถพบได้ใน ที่เก็บของ GitHub ไฟล์ README และไฟล์ Manifest ความคิดเห็นที่อธิบายสิ่งที่ต้องเปลี่ยนแปลงเพื่อเรียกใช้ตัวอย่างในเวอร์ชันเสถียร ของ Android Studio

เตรียม SDK ของคุณ

  1. สร้างไดเรกทอรีระดับโมดูลด้วยตนเอง โดยนี่จะทำหน้าที่เป็น Wrapper ของ รหัสการติดตั้งใช้งานเพื่อสร้าง SDK APK ในไดเรกทอรีใหม่ ให้เพิ่ม build.gradle และเติมข้อมูลด้วยข้อมูลโค้ดต่อไปนี้ ใช้แท็กที่ไม่ซ้ำกัน ของ SDK ที่เปิดใช้รันไทม์ (RE-SDK) และระบุเวอร์ชัน รวม โมดูลคลังของคุณในส่วน dependencies

    plugins {
        id 'com.android.privacy-sandbox-sdk'
    }
    
    android {
        compileSdkPreview 'TiramisuPrivacySandbox'
        minSdkPreview 'TiramisuPrivacySandbox'
        namespace = "com.example.example-sdk"
    
        bundle {
            packageName = "com.example.privacysandbox.provider"
            sdkProviderClassName = "com.example.sdk_implementation.SdkProviderImpl"
            setVersion(1, 0, 0)
        }
    }
    
    dependencies {
        include project(':<your-library-here>')
    }
    
  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 และแสดงผลมุมมองที่จะแสดงผลจากระยะไกล ตามความกว้างและความสูงที่ระบุเป็นพิกเซล

ข้อมูลโค้ดต่อไปนี้แสดงวิธีลบล้างเมธอดเหล่านี้

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

SDK แซนด์บ็อกซ์ตัวควบคุม

SdkSandboxController เป็น Wrapper ของบริการระบบที่อิงตามบริบทที่ใช้ได้ SDK SDK สามารถดึงข้อมูลนี้ได้โดยใช้บริบทที่ได้รับจาก SandboxedSdkProvider#getContext() และการเรียกใช้ context.getSystemService(SdkSandboxController.class) ในบริบทนี้ ตัวควบคุมมี API ที่ช่วยให้ SDK โต้ตอบและรับข้อมูลจาก Privacy Sandbox

API ส่วนใหญ่ในตัวควบคุมจะมีข้อยกเว้น หาก SandboxedSdkContext ไม่ใช่ บริบทที่ใช้ในการเข้าถึง เราวางแผนที่จะทำให้ Wrapper บริการไม่พร้อมใช้งานสำหรับ ในบริบทอื่นๆ SdkSandboxController มีไว้เพื่อการใช้งานโดยผู้ให้บริการ SDK และไม่แนะนำให้ใช้สำหรับนักพัฒนาแอป

การสื่อสารระหว่าง SDK กับ SDK

SDK ในรันไทม์ควรที่จะสื่อสารกันได้เพื่อรองรับ สื่อกลางและกรณีการใช้งานที่เกี่ยวข้อง ชุดเครื่องมือที่อธิบายในที่นี้มี เพื่อทำงานกับ SDK ซึ่งพร้อมใช้งานสำหรับ SDK อื่นๆ ภายใน แซนด์บ็อกซ์ การใช้งานรันไทม์ของ SDK นี้เป็นขั้นตอนแรกในการเปิดใช้ SDK เพื่อ การสื่อสารเกี่ยวกับ SDK และอาจยังไม่ครอบคลุมกรณีการใช้งานทั้งหมดสำหรับสื่อกลางใน Privacy Sandbox

getSandboxedSdks() API ใน SdkSandboxController จะมี คลาส SandboxedSdk สำหรับ SDK ที่โหลดทั้งหมดใน Privacy Sandbox ออบเจ็กต์ SandboxedSdk มีรายละเอียดเกี่ยวกับ SDK และsdkInterfaceสำหรับ ในการสื่อสารด้วย

SDK ใน Privacy Sandbox ควรใช้ข้อมูลโค้ดที่คล้ายกับ เพื่อติดต่อกับ SDK อื่นๆ สมมติว่าโค้ดนี้เขียนขึ้นเพื่อเปิดใช้ "SDK1" ถึง สื่อสารกับ "SDK2" ซึ่งทั้ง 2 อย่างนี้โหลดโดยแอปในความเป็นส่วนตัว แซนด์บ็อกซ์

SdkSandboxController controller = mSdkContext
    .getSystemService(SdkSandboxController.class);
List<SandboxedSdk> sandboxedSdks = controller.getSandboxedSdks();
SandboxedSdk sdk2 = sandboxedSdks.stream().filter( // The SDK it wants to
    // connect to, based on SDK name or SharedLibraryInfo.
try {
    IBinder binder = sdk2.getInterface();
    ISdkApi sdkApi = ISdkApi.Stub.asInterface(binder);
    // Call API on SDK2
    message = sdkApi.getMessage();
    } catch (RemoteException e) {
        throw new RuntimeException(e);
}

ในตัวอย่างข้างต้น SDK1 เพิ่มไลบรารี AIDL ของ SDK2 เป็นทรัพยากร Dependency SDK ของไคลเอ็นต์นี้มีโค้ด Binder ที่ AIDL สร้างขึ้น SDK ทั้ง 2 แบบควร ส่งออกไลบรารี AIDL นี้ ซึ่งจะเหมือนกับสิ่งที่แอปคาดว่าจะทําเมื่อ จะสื่อสารกับ SDK ใน Privacy Sandbox

ระบบจะเพิ่มการรองรับวิธีแชร์อินเทอร์เฟซระหว่าง SDK ที่สร้างขึ้นโดยอัตโนมัติโดยอัตโนมัติ ในอนาคต

SDK ในรันไทม์อาจต้องสื่อสารกับทรัพยากร Dependency ของแอปและ SDK โฆษณา ที่ยังไม่เปิดใช้รันไทม์

registerAppOwnedSdkSandboxInterface() API ใน SdkSandboxManager มี วิธีที่ SDK ที่ไม่ได้เปิดใช้รันไทม์ให้ลงทะเบียนอินเทอร์เฟซกับ แพลตฟอร์ม getAppOwnedSdkSandboxInterfaces() API ใน SdkSandboxController จะให้ AppOwnedSdkSandboxInterface สำหรับทั้งหมด SDK ที่ลงทะเบียนแบบคงที่และคงที่

ตัวอย่างต่อไปนี้จะแสดงวิธีลงทะเบียนอินเทอร์เฟซเพื่อให้สามารถสร้าง พร้อมใช้งานสำหรับการสื่อสารเกี่ยวกับ SDK ที่เปิดใช้รันไทม์

// Register AppOwnedSdkSandboxInterface
mSdkSandboxManager.registerAppOwnedSdkSandboxInterface(
    new AppOwnedSdkSandboxInterface(
        APP_OWNED_SDK_NAME, (long) APP_OWNED_SDK_VERSION, new AppOwnedSdkApi())
    );

ตัวอย่างนี้แสดงถึงวิธีเครื่องมือการสื่อสารกับ SDK ที่เปิดใช้รันไทม์:

// Get AppOwnedSdkSandboxInterface
List<AppOwnedSdkSandboxInterface> appOwnedSdks = mSdkContext
        .getSystemService(SdkSandboxController.class)
        .getAppOwnedSdkSandboxInterfaces();
    AppOwnedSdkSandboxInterface appOwnedSdk = appOwnedSdks.stream()
        .filter(s -> s.getName().contains(APP_OWNED_SDK_NAME))
        .findAny()
        .get();
    IAppOwnedSdkApi appOwnedSdkApi =
        IAppOwnedSdkApi.Stub.asInterface(appOwnedSdk.getInterface());
    message = appOwnedSdkApi.getMessage();

เนื่องจาก SDK โฆษณาที่ไม่ได้เปิดใช้รันไทม์อาจลงทะเบียนไม่ได้ เราเสนอการสร้าง SDK สื่อกลางที่จัดการการลงทะเบียน และรวม SDK ของพาร์ทเนอร์หรือแอปเป็นทรัพยากร Dependency โดยตรง SDK ของสื่อกลางนี้ สร้างการสื่อสารระหว่าง SDK กับทรัพยากร Dependency ที่ไม่ เปิดใช้รันไทม์และสื่อกลางที่เปิดใช้รันไทม์ซึ่งทำหน้าที่เป็นอะแดปเตอร์

การสนับสนุนกิจกรรม

SDK ที่เปิดใช้รันไทม์จะเพิ่มแท็กกิจกรรมลงในไฟล์ Manifest ไม่ได้และทำไม่ได้ เริ่มกิจกรรมของตนเองโดยตรง ให้สิทธิ์เข้าถึงออบเจ็กต์ Activity โดยการลงทะเบียน SdkSandboxActivityHandler และเริ่มกิจกรรมแซนด์บ็อกซ์:

1. ลงทะเบียน SdkSandboxActivityHandler

ลงทะเบียนอินสแตนซ์ของ SdkSandboxActivityHandler โดยใช้ วันที่ SdkSandboxController#registerSdkSandboxActivityHandler(SandboxedActivityHandler)

API จะลงทะเบียนออบเจ็กต์ดังกล่าวและแสดงผลออบเจ็กต์ IBinder ซึ่งระบุ SdkSandboxActivityHandler ที่ผ่านไปแล้ว

public interface SdkSandboxActivityHandler {
    void onActivityCreated(Activity activity);
}

API จะลงทะเบียนออบเจ็กต์ดังกล่าวและแสดงผลออบเจ็กต์ IBinder ซึ่งระบุ SdkSandboxActivityHandler ที่ผ่านไปแล้ว

2. เริ่มกิจกรรมแซนด์บ็อกซ์

SDK จะส่งโทเค็นที่ส่งกลับเพื่อระบุ SdkSandboxActivityHandler ไปยังแอปไคลเอ็นต์ จากนั้นแอปไคลเอ็นต์จะโทร SdkSandboxManager#startSdkSandboxActivity(Activity, Binder) ผ่าน กิจกรรมที่จะเริ่มใช้แซนด์บ็อกซ์ และโทเค็นที่ระบุข้อมูลการลงทะเบียน SdkSandboxActivityHandler

ขั้นตอนนี้จะเริ่มกิจกรรมแพลตฟอร์มใหม่ที่ทํางานในรันไทม์ของ SDK เดียวกันกับ SDK ที่ขอ

เมื่อกิจกรรมเริ่มต้น SDK จะได้รับแจ้งผ่านการเรียกไปยัง SdkSandboxActivityHandler#onActivityCreated(Activity) ในฐานะส่วนหนึ่งของ การเรียกใช้ Activity#OnCreate(Bundle)

ตัวอย่างเช่น เมื่อมีสิทธิ์เข้าถึงออบเจ็กต์ Activity และผู้โทรสามารถตั้งค่า contentViewการดูโดยโทรหา Activity#setContentView(View)

หากต้องการลงทะเบียน Callback ของวงจร ให้ใช้ Activity#registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks)

หากต้องการลงทะเบียน OnBackInvokedCallback กับกิจกรรมที่ผ่านแล้ว ให้ใช้ Activity#getOnBackInvokedDispatcher().registerOnBackInvokedCallback(Int, OnBackInvokedCallback)

ทดสอบโปรแกรมเล่นวิดีโอในรันไทม์ของ SDK

นอกเหนือจากการสนับสนุนโฆษณาแบนเนอร์แล้ว Privacy Sandbox ยังมุ่งมั่นที่จะ รองรับโปรแกรมเล่นวิดีโอที่ทำงานภายในรันไทม์ของ SDK

ขั้นตอนการทดสอบโปรแกรมเล่นวิดีโอจะคล้ายกับการทดสอบโฆษณาแบนเนอร์ เปลี่ยน getView() ของจุดแรกเข้าของ SDK เพื่อรวมโปรแกรมเล่นวิดีโอไว้ใน แสดงผลออบเจ็กต์ View รายการ ทดสอบขั้นตอนทั้งหมดของวิดีโอเพลเยอร์ที่คุณคาดว่าจะทำ ที่ Privacy Sandbox รองรับ โปรดทราบว่าการสื่อสารระหว่าง SDK กับ แอปไคลเอ็นต์เกี่ยวกับวงจรของวิดีโอ จึงอยู่นอกเหนือขอบเขตการทำงาน ยังไม่จำเป็นต้องป้อนคำติชมสำหรับฟังก์ชันนี้

การทดสอบและความคิดเห็นของคุณจะช่วยให้มั่นใจได้ว่ารันไทม์ของ SDK สนับสนุน โปรแกรมเล่นวิดีโอที่คุณต้องการได้ด้วย

ข้อมูลโค้ดต่อไปนี้แสดงวิธีการแสดงผลวิดีโอแบบง่าย โหลดจาก 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;
        }
    }

การใช้ API พื้นที่เก็บข้อมูลใน SDK ของคุณ

SDK ในรันไทม์ของ SDK จะเข้าถึง อ่าน หรือเขียนในแอปไม่ได้อีกต่อไป ที่จัดเก็บข้อมูลภายในและในทางกลับกันด้วย รันไทม์ของ SDK จะได้รับการจัดสรรพื้นที่เก็บข้อมูลภายในของตนเอง ซึ่งก็คือ แยกต่างหากจากแอป

SDK จะสามารถเข้าถึงที่จัดเก็บข้อมูลภายในที่แยกต่างหากนี้โดยใช้ไฟล์ Storage API ในออบเจ็กต์ Context ที่แสดงผลโดย SandboxedSdkProvider#getContext() SDK สามารถใช้ได้เฉพาะที่จัดเก็บข้อมูลภายในเท่านั้น จึงมีเพียง API ที่จัดเก็บข้อมูลภายใน เช่น Context.getFilesDir() หรือ Context.getCacheDir() จะใช้งานได้ ดูตัวอย่างเพิ่มเติมใน เข้าถึงจากที่จัดเก็บข้อมูลภายใน

ไม่รองรับการเข้าถึงที่จัดเก็บข้อมูลภายนอกจากรันไทม์ของ SDK กำลังเรียก API ไปยัง การเข้าถึงที่จัดเก็บข้อมูลภายนอกจะส่งกลับข้อยกเว้นหรือแสดงผล null หลายรายการ ตัวอย่าง:

ใน Android 13 SDK ทั้งหมดในรันไทม์ของ SDK จะแชร์ที่จัดเก็บข้อมูลภายใน ที่จัดสรรสำหรับรันไทม์ของ SDK แล้ว พื้นที่เก็บข้อมูลจะยังคงอยู่จนกว่าแอปไคลเอ็นต์จะ ถอนการติดตั้งแล้ว หรือเมื่อล้างข้อมูลแอปไคลเอ็นต์แล้ว

คุณต้องใช้ Context ที่ SandboxedSdkProvider.getContext() ส่งคืนสำหรับ พื้นที่เก็บข้อมูล การใช้ API พื้นที่เก็บไฟล์กับอินสแตนซ์ออบเจ็กต์ Context อื่นๆ เช่น เราไม่รับประกันว่าบริบทของแอปพลิเคชันนั้นจะทำงานตามที่คาดไว้ในทุกสถานการณ์ หรือในอนาคต

ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้พื้นที่เก็บข้อมูลในรันไทม์ของ 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);
        }
    }

}

    

พื้นที่เก็บข้อมูลต่อ 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

กำลังอ่านSharedPreferencesของลูกค้า

แอปไคลเอ็นต์เลือกที่จะแชร์ชุดคีย์จาก SharedPreferences กับ SdkSandbox SDK สามารถอ่านข้อมูลที่ซิงค์จากแอปไคลเอ็นต์โดยใช้ SdkSanboxController#getClientSharedPreferences() API SharedPreferences ซึ่ง API นี้แสดงผลไว้สำหรับการอ่านอย่างเดียว คุณไม่ควรเขียนข้อความนี้

เข้าถึงรหัสโฆษณาที่จัดหาโดยบริการ Google Play

หาก SDK ของคุณต้องการเข้าถึงรหัสโฆษณาที่บริการ Google Play ให้ไว้ ให้ทำดังนี้

  • ประกาศสิทธิ์ android.permission.ACCESS_ADSERVICES_AD_ID ในไฟล์ Manifest ของ SDK
  • ใช้ AdIdManager#getAdId() เพื่อดึงค่าแบบไม่พร้อมกัน

เข้าถึงรหัสชุดแอปที่ได้รับจากบริการ Google Play

หาก SDK ของคุณต้องการเข้าถึงรหัสชุดแอปจากบริการ Google Play ให้ทำดังนี้

  • ใช้ AppSetIdManager#getAppSetId() เพื่อดึงค่าแบบไม่พร้อมกัน

อัปเดตแอปไคลเอ็นต์

หากต้องการเรียกใช้ SDK ที่ทำงานอยู่ในรันไทม์ของ SDK ให้ทำดังนี้ การเปลี่ยนแปลงของแอปไคลเอ็นต์การโทร

  1. เพิ่มสิทธิ์ INTERNET และ ACCESS_NETWORK_STATE ไปยัง ไฟล์ Manifest ของแอป

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    
  2. ในกิจกรรมของแอปที่มีโฆษณา ให้ประกาศการอ้างอิง SdkSandboxManager เป็นบูลีนเพื่อดูว่า SDK โหลดแล้วหรือไม่ และ ออบเจ็กต์ SurfaceView สำหรับการแสดงผลระยะไกล

    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. ตรวจสอบว่ากระบวนการรันไทม์ของ 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. กำหนดคลาส Callback โดยการใช้ OutcomeReceiver เพื่อโต้ตอบ กับ SDK ในรันไทม์หลังจากโหลดเสร็จแล้ว ในรายการต่อไปนี้ ตัวอย่างเช่น ไคลเอ็นต์ใช้ Callback เพื่อรอจนกว่า SDK จะโหลดแล้ว สำเร็จ แล้วพยายามแสดงผลมุมมองเว็บจาก SDK Callback จะกำหนดภายหลังในขั้นตอนนี้

    Kotlin

        private inner class LoadSdkOutcomeReceiverImpl private constructor() :
                OutcomeReceiver<SandboxedSdk?, LoadSdkException?> {
    
          override fun onResult(sandboxedSdk: SandboxedSdk) {
              mSdkLoaded = true
    
              val binder: IBinder = sandboxedSdk.getInterface()
              if (!binderInterface.isPresent()) {
                  // SDK is not loaded anymore.
                  return
              }
              val sdkInterface: ISdkInterface = ISdkInterface.Stub.asInterface(binder)
              sdkInterface.doSomething()
    
              Handler(Looper.getMainLooper()).post {
                  val bundle = Bundle()
                  bundle.putInt(SdkSandboxManager.EXTRA_WIDTH_IN_PIXELS, mClientView.getWidth())
                  bundle.putInt(SdkSandboxManager.EXTRA_HEIGHT_IN_PIXELS, mClientView.getHeight())
                  bundle.putInt(SdkSandboxManager.EXTRA_DISPLAY_ID, display!!.displayId)
                  bundle.putInt(SdkSandboxManager.EXTRA_HOST_TOKEN, mClientView.getHostToken())
                  mSdkSandboxManager!!.requestSurfacePackage(
                          SDK_NAME, bundle, { obj: Runnable -> obj.run() },
                          RequestSurfacePackageOutcomeReceiverImpl())
              }
          }
    
          override fun onError(error: LoadSdkException) {
                  // Log or show error.
          }
        }
    

    Java

        import static android.app.sdksandbox.SdkSandboxManager.EXTRA_DISPLAY_ID;
        import static android.app.sdksandbox.SdkSandboxManager.EXTRA_HEIGHT_IN_PIXELS;
        import static android.app.sdksandbox.SdkSandboxManager.EXTRA_HOST_TOKEN;
        import static android.app.sdksandbox.SdkSandboxManager.EXTRA_WIDTH_IN_PIXELS;
    
        private class LoadSdkOutcomeReceiverImpl
                implements OutcomeReceiver<LoadSdkResponse, LoadSdkException> {
            private LoadSdkOutcomeReceiverImpl() {}
    
            @Override
            public void onResult(@NonNull SandboxedSdk sandboxedSdk) {
                mSdkLoaded = true;
    
                IBinder binder = sandboxedSdk.getInterface();
                if (!binderInterface.isPresent()) {
                    // SDK is not loaded anymore.
                    return;
                }
                ISdkInterface sdkInterface = ISdkInterface.Stub.asInterface(binder);
                sdkInterface.doSomething();
    
                new Handler(Looper.getMainLooper()).post(() -> {
                    Bundle bundle = new Bundle();
                    bundle.putInt(EXTRA_WIDTH_IN_PIXELS, mClientView.getWidth());
                    bundle.putInt(EXTRA_HEIGHT_IN_PIXELS, mClientView.getHeight());
                    bundle.putInt(EXTRA_DISPLAY_ID, getDisplay().getDisplayId());
                    bundle.putInt(EXTRA_HOST_TOKEN, mClientView.getHostToken());
    
                    mSdkSandboxManager.requestSurfacePackage(
                            SDK_NAME, bundle, Runnable::run,
                            new RequestSurfacePackageOutcomeReceiverImpl());
                });
            }
    
            @Override
            public void onError(@NonNull LoadSdkException error) {
                // Log or show error.
            }
        }
    

    วิธีกลับไปมุมมองระยะไกลจาก SDK ในรันไทม์ขณะโทร requestSurfacePackage() ใช้อินเทอร์เฟซ OutcomeReceiver<Bundle, RequestSurfacePackageException>:

    Kotlin

        private inner class RequestSurfacePackageOutcomeReceiverImpl :
                OutcomeReceiver<Bundle, RequestSurfacePackageException> {
            fun onResult(@NonNull result: Bundle) {
                Handler(Looper.getMainLooper())
                        .post {
                            val surfacePackage: SurfacePackage = result.getParcelable(
                                    EXTRA_SURFACE_PACKAGE,
                                    SurfacePackage::class.java)
                            mRenderedView.setChildSurfacePackage(surfacePackage)
                            mRenderedView.setVisibility(View.VISIBLE)
                        }
            }
    
            fun onError(@NonNull error: RequestSurfacePackageException?) {
                // Error handling
            }
        }
    

    Java

        import static android.app.sdksandbox.SdkSandboxManager.EXTRA_SURFACE_PACKAGE;
    
        private class RequestSurfacePackageOutcomeReceiverImpl
                implements OutcomeReceiver<Bundle, RequestSurfacePackageException> {
            @Override
            public void onResult(@NonNull Bundle result) {
                new Handler(Looper.getMainLooper())
                        .post(
                                () -> {
                                    SurfacePackage surfacePackage =
                                            result.getParcelable(
                                                    EXTRA_SURFACE_PACKAGE,
                                                    SurfacePackage.class);
                                    mRenderedView.setChildSurfacePackage(surfacePackage);
                                    mRenderedView.setVisibility(View.VISIBLE);
                                });
            }
            @Override
            public void onError(@NonNull RequestSurfacePackageException error) {
                // Error handling
            }
        }
    

    เมื่อแสดงมุมมองเสร็จแล้ว อย่าลืมปล่อย SurfacePackage โดยโทรหา:

    surfacePackage.notifyDetachedFromWindow()
    
  5. ใน onCreate() ให้เริ่มต้น SdkSandboxManager ซึ่งเป็น Callback ที่จำเป็น แล้วส่งคำขอเพื่อโหลด 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. แอปเลือกที่จะแชร์บางคีย์ของ SharedPreferences เริ่มต้นได้ ด้วยแซนด์บ็อกซ์ สามารถทำได้โดยการโทร SdkSandboxManager#addSyncedSharedPreferencesKeys(Set<String>keys) วิธี ในอินสแตนซ์ใดก็ได้ของเครื่องมือจัดการ SdkSandbox เมื่อแอปแจ้ง SdkSandboxManager คีย์ที่จะซิงค์ SdkSandboxManager จะซิงค์ข้อมูล ค่าของคีย์เหล่านั้นลงในแซนด์บ็อกซ์และ SDK จากนั้นจะอ่านค่าได้โดยใช้ SdkSandboxController#getClientSharedPreferences โปรดดู การอ่านค่ากำหนดที่แชร์ของไคลเอ็นต์เพิ่มเติม

    ชุดคีย์ที่ซิงค์ไม่อยู่ในการรีสตาร์ทแอปและข้อมูล ที่ซิงค์กับแซนด์บ็อกซ์จะถูกลบเมื่อรีสตาร์ทแซนด์บ็อกซ์ ดังนั้น สิ่งสำคัญก็คือ แอปจะเริ่มการซิงค์โดยโทรหา addSyncedSharedPreferencesKeys ทุก เวลาที่แอปเริ่มทำงาน

    คุณสามารถแก้ไขชุดคีย์ที่จะซิงค์ด้วยการเรียกใช้ได้ SdkSandboxManager#removeSyncedSharedPreferencesKeys(Set<String>keys) ถึง นำคีย์ออก หากต้องการดูชุดคีย์ปัจจุบันที่ซิงค์ ให้ใช้ SdkSandboxManager#getSyncedSharedPreferencesKeys()

    เราขอแนะนำให้คุณใช้ชุดคีย์ให้เล็กที่สุดและใช้คีย์นี้ต่อเมื่อ ตามความจำเป็น หากต้องการส่งข้อมูลไปยัง SDK เพื่อวัตถุประสงค์ทั่วไป โปรดสื่อสารกับ SDK โดยตรงโดยใช้อินเทอร์เฟซ SandboxedSdk ต สถานการณ์ที่เป็นไปได้ในการใช้ API เหล่านี้คือ เมื่อแอปใช้ SDK สำหรับแพลตฟอร์มการจัดการความยินยอม (CMP) แล้ว SDK ภายในแซนด์บ็อกซ์จะเป็น สนใจอ่านข้อมูลที่ CMP SDK จัดเก็บโดยค่าเริ่มต้น SharedPreferences

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        
        // At some point, initiate the set of keys for synchronization with sandbox
        mSdkSandboxManager.addSyncedSharedPreferencesKeys(Set.of("foo", "bar"));
    }
    

    Java

    @Override
        protected void onCreate(Bundle savedInstanceState) {
        
        // At some point, initiate the set of keys for synchronization with sandbox
        mSdkSandboxManager.addSyncedSharedPreferencesKeys(Set.of("foo", "bar"));
    }
    
  7. วิธีจัดการกรณีที่กระบวนการแซนด์บ็อกซ์ SDK หยุดโดยไม่คาดคิด กำหนดการใช้งานสำหรับอินเทอร์เฟซ 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);
              }
          }
    

    วิธีลงทะเบียน Callback นี้เพื่อรับข้อมูลว่าแซนด์บ็อกซ์ SDK เมื่อใด ยุติการใช้งานแล้ว คุณสามารถเพิ่มบรรทัดต่อไปนี้ได้ทุกเมื่อ

    Kotlin

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

    Java

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

    เนื่องจากสถานะของแซนด์บ็อกซ์จะสูญหายไปเมื่อกระบวนการสิ้นสุดลง การดู ที่แสดงผลจากระยะไกลโดย SDK อาจทำงานไม่ถูกต้องอีกต่อไป หากต้องการโต้ตอบกับ SDK ต่อไป ต้องโหลดมุมมองเหล่านี้อีกครั้งเพื่อให้ จะเป็นการเริ่มกระบวนการแซนด์บ็อกซ์ใหม่

  8. เพิ่มทรัพยากร Dependency ของโมดูล SDK ในแอปไคลเอ็นต์ build.gradle:

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

ทดสอบแอป

หากต้องการเรียกใช้แอปไคลเอ็นต์ ให้ติดตั้งแอป SDK และแอปไคลเอ็นต์ลงในอุปกรณ์ทดสอบ โดยใช้ Android Studio หรือบรรทัดคำสั่ง

ติดตั้งใช้งานผ่าน Android Studio

เมื่อติดตั้งใช้งานผ่าน Android Studio ให้ทำตามขั้นตอนต่อไปนี้

  1. เปิดโปรเจ็กต์ Android Studio สำหรับแอปไคลเอ็นต์
  2. ไปที่เรียกใช้ > แก้ไขการกำหนดค่า หน้าต่างการกำหนดค่าเรียกใช้/แก้ไขข้อบกพร่อง จะปรากฏขึ้น
  3. ในส่วนตัวเลือกการเปิดตัว ให้ตั้งค่าการเปิดตัวเป็นกิจกรรมที่ระบุ
  4. คลิกเมนู 3 จุดข้างกิจกรรม แล้วเลือกกิจกรรมหลัก สำหรับลูกค้าของคุณ
  5. คลิกใช้ แล้วคลิกตกลง
  6. คลิกเรียกใช้ เพื่อติดตั้งแอปไคลเอ็นต์และ SDK ในอุปกรณ์ทดสอบ

ทำให้ใช้งานได้ในบรรทัดคำสั่ง

เมื่อทำให้ใช้งานได้โดยใช้บรรทัดคำสั่ง ให้ทำตามขั้นตอนในรายการต่อไปนี้ ส่วนนี้จะถือว่าชื่อของโมดูลแอป SDK ของคุณคือ sdk-app และ ชื่อของโมดูลแอปไคลเอ็นต์คือ client-app

  1. จากเทอร์มินัลบรรทัดคำสั่ง ให้สร้าง APK SDK ของ Privacy Sandbox โดยทำดังนี้

    ./gradlew :client-app:buildPrivacySandboxSdkApksForDebug
    

    การดำเนินการนี้จะแสดงผลตำแหน่งสำหรับ APK ที่สร้างขึ้น APK เหล่านี้รับรองด้วย คีย์การแก้ไขข้อบกพร่องในเครื่อง และต้องใช้เส้นทางนี้ในคำสั่งถัดไป

  2. ติดตั้ง APK ในอุปกรณ์

    adb install -t /path/to/your/standalone.apk
    
  3. ใน Android Studio คลิกเรียกใช้ > แก้ไขการกำหนดค่า ฟังก์ชันเรียกใช้/แก้ไขข้อบกพร่อง หน้าต่างการกำหนดค่าจะปรากฏขึ้น

  4. ในส่วนตัวเลือกการติดตั้ง ให้ตั้งค่าทำให้ใช้งานได้เป็น APK เริ่มต้น

  5. คลิกใช้ แล้วคลิกตกลง

  6. คลิก Run เพื่อติดตั้ง Bundle APK ในอุปกรณ์ทดสอบ

แก้ไขข้อบกพร่องของแอป

หากต้องการแก้ไขข้อบกพร่องของแอปไคลเอ็นต์ ให้คลิกแก้ไขข้อบกพร่อง ใน Android Studio

หากต้องการแก้ไขข้อบกพร่องของแอป SDK ให้ไปที่เรียกใช้ > Attach to Process ซึ่งแสดงป๊อปอัป หน้าจอ (แสดงด้านล่าง) เลือกช่องแสดงกระบวนการทั้งหมด ในรายการที่ ปรากฏขึ้น ให้มองหากระบวนการที่ชื่อ CLIENT_APP_PROCESS_sdk_sandbox เลือกตัวเลือกนี้และเพิ่มเบรกพอยท์ในโค้ดของแอป SDK ไปยัง เริ่มแก้ไขข้อบกพร่อง SDK ของคุณ

วันที่ ขั้นตอนของแอป SDK จะปรากฏในมุมมองรายการบริเวณด้านล่าง
  ของกล่องโต้ตอบ
หน้าจอเลือกกระบวนการ ซึ่งคุณสามารถ เลือกแอป SDK ที่จะแก้ไขข้อบกพร่อง

เริ่มและหยุดรันไทม์ของ SDK จากบรรทัดคำสั่ง

ใช้คำสั่ง Shell ต่อไปนี้เพื่อเริ่มขั้นตอนรันไทม์ของ 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 ใดโหลดอยู่

คุณสามารถตรวจสอบว่า SDK ใดโหลดอยู่ในปัจจุบันโดยใช้ getSandboxedSdks ภายในฟังก์ชัน SdkSandboxManager

ข้อจำกัด

ดูรายการความสามารถที่กำลังดำเนินการอยู่สำหรับรันไทม์ของ SDK ได้ที่ บันทึกประจำรุ่น

ตัวอย่างโค้ด

ที่เก็บรันไทม์ของ SDK และที่เก็บ API ที่รักษาความเป็นส่วนตัว ใน GitHub มีชุดโปรเจ็กต์ Android Studio แต่ละโปรเจ็กต์ที่จะช่วยให้คุณได้รับ ที่เริ่มใช้งาน ซึ่งรวมถึงตัวอย่างที่สาธิตวิธีเริ่มต้นและเรียกใช้ SDK รันไทม์

รายงานข้อบกพร่องและปัญหา

ความคิดเห็นของคุณเป็นส่วนสำคัญของ Privacy Sandbox ใน Android โปรดแจ้งให้เราทราบ ของปัญหาที่คุณพบหรือแนวคิดในการปรับปรุง Privacy Sandbox ใน Android