SDK রানটাইম বিকাশকারীর নির্দেশিকা, SDK রানটাইম বিকাশকারীর নির্দেশিকা

আপনি Android ডকুমেন্টেশনের গোপনীয়তা স্যান্ডবক্সের মাধ্যমে পড়ার সময়, আপনি যে প্রোগ্রামটির সাথে কাজ করছেন সেটি নির্বাচন করতে বিকাশকারী পূর্বরূপ বা বিটা বোতামটি ব্যবহার করুন, কারণ নির্দেশাবলী পরিবর্তিত হতে পারে।


মতামত প্রদান করুন

SDK রানটাইম SDK-কে একটি ডেডিকেটেড স্যান্ডবক্সে চালানোর অনুমতি দেয় যা কলিং অ্যাপ থেকে আলাদা। SDK রানটাইম ব্যবহারকারীর ডেটা সংগ্রহের আশেপাশে উন্নত সুরক্ষা এবং গ্যারান্টি প্রদান করে। এটি একটি পরিবর্তিত কার্যকরী পরিবেশের মাধ্যমে করা হয় যা ডেটা অ্যাক্সেসের অধিকার এবং অনুমোদিত অনুমতিগুলির সেটকে সীমাবদ্ধ করে। ডিজাইন প্রস্তাবে SDK রানটাইম সম্পর্কে আরও জানুন।

এই পৃষ্ঠার পদক্ষেপগুলি আপনাকে একটি রানটাইম-সক্ষম SDK তৈরির প্রক্রিয়ার মাধ্যমে গাইড করে যা একটি ওয়েব-ভিত্তিক দৃশ্যকে সংজ্ঞায়িত করে যা দূরবর্তীভাবে একটি কলিং অ্যাপে রেন্ডার করা যেতে পারে।

পরিচিত সীমাবদ্ধতা

SDK রানটাইমের জন্য চলমান ক্ষমতার তালিকার জন্য, রিলিজ নোটগুলি দেখুন।

পরবর্তী প্রধান অ্যান্ড্রয়েড প্ল্যাটফর্ম রিলিজে নিম্নলিখিত সীমাবদ্ধতাগুলি সংশোধন করা হবে বলে আশা করা হচ্ছে।

  • একটি স্ক্রোলযোগ্য দৃশ্যের মধ্যে বিজ্ঞাপন রেন্ডারিং। উদাহরণস্বরূপ, RecyclerView সঠিকভাবে কাজ করে না।
    • আপনি আকার পরিবর্তন করার সময় জ্যাঙ্ক অনুভব করতে পারেন।
    • ব্যবহারকারীর স্পর্শ স্ক্রোল ইভেন্ট সঠিকভাবে রানটাইম পাস করা হয় না.
  • স্টোরেজ API

নিম্নলিখিত সমস্যাটি 2023 সালে ঠিক করা হবে:

  • getAdId এবং getAppSetId APIগুলি এখনও সঠিকভাবে কাজ করে না কারণ এইগুলির জন্য সমর্থন এখনও সক্রিয় করা হয়নি৷

তুমি শুরু করার আগে

শুরু করার আগে, নিম্নলিখিত পদক্ষেপগুলি সম্পূর্ণ করুন:

  1. অ্যান্ড্রয়েডে গোপনীয়তা স্যান্ডবক্সের জন্য আপনার বিকাশের পরিবেশ সেট আপ করুন ৷ SDK রানটাইম সমর্থন করার জন্য টুলিং সক্রিয় বিকাশের অধীনে রয়েছে, তাই এই নির্দেশিকাটির জন্য আপনাকে Android স্টুডিওর সর্বশেষ ক্যানারি সংস্করণ ব্যবহার করতে হবে। আপনি অ্যান্ড্রয়েড স্টুডিওর এই সংস্করণটি আপনার ব্যবহার করা অন্যান্য সংস্করণের সমান্তরালে চালাতে পারেন, তাই এই প্রয়োজনীয়তা আপনার জন্য কাজ না করলে অনুগ্রহ করে আমাদের জানান

  2. হয় একটি সমর্থিত ডিভাইসে একটি সিস্টেম ইমেজ ইনস্টল করুন বা Android-এ গোপনীয়তা স্যান্ডবক্সের জন্য সমর্থন অন্তর্ভুক্ত করে এমন একটি এমুলেটর সেট আপ করুন

অ্যান্ড্রয়েড স্টুডিওতে আপনার প্রকল্প সেট আপ করুন

SDK রানটাইম ব্যবহার করে দেখতে, একটি মডেল ব্যবহার করুন যা ক্লায়েন্ট-সার্ভার মডেলের অনুরূপ। প্রধান পার্থক্য হল অ্যাপ (ক্লায়েন্ট) এবং SDKs ("সার্ভার") একই ডিভাইসে চলে।

  1. আপনার প্রকল্পে একটি অ্যাপ মডিউল যোগ করুন। এই মডিউলটি ক্লায়েন্ট হিসাবে কাজ করে যা SDK চালায়।
  2. আপনার অ্যাপ মডিউলে, SDK রানটাইম সক্ষম করুন , প্রয়োজনীয় অনুমতিগুলি ঘোষণা করুন এবং API-নির্দিষ্ট বিজ্ঞাপন পরিষেবাগুলি কনফিগার করুন
  3. আপনার প্রকল্পে একটি লাইব্রেরি মডিউল যোগ করুন। এই মডিউলটিতে আপনার SDK কোড রয়েছে।
  4. আপনার SDK মডিউলে, প্রয়োজনীয় অনুমতিগুলি ঘোষণা করুন৷ এই মডিউলে আপনাকে API-নির্দিষ্ট বিজ্ঞাপন পরিষেবাগুলি কনফিগার করার দরকার নেই৷
  5. আপনার লাইব্রেরি মডিউলের build.gradle ফাইলের dependencies সরান যা আপনার SDK ব্যবহার করে না৷ বেশিরভাগ ক্ষেত্রে, আপনি সমস্ত নির্ভরতা মুছে ফেলতে পারেন। আপনি একটি নতুন ডিরেক্টরি তৈরি করে এটি করতে পারেন যার নাম আপনার SDK-এর সাথে মিলে যায়৷
  6. com.android.privacy-sandbox-sdk টাইপ ব্যবহার করে ম্যানুয়ালি একটি নতুন মডিউল তৈরি করুন। আপনার ডিভাইসে স্থাপন করা যেতে পারে এমন একটি APK তৈরি করতে এটি SDK কোডের সাথে একত্রিত করা হয়েছে। আপনি একটি নতুন ডিরেক্টরি তৈরি করে এটি করতে পারেন যার নাম আপনার SDK-এর সাথে মিলে যায়৷ একটি খালি build.gradle ফাইল যোগ করুন। এই ফাইলের বিষয়বস্তু এই গাইডে পরে পপুলেট করা হবে।

  7. আপনার gradle.properties ফাইলে নিম্নলিখিত স্নিপেট যোগ করুন:

    android.experimental.privacysandboxsdk.enable=true
    
  8. Tiramisu (এক্সটেনশন লেভেল 4) এমুলেটর ইমেজটি ডাউনলোড করুন এবং এই ইমেজটি দিয়ে একটি এমুলেটর তৈরি করুন যাতে প্লে স্টোর অন্তর্ভুক্ত থাকে।

আপনি একজন SDK ডেভেলপার বা অ্যাপ ডেভেলপার কিনা তার উপর নির্ভর করে, আপনার কাছে পূর্ববর্তী অনুচ্ছেদে বর্ণিত একটির থেকে আলাদা চূড়ান্ত সেটআপ থাকতে পারে।

Android স্টুডিও বা অ্যান্ড্রয়েড ডিবাগ ব্রিজ (ADB) ব্যবহার করে আপনি যেভাবে একটি অ্যাপ ইনস্টল করবেন একইভাবে একটি টেস্ট ডিভাইসে SDK ইনস্টল করুন।আপনাকে শুরু করতে সাহায্য করার জন্য, আমরা কোটলিন এবং জাভা প্রোগ্রামিং ভাষায় নমুনা অ্যাপ তৈরি করেছি, যা এই GitHub সংগ্রহস্থলে পাওয়া যাবে। README এবং ম্যানিফেস্ট ফাইলগুলিতে মন্তব্য রয়েছে যা বর্ণনা করে যে Android স্টুডিওর স্থিতিশীল সংস্করণে নমুনা চালানোর জন্য কী পরিবর্তন করতে হবে৷

আপনার SDK প্রস্তুত করুন

  1. ম্যানুয়ালি একটি মডিউল-স্তরের ডিরেক্টরি তৈরি করুন। এটি SDK APK তৈরি করতে আপনার বাস্তবায়ন কোডের চারপাশে মোড়ক হিসাবে কাজ করে। নতুন ডিরেক্টরিতে, একটি 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 আপনার SDK-এর জন্য একটি Context বস্তু রয়েছে, যা আপনি getContext() কল করে অ্যাক্সেস করতে পারেন। onLoadSdk() চালু করা হলেই এই প্রসঙ্গটি অ্যাক্সেস করতে হবে।

আপনার SDK অ্যাপটি কম্পাইল করার জন্য, আপনাকে SDK লাইফসাইকেল পরিচালনা করার পদ্ধতিগুলি ওভাররাইড করতে হবে:

onLoadSdk()

স্যান্ডবক্সে SDK লোড করে, এবং যখন SDK একটি নতুন SandboxedSdk অবজেক্টের ভিতরে মোড়ানো IBinder অবজেক্ট হিসাবে তার ইন্টারফেস পাস করে অনুরোধগুলি পরিচালনা করার জন্য প্রস্তুত হয় তখন কলিং অ্যাপটিকে অবহিত করে৷ আবদ্ধ পরিষেবা নির্দেশিকা IBinder প্রদানের বিভিন্ন উপায় প্রদান করে। আপনার উপায় বেছে নেওয়ার জন্য আপনার নমনীয়তা আছে, তবে এটি অবশ্যই SDK এবং কলিং অ্যাপের জন্য সামঞ্জস্যপূর্ণ হতে হবে।

একটি উদাহরণ হিসাবে AIDL ব্যবহার করে, আপনার IBinder উপস্থাপন করার জন্য একটি AIDL ফাইল সংজ্ঞায়িত করা উচিত যা অ্যাপ দ্বারা ভাগ করা এবং ব্যবহার করা হবে:

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

আপনার বিজ্ঞাপনের জন্য ভিউ তৈরি করে এবং সেট আপ করে, অন্য যেকোন অ্যান্ড্রয়েড ভিউয়ের মতোই ভিউ শুরু করে এবং পিক্সেলে প্রদত্ত প্রস্থ এবং উচ্চতার উইন্ডোতে দূরবর্তীভাবে রেন্ডার করা ভিউ ফিরিয়ে দেয়।

নিম্নলিখিত কোড স্নিপেট এই পদ্ধতিগুলিকে কীভাবে ওভাররাইড করতে হয় তা প্রদর্শন করে:

কোটলিন

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 রানটাইমে ভিডিও প্লেয়ার পরীক্ষা করুন

ব্যানার বিজ্ঞাপনগুলিকে সমর্থন করার পাশাপাশি, গোপনীয়তা স্যান্ডবক্স SDK রানটাইমের ভিতরে চলমান ভিডিও প্লেয়ারকে সমর্থন করতে প্রতিশ্রুতিবদ্ধ৷

ভিডিও প্লেয়ার পরীক্ষা করার জন্য প্রবাহ ব্যানার বিজ্ঞাপন পরীক্ষার অনুরূপ। প্রত্যাবর্তিত View অবজেক্টে একটি ভিডিও প্লেয়ার অন্তর্ভুক্ত করতে আপনার SDK-এর এন্ট্রি পয়েন্টের getView() পদ্ধতিটি পরিবর্তন করুন৷ আপনি গোপনীয়তা স্যান্ডবক্স দ্বারা সমর্থিত হবে এমন সমস্ত ভিডিও প্লেয়ার ফ্লো পরীক্ষা করুন৷ মনে রাখবেন যে ভিডিওর জীবনচক্র সম্পর্কে SDK এবং ক্লায়েন্ট অ্যাপের মধ্যে যোগাযোগ সুযোগের বাইরে, তাই এই কার্যকারিতার জন্য প্রতিক্রিয়ার এখনও প্রয়োজন নেই৷

আপনার পরীক্ষা এবং প্রতিক্রিয়া নিশ্চিত করবে যে SDK রানটাইম আপনার পছন্দের ভিডিও প্লেয়ারের সমস্ত ব্যবহারের ক্ষেত্রে সমর্থন করে৷

নিচের কোড স্নিপেটটি দেখায় কিভাবে একটি ইউআরএল থেকে লোড হওয়া একটি সাধারণ ভিডিও ভিউ ফেরত দেওয়া যায়।

কোটলিন

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

আপনার SDK-এ স্টোরেজ API ব্যবহার করা

SDK রানটাইমে SDKগুলি আর কোনও অ্যাপের অভ্যন্তরীণ স্টোরেজে অ্যাক্সেস, পড়তে বা লিখতে পারে না এবং এর বিপরীতে। SDK রানটাইমকে তার নিজস্ব অভ্যন্তরীণ স্টোরেজ এলাকা বরাদ্দ করা হবে, যা অ্যাপ থেকে আলাদা হওয়ার নিশ্চয়তা।

SDKs SandboxedSdkProvider#getContext() দ্বারা প্রত্যাবর্তিত Context অবজেক্টে ফাইল স্টোরেজ API ব্যবহার করে এই পৃথক অভ্যন্তরীণ স্টোরেজ অ্যাক্সেস করতে সক্ষম হবে। SDK শুধুমাত্র অভ্যন্তরীণ স্টোরেজ ব্যবহার করতে পারে, তাই শুধুমাত্র অভ্যন্তরীণ স্টোরেজ API, যেমন Context.getFilesDir() বা Context.getCacheDir() কাজ করবে। অভ্যন্তরীণ স্টোরেজ থেকে অ্যাক্সেসে আরও উদাহরণ দেখুন।

SDK রানটাইম থেকে বাহ্যিক সঞ্চয়স্থানে অ্যাক্সেস সমর্থিত নয়। বাহ্যিক সঞ্চয়স্থান অ্যাক্সেস করার জন্য API-কে কল করা হয় একটি ব্যতিক্রম ছুঁড়ে দেবে বা null দেবে। বেশ কয়েকটি উদাহরণ:

Android 13-এ, SDK রানটাইমের সমস্ত SDKগুলি SDK রানটাইমের জন্য বরাদ্দ করা অভ্যন্তরীণ স্টোরেজ ভাগ করবে৷ ক্লায়েন্ট অ্যাপ আনইনস্টল না হওয়া পর্যন্ত বা ক্লায়েন্ট অ্যাপের ডেটা পরিষ্কার না হওয়া পর্যন্ত স্টোরেজ বজায় থাকবে।

স্টোরেজের জন্য আপনাকে অবশ্যই SandboxedSdkProvider.getContext() দ্বারা প্রত্যাবর্তিত Context ব্যবহার করতে হবে। অন্য কোনো Context অবজেক্ট ইনস্ট্যান্সে ফাইল স্টোরেজ API ব্যবহার করা, যেমন অ্যাপ্লিকেশন প্রসঙ্গ, সমস্ত পরিস্থিতিতে বা ভবিষ্যতে প্রত্যাশিতভাবে কাজ করার গ্যারান্টি দেওয়া হয় না।

নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে 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 কতটা স্টোরেজ ব্যবহার করে তা হিসাব করতে সাহায্য করে।

অ্যান্ড্রয়েড 13-এ, শুধুমাত্র একটি এপিআই প্রতি-SDK সঞ্চয়স্থানে একটি পথ ফেরত দেয়: Context#getDataDir()

Android 14-এ, Context অবজেক্টের সমস্ত অভ্যন্তরীণ স্টোরেজ API প্রতিটি SDK-এর জন্য একটি স্টোরেজ পাথ ফেরত দেয়। আপনাকে নিম্নলিখিত adb কমান্ডটি চালিয়ে এই বৈশিষ্ট্যটি সক্ষম করতে হতে পারে:

adb shell device_config put adservices sdksandbox_customized_sdk_context_enabled true

Google Play পরিষেবাগুলির দ্বারা প্রদত্ত বিজ্ঞাপন আইডি অ্যাক্সেস করুন৷

যদি আপনার SDK-এর Google Play পরিষেবার দ্বারা প্রদত্ত বিজ্ঞাপন আইডিতে অ্যাক্সেসের প্রয়োজন হয়:

  • SDK-এর ম্যানিফেস্টে android.permission.ACCESS_ADSERVICES_AD_ID অনুমতি ঘোষণা করুন।
  • অ্যাসিঙ্ক্রোনাস মান পুনরুদ্ধার করতে 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 নিক্ষেপ করা হবে।

      • একটি LoadSdkException নিক্ষেপ করা হয়েছে কিনা তা যাচাই করতে SandboxedSdk এর একটি উদাহরণের জন্য OutcomeReceiver চেক করুন। একটি ব্যতিক্রম নির্দেশ করে যে SDK রানটাইম উপলব্ধ নাও হতে পারে।

    যদি SdkSandboxState বা loadSdk কল ব্যর্থ হয়, তাহলে SDK রানটাইম উপলভ্য নয় এবং কলটি বিদ্যমান SDK-এ ফলব্যাক করা উচিত।

  4. লোড হওয়ার পর রানটাইমে SDK-এর সাথে ইন্টারঅ্যাক্ট করার জন্য OutcomeReceiver প্রয়োগ করে একটি কলব্যাক ক্লাস সংজ্ঞায়িত করুন। নিম্নলিখিত উদাহরণে, ক্লায়েন্ট SDK সফলভাবে লোড না হওয়া পর্যন্ত অপেক্ষা করার জন্য একটি কলব্যাক ব্যবহার করে, তারপর SDK থেকে একটি ওয়েব ভিউ রেন্ডার করার চেষ্টা করে৷ এই ধাপে কলব্যাকগুলি পরে সংজ্ঞায়িত করা হয়েছে।

    কোটলিন

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

    জাভা

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

    requestSurfacePackage() কল করার সময় রানটাইমে SDK থেকে রিমোট ভিউ ফিরে পেতে, OutcomeReceiver<Bundle, RequestSurfacePackageException> ইন্টারফেস প্রয়োগ করুন:

    কোটলিন

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

    জাভা

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

    দৃশ্য দেখানো হয়ে গেলে, কল করে 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. আপনার ক্লায়েন্ট অ্যাপের build.gradle এ আপনার SDK মডিউলের উপর নির্ভরতা যোগ করুন:

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

আপনার অ্যাপ্লিকেশন পরীক্ষা করুন

আপনার ক্লায়েন্ট অ্যাপ চালানোর জন্য, Android স্টুডিও বা কমান্ড লাইন ব্যবহার করে আপনার পরীক্ষা ডিভাইসে SDK অ্যাপ এবং ক্লায়েন্ট অ্যাপ ইনস্টল করুন।

অ্যান্ড্রয়েড স্টুডিওর মাধ্যমে স্থাপন করুন

অ্যান্ড্রয়েড স্টুডিওর মাধ্যমে স্থাপন করার সময়, নিম্নলিখিত পদক্ষেপগুলি সম্পূর্ণ করুন:

  1. আপনার ক্লায়েন্ট অ্যাপের জন্য অ্যান্ড্রয়েড স্টুডিও প্রকল্প খুলুন।
  2. Run > Edit Configurations এ যান। রান/ডিবাগ কনফিগারেশন উইন্ডো প্রদর্শিত হবে।
  3. লঞ্চ বিকল্পের অধীনে, নির্দিষ্ট কার্যকলাপে লঞ্চ সেট করুন।
  4. অ্যাক্টিভিটির পাশের তিন ডট মেনুতে ক্লিক করুন এবং আপনার ক্লায়েন্টের জন্য প্রধান অ্যাক্টিভিটি নির্বাচন করুন।
  5. প্রয়োগ করুন এবং তারপর ওকে ক্লিক করুন।
  6. রান ক্লিক করুন আপনার টেস্ট ডিভাইসে ক্লায়েন্ট অ্যাপ এবং SDK ইনস্টল করতে।

কমান্ড লাইনে স্থাপন করুন

কমান্ড লাইন ব্যবহার করে স্থাপন করার সময়, নিম্নলিখিত তালিকার ধাপগুলি সম্পূর্ণ করুন। এই বিভাগটি ধরে নেয় যে আপনার SDK অ্যাপ মডিউলের নাম হল sdk-app এবং আপনার ক্লায়েন্ট অ্যাপ মডিউলের নাম হল client-app

  1. একটি কমান্ড লাইন টার্মিনাল থেকে, গোপনীয়তা স্যান্ডবক্স SDK APK তৈরি করুন:

    ./gradlew :client-app:buildPrivacySandboxSdkApksForDebug
    

    এটি জেনারেট করা APKগুলির জন্য অবস্থান বের করে। এই APKগুলি আপনার স্থানীয় ডিবাগ কী দিয়ে স্বাক্ষরিত। পরবর্তী কমান্ডে আপনার এই পথটি প্রয়োজন।

  2. আপনার ডিভাইসে APK ইনস্টল করুন:

    adb install -t /path/to/your/standalone.apk
    
  3. অ্যান্ড্রয়েড স্টুডিওতে, রান > কনফিগারেশন সম্পাদনা করুন ক্লিক করুন। রান/ডিবাগ কনফিগারেশন উইন্ডো প্রদর্শিত হবে।

  4. ইনস্টলেশন বিকল্পের অধীনে, ডিফল্ট APK-স্থাপন সেট করুন।

  5. প্রয়োগ করুন এবং তারপর ওকে ক্লিক করুন।

  6. আপনার টেস্ট ডিভাইসে APK বান্ডেল ইনস্টল করতে Run এ ক্লিক করুন।

আপনার অ্যাপস ডিবাগ করুন

ক্লায়েন্ট অ্যাপ ডিবাগ করতে, ডিবাগ এ ক্লিক করুন অ্যান্ড্রয়েড স্টুডিওতে বোতাম।

SDK অ্যাপটি ডিবাগ করতে, Run > Attach to Process এ যান, যা আপনাকে একটি পপআপ স্ক্রীন দেখায় (নীচে দেখানো হয়েছে)। সমস্ত প্রক্রিয়া দেখান বাক্সটি চেক করুন। প্রদর্শিত তালিকায়, 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 রানটাইমের জন্য চলমান ক্ষমতার তালিকার জন্য, রিলিজ নোটগুলি দেখুন।

কোড নমুনা

GitHub-এ SDK রানটাইম এবং গোপনীয়তা সংরক্ষণ APIs সংগ্রহস্থলে আপনাকে শুরু করতে সাহায্য করার জন্য পৃথক Android স্টুডিও প্রকল্পগুলির একটি সেট রয়েছে, যার মধ্যে নমুনাগুলি রয়েছে যা প্রদর্শন করে যে কীভাবে SDK রানটাইম শুরু করতে হয় এবং কল করতে হয়।

বাগ এবং সমস্যা রিপোর্ট করুন

আপনার প্রতিক্রিয়া Android এ গোপনীয়তা স্যান্ডবক্সের একটি গুরুত্বপূর্ণ অংশ! Android-এ গোপনীয়তা স্যান্ডবক্সের উন্নতির জন্য আপনার খুঁজে পাওয়া যেকোন সমস্যা বা ধারণা সম্পর্কে আমাদের জানান।

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %} ,

আপনি Android ডকুমেন্টেশনের গোপনীয়তা স্যান্ডবক্সের মাধ্যমে পড়ার সময়, আপনি যে প্রোগ্রামটির সাথে কাজ করছেন সেটি নির্বাচন করতে বিকাশকারী পূর্বরূপ বা বিটা বোতামটি ব্যবহার করুন, কারণ নির্দেশাবলী পরিবর্তিত হতে পারে।


মতামত প্রদান করুন

SDK রানটাইম SDK-কে একটি ডেডিকেটেড স্যান্ডবক্সে চালানোর অনুমতি দেয় যা কলিং অ্যাপ থেকে আলাদা। SDK রানটাইম ব্যবহারকারীর ডেটা সংগ্রহের আশেপাশে উন্নত সুরক্ষা এবং গ্যারান্টি প্রদান করে। এটি একটি পরিবর্তিত কার্যকরী পরিবেশের মাধ্যমে করা হয় যা ডেটা অ্যাক্সেসের অধিকার এবং অনুমোদিত অনুমতিগুলির সেটকে সীমাবদ্ধ করে। ডিজাইন প্রস্তাবে SDK রানটাইম সম্পর্কে আরও জানুন।

এই পৃষ্ঠার পদক্ষেপগুলি আপনাকে একটি রানটাইম-সক্ষম SDK তৈরির প্রক্রিয়ার মাধ্যমে গাইড করে যা একটি ওয়েব-ভিত্তিক দৃশ্যকে সংজ্ঞায়িত করে যা দূরবর্তীভাবে একটি কলিং অ্যাপে রেন্ডার করা যেতে পারে।

পরিচিত সীমাবদ্ধতা

SDK রানটাইমের জন্য চলমান ক্ষমতার তালিকার জন্য, রিলিজ নোটগুলি দেখুন।

পরবর্তী প্রধান অ্যান্ড্রয়েড প্ল্যাটফর্ম রিলিজে নিম্নলিখিত সীমাবদ্ধতাগুলি সংশোধন করা হবে বলে আশা করা হচ্ছে।

  • একটি স্ক্রোলযোগ্য দৃশ্যের মধ্যে বিজ্ঞাপন রেন্ডারিং। উদাহরণস্বরূপ, RecyclerView সঠিকভাবে কাজ করে না।
    • আপনি আকার পরিবর্তন করার সময় জ্যাঙ্ক অনুভব করতে পারেন।
    • ব্যবহারকারীর স্পর্শ স্ক্রোল ইভেন্ট সঠিকভাবে রানটাইম পাস করা হয় না.
  • স্টোরেজ API

নিম্নলিখিত সমস্যাটি 2023 সালে ঠিক করা হবে:

  • getAdId এবং getAppSetId APIগুলি এখনও সঠিকভাবে কাজ করে না কারণ এইগুলির জন্য সমর্থন এখনও সক্রিয় করা হয়নি৷

তুমি শুরু করার আগে

শুরু করার আগে, নিম্নলিখিত পদক্ষেপগুলি সম্পূর্ণ করুন:

  1. অ্যান্ড্রয়েডে গোপনীয়তা স্যান্ডবক্সের জন্য আপনার বিকাশের পরিবেশ সেট আপ করুন ৷ SDK রানটাইম সমর্থন করার জন্য টুলিং সক্রিয় বিকাশের অধীনে রয়েছে, তাই এই নির্দেশিকাটির জন্য আপনাকে Android স্টুডিওর সর্বশেষ ক্যানারি সংস্করণ ব্যবহার করতে হবে। আপনি অ্যান্ড্রয়েড স্টুডিওর এই সংস্করণটি আপনার ব্যবহার করা অন্যান্য সংস্করণের সমান্তরালে চালাতে পারেন, তাই এই প্রয়োজনীয়তা আপনার জন্য কাজ না করলে অনুগ্রহ করে আমাদের জানান

  2. হয় একটি সমর্থিত ডিভাইসে একটি সিস্টেম ইমেজ ইনস্টল করুন বা Android-এ গোপনীয়তা স্যান্ডবক্সের জন্য সমর্থন অন্তর্ভুক্ত করে এমন একটি এমুলেটর সেট আপ করুন

অ্যান্ড্রয়েড স্টুডিওতে আপনার প্রকল্প সেট আপ করুন

SDK রানটাইম ব্যবহার করে দেখতে, একটি মডেল ব্যবহার করুন যা ক্লায়েন্ট-সার্ভার মডেলের অনুরূপ। প্রধান পার্থক্য হল অ্যাপ (ক্লায়েন্ট) এবং SDKs ("সার্ভার") একই ডিভাইসে চলে।

  1. আপনার প্রকল্পে একটি অ্যাপ মডিউল যোগ করুন। এই মডিউলটি ক্লায়েন্ট হিসাবে কাজ করে যা SDK চালায়।
  2. আপনার অ্যাপ মডিউলে, SDK রানটাইম সক্ষম করুন , প্রয়োজনীয় অনুমতিগুলি ঘোষণা করুন এবং API-নির্দিষ্ট বিজ্ঞাপন পরিষেবাগুলি কনফিগার করুন
  3. আপনার প্রকল্পে একটি লাইব্রেরি মডিউল যোগ করুন। এই মডিউলটিতে আপনার SDK কোড রয়েছে।
  4. আপনার SDK মডিউলে, প্রয়োজনীয় অনুমতিগুলি ঘোষণা করুন৷ এই মডিউলে আপনাকে API-নির্দিষ্ট বিজ্ঞাপন পরিষেবাগুলি কনফিগার করার দরকার নেই৷
  5. আপনার লাইব্রেরি মডিউলের build.gradle ফাইলের dependencies সরান যা আপনার SDK ব্যবহার করে না৷ বেশিরভাগ ক্ষেত্রে, আপনি সমস্ত নির্ভরতা মুছে ফেলতে পারেন। আপনি একটি নতুন ডিরেক্টরি তৈরি করে এটি করতে পারেন যার নাম আপনার SDK-এর সাথে মিলে যায়৷
  6. com.android.privacy-sandbox-sdk টাইপ ব্যবহার করে ম্যানুয়ালি একটি নতুন মডিউল তৈরি করুন। আপনার ডিভাইসে স্থাপন করা যেতে পারে এমন একটি APK তৈরি করতে এটি SDK কোডের সাথে একত্রিত করা হয়েছে। আপনি একটি নতুন ডিরেক্টরি তৈরি করে এটি করতে পারেন যার নাম আপনার SDK-এর সাথে মিলে যায়৷ একটি খালি build.gradle ফাইল যোগ করুন। এই ফাইলের বিষয়বস্তু এই গাইডে পরে পপুলেট করা হবে।

  7. আপনার gradle.properties ফাইলে নিম্নলিখিত স্নিপেট যোগ করুন:

    android.experimental.privacysandboxsdk.enable=true
    
  8. Tiramisu (এক্সটেনশন লেভেল 4) এমুলেটর ইমেজটি ডাউনলোড করুন এবং এই ইমেজটি দিয়ে একটি এমুলেটর তৈরি করুন যাতে প্লে স্টোর অন্তর্ভুক্ত থাকে।

আপনি একজন SDK ডেভেলপার বা অ্যাপ ডেভেলপার কিনা তার উপর নির্ভর করে, আপনার কাছে পূর্ববর্তী অনুচ্ছেদে বর্ণিত একটির থেকে আলাদা চূড়ান্ত সেটআপ থাকতে পারে।

Android স্টুডিও বা অ্যান্ড্রয়েড ডিবাগ ব্রিজ (ADB) ব্যবহার করে আপনি যেভাবে একটি অ্যাপ ইনস্টল করবেন একইভাবে একটি টেস্ট ডিভাইসে SDK ইনস্টল করুন।আপনাকে শুরু করতে সাহায্য করার জন্য, আমরা কোটলিন এবং জাভা প্রোগ্রামিং ভাষায় নমুনা অ্যাপ তৈরি করেছি, যা এই GitHub সংগ্রহস্থলে পাওয়া যাবে। README এবং ম্যানিফেস্ট ফাইলগুলিতে মন্তব্য রয়েছে যা বর্ণনা করে যে Android স্টুডিওর স্থিতিশীল সংস্করণে নমুনা চালানোর জন্য কী পরিবর্তন করতে হবে৷

আপনার SDK প্রস্তুত করুন

  1. ম্যানুয়ালি একটি মডিউল-স্তরের ডিরেক্টরি তৈরি করুন। এটি SDK APK তৈরি করতে আপনার বাস্তবায়ন কোডের চারপাশে মোড়ক হিসাবে কাজ করে। নতুন ডিরেক্টরিতে, একটি 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 আপনার SDK-এর জন্য একটি Context বস্তু রয়েছে, যা আপনি getContext() কল করে অ্যাক্সেস করতে পারেন। onLoadSdk() চালু করা হলেই এই প্রসঙ্গটি অ্যাক্সেস করতে হবে।

আপনার SDK অ্যাপটি কম্পাইল করার জন্য, আপনাকে SDK লাইফসাইকেল পরিচালনা করার পদ্ধতিগুলি ওভাররাইড করতে হবে:

onLoadSdk()

স্যান্ডবক্সে SDK লোড করে, এবং যখন SDK একটি নতুন SandboxedSdk অবজেক্টের ভিতরে মোড়ানো IBinder অবজেক্ট হিসাবে তার ইন্টারফেস পাস করে অনুরোধগুলি পরিচালনা করার জন্য প্রস্তুত হয় তখন কলিং অ্যাপটিকে অবহিত করে৷ আবদ্ধ পরিষেবা নির্দেশিকা IBinder প্রদানের বিভিন্ন উপায় প্রদান করে। আপনার উপায় বেছে নেওয়ার জন্য আপনার নমনীয়তা আছে, তবে এটি অবশ্যই SDK এবং কলিং অ্যাপের জন্য সামঞ্জস্যপূর্ণ হতে হবে।

একটি উদাহরণ হিসাবে AIDL ব্যবহার করে, আপনার IBinder উপস্থাপন করার জন্য একটি AIDL ফাইল সংজ্ঞায়িত করা উচিত যা অ্যাপ দ্বারা ভাগ করা এবং ব্যবহার করা হবে:

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

আপনার বিজ্ঞাপনের জন্য ভিউ তৈরি করে এবং সেট আপ করে, অন্য যেকোন অ্যান্ড্রয়েড ভিউয়ের মতোই ভিউ শুরু করে এবং পিক্সেলে প্রদত্ত প্রস্থ এবং উচ্চতার উইন্ডোতে দূরবর্তীভাবে রেন্ডার করা ভিউ ফিরিয়ে দেয়।

নিম্নলিখিত কোড স্নিপেট এই পদ্ধতিগুলিকে কীভাবে ওভাররাইড করতে হয় তা প্রদর্শন করে:

কোটলিন

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

এসডিকে রানটাইমে ভিডিও খেলোয়াড়দের পরীক্ষা করুন

ব্যানার বিজ্ঞাপনগুলিকে সমর্থন করার পাশাপাশি, গোপনীয়তা স্যান্ডবক্স এসডিকে রানটাইমের অভ্যন্তরে চলমান ভিডিও খেলোয়াড়দের সমর্থন করার জন্য প্রতিশ্রুতিবদ্ধ।

ভিডিও প্লেয়ারগুলি পরীক্ষার জন্য প্রবাহ ব্যানার বিজ্ঞাপনগুলির পরীক্ষার মতো। ফিরে আসা View অবজেক্টে কোনও ভিডিও প্লেয়ারকে অন্তর্ভুক্ত করতে আপনার এসডিকে এন্ট্রি পয়েন্টের getView() পদ্ধতিটি পরিবর্তন করুন। আপনি গোপনীয়তা স্যান্ডবক্স দ্বারা সমর্থিত হওয়ার প্রত্যাশা করে এমন সমস্ত ভিডিও প্লেয়ার প্রবাহ পরীক্ষা করুন। নোট করুন যে ভিডিওর লাইফসাইকেল সম্পর্কে এসডিকে এবং ক্লায়েন্ট অ্যাপের মধ্যে যোগাযোগের সুযোগের বাইরে, সুতরাং এই কার্যকারিতার জন্য এখনও প্রতিক্রিয়া প্রয়োজন হয় না।

আপনার পরীক্ষা এবং প্রতিক্রিয়া নিশ্চিত করবে যে এসডিকে রানটাইম আপনার পছন্দসই ভিডিও প্লেয়ারের সমস্ত ব্যবহারের ক্ষেত্রে সমর্থন করে।

নিম্নলিখিত কোড স্নিপেট প্রদর্শন করে যে কীভাবে একটি সাধারণ ভিডিও ভিউ যা কোনও ইউআরএল থেকে লোড হয়।

কোটলিন

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

আপনার এসডিকে স্টোরেজ এপিআই ব্যবহার করে

এসডিকে রানটাইমের এসডিকে আর কোনও অ্যাপের অভ্যন্তরীণ স্টোরেজে আর অ্যাক্সেস, পড়তে বা লিখতে পারে না এবং বিপরীতে। এসডিকে রানটাইমকে তার নিজস্ব অভ্যন্তরীণ স্টোরেজ অঞ্চল বরাদ্দ করা হবে, যা অ্যাপ থেকে পৃথক হওয়ার গ্যারান্টিযুক্ত।

SandboxedSdkProvider#getContext() দ্বারা ফিরে আসা Context ফাইল স্টোরেজ এপিআই ব্যবহার করে এসডিকে এই পৃথক অভ্যন্তরীণ স্টোরেজটি অ্যাক্সেস করতে সক্ষম হবে। এসডিকে কেবল অভ্যন্তরীণ স্টোরেজ ব্যবহার করতে পারে, সুতরাং কেবলমাত্র অভ্যন্তরীণ স্টোরেজ এপিআই যেমন Context.getFilesDir() বা Context.getCacheDir() কাজ করবে। অভ্যন্তরীণ স্টোরেজ থেকে অ্যাক্সেসের আরও উদাহরণ দেখুন।

এসডিকে রানটাইম থেকে বাহ্যিক স্টোরেজ অ্যাক্সেস সমর্থিত নয়। বাহ্যিক স্টোরেজ অ্যাক্সেসের জন্য এপিআইগুলিকে কল করা হয় ব্যতিক্রম ছুঁড়ে ফেলবে বা null ফিরে আসবে। বেশ কয়েকটি উদাহরণ:

অ্যান্ড্রয়েড 13 -এ, এসডিকে রানটাইমের সমস্ত এসডিকে এসডিকে রানটাইমের জন্য বরাদ্দকৃত অভ্যন্তরীণ স্টোরেজটি ভাগ করবে। ক্লায়েন্ট অ্যাপ্লিকেশনটি আনইনস্টল না করা বা ক্লায়েন্ট অ্যাপ্লিকেশন ডেটা পরিষ্কার করা না হওয়া পর্যন্ত স্টোরেজটি অব্যাহত থাকবে।

স্টোরেজের জন্য আপনাকে অবশ্যই SandboxedSdkProvider.getContext() দ্বারা ফিরে আসা Context ব্যবহার করতে হবে। অন্য কোনও Context ফাইল স্টোরেজ এপিআই ব্যবহার করা যেমন অ্যাপ্লিকেশন প্রসঙ্গে, সমস্ত পরিস্থিতিতে বা ভবিষ্যতে প্রত্যাশার মতো কাজ করার গ্যারান্টিযুক্ত নয়।

নিম্নলিখিত কোড স্নিপেটটি কীভাবে এসডিকে রানটাইমে স্টোরেজ ব্যবহার করবেন তা প্রদর্শন করে:

কোটলিন

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

}

    

প্রতি এসডিকে স্টোরেজ

প্রতিটি এসডিকে রানটাইমের জন্য পৃথক অভ্যন্তরীণ স্টোরেজের মধ্যে, প্রতিটি এসডিকে এর নিজস্ব স্টোরেজ ডিরেক্টরি থাকে। প্রতি এসডিকে স্টোরেজ এসডিকে রানটাইমের অভ্যন্তরীণ স্টোরেজের একটি যৌক্তিক বিভাজন যা প্রতিটি এসডিকে কতটা সঞ্চয় করে তা অ্যাকাউন্টে সহায়তা করে।

অ্যান্ড্রয়েড 13-এ, কেবলমাত্র একটি এপিআই প্রতি এসডিকে স্টোরেজে একটি পথ ফেরত দেয়: Context#getDataDir()

অ্যান্ড্রয়েড 14 এ, Context সমস্ত অভ্যন্তরীণ স্টোরেজ এপিআই প্রতিটি এসডিকে জন্য স্টোরেজ পাথ ফেরত দেয়। নিম্নলিখিত এডিবি কমান্ডটি চালিয়ে আপনার এই বৈশিষ্ট্যটি সক্ষম করতে হবে:

adb shell device_config put adservices sdksandbox_customized_sdk_context_enabled true

গুগল প্লে পরিষেবাদি দ্বারা সরবরাহিত বিজ্ঞাপন আইডি অ্যাক্সেস করুন

যদি আপনার এসডিকে গুগল প্লে পরিষেবাদি দ্বারা সরবরাহিত বিজ্ঞাপন আইডিতে অ্যাক্সেসের প্রয়োজন হয়:

  • Sdk এর ম্যানিফেস্টে android.permission.ACCESS_ADSERVICES_AD_ID অনুমতি ঘোষণা করুন।
  • AdIdManager#getAdId() ব্যবহার করুন asynchronconlyভাবে মানটি পুনরুদ্ধার করতে।

গুগল প্লে পরিষেবাদি দ্বারা সরবরাহিত অ্যাপ্লিকেশন সেট আইডি অ্যাক্সেস করুন

যদি আপনার এসডিকে গুগল প্লে পরিষেবাদি দ্বারা সরবরাহিত অ্যাপ্লিকেশন সেট আইডিতে অ্যাক্সেসের প্রয়োজন হয়:

  • AppSetIdManager#getAppSetId() ব্যবহার করুন অ্যাসিঙ্ক্রোনালি মানটি পুনরুদ্ধার করতে।

ক্লায়েন্ট অ্যাপ্লিকেশন আপডেট করুন

এসডিকে রানটাইমে চলমান একটি এসডিকে কল করার জন্য, কলিং ক্লায়েন্ট অ্যাপ্লিকেশনটিতে নিম্নলিখিত পরিবর্তনগুলি করুন:

  1. আপনার অ্যাপের ম্যানিফেস্টে INTERNET এবং ACCESS_NETWORK_STATE অনুমতিগুলি যুক্ত করুন:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    
  2. আপনার অ্যাপ্লিকেশনটির ক্রিয়াকলাপে একটি বিজ্ঞাপন অন্তর্ভুক্ত রয়েছে, SdkSandboxManager একটি রেফারেন্স ঘোষণা করুন, এসডিকে লোড হয়েছে কিনা তা জানতে একটি বুলিয়ান এবং রিমোট রেন্ডারিংয়ের জন্য একটি 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. ডিভাইসে এসডিকে রানটাইম প্রক্রিয়া উপলব্ধ কিনা তা পরীক্ষা করুন।

    1. SdkSandboxState ধ্রুবক পরীক্ষা করুন ( getSdkSandboxState() )। SDK_SANDBOX_STATE_ENABLED_PROCESS_ISOLATION অর্থ এসডিকে রানটাইম উপলব্ধ।

    2. পরীক্ষা করুন যে কলিং loadSdk() সফল। যদি কোনও ব্যতিক্রম নিক্ষেপ না করা হয় তবে এটি সফল, এবং রিসিভারটি SandboxedSdk উদাহরণ।

      • অগ্রভাগ থেকে loadSdk() কল করুন। যদি এটি ব্যাকগ্রাউন্ড থেকে বলা হয় তবে একটি SecurityException নিক্ষেপ করা হবে।

      • কোনও LoadSdkException নিক্ষেপ করা হয়েছে কিনা তা যাচাই করার জন্য SandboxedSdk উদাহরণের জন্য OutcomeReceiver পরীক্ষা করুন। একটি ব্যতিক্রম নির্দেশ করে যে এসডিকে রানটাইম উপলব্ধ নাও হতে পারে।

    যদি SdkSandboxState বা loadSdk কল ব্যর্থ হয় তবে এসডিকে রানটাইম পাওয়া যায় না এবং কলটি বিদ্যমান এসডিকে -তে পতিত হওয়া উচিত।

  4. লোড হওয়ার পরে রানটাইমে এসডিকে -র সাথে যোগাযোগের জন্য OutcomeReceiver প্রয়োগ করে একটি কলব্যাক ক্লাস সংজ্ঞায়িত করুন। নিম্নলিখিত উদাহরণে, ক্লায়েন্ট এসডিকে সফলভাবে লোড না হওয়া পর্যন্ত অপেক্ষা করতে একটি কলব্যাক ব্যবহার করে, তারপরে এসডিকে থেকে একটি ওয়েব ভিউ রেন্ডার করার চেষ্টা করে। কলব্যাকগুলি এই পদক্ষেপে পরে সংজ্ঞায়িত করা হয়।

    কোটলিন

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

    জাভা

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

    requestSurfacePackage() কল করার সময় রানটাইমটিতে এসডিকে থেকে একটি দূরবর্তী দৃশ্য ফিরে পেতে, OutcomeReceiver<Bundle, RequestSurfacePackageException> ইন্টারফেসটি প্রয়োগ করুন:

    কোটলিন

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

    জাভা

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

    দৃশ্যটি দেখানোর পরে, কল করে SurfacePackage প্রকাশ করতে ভুলবেন না:

    surfacePackage.notifyDetachedFromWindow()
    
  5. onCreate() এ, SdkSandboxManager , প্রয়োজনীয় কলব্যাকগুলি আরম্ভ করুন এবং তারপরে এসডিকে লোড করার জন্য একটি অনুরোধ করুন:

    কোটলিন

    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. এসডিকে স্যান্ডবক্স প্রক্রিয়াটি অপ্রত্যাশিতভাবে শেষ হয়ে গেলে কেসটি পরিচালনা করতে, 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);
              }
          }
    

    এসডিকে স্যান্ডবক্সটি কখন সমাপ্ত হয়েছে সে সম্পর্কে তথ্য পেতে এই কলব্যাকটি নিবন্ধভুক্ত করতে, যে কোনও সময় নিম্নলিখিত লাইন যুক্ত করুন:

    কোটলিন

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

    জাভা

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

    যেহেতু স্যান্ডবক্সের অবস্থাটি হারিয়ে যায় যখন এর প্রক্রিয়াটি সমাপ্ত হয়, এসডিকে দ্বারা দূরবর্তীভাবে রেন্ডার করা দর্শনগুলি আর সঠিকভাবে কাজ করতে পারে না। এসডিকেগুলির সাথে কথোপকথন চালিয়ে যাওয়ার জন্য, এই মতামতগুলি অবশ্যই আবার লোড করা উচিত যাতে একটি নতুন স্যান্ডবক্স প্রক্রিয়া শুরু হয়।

  7. আপনার ক্লায়েন্ট অ্যাপের build.gradle আপনার এসডিকে মডিউলটির উপর নির্ভরতা যুক্ত করুন grad

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

আপনার অ্যাপ্লিকেশন পরীক্ষা করুন

আপনার ক্লায়েন্ট অ্যাপ্লিকেশনটি চালাতে, অ্যান্ড্রয়েড স্টুডিও বা কমান্ড লাইন ব্যবহার করে আপনার পরীক্ষার ডিভাইসে এসডিকে অ্যাপ্লিকেশন এবং ক্লায়েন্ট অ্যাপটি ইনস্টল করুন।

অ্যান্ড্রয়েড স্টুডিওর মাধ্যমে মোতায়েন করুন

অ্যান্ড্রয়েড স্টুডিওর মাধ্যমে মোতায়েন করার সময়, নিম্নলিখিত পদক্ষেপগুলি সম্পূর্ণ করুন:

  1. আপনার ক্লায়েন্ট অ্যাপের জন্য অ্যান্ড্রয়েড স্টুডিও প্রকল্পটি খুলুন।
  2. রান> কনফিগারেশন সম্পাদনা করতে যান। রান/ডিবাগ কনফিগারেশন উইন্ডোটি প্রদর্শিত হবে।
  3. লঞ্চ বিকল্পগুলির অধীনে, নির্দিষ্ট ক্রিয়াকলাপে লঞ্চটি সেট করুন।
  4. ক্রিয়াকলাপের পাশের তিনটি বিন্দু মেনুতে ক্লিক করুন এবং আপনার ক্লায়েন্টের জন্য প্রধান ক্রিয়াকলাপটি নির্বাচন করুন।
  5. প্রয়োগ ক্লিক করুন এবং তারপরে ঠিক আছে
  6. রান ক্লিক করুন আপনার পরীক্ষার ডিভাইসে ক্লায়েন্ট অ্যাপ্লিকেশন এবং এসডিকে ইনস্টল করতে।

কমান্ড লাইনে মোতায়েন করুন

কমান্ড লাইন ব্যবহার করে মোতায়েন করার সময়, নিম্নলিখিত তালিকার পদক্ষেপগুলি সম্পূর্ণ করুন। এই বিভাগটি ধরে নিয়েছে যে আপনার এসডিকে অ্যাপ্লিকেশন মডিউলটির নাম sdk-app এবং আপনার ক্লায়েন্ট অ্যাপ্লিকেশন মডিউলটির নাম client-app

  1. একটি কমান্ড লাইন টার্মিনাল থেকে, গোপনীয়তা স্যান্ডবক্স এসডিকে এপিকস তৈরি করুন:

    ./gradlew :client-app:buildPrivacySandboxSdkApksForDebug
    

    এটি উত্পন্ন এপিকেগুলির জন্য অবস্থানকে আউটপুট করে। এই APKS আপনার স্থানীয় ডিবাগ কী দিয়ে স্বাক্ষরিত। আপনার পরবর্তী কমান্ডে এই পথটি দরকার।

  2. আপনার ডিভাইসে APK ইনস্টল করুন:

    adb install -t /path/to/your/standalone.apk
    
  3. অ্যান্ড্রয়েড স্টুডিওতে, রান> কনফিগারেশনগুলি সম্পাদনা করুন ক্লিক করুন। রান/ডিবাগ কনফিগারেশন উইন্ডোটি প্রদর্শিত হবে।

  4. ইনস্টলেশন বিকল্পগুলির অধীনে, ডিফল্ট এপিকে মোতায়েন সেট করুন।

  5. প্রয়োগ ক্লিক করুন এবং তারপরে ঠিক আছে

  6. আপনার পরীক্ষার ডিভাইসে APK বান্ডিল ইনস্টল করতে রান ক্লিক করুন।

আপনার অ্যাপ্লিকেশনগুলি ডিবাগ করুন

ক্লায়েন্ট অ্যাপ্লিকেশনটি ডিবাগ করতে, ডিবাগটি ক্লিক করুন অ্যান্ড্রয়েড স্টুডিওতে বোতাম।

এসডিকে অ্যাপ্লিকেশনটি ডিবাগ করতে, প্রক্রিয়াটি চালাতে যান> প্রক্রিয়াটি করুন , যা আপনাকে একটি পপআপ স্ক্রিন দেখায় (নীচে দেখানো হয়েছে)। সমস্ত প্রক্রিয়া বাক্স শো পরীক্ষা করুন। প্রদর্শিত তালিকায়, CLIENT_APP_PROCESS _sdk_sandbox নামে একটি প্রক্রিয়া সন্ধান করুন। এই বিকল্পটি নির্বাচন করুন এবং আপনার এসডিকে ডিবাগিং শুরু করতে এসডিকে অ্যাপের কোডে ব্রেকপয়েন্টগুলি যুক্ত করুন।

এসডিকে অ্যাপ্লিকেশন প্রক্রিয়াটি ডায়ালগের নীচের দিকে একটি তালিকার দৃশ্যে উপস্থিত হয়
প্রক্রিয়া স্ক্রিনটি চয়ন করুন , যেখানে আপনি ডিবাগ করতে এসডিকে অ্যাপ্লিকেশনটি নির্বাচন করতে পারেন।

কমান্ড লাইন থেকে এসডিকে রানটাইম শুরু করুন এবং বন্ধ করুন

আপনার অ্যাপ্লিকেশনটির জন্য এসডিকে রানটাইম প্রক্রিয়া শুরু করতে, নিম্নলিখিত শেল কমান্ডটি ব্যবহার করুন:

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

একইভাবে, এসডিকে রানটাইম প্রক্রিয়া বন্ধ করতে, এই কমান্ডটি চালান:

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

সীমাবদ্ধতা

এসডিকে রানটাইমের জন্য অগ্রগতি ক্ষমতার তালিকার জন্য, রিলিজ নোটগুলি দেখুন।

কোড নমুনা

এসডিকে রানটাইম এবং গোপনীয়তা সংরক্ষণ করে গিটহাবের এপিআই সংগ্রহস্থল সংরক্ষণ করে আপনাকে শুরু করতে সহায়তা করার জন্য পৃথক অ্যান্ড্রয়েড স্টুডিও প্রকল্পগুলির একটি সেট রয়েছে, এমন নমুনাগুলি সহ যা এসডিকে রানটাইম কীভাবে শুরু করতে এবং কল করতে হয় তা প্রদর্শন করে।

বাগ এবং সমস্যা রিপোর্ট করুন

আপনার প্রতিক্রিয়া অ্যান্ড্রয়েডের গোপনীয়তা স্যান্ডবক্সের একটি গুরুত্বপূর্ণ অংশ! অ্যান্ড্রয়েডে গোপনীয়তা স্যান্ডবক্সের উন্নতির জন্য আপনি যে কোনও সমস্যা বা ধারণাগুলি সম্পর্কে আমাদের ধারণাগুলি সম্পর্কে জানতে দিন।

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %}