בהמשך לקריאה על ארגז החול לפרטיות ב-Android תיעוד, השתמשו בלחצן תצוגה מקדימה למפתחים או בטא כדי לבחור בגרסת התוכנה שאיתה אתם עובדים, כי ההוראות עשויות להשתנות.
זמן הריצה של ה-SDK מאפשר לערכות ה-SDK לפעול בארגז חול (Sandbox) ייעודי בנפרד את אפליקציית השיחות. זמן הריצה ל-SDK מספק אמצעי הגנה ואחריות משופרים סביב איסוף נתוני משתמשים. הפעולה הזו מתבצעת באמצעות שינוי הרצה שמגבילה את הרשאות הגישה לנתונים ואת קבוצת ההרשאות המותרות. מידע נוסף על זמן הריצה ל-SDK זמין בהצעה לעיצוב.
השלבים בדף הזה מנחים אתכם בתהליך היצירה של ערכת SDK שתואמת לזמן ריצה, שמגדירה תצוגה מבוססת-אינטרנט שניתן לעבד מרחוק. לאפליקציית שיחות.
מגבלות ידועות
לרשימת היכולות בתהליך פיתוח בשביל זמן הריצה של ה-SDK, אפשר לעיין בגרסה הערות.
ההגבלות הבאות צפויות שיתוקנו במכשירי Android העיקריים הבאים מהדורת פלטפורמה.
- רינדור מודעה בתצוגה שניתן לגלול. לדוגמה,
RecyclerView
לא פועלות כראוי.- ייתכנו בעיות בשינוי הגודל.
- אירועי גלילה במגע של המשתמש לא מועברים כראוי לסביבת זמן הריצה.
- ממשק API לאחסון
- אחסון לפי SDK לא זמין ב-Android 13.
הבעיה הבאה תיפתר בשנת 2023:
- ממשקי ה-API
getAdId
ו-getAppSetId
עדיין לא פועלים כראוי מאז התמיכה של השפות האלה טרם הופעלו.
לפני שמתחילים
לפני שמתחילים, צריך לבצע את השלבים הבאים:
להגדיר את סביבת הפיתוח לארגז החול לפרטיות ב- Android. כלים שתומכים בזמן הריצה של ה-SDK נמצאים בפיתוח פעיל, לכן במדריך זה תידרשו להשתמש בגרסה העדכנית ביותר של Android Canary Studio. אפשר להפעיל את הגרסה הזו של Android Studio במקביל לגרסה אחרת הגרסאות שבהן השתמשת, לכן עליך להודיע לנו אם הדרישה הזו לא עובד בשבילכם.
מתקינים תמונת מערכת במכשיר נתמך או להגדיר אמולטור שכולל תמיכה בארגז החול לפרטיות ב- Android.
הגדרת הפרויקט ב-Android Studio
כדי לנסות את זמן הריצה של ה-SDK, צריך להשתמש במודל שדומה client-server model. ההבדל העיקרי הוא שאפליקציות לקוח) וערכות SDK ("השרת") פועלות באותו מכשיר.
- מוסיפים מודול אפליקציה לפרויקט. המודול הזה משמש כלקוח שעומד בבסיס ה-SDK.
- במודול האפליקציה, מפעילים את זמן הריצה של ה-SDK. להצהיר על ההרשאות הנדרשות להגדיר שירותי מודעות שספציפיים ל-API.
- מוסיפים לפרויקט מודול אחד של ספרייה. המודול הזה מכיל את קוד ה-SDK שלך.
- אתם צריכים להצהיר על ההרשאות הדרושות במודול ה-SDK. לא צריך להגדיר שירותי מודעות ספציפיים לממשק API במודול הזה.
- מסירים את
dependencies
מהקובץbuild.gradle
של מודול הספרייה, שערכת ה-SDK לא משתמשת בהם. ברוב המקרים, אפשר להסיר את כל יחסי התלות. שלך כדי לעשות זאת, תוכלו ליצור ספרייה חדשה ששמה תואם ל-SDK שלכם. יצירה ידנית של מודול חדש באמצעות
com.android.privacy-sandbox-sdk
מהסוג הזה. החבילה הזו מגיעה עם קוד ה-SDK כדי ליצור APK שאפשר שנפרסו במכשיר. כדי לעשות זאת, אפשר ליצור ספרייה חדשה שתואם ל-SDK שלך. מוסיפים קובץbuild.gradle
ריק. התוכן בקובץ הזה יאוכלסו בהמשך המדריך הזה.מוסיפים את קטע הקוד הבא לקובץ
gradle.properties
:android.experimental.privacysandboxsdk.enable=true
הורדה של תמונת האמולטור Tiramisu (Extension Level 4) ויצירה אמולטור עם התמונה הזו שכולל את חנות Play.
תלוי אם אתם מפתחי SDK או מפתחי אפליקציות, ההגדרה הסופית שונה מההגדרה שתואר בפסקה הקודמת.
מתקינים את ה-SDK במכשיר בדיקה, בדומה לאופן שבו מתקינים אפליקציה, באמצעות את Android Studio או Android Debug Bridge (ADB). כדי לעזור לך להתחיל, יצרנו אפליקציות לדוגמה ב-Kotlin וב-Java את שפות התכנות האלה, מאגר GitHub. קובצי ה-README וקובצי המניפסט כוללים הערות שמתארות מה צריך לשנות כדי להריץ את הדוגמה בגרסאות יציבות של Android Studio.
הכנת ה-SDK
יצירת ספרייה ברמת המודול באופן ידני. הוא משמש כ-wrapper את קוד ההטמעה כדי לבנות את ה-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>') }
אפשר ליצור כיתה בספריית ההטמעה שתשמש כנקודת כניסה ב-SDK שלך. שם הכיתה צריך להיות ממופה לערך של
sdkProviderClassName
והארכהSandboxedSdkProvider
.
נקודת הכניסה ל-SDK מתחילה בתאריך SandboxedSdkProvider
.
SandboxedSdkProvider
מכיל אובייקט Context
ל-SDK, שאותו אפשר
גישה באמצעות getContext()
. צריך לגשת להקשר הזה רק פעם אחת
בוצעה הפעלה של onLoadSdk()
.
כדי שאפליקציית ה-SDK תעבור הידור (compile), צריך לשנות את השיטות לטיפול ב-SDK מחזור חיים:
onLoadSdk()
טוענת את ה-SDK ל-Sandbox, ושולחת הודעה לאפליקציית הקריאה כשה-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
בנוסף לתמיכה במודעות באנר, 'ארגז החול לפרטיות' מחויב עוד תמיכה בנגני וידאו שפועלים בתוך זמן הריצה של ה-SDK.
תהליך הבדיקה של נגני הווידאו דומה לתהליך הבדיקה של מודעות באנר. משנים את
שיטה getView()
בנקודת הכניסה של ה-SDK להכללת נגן וידאו
הוחזר אובייקט View
. בדיקת כל הזרימה של נגן הווידאו כמצופה
נתמכים על ידי ארגז החול לפרטיות. שימו לב שהתקשורת בין ה-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
. כמה
דוגמאות:
- גישה לקבצים באמצעות Storage Access Framework תוביל
SecurityException
. - הפונקציה
getExternalFilsDir()
תמיד תחזירnull
.
ב-Android 13, כל ערכות ה-SDK בזמן הריצה של ה-SDK יחלקו את האחסון הפנימי שהוקצה לזמן הריצה של ה-SDK. האחסון יישמר עד שאפליקציית הלקוח הוסרה, או כשמנקים את הנתונים של אפליקציית הלקוח.
עליך להשתמש בContext
שהוחזר על ידי SandboxedSdkProvider.getContext()
ל
אחסון. שימוש ב-File Storage 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
גישה למזהה הפרסום שסופק על ידי Google Play Services
אם ל-SDK נדרשת גישה למזהה הפרסום שסופק על ידי Google Play Services:
- צריך להצהיר על ההרשאה
android.permission.ACCESS_ADSERVICES_AD_ID
במניפסט של ה-SDK. - כדי לאחזר את הערך באופן אסינכרוני, משתמשים ב-
AdIdManager#getAdId()
.
גישה למזהה קבוצת האפליקציות שסופק על ידי Google Play Services
אם ל-SDK נדרשת גישה למזהה קבוצת האפליקציות שסופק על ידי Google Play Services:
- כדי לאחזר את הערך באופן אסינכרוני, משתמשים ב-
AppSetIdManager#getAppSetId()
.
עדכון אפליקציות לקוח
כדי לשלוח קריאה לערכת SDK שרצה בזמן הריצה של ה-SDK, צריך לבצע את הפעולות הבאות שינויים באפליקציית הלקוח לשיחות:
הוספת ההרשאות
INTERNET
ו-ACCESS_NETWORK_STATE
ל המניפסט של האפליקציה:<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
בפעילות של האפליקציה שכוללת מודעה, צריך להצהיר על הפניה אל
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;
צריך לבדוק אם תהליך זמן הריצה של ה-SDK זמין במכשיר.
בודקים את הקבוע
SdkSandboxState
(getSdkSandboxState()
).SDK_SANDBOX_STATE_ENABLED_PROCESS_ISOLATION
פירושו שזמן הריצה של ה-SDK זמינים.כדאי לוודא שהשיחה אל
loadSdk()
בוצעה בהצלחה. הפעולה תצליח אם אין חריגות, והמקבל הוא מופע שלSandboxedSdk
התקשרות אל
loadSdk()
דרך החזית. אם הוא נקרא רקע יזרקSecurityException
.בודקים ב-
OutcomeReceiver
מופע שלSandboxedSdk
כדי לבדוק אם זרועLoadSdkException
. חריגה מציינת יכול להיות שזמן הריצה של ה-SDK לא יהיה זמין.
אם הקריאה
SdkSandboxState
אוloadSdk
נכשלות, זמן הריצה של ה-SDK לא והשיחה צריכה לחזור ל-SDK הקיים.להגדיר מחלקה של קריאה חוזרת (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()
ב-
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); }
כדי לטפל בבעיה כשתהליך ה-Sandbox של ה-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); } }
כדי לרשום את הקריאה החוזרת הזו לקבלת מידע על מועד ה-Sandbox של ה-SDK הסתיים, הוסף את השורה הבאה בכל עת:
Kotlin
mSdkSandboxManager.addSdkSandboxProcessDeathCallback({ obj: Runnable -> obj.run() }, SdkSandboxLifecycleCallbackImpl())
Java
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, new SdkSandboxLifecycleCallbackImpl());
מאחר שהמצב של ארגז החול אובד כשהתהליך מסתיים, הצפיות יכול להיות שערכת ה-SDK מעבדת מרחוק את הנתונים שלה. כדי להמשיך את האינטראקציה עם ערכות ה-SDK, צריך לטעון את התצוגות האלה שוב מתחיל תהליך חדש של Sandbox.
צריך להוסיף תלות במודול ה-SDK לאפליקציית הלקוח
build.gradle
:dependencies { ... implementation project(':<your-sdk-module>') ... }
בדיקת האפליקציות
כדי להריץ את אפליקציית הלקוח, צריך להתקין את אפליקציית ה-SDK ואת אפליקציית הלקוח במכשיר הבדיקה באמצעות Android Studio או שורת הפקודה.
פריסה דרך Android Studio
כשפורסים דרך Android Studio, מבצעים את השלבים הבאים:
- פותחים את פרויקט Android Studio של אפליקציית הלקוח.
- עוברים אל Run > עורכים את ההגדרות האישיות. החלון Run/Debug Configuration מופיעה.
- בקטע Launch options (אפשרויות הפעלה), מגדירים את Launch (הפעלה) כ-Specified Activity (פעילות ספציפית).
- לוחצים על תפריט שלוש הנקודות שלצד 'פעילות' ובוחרים באפשרות פעילות ראשית. עבור הלקוח שלך.
- לוחצים על אישור ואז על אישור.
- לוחצים על הפעלה.
כדי להתקין את אפליקציית הלקוח ואת ה-SDK במכשיר הבדיקה.
פריסה בשורת הפקודה
בפריסה באמצעות שורת הפקודה, צריך להשלים את השלבים ברשימה הבאה.
הקטע הזה מניח שהשם של מודול ה-SDK של אפליקציית ה-SDK הוא sdk-app
,
השם של מודול אפליקציית הלקוח הוא client-app
.
מטרמינל של שורת הפקודה, יוצרים את חבילות ה-APK של ה-SDK של ארגז החול לפרטיות:
./gradlew :client-app:buildPrivacySandboxSdkApksForDebug
נוצר פלט של המיקום של חבילות ה-APK שנוצרו. חבילות ה-APK האלה חתומות עם את המפתח המקומי לניפוי באגים. הנתיב הזה צריך להיות בפקודה הבאה.
מתקינים את ה-APK במכשיר:
adb install -t /path/to/your/standalone.apk
ב-Android Studio, לוחצים על הפעלה > עורכים את ההגדרות האישיות. הכלי הפעלה/ניפוי באגים חלון מופיע.
בקטע אפשרויות התקנה, מגדירים את פריסה לערך APK ברירת המחדל.
לוחצים על אישור ואז על אישור.
לוחצים על Run כדי להתקין את חבילת ה-APK במכשיר הבדיקה.
ניפוי באגים באפליקציות
כדי לנפות באגים באפליקציית הלקוח, לוחצים על ניפוי באגים.
ב-Android Studio.
כדי לנפות באגים באפליקציית ה-SDK, עוברים אל הפעלה > צירוף לתהליך, שבו מוצג חלון קופץ
(מוצג למטה). מסמנים את התיבה הצגת כל התהליכים. ברשימה
מופיע, מחפשים תהליך בשם CLIENT_APP_PROCESS_sdk_sandbox
. יש לבחור באפשרות הזו ולהוסיף נקודות עצירה בקוד של אפליקציית ה-SDK כדי
אפשר להתחיל לנפות באגים ב-SDK.
![תהליך אפליקציית ה-SDK מופיע בתצוגת רשימה בחלק התחתון של המסך
של תיבת הדו-שיח](https://developers.google.cn/static/privacy-sandbox/assets/images/android/debug-sdk-app.png?authuser=9&hl=he)
איך מפעילים ומפסיקים את זמן הריצה של ה-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 ולקרוא לו זמן ריצה.דיווח על באגים ובעיות
המשוב שלכם הוא חלק חיוני בארגז החול לפרטיות ב-Android. נשמח לשמוע ממך על כל בעיות שמצאתם או רעיונות לשיפור ארגז החול לפרטיות ב-Android.
מומלץ עבורך
- הערה: טקסט הקישור מוצג כאשר JavaScript מושבת
- זמן ריצה ל-SDK
- נתוני גרסה
- Protected Audience API במדריך למפתחים של Android