ডিভাইস ট্রাস্ট সিগন্যাল পাওয়ার উদ্দেশ্যে AMAPI SDK ব্যবহার করার জন্য এই ডকুমেন্টটি আপনার প্রাথমিক গাইড হওয়া উচিত।
AMAPI SDK আপনার অ্যাপ্লিকেশনকে Android Device Policy (ADP) অ্যাপ থেকে ডিভাইসের বিশ্বাসযোগ্যতা সংক্রান্ত সিগন্যাল অ্যাক্সেস করার অনুমতি দেয়। আপনার অ্যাপ তখন ডিভাইসের বিশ্বাসযোগ্যতার স্ট্যাটাস গণনা করতে এবং বেছে নেওয়া ব্যবসায়িক লজিক কার্যকর করতে এই সিগন্যালগুলি ব্যবহার করতে পারে।
পূর্বশর্ত
- ডিভাইস ট্রাস্ট সিগন্যাল পড়ার জন্য আপনার অ্যাপ্লিকেশনকে অবশ্যই অনুমোদিত হতে হবে:
- AMAPI-ম্যানেজ করা ডিভাইসে কম্প্যানিয়ন অ্যাপ: নীতিতে
COMPANION_APPভূমিকা অ্যাসাইন করা অ্যাপ্লিকেশনগুলি সম্পূর্ণভাবে ম্যানেজ করা ডিভাইসে বা কোনও কাজের প্রোফাইলের ভিতর থেকে (কাজের প্রোফাইল থেকে সিগন্যালে সীমিত অ্যাক্সেস সহ) অনুমোদিত তালিকায় না থেকেও ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস করতে পারে। বিস্তারিত জানতে, অ্যাপ্লিকেশন ভূমিকা ম্যানেজ করা, নীতি কনফিগারেশন এবং কম্প্যানিয়ন অ্যাপ থেকে অ্যাক্সেস সিগন্যাল দেখুন। - অন্য সব অ্যাপ্লিকেশন ও এনভায়রনমেন্ট: ব্যক্তিগত প্রোফাইলের ভিতর থেকে, ম্যানেজ করা হয় না এমন ডিভাইসে, কাস্টম DPC-এর মাধ্যমে ম্যানেজ করা ডিভাইসে
অথবা
COMPANION_APPভূমিকা ছাড়া ডিভাইসের বিশ্বাসযোগ্যতা সংক্রান্ত সিগন্যাল অ্যাক্সেস করতে হলে, আপনার অ্যাপ্লিকেশনকে অনুমোদিত তালিকায় থাকতে হবে। কীভাবে আবেদন করতে হবে সেই সম্পর্কে তথ্য পেতে, ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস পৃষ্ঠায় যান।
- AMAPI-ম্যানেজ করা ডিভাইসে কম্প্যানিয়ন অ্যাপ: নীতিতে
- Android Enterprise আপনার ক্লায়েন্ট অ্যাপ্লিকেশনে Play Integrity API-এর সুইট ইন্টিগ্রেট করার এবং ডিভাইসের বিশ্বাসযোগ্যতা সংক্রান্ত সিগন্যাল পড়ার ও তার উপর নির্ভর করার আগে ফলাফল রেফার করার সুপারিশ করে। Play Integrity API চেক পাস করতে পারেনি এমন ডিভাইসকে বিশ্বাস করা উচিত নয়, এমনকি বিশ্বাসযোগ্যতা নির্ধারণের জন্য ডিভাইস থেকে প্রাপ্ত কোনও সিগন্যালও ব্যবহার করা উচিত নয়। আরও বিবরণের জন্য আপনি Play Integrity-র ডকুমেন্টেশন দেখতে পারেন।
আপনার অ্যাপ্লিকেশনে AMAPI SDK-এর সাথে ইন্টিগ্রেট করুন
ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস করতে, আপনার অ্যাপ্লিকেশনকে AMAPI SDK-এর সাথে ইন্টিগ্রেট করতে হবে। আপনি এই লাইব্রেরি সম্পর্কে এবং কীভাবে এটি আপনার অ্যাপ্লিকেশনে যোগ করবেন সে সম্পর্কে আরও তথ্য AMAPI SDK ইন্টিগ্রেশন গাইডে পেতে পারেন।
প্রয়োজনীয় অনুমতি যোগ করুন
Device Trust from Android Enterprise API থেকে পাওয়া কয়েকটি সিগন্যালের জন্য অ্যাপকে সেই একই অনুমতি ঘোষণা করতে হয় যা এই তথ্য অ্যাক্সেস করার জন্য প্রথমেই প্রয়োজন হয়, বিশেষ করে:
| সিগন্যাল | প্রয়োজনীয় অনুমতি |
|---|---|
| নেটওয়ার্ক স্ট্যাটাস | ACCESS_NETWORK_STATE |
| স্ক্রিন লক জটিলতা | REQUEST_PASSWORD_COMPLEXITY |
এইসব অনুমতি অ্যাপের AndroidManifest.xml-এ অন্তর্ভুক্ত না থাকলে,
Device Trust from Android Enterprise API সংশ্লিষ্ট সিগন্যালের মেটাডেটাতে
PERMISSION_ISSUE রিটার্ন করবে:
internalDeviceSettings=DeviceSettings{
screenLockComplexity=COMPLEXITY_UNSPECIFIED,
internalScreenLockComplexityMetadata=Metadata{
dataIssues=[
DataIssue{
issueType=PERMISSION_ISSUE,
issueLevel=WARNING,
issueDetails=IssueDetailsCase{none}
}
]
},
আরও তথ্যের জন্য উপলভ্য ডিভাইস ট্রাস্ট সিগন্যাল-এর তালিকা দেখুন।
ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস করার ধাপ
অনুমতি তালিকায় থাকা অ্যাপ্লিকেশনগুলিকে (ব্যক্তিগত প্রোফাইল বা ম্যানেজ করা হয় না এমন ডিভাইসে চলা অ্যাপ সহ) অবশ্যই যাচাই করতে হবে যে ক্লায়েন্ট এনভায়রনমেন্ট আপ-টু-ডেট আছে কিনা এবং সিগন্যালের অনুরোধ করার আগে প্রয়োজন হলে এটি প্রস্তুত করতে হবে।
সাদা তালিকায় থাকা অ্যাপ্লিকেশনগুলির জন্য ডিভাইসের বিশ্বাসযোগ্যতা সংক্রান্ত সিগন্যাল অ্যাক্সেস করার ধাপগুলি হল:
- ক্লায়েন্ট এনভায়রনমেন্ট যাচাই করা
- ক্লায়েন্ট এনভায়রনমেন্ট তৈরি করা
- ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস করা

ক্লায়েন্ট এনভায়রনমেন্ট যাচাই করুন
নিম্নলিখিত কোডের উদাহরণ থেকে বোঝা যায় যে ADP অ্যাপের বর্তমান অবস্থা জানতে কীভাবে getEnvironment ব্যবহার করতে হয়।
আপনার অ্যাপ্লিকেশন তখন ক্যাশে করা deviceClient ইনস্ট্যান্স ব্যবহার করে ডিভাইসের বিশ্বাসযোগ্যতা সংক্রান্ত সিগন্যাল অ্যাক্সেস করতে পারে, যদি এনভায়রনমেন্ট
রেডি ও আপ-টু-ডেট থাকে (ডিভাইসের বিশ্বাসযোগ্যতা সংক্রান্ত সিগন্যাল অ্যাক্সেস করুন দেখুন)।
Kotlin
import com.google.android.managementapi.common.model.Role import com.google.android.managementapi.device.DeviceClient import com.google.android.managementapi.device.DeviceClientFactory import com.google.android.managementapi.device.model.GetDeviceRequest import com.google.android.managementapi.environment.EnvironmentClient import com.google.android.managementapi.environment.EnvironmentClientFactory import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.INSTALLED import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.NOT_INSTALLED import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.READY import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.Version.UP_TO_DATE import com.google.android.managementapi.environment.model.GetEnvironmentRequest import com.google.android.managementapi.environment.model.PrepareEnvironmentRequest try { val context = applicationContext val roles = listOf(Role.builder().setRoleType(Role.RoleType.IDENTITY_PROVIDER).build()) val request = GetEnvironmentRequest.builder().setRoles(roles).build() val environmentClient = EnvironmentClientFactory.create(context) val environmentResponse = environmentClient.getEnvironment(request) if (environmentResponse.hasAndroidDevicePolicyEnvironment()) { val adpEnvironment = environmentResponse.androidDevicePolicyEnvironment if (adpEnvironment.state == READY && adpEnvironment.version == UP_TO_DATE) { // AMAPI Environment State OK, Version OK. Requesting Device signals.. checkDevice(deviceClient) } else if (adpEnvironment.state == INSTALLED) { // prepareEnvironment should be called, calling // prepareEnvironment won't show the UI prepareEnvironment(context, environmentClient) } else if (adpEnvironment.state == NOT_INSTALLED) { // prepareEnvironment should be called, calling // prepareEnvironment will show the UI prepareEnvironment(context, environmentClient) } } } catch (e: Exception) { Log.e(TAG, "Exception", e) }
Java
import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.INSTALLED; import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.NOT_INSTALLED; import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.READY; import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.Version.UP_TO_DATE; import com.google.android.managementapi.common.model.Role; import com.google.android.managementapi.device.DeviceClient; import com.google.android.managementapi.device.DeviceClientFactory; import com.google.android.managementapi.device.model.Device; import com.google.android.managementapi.device.model.GetDeviceRequest; import com.google.android.managementapi.environment.EnvironmentClient; import com.google.android.managementapi.environment.EnvironmentClientFactory; import com.google.android.managementapi.environment.model.Environment; import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment; import com.google.android.managementapi.environment.model.GetEnvironmentRequest; import com.google.android.managementapi.environment.model.PrepareEnvironmentRequest; import com.google.android.managementapi.environment.model.PrepareEnvironmentResponse; try { Context context = getApplicationContext(); ImmutableListroles = new ImmutableList.Builder () .add(Role.builder() .setRoleType(Role.RoleType.IDENTITY_PROVIDER) .build()) .build(); EnvironmentClient environmentClient = EnvironmentClientFactory.create(context); GetEnvironmentRequest request = GetEnvironmentRequest.builder() .setRoles(roles) .build(); ListenableFuture getEnvironmentFuture = environmentClient.getEnvironmentAsync(request); Futures.addCallback(getEnvironmentFuture, new FutureCallback<>() { @Override public void onSuccess(Environment environment) { AndroidDevicePolicyEnvironment adpEnvironment = environment.getAndroidDevicePolicyEnvironment(); AndroidDevicePolicyEnvironment.State state = adpEnvironment.getState(); AndroidDevicePolicyEnvironment.Version version = adpEnvironment.getVersion(); if (state == READY && version == UP_TO_DATE) { // AMAPI Environment State OK, Version OK. Requesting Device signals.. checkDevice(deviceClient); } else if (state == INSTALLED) { // prepareEnvironment should be called, calling // prepareEnvironment won't show the UI prepareEnvironment(context, environmentClient); } else if (state == NOT_INSTALLED) { // prepareEnvironment should be called, calling // prepareEnvironment will show the UI prepareEnvironment(context, environmentClient); } } @Override public void onFailure(Throwable t) { Log.d(TAG, t.toString()); } }, MoreExecutors.directExecutor()); } catch (Exception e) { Log.d(TAG, e.toString()); }
ADP অ্যাপ ইনস্টল করা থাকলেও আপ-টু-ডেট না থাকলে, আপনার অ্যাপ্লিকেশনকে
prepareEnvironment কল করতে হবে যাতে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই ADP অ্যাপ আপডেট করা যায়।
ADP অ্যাপ ইনস্টল করা না থাকলে, আপনার অ্যাপ্লিকেশন prepareEnvironment
কল করতে পারে যাতে ব্যবহারকারীকে ADP অ্যাপ ইনস্টল করার জন্য প্রম্পট করা যায়।
ক্লায়েন্ট এনভায়রনমেন্ট প্রস্তুত করুন দেখুন।
ক্লায়েন্ট এনভায়রনমেন্ট তৈরি করা
ADP অ্যাপ আগে থেকেই ইনস্টল করা থাকলে, API ব্যবহারকারীর হস্তক্ষেপ ছাড়াই এটি আপডেট করবে।
ADP অ্যাপ ইনস্টল করা না থাকলে, API ব্যবহারকারীকে ADP অ্যাপ ইনস্টল করার জন্য অনুমতি দিতে বলবে।
ব্যবহারকারীর পছন্দ মনিটর করার জন্য কলব্যাক রেজিস্টার করা সম্ভব। আরও তথ্যের জন্য ADP অ্যাপ ইনস্টল করার সময় ব্যবহারকারীর ইন্টার্যাকশন ট্র্যাক করা দেখুন।
আমরা সাজেস্ট করি যে prepareEnvironment কলটি যেন ফোরগ্রাউন্ড প্রসেস থেকে করা হয়, অনবোর্ডিং UX ফ্লো চলাকালীন যাতে ব্যবহারকারী Android Device Policy ইনস্টল করুন
মডেল ডায়ালগ দেখে অবাক না হয়ে যান।
ফোরগ্রাউন্ড প্রসেস থেকে কল করা সম্ভব না হলে, কারণ এটি একটি ওয়েব ফ্লো
এবং Android কম্পোনেন্টে কোনও UI নেই, ব্যাকগ্রাউন্ড থেকে কল করার অনুমতি দেওয়া হয়
প্রয়োজনীয়তা যে এটি অনবোর্ডিং UX ফ্লো চলাকালীন ঘটে।
পরিবেশ সঠিকভাবে সেট-আপ করা হয়ে গেলে, ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস করা সম্ভব। ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস করুন দেখুন।
Kotlin
try { val myNotificationReceiverService = ComponentName( context, MyNotificationReceiverService::class.java ) val roles = listOf(Role.builder().setRoleType(Role.RoleType.IDENTITY_PROVIDER).build()) val request = PrepareEnvironmentRequest.builder().setRoles(roles).build() val response = environmentClient.prepareEnvironment(request, myNotificationReceiverService) val environment = response.environment val adpEnvironment = environment.androidDevicePolicyEnvironment val state = adpEnvironment.state val version = adpEnvironment.version if (state == READY && version == UP_TO_DATE) { // Environment is prepared, access device posture signals using // DeviceClient. checkDevice(deviceClient) } else { // The prepareEnvironment call failed to prepare Log.w( TAG, "AMAPI environment was not ready: " + state + " - " + version ) } } catch (e: java.lang.Exception) { Log.d(TAG, e.toString()) }
Java
try { ComponentName myNotificationReceiverService = new ComponentName( context, MyNotificationReceiverService.class ); ImmutableListroles = new ImmutableList.Builder () .add(Role.builder() .setRoleType(Role.RoleType.IDENTITY_PROVIDER) .build()) .build(); PrepareEnvironmentRequest request = PrepareEnvironmentRequest.builder() .setRoles(roles) .build(); ListenableFuture environmentFuture = environmentClient.prepareEnvironmentAsync( request, myNotificationReceiverService ); Futures.addCallback(environmentFuture, new FutureCallback<>() { @Override public void onSuccess(PrepareEnvironmentResponse response) { Environment environment = response.getEnvironment(); AndroidDevicePolicyEnvironment adpEnvironment = environment.getAndroidDevicePolicyEnvironment(); AndroidDevicePolicyEnvironment.State state = adpEnvironment.getState(); AndroidDevicePolicyEnvironment.Version version = adpEnvironment.getVersion(); if (state == READY && version == UP_TO_DATE) { // AMAPI Environment State OK, Version OK. Requesting Device signals.. checkDevice(deviceClient); } else { // The prepareEnvironment call failed to prepare Log.w( TAG, "AMAPI environment was not ready: " + adpEnvironment.getState() + " - " + adpEnvironment.getVersion() ); } } @Override public void onFailure(@NonNull Throwable t) { // Handle the error Log.d(TAG, "AMAPI response did not contain an ADP environment"); } }, MoreExecutors.directExecutor()); } catch (Exception e) { Log.d(TAG, e.toString()); }
ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস করুন
DeviceClient ব্যবহারের সাজেশন
deviceClient ইনস্ট্যান্স (বা EnvironmentClient ইনস্ট্যান্স) তৈরি করলে
Android Device Policy (ADP) অ্যাপের সাথে একটি কমিউনিকেশন চ্যানেল তৈরি হয়
যা আইডল থাকলে অটোমেটিক আনবাইন্ড হয়ে যায়। Because client instances don't expose an
explicit shutdown method, creating and discarding multiple instances leaves
orphaned channels to be garbage-collected.
পারফর্ম্যান্স অপ্টিমাইজ করতে এবং অনাথ চ্যানেল এড়াতে,
DeviceClientFactory.create(context.applicationContext) ব্যবহার করে অ্যাপ্লিকেশন স্কোপে
DeviceClient-এর একটি একক ইনস্ট্যান্স তৈরি করুন এবং আপনার অ্যাপ্লিকেশন জুড়ে পুনরায় ব্যবহারের জন্য এটি ক্যাশে করুন—উদাহরণস্বরূপ, একটি অ্যাপ্লিকেশন-স্কোপড সিঙ্গলটন হিসাবে বা
ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করে।
আপনি যে ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস করতে চান, Device অবজেক্টের অনুরোধ করতে আপনার ক্যাশে করা
deviceClient ইনস্ট্যান্স ব্যবহার করুন:
Kotlin
runCatching { deviceClient.getDeviceAwait(GetDeviceRequest.getDefaultInstance()) }.onFailure { t -> Log.d(TAG, t.toString()) }.onSuccess { device -> // Access device posture signals available in device val deviceString = device.toString() Log.d(TAG, deviceString) }
Java
ListenableFuturedeviceFuture = deviceClient.getDevice(GetDeviceRequest.getDefaultInstance()); Futures.addCallback(deviceFuture, new FutureCallback () { @Override public void onSuccess(Device device) { // Access device posture signals available in device String deviceString = device.toString(); Log.d(TAG, deviceString); } @Override public void onFailure(Throwable t) { Log.d(TAG, t.toString()); } }, MoreExecutors.directExecutor());
কম্প্যানিয়ন অ্যাপ থেকে সিগন্যাল অ্যাক্সেস করুন
সম্পূর্ণভাবে ম্যানেজ করা ডিভাইসে অথবা Android Management API (AMAPI) দিয়ে ম্যানেজ করা অফিস প্রোফাইলের মধ্যে থেকে,
COMPANION_APP ভূমিকা অ্যাসাইন করা কোনও অ্যাপ্লিকেশন,
সাদা তালিকায় রেজিস্টার না করেই ডিভাইসের বিশ্বাসযোগ্যতা সংক্রান্ত সিগন্যাল পড়তে পারে।
অফিস প্রোফাইলের (কোম্পানির মালিকানাধীন বা ব্যক্তিগত মালিকানাধীন ডিভাইস) মধ্যে থেকে কল করা হলে, আপনার অ্যাপটি অবশ্যই অফিস প্রোফাইলের মধ্যে চালাতে হবে এবং অ্যাক্সেস অফিস প্রোফাইল থেকে সিগন্যালে সীমাবদ্ধ (যেমন, ম্যানেজমেন্ট স্টেট, স্ক্রিন লক জটিলতা এবং ইনস্টল করা অ্যাপ্লিকেশনগুলি শুধুমাত্র অফিস প্রোফাইলকে প্রতিফলিত করে)।
১. নীতিতে COMPANION_APP ভূমিকা অ্যাসাইন করুন
applications নীতি তালিকায় আপনার অ্যাপ্লিকেশনকে roleType: "COMPANION_APP"-এর অনুমতি দিতে
আপনার EMM নীতি কনফিগার করুন:
- আপনার অ্যাপের ম্যানিফেস্ট কনফিগার করতে এবং ঐচ্ছিকভাবে ভূমিকা অ্যাসাইনমেন্ট শুনতে, অ্যাপ্লিকেশন ভূমিকা ম্যানেজ করুন দেখুন।
- নীতি কনফিগারেশন সিনট্যাক্সের জন্য, নীতি কনফিগারেশন দেখুন।
২. DeviceClient-এর মাধ্যমে সরাসরি সিগন্যাল পড়ুন
DeviceClientFactory.create (
DeviceClient ব্যবহারের সাজেশন দেখুন) ব্যবহার করে অ্যাপ্লিকেশন স্কোপে একটি deviceClient ইনস্ট্যান্স তৈরি ও ক্যাশে করুন, তারপর
সরাসরি Device অবজেক্টের অনুরোধ করুন:
Kotlin
import android.content.Context import android.util.Log import com.google.android.managementapi.device.DeviceClient import com.google.android.managementapi.device.DeviceClientFactory import com.google.android.managementapi.device.model.GetDeviceRequest // Instantiate once at application scope (for example, using dependency injection) // to reuse a single DeviceClient instance across your app. class DeviceTrustRepository(context: Context) { private val deviceClient: DeviceClient = DeviceClientFactory.create(context.applicationContext) suspend fun readSignalsFromCompanionApp() { runCatching { deviceClient.getDeviceAwait(GetDeviceRequest.getDefaultInstance()) }.onSuccess { device -> Log.d(TAG, "Device signals: $device") }.onFailure { t -> Log.e(TAG, "Failed to read device signals", t) } } companion object { private const val TAG = "DeviceTrustRepository" } }
Java
import android.content.Context; import android.util.Log; import com.google.android.managementapi.device.DeviceClient; import com.google.android.managementapi.device.DeviceClientFactory; import com.google.android.managementapi.device.model.Device; import com.google.android.managementapi.device.model.GetDeviceRequest; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; // Instantiate once at application scope (for example, using dependency injection) // to reuse a single DeviceClient instance across your app. public class DeviceTrustRepository { private static final String TAG = "DeviceTrustRepository"; private final DeviceClient deviceClient; public DeviceTrustRepository(Context context) { this.deviceClient = DeviceClientFactory.create(context.getApplicationContext()); } public void readSignalsFromCompanionApp() { ListenableFuturedeviceFuture = deviceClient.getDevice(GetDeviceRequest.getDefaultInstance()); Futures.addCallback(deviceFuture, new FutureCallback () { @Override public void onSuccess(Device device) { Log.d(TAG, "Device signals: " + device); } @Override public void onFailure(Throwable t) { Log.e(TAG, "Failed to read device signals", t); } }, MoreExecutors.directExecutor()); } }
সমস্যা ম্যানেজ করা
আপনার অ্যাপ ডিভাইস ট্রাস্টের অনুরোধ করলে এবং কলটি ব্যর্থ হলে, আপনার অ্যাপ একটি ব্যতিক্রম পায়। এই ব্যতিক্রমগুলি বিভিন্ন কারণে ঘটতে পারে, যেমন:
SecurityException- আপনার অ্যাপের কাছে অনুরোধ করার অনুমতি নেই (যেমন, প্রয়োজন হলেও আপনার অ্যাপ অনুমোদিত তালিকায় রেজিস্টার করা নেই, AMAPI-ম্যানেজ করা ডিভাইসেCOMPANION_APPভূমিকা অ্যাসাইন করা নেই অথবা কম্প্যানিয়ন অ্যাপ হিসেবেprepareEnvironment-কে কল করা হয়েছে যা অনুমোদিত তালিকায় নেই)। ডিভাইস ট্রাস্ট সিগন্যাল অ্যাক্সেস এবং কম্প্যানিয়ন অ্যাপ থেকে সিগন্যাল অ্যাক্সেস করুন দেখুন।AmapiSdkException- ADP-এর সাবক্লাস নেই বা রেডি নেই। এটি কোনও ক্ষণস্থায়ী অবস্থার কারণে হতে পারে এবং আপনাকে আবার কল করার চেষ্টা করতে হবে।
স্ট্র্যাটেজি আবার চেষ্টা করুন
ট্রানজিয়েন্ট কন্ডিশনের কারণে হওয়া ব্যতিক্রমের জন্য, এক্সপোনেনশিয়াল ব্যাকঅফ সহ আবার চেষ্টা করার স্ট্র্যাটেজি প্রয়োগ করুন। প্রথমবার ব্যর্থ হওয়ার পরে, আবার চেষ্টা করার আগে ৫ সেকেন্ডের প্রাথমিক বিলম্বের সাথে শুরু করুন।
প্রতিবার এক্সপোনেনশিয়ালি বর্ধিত বিলম্ব (১০ সেকেন্ড, ২০ সেকেন্ড ইত্যাদি) ব্যবহার করে এক্সিট কন্ডিশন হিসেবে সর্বাধিক সংখ্যক প্রচেষ্টার সাথে একটি পুনরায় চেষ্টা করার কৌশল প্রয়োগ করুন।
ADP অ্যাপ ইনস্টল করার সময় ব্যবহারকারীর ইন্টার্যাকশন ট্র্যাক করা
prepareEnvironment চলাকালীন ডিভাইসে ADP অ্যাপ ইনস্টল করার প্রয়োজন হলে,
আপনার অ্যাপ্লিকেশন NotificationReceiverService প্রয়োগ করে ব্যবহারকারীর ইন্টার্যাকশন ট্র্যাক করতে পারে,
যাতে getPrepareEnvironmentListener ওভাররাইড করে বিজ্ঞপ্তি পাওয়া যায়:
Kotlin
import android.util.Log import com.google.android.managementapi.environment.EnvironmentListener import com.google.android.managementapi.environment.model.EnvironmentEvent.EventCase.Kind.ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED import com.google.android.managementapi.environment.model.EnvironmentEvent import com.google.android.managementapi.notification.NotificationReceiverService class MyNotificationReceiverService : NotificationReceiverService() { override fun getPrepareEnvironmentListener(): EnvironmentListener { return MyEnvironmentListener() } } class MyEnvironmentListener : EnvironmentListener { override fun onEnvironmentEvent( event: EnvironmentEvent ) { if (event.event.kind == ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED) { Log.d(TAG, "User provided install consent") } else { Log.d(TAG, "User rejected install consent") } } companion object { private val TAG: String = MyEnvironmentListener::class.java.simpleName } }
Java
import static com.google.android.managementapi.environment.model.EnvironmentEvent.EventCase.Kind.ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED; import android.util.Log; import androidx.annotation.NonNull; import com.google.android.managementapi.environment.EnvironmentListener; import com.google.android.managementapi.environment.model.EnvironmentEvent; import com.google.android.managementapi.notification.NotificationReceiverService; class MyNotificationReceiverService extends NotificationReceiverService { @NonNull @Override protected EnvironmentListener getPrepareEnvironmentListener() { return new MyEnvironmentListener(); } } class MyEnvironmentListener implements EnvironmentListener { final private String TAG = MyEnvironmentListener.class.getSimpleName(); @Override public void onEnvironmentEvent(EnvironmentEvent event) { if (event.getEvent().getKind() == ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED) { Log.d(TAG, "User provided install consent"); } else { Log.d(TAG, "User rejected install consent"); } } }
পরিচিত সমস্যা
এই মুহূর্তে কোনও সমস্যা নেই।