একটি অ্যান্ড্রয়েড ম্যানেজমেন্ট API ভিত্তিক EMM হিসাবে, আপনি দূরবর্তীভাবে ডিভাইসগুলিতে কাস্টম অ্যাপ্লিকেশনগুলি পরিচালনা করতে পারেন। এর মধ্যে এই অ্যাপগুলি ইনস্টল এবং আনইনস্টল করা উভয়ই অন্তর্ভুক্ত। AMAPI SDK ব্যবহার করে স্থানীয়ভাবে একটি এক্সটেনশন অ্যাপ তৈরি করে এই কার্যকারিতা অর্জন করা হয়।
পূর্বশর্ত
- আপনার এক্সটেনশন অ্যাপটি AMAPI SDK-এর সাথে একত্রিত।
- ডিভাইসটি সম্পূর্ণরূপে পরিচালিত হয়।
- AMAPI SDK v1.6.0-rc01 বা উচ্চতর প্রয়োজন৷
1. বৈশিষ্ট্যটি ব্যবহার করার জন্য আপনার অ্যাপ প্রস্তুত করুন৷
1.1। আপনার এক্সটেনশন অ্যাপে AMAPI SDK-এর সাথে একীভূত করুন
কাস্টম অ্যাপ পরিচালনা প্রক্রিয়ার জন্য আপনাকে আপনার এক্সটেনশন অ্যাপে AMAPI SDK সংহত করতে হবে। আপনি AMAPI SDK ইন্টিগ্রেশন গাইডে এই লাইব্রেরি এবং কীভাবে এটি আপনার অ্যাপে যুক্ত করবেন সে সম্পর্কে আরও তথ্য পেতে পারেন।
1.2। FileProvider
সমর্থন করতে আপনার অ্যাপের ম্যানিফেস্ট আপডেট করুন
- AMAPI SDK ইন্টিগ্রেশন গাইডে দেখানো হিসাবে Android ডিভাইস নীতি (ADP) অ্যাপ্লিকেশনের জন্য আপনার
AndroidManifest.xml
এ<queries>
উপাদান যোগ করুন। -
<application>
ট্যাগের ভিতরে আপনার অ্যাপেরAndroidManifest.xml
এ নিম্নলিখিত<provider>
স্নিপেটটি প্রয়োগ করুন। এই স্নিপেটটি কাস্টম অ্যাপ APK শেয়ার করার সময় ফাইল সংরক্ষণ করতে ব্যবহার করা হয়, AMAPI ব্যবহার করে কাস্টম অ্যাপের ইনস্টলেশন সক্ষম করে।
AndroidManifest.xml
:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.customapp">
<queries>
<package android:name="com.google.android.apps.work.clouddpc" />
</queries>
<application>
<!--This is used to store files when sharing the custom app apk.-->
<provider
android:name="com.google.android.managementapi.customapp.provider.CustomAppProvider"
android:authorities="${applicationId}.AmapiCustomAppProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
</application>
</manifest>
- কাস্টম apks-এর জন্য স্টোরেজ পাথ ধারণকারী আপনার অ্যাপের
res/xml/
ডিরেক্টরিতে একটি নতুন XML ফাইল তৈরি করুন।
file_provider_paths.xml
:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path
name="android_managementapi_custom_apks"
path="com.google.android.managementapi/customapp/apks/" />
</paths>
2. AMAPI SDK-এর কাস্টম অ্যাপ বৈশিষ্ট্যের সাথে একীভূত করুন
2.1। ইনস্টলেশনের জন্য কাস্টম APK ফাইল প্রস্তুত করুন
স্থাপন করার আগে, অ্যাপ্লিকেশনটির APK ফাইলটি ইনস্টলেশনের জন্য প্রস্তুত থাকতে হবে। নিম্নলিখিত কোড স্নিপেট প্রক্রিয়াটি প্রদর্শন করে:
কোটলিন
import android.net.Uri import androidx.core.net.Uri import java.io.File ... import com.google.android.managementapi.commands.LocalCommandClient import com.google.android.managementapi.commands.LocalCommandClient.InstallCustomAppCommandHelper import com.google.android.managementapi.commands.LocalCommandClientFactory ... fun prepareApkFile(): Uri? { // Get the storage location of custom APK files from AM API val client: LocalCommandClient = LocalCommandClientFactory.create(context) val installCustomAppCommandHelper = client.installCustomAppCommandHelper val customApksStorageDir: File = installCustomAppCommandHelper.customApksStorageDirectory ?: return null // Once you get hold of the custom APKs storage directory, you must store your custom APK // in that location before issuing the install command. val customApkFile: File = fetchMyAppToDir(customApksStorageDir) ?: return null val customApkFileUri: Uri = customApkFile.toUri() return customApkFileUri }
জাভা
import android.net.Uri; import androidx.core.net.Uri; import java.io.File; ... import com.google.android.managementapi.commands.LocalCommandClient; import com.google.android.managementapi.commands.LocalCommandClient.InstallCustomAppCommandHelper; import com.google.android.managementapi.commands.LocalCommandClientFactory; ... Uri prepareApkFile() { // Get the storage location of custom APK files from AM API LocalCommandClient client = LocalCommandClientFactory.create(); InstallCustomAppCommandHelper installCustomAppCommandHelper = client.getInstallCustomAppCommandHelper(); File customApksStorageDir = installCustomAppCommandHelper.getCustomApksStorageDirectory(); // Once you get hold of the custom APKs storage directory, you must store your custom APK // in that location before issuing the install command. File customApkFile = fetchMyAppToDir(customApksStorageDir); Uri customApkFileUri = Uri.fromFile(customApkFile); ... }
2.2। একটি কাস্টম অ্যাপ ইনস্টল করার জন্য একটি অনুরোধ জারি করুন৷
নিম্নলিখিত স্নিপেটটি দেখায় কিভাবে একটি কাস্টম অ্যাপ ইনস্টল করার জন্য একটি অনুরোধ জারি করতে হয়:
কোটলিন
import android.content.Context import android.net.Uri import android.util.Log import com.google.android.managementapi.commands.LocalCommandClientFactory import com.google.android.managementapi.commands.model.Command import com.google.android.managementapi.commands.model.IssueCommandRequest import com.google.android.managementapi.commands.model.IssueCommandRequest.InstallCustomApp import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.guava.await import kotlinx.coroutines.withContext import java.lang.Exception private const val TAG = "MyClass" ... // Requires a file URI of the APK file. fun issueInstallCustomAppCommand(packageName: String, fileUri: Uri) { coroutineScope.launch { try { withContext(coroutineScope.coroutineContext) { val result: Command = LocalCommandClientFactory.create(context) .issueCommand(createInstallCustomAppRequest(packageName, fileUri)).await() // Process the returned command result here. Log.i(TAG, "Successfully issued command: $result") } } catch (t: Exception) { Log.e(TAG, "Failed to issue command", t) // Handle the exception (e.g., show an error message) } finally { // Make sure to clean up the apk file after the command is executed. cleanUpApkFile(fileUri) } } } private fun createInstallCustomAppRequest(packageName: String, fileUri: Uri): IssueCommandRequest { return IssueCommandRequest.builder() .setInstallCustomApp( InstallCustomApp.builder() .setPackageName(packageName) .setPackageUri(fileUri.toString()) .build() ) .build() } }
জাভা
import android.util.Log; ... import com.google.android.managementapi.commands.LocalCommandClientFactory; import com.google.android.managementapi.commands.model.Command; import com.google.android.managementapi.commands.model.GetCommandRequest; import com.google.android.managementapi.commands.model.IssueCommandRequest; import com.google.android.managementapi.commands.model.IssueCommandRequest.ClearAppsData; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.MoreExecutors; ... // Requires a file URI of the APK file. void issueInstallCustomAppCommand(String packageName, Uri fileUri) { Futures.addCallback( LocalCommandClientFactory.create(getContext()) .issueCommand(createInstallCustomAppRequest(packageName, fileUri)), new FutureCallback() { @Override public void onSuccess(Command result) { // Process the returned command result here. Log.i(TAG, "Successfully issued command"); } @Override public void onFailure(Throwable t) { Log.e(TAG, "Failed to issue command", t); } }, MoreExecutors.directExecutor()); } IssueCommandRequest createInstallCustomAppRequest(String packageName, Uri fileUri) { return IssueCommandRequest.builder() .setInstallCustomApp( InstallCustomApp.builder() .setPackageName(packageName) .setPackageUri(fileUri.toString()) .build() ) .build(); }
2.3। ইনস্টল করা অ্যাপ পেতে একটি অনুরোধ জারি করুন
কোটলিন
import android.content.Context import com.google.android.managementapi.device.DeviceClientFactory import com.google.android.managementapi.device.model.GetDeviceRequest import kotlinx.coroutines.guava.await suspend fun getInstalledApps(context: Context) = DeviceClientFactory.create(context) .getDevice(GetDeviceRequest.getDefaultInstance()) .await() .getApplicationReports()
জাভা
import android.content.Context; import com.google.android.managementapi.device.DeviceClientFactory; import com.google.android.managementapi.device.model.GetDeviceRequest; import com.google.android.managementapi.device.model.Device; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import java.util.List; import java.util.concurrent.Executor; public ListenableFuture<List> getInstalledApps() { ListenableFuture deviceFuture = DeviceClientFactory.create(context) .getDevice(GetDeviceRequest.getDefaultInstance()); return Futures.transform( deviceFuture, Device::getApplicationReports, executor // Use the provided executor ); }
3. কাস্টম অ্যাপস ম্যানেজমেন্ট নীতি সহ ডিভাইসের ব্যবস্থা করুন
আপনি পরিচালনা করতে চান এমন কাস্টম অ্যাপগুলির সাথে একটি
policy
সেট আপ করুন৷{ "statusReportingSettings": { "applicationReportsEnabled": true }, "applications": [ { "signingKeyCerts": [ { "signingKeyCertFingerprintSha256": <sha256 signing key certificate hash value> } ], "packageName": "<emm_extensibility_app>", "installType": "AVAILABLE", "lockTaskAllowed": true, "defaultPermissionPolicy": "GRANT", "extensionConfig": { "notificationReceiver": "com.example.customapp.NotificationReceiverService" } }, { "signingKeyCerts": [ { "signingKeyCertFingerprintSha256": <sha256 signing key certificate hash value> }, ], "packageName": "<custom_app>", "installType": "CUSTOM", "lockTaskAllowed": true, "defaultPermissionPolicy": "GRANT", "customAppConfig": { "userUninstallSettings": "DISALLOW_UNINSTALL_BY_USER" } } ] } ```
enterprises.enrollmentTokens.create কল করে ডিভাইসের জন্য একটি নথিভুক্তি টোকেন তৈরি করুন,
PERSONAL_USAGE_DISALLOWED
এ সেট করাallowPersonalUsage
এর সাথে।তালিকাভুক্তি টোকেন সহ সম্পূর্ণরূপে পরিচালিত মোডে ডিভাইসের ব্যবস্থা করুন ।
পরিচালিত প্লে থেকে আপনার এক্সটেনসিবিলিটি অ্যাপ ইনস্টল করুন।
আপনার এক্সটেনসিবিলিটি অ্যাপ:
- কাস্টম অ্যাপের APK ফাইল ডাউনলোড করতে পারেন
- কাস্টম অ্যাপ ইনস্টল করার জন্য একটি অনুরোধ জারি করতে পারে (আগে দেখানো কোড স্নিপেট পড়ুন)
- একটি প্রতিক্রিয়া পাওয়া উচিত
API
সার্ভার-ক্লায়েন্ট API
তালিকাভুক্ত নতুন ক্ষেত্র এবং enums পড়ুন: