Android Management API (AMAPI) SDK'sı, EMM tarafından belirtilen bir uzantı uygulamasının doğrudan Android Device Policy (ADP) ile iletişim kurmasına ve cihazda Commands yürütmesine olanak tanır.
AMAPI SDK'sı ile entegrasyon bölümünde bu kitaplık ve uygulamanıza nasıl ekleneceği hakkında daha fazla bilgi verilmektedir.
SDK entegre edildikten sonra uzantı uygulamanız ADP ile iletişim kurarak şunları yapabilir:
Komut verme
Uzantı uygulaması, ADP kullanılarak komutların verilmesini isteyebilir.
IssueCommandRequest, verilecek komut ve belirli parametrelerle ilgili ayrıntıları içeren istek nesnesini içerir.
Uygulama verilerini temizleme
Aşağıdaki snippet'te, paketin verilerini temizleme isteğinin nasıl gönderileceği gösterilmektedir:
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;
...
void issueClearAppDataCommand(ImmutableList<String> packageNames) {
Futures.addCallback(
LocalCommandClientFactory.create(getContext())
.issueCommand(createClearAppRequest(packageNames)),
new FutureCallback<Command>() {
@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 createClearAppRequest(ImmutableList<String> packageNames) {
return IssueCommandRequest.builder()
.setClearAppsData(
ClearAppsData.builder()
.setPackageNames(packageNames)
.build()
)
.build();
}
...
Önceki örnekte, belirtilen paketler için uygulama verilerini temizleme isteğinin nasıl gönderildiği ve komutun başarıyla gönderilmesinin nasıl beklendiği gösterilmektedir. Başarıyla verilirse geçerli komut durumunu ve daha sonra uzun süre çalışan komutların durumunu sorgulamak için kullanılabilecek komut kimliğini içeren bir Command nesnesi döndürülür.
Cihazı veya iş profilini silme
BT yöneticisi, LOCAL_DEVICE_WIPE_COMMAND_ALLOWED ek özelliğiyle COMPANION_APP rolünü atadığında tamamlayıcı uygulama yerel bir Wipe komutu verebilir. Şirkete ait cihazlarda bu işlem, cihazı fabrika ayarlarına sıfırlar. İş profili olan kişisel cihazlarda ise iş profilini kaldırır. Uygulama bu role ve ek özelliğe sahip değilse istek başarısız olur. Ayrıntılı bilgi için Politika Yapılandırması başlıklı makaleyi inceleyin.
Her iki Wipe parametresi de isteğe bağlıdır. Bir değer belirtmek istemiyorsanız oluşturucu ayarlayıcıyı atlayın veya boş bir koleksiyon ya da boş bir dize iletin (null değerini iletmeyin).
WipeDataFlagdeğerleri, hangi verilerin silineceğini kontrol eder:PRESERVE_RESET_PROTECTION_DATA: Varsayılan olarak silinen fabrika ayarlarına sıfırlama koruması verilerini saklar. Yalnızca şirkete ait cihazlar için geçerlidir.WIPE_EXTERNAL_STORAGE: SD kartlar gibi harici depolama alanlarını da siler. Yalnızca şirkete ait cihazlar için geçerlidir.WIPE_ESIMS: Şirkete ait cihazlardan tüm eSIM'leri kaldırır. Kişisel cihazlarda yalnızca yönetilen eSIM'leri kaldırır (Android 16 veya sonraki sürümlerde, bu işaretin ayarlanıp ayarlanmadığına bakılmaksızın yönetilen eSIM'ler her zaman iş profiliyle birlikte kaldırılır).
wipeReason: İş profili kişisel bir cihazdan kaldırıldığında kullanıcıya gösterilen, en fazla 200 karakterlik kısa bir mesaj. Şirkete ait cihazları etkilemez.
Aşağıdaki snippet'te, cihazı veya iş profilini silme isteğinin nasıl gönderileceği gösterilmektedir:
Kotlin
import android.content.Context
import android.util.Log
...
import com.google.android.managementapi.commands.CommandException
import com.google.android.managementapi.commands.LocalCommandClientFactory
import com.google.android.managementapi.commands.model.IssueCommandRequest
import com.google.android.managementapi.commands.model.IssueCommandRequest.Wipe
import com.google.android.managementapi.commands.model.IssueCommandRequest.Wipe.WipeDataFlag
...
suspend fun issueWipeCommand(
context: Context,
wipeDataFlags: List<WipeDataFlag>,
wipeReason: String,
) {
try {
val command =
LocalCommandClientFactory.create(context)
.issueCommandAwait(createWipeRequest(wipeDataFlags, wipeReason))
Log.i(TAG, "Successfully issued wipe command: ${command.commandId}")
} catch (e: CommandException) {
Log.e(TAG, "Failed to issue wipe command", e)
}
}
fun createWipeRequest(
wipeDataFlags: List<WipeDataFlag>,
wipeReason: String,
): IssueCommandRequest =
IssueCommandRequest.builder()
.setWipe(
Wipe.builder()
.setWipeDataFlags(wipeDataFlags)
.setWipeReason(wipeReason)
.build()
)
.build()
...
Java
import android.content.Context;
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.Wipe;
import com.google.android.managementapi.commands.model.IssueCommandRequest.Wipe.WipeDataFlag;
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;
...
void issueWipeCommand(
Context context,
ImmutableList<WipeDataFlag> wipeDataFlags,
String wipeReason) {
Futures.addCallback(
LocalCommandClientFactory.create(context)
.issueCommand(createWipeRequest(wipeDataFlags, wipeReason)),
new FutureCallback<Command>() {
@Override
public void onSuccess(Command result) {
Log.i(TAG, "Successfully issued wipe command: " + result.getCommandId());
}
@Override
public void onFailure(Throwable t) {
Log.e(TAG, "Failed to issue wipe command", t);
}
},
MoreExecutors.directExecutor());
}
IssueCommandRequest createWipeRequest(
ImmutableList<WipeDataFlag> wipeDataFlags, String wipeReason) {
return IssueCommandRequest.builder()
.setWipe(
Wipe.builder()
.setWipeDataFlags(wipeDataFlags)
.setWipeReason(wipeReason)
.build())
.build();
}
...
Komutu Al
Uzantı uygulaması, daha önce gönderilen komut isteklerinin durumunu sorgulayabilir. Bir komutun durumunu almak için komut kimliğine ihtiyacınız vardır (komut verme isteğinden edinilebilir). Aşağıdaki snippet'te, ADP'ye nasıl GetCommandRequest gönderileceği gösterilmektedir.
import android.util.Log;
...
import com.google.android.managementapi.commands.LocalCommandClientFactory;
...
import com.google.android.managementapi.commands.model.GetCommandRequest;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
...
void getCommand(String commandId) {
Futures.addCallback(
LocalCommandClientFactory.create(getApplication())
.getCommand(GetCommandRequest.builder().setCommandId(commandId).build()),
new FutureCallback<Command>() {
@Override
public void onSuccess(Command result) {
// Process the returned command result here
Log.i(Constants.TAG, "Successfully issued command");
}
@Override
public void onFailure(Throwable t) {
Log.e(Constants.TAG, "Failed to issue command", t);
}
},
MoreExecutors.directExecutor());
}
...
Komut durumu değişikliği geri çağırmalarını dinleme
Uzantı uygulaması, aşağıdaki adımları uygulayarak uzun süre çalışan komutların durum değişiklikleriyle ilgili güncellemeleri almak için isteğe bağlı olarak bir geri çağırma kaydedebilir:
- Komut durumu değişiklikleri
CommandListener'ye bildirilir. Bu arayüzü uygulamanızda uygulayın ve alınan durum güncellemelerinin nasıl işleneceğine dair uygulama sağlayın. NotificationReceiverServicesınıfını genişletin vegetCommandListeneryöntemiyle birCommandListenerörneği sağlayın.Uygulamanıza
COMPANION_APProlünü atamak için uygulama politikasını yapılandırın (Politika Yapılandırması bölümüne bakın).import com.google.android.managementapi.commands.CommandListener; import com.google.android.managementapi.notification.NotificationReceiverService; ... public class SampleCommandService extends NotificationReceiverService { @Override public CommandListener getCommandListener() { // return the concrete implementation from previous step return ...; } }
Politika Yapılandırması
Tamamlayıcı uygulamanın ADP ile doğrudan iletişim kurmasını sağlamak için EMM'nin, uygulama politikasındaki roles alanını kullanarak uygulamaya COMPANION_APP rolünü ataması gerekir:
"applications": [{
"packageName": "com.amapi.extensibility.demo",
"installType": "FORCE_INSTALLED",
"roles": [
{ "roleType": "COMPANION_APP" }
]
}]
Tamamlayıcı uygulamanın yerel bir Wipe komutu vermesine izin vermek için extraCapabilities.localDeviceWipeCommand değerini LOCAL_DEVICE_WIPE_COMMAND_ALLOWED olarak ayarlayın:
"applications": [{
"packageName": "com.amapi.extensibility.demo",
"installType": "FORCE_INSTALLED",
"roles": [
{
"roleType": "COMPANION_APP",
"extraCapabilities": {
"localDeviceWipeCommand": "LOCAL_DEVICE_WIPE_COMMAND_ALLOWED"
}
}
]
}]
Kullanabileceğiniz diğer seçenekler için Uygulama rolü politikalarıyla cihazın temel hazırlığını yapma başlıklı makaleyi inceleyin.
Komut durumu değişikliklerini dinleyen hizmet, ADP tarafından uygulamanın manifest dosyasındaki meta veriler kullanılarak otomatik olarak bulunur ve artık politikada notificationReceiver olarak belirtilmesi gerekmez. Uygulamanızı ve manifestinizi nasıl hazırlayacağınızla ilgili ayrıntılar için Uygulama rollerini yönetme başlıklı makaleyi inceleyin.
Test
Birim testi
LocalCommandClient bir arayüzdür ve bu nedenle test edilebilir bir uygulama sunulmasına olanak tanır.
Entegrasyon testi
ADP ile test yapmak için aşağıdaki bilgilere ihtiyacınız olacaktır:
- Uzantı uygulamasının paket adı.
- Uygulama paketiyle ilişkili imzanın Base64 kodlu SHA-256 karması.
- İsteğe bağlı olarak, geri çağırma test ediliyorsa geri çağırmayı desteklemek için yeni eklenen hizmetten hizmetin tam adı. (Örnekte
CommandService'nin tam adı).