Este manual ajuda desenvolvedores e integradores de sistemas a aprimorar seus conhecimentos do Google Cloud. Siga nossas instruções e encontre soluções para dispositivos dedicados o comportamento dos modelos. Este manual funciona melhor para desenvolvedores que já têm uma experiência dedicada dispositivo do Google. se estiver começando, leia o artigo Dispositivos dedicados geral do Google.
Apps de casa personalizada
Estas receitas são úteis se você estiver desenvolvendo um app para substituir o Android Home. tela e acesso rápido.
Seja o app de início
É possível definir seu app como o app inicial do dispositivo para que ele seja iniciado. automaticamente quando o dispositivo é ligado. Você também pode ativar o botão "Início" que coloca seu app da lista de permissões em primeiro plano. modo de tarefa.
Todos os apps de casa processam a categoria de intent CATEGORY_HOME
. Essa
é como o sistema reconhece um app de início. Para se tornar o app de início padrão, defina um
das atividades do seu app como o gerenciador preferencial de intent da página inicial, chamando
DevicePolicyManager.addPersistentPreferredActivity()
conforme mostrado neste exemplo:
Kotlin
// Create an intent filter to specify the Home category. val filter = IntentFilter(Intent.ACTION_MAIN) filter.addCategory(Intent.CATEGORY_HOME) filter.addCategory(Intent.CATEGORY_DEFAULT) // Set the activity as the preferred option for the device. val activity = ComponentName(context, KioskModeActivity::class.java) val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager dpm.addPersistentPreferredActivity(adminName, filter, activity)
Java
// Create an intent filter to specify the Home category. IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); filter.addCategory(Intent.CATEGORY_HOME); filter.addCategory(Intent.CATEGORY_DEFAULT); // Set the activity as the preferred option for the device. ComponentName activity = new ComponentName(context, KioskModeActivity.class); DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); dpm.addPersistentPreferredActivity(adminName, filter, activity);
Você ainda precisa declarar o filtro de intent. no arquivo de manifesto do app, conforme mostrado no snippet XML abaixo:
<activity
android:name=".KioskModeActivity"
android:label="@string/kiosk_mode"
android:launchMode="singleInstance"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Normalmente, você não quer que seu app de tela de início apareça na tela "Visão geral".
No entanto, não é necessário adicionar excludeFromRecents
declaração de atividade porque o acesso rápido do Android oculta os elementos
atividade quando o sistema está em execução no modo de bloqueio de tarefas.
Mostrar tarefas separadas
FLAG_ACTIVITY_NEW_TASK
pode ser uma flag útil para
de tela de início, porque cada nova tarefa aparece como um item separado na
Visão geral. Para saber mais sobre as tarefas na tela "Visão geral", leia Recentes
Tela.
Quiosques públicos
Essas receitas são ótimas para dispositivos autônomos em espaços públicos, mas também podem ajudam muitos usuários de dispositivos dedicados a se concentrarem em suas tarefas.
Bloquear o dispositivo
Para garantir que os dispositivos sejam usados para a finalidade pretendida, é possível adicionar restrições de usuário listadas na tabela 1.
Restrição de usuários | Descrição |
---|---|
DISALLOW_FACTORY_RESET |
Impede que um usuário redefina o dispositivo para a configuração original. Os administradores de dispositivos totalmente gerenciados e o usuário principal podem configurar isso. e a segunda é a restrição de recursos. |
DISALLOW_SAFE_BOOT |
Impede que um usuário inicie o dispositivo em modo de segurança em que o sistema não vai iniciar o app automaticamente. Administradores do os dispositivos gerenciados e o usuário principal podem definir essa restrição. |
DISALLOW_MOUNT_PHYSICAL_MEDIA |
Impede que o usuário do dispositivo monte qualquer volume de armazenamento possível ao dispositivo. Os administradores de dispositivos totalmente gerenciados e o usuário principal você pode definir essa restrição. |
DISALLOW_ADJUST_VOLUME |
Desativa o som do dispositivo e impede que o usuário do dispositivo altere o som configurações de volume e vibração. Verifique se o quiosque não precisa de áudio para reprodução de mídia ou recursos de acessibilidade. Os administradores de contas totalmente gerenciadas dispositivos, o usuário principal, os usuários secundários e os perfis de trabalho podem definir isso e a segunda é a restrição de recursos. |
DISALLOW_ADD_USER |
Impede que o usuário do dispositivo adicione novos usuários, como secundários ou usuários restritos. O sistema adiciona automaticamente essa restrição de usuário a dispositivos totalmente gerenciados, mas pode ter sido apagado. Administradores do os dispositivos gerenciados e o usuário principal podem definir essa restrição. |
O snippet a seguir mostra como definir as restrições:
Kotlin
// If the system is running in lock task mode, set the user restrictions // for a kiosk after launching the activity. arrayOf( UserManager.DISALLOW_FACTORY_RESET, UserManager.DISALLOW_SAFE_BOOT, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, UserManager.DISALLOW_ADJUST_VOLUME, UserManager.DISALLOW_ADD_USER).forEach { dpm.addUserRestriction(adminName, it) }
Java
// If the system is running in lock task mode, set the user restrictions // for a kiosk after launching the activity. String[] restrictions = { UserManager.DISALLOW_FACTORY_RESET, UserManager.DISALLOW_SAFE_BOOT, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, UserManager.DISALLOW_ADJUST_VOLUME, UserManager.DISALLOW_ADD_USER}; for (String restriction: restrictions) dpm.addUserRestriction(adminName, restriction);
Convém remover essas restrições quando o aplicativo estiver no modo de administrador.
que um administrador de TI ainda possa usar esses recursos para manutenção de dispositivos. Para limpar
a restrição, chame
DevicePolicyManager.clearUserRestriction()
Suprimir caixas de diálogo de erro
Em alguns ambientes, como demonstrações na loja ou informações públicas
for exibido, talvez você não queira mostrar caixas de diálogo de erro aos usuários. No Android 9.0 (API
nível 28) ou superior, é possível suprimir caixas de diálogo de erro do sistema para
apps que não respondem, adicionando o
Usuário do DISALLOW_SYSTEM_ERROR_DIALOGS
e a segunda é a restrição de recursos. O sistema reinicia os apps que não respondem, como se o usuário do dispositivo tivesse fechado
o app na caixa de diálogo. O exemplo a seguir mostra como fazer isso:
Kotlin
override fun onEnabled(context: Context, intent: Intent) { val dpm = getManager(context) val adminName = getWho(context) dpm.addUserRestriction(adminName, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS) }
Java
public void onEnabled(Context context, Intent intent) { DevicePolicyManager dpm = getManager(context); ComponentName adminName = getWho(context); dpm.addUserRestriction(adminName, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS); }
Se um administrador do usuário principal ou secundário definir essa restrição, o sistema suprime caixas de diálogo de erro apenas para esse usuário. Se um administrador de uma conta de serviço dispositivo definir essa restrição, o sistema suprima caixas de diálogo para todos os usuários.
Manter a tela ativada
Se você estiver construindo um quiosque, pode impedir um dispositivo que
sono quando está executando a atividade do app. Adicionar
a sinalização de layout FLAG_KEEP_SCREEN_ON
à
conforme mostrado neste exemplo:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Keep the screen on and bright while this kiosk activity is running. window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Keep the screen on and bright while this kiosk activity is running. getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); }
Verifique se o dispositivo está conectado a uma fonte de alimentação, USB ou sem fio.
carregador. Registrar-se em transmissões de troca de bateria e usar BatteryManager
para descobrir o estado de carregamento. É possível até enviar alertas remotos para um
administrador caso o dispositivo seja desconectado. Para instruções detalhadas, leia
Monitorar o nível de bateria e o carregamento
Estado.
Você também pode definir o STAY_ON_WHILE_PLUGGED_IN
configuração global para manter o dispositivo ativado enquanto ele está conectado a uma fonte de energia.
Os administradores de dispositivos totalmente gerenciados no Android 6.0 (nível 23 da API) ou versões mais recentes podem
chame DevicePolicyManager.setGlobalSetting()
, conforme mostrado
no exemplo a seguir:
Kotlin
val pluggedInto = BatteryManager.BATTERY_PLUGGED_AC or BatteryManager.BATTERY_PLUGGED_USB or BatteryManager.BATTERY_PLUGGED_WIRELESS dpm.setGlobalSetting(adminName, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, pluggedInto.toString())
Java
int pluggedInto = BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS; dpm.setGlobalSetting( adminName, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, String.valueOf(pluggedInto));
Pacotes de apps
Esta seção contém receitas para instalar apps com eficiência em dispositivos dedicados.
Armazenar pacotes de apps em cache
Se os usuários de um dispositivo compartilhado compartilharem um conjunto comum de apps, isso facilita e evitar o download de aplicativos sempre que possível. Para simplificar o gerenciamento o provisionamento em dispositivos compartilhados com um conjunto fixo de usuários, como dispositivos "shift workers", no Android 9.0 (nível 28 da API) ou mais recente, é possível armazenar apps em cache pacotes (APKs) necessários para sessões multiusuário.
A instalação de um APK armazenado em cache (que já está instalado no dispositivo) acontece em dois estágios:
- O componente de administração de um dispositivo totalmente gerenciado (ou um delegado). Consulte seguinte) define a lista de APKs a serem mantidos no dispositivo.
- Os componentes de administrador de usuários secundários afiliados (ou seus delegados) podem instalar o APK armazenado em cache em nome do usuário. Os administradores do grupo do dispositivo, o usuário principal ou um perfil de trabalho afiliado (ou os delegados) também podem instalar o app em cache, se necessário.
Para definir a lista de APKs a serem mantidos no dispositivo, o administrador chama
DevicePolicyManager.setKeepUninstalledPackages()
Esse método não verifica se o APK está instalado no dispositivo, útil se você
querem instalar um app antes de precisar dele para o usuário. Para conferir uma lista
pacotes definidos anteriormente, é possível chamar
DevicePolicyManager.getKeepUninstalledPackages()
Depois de chamar setKeepUninstalledPackages()
com mudanças ou quando uma instância secundária
o usuário for excluído, o sistema excluirá todos os APKs armazenados em cache que não forem mais necessários.
Para instalar um APK armazenado em cache, chame
DevicePolicyManager.installExistingPackage()
Esse método só pode instalar um app que o sistema já armazenou em cache.
solução de dispositivo dedicado (ou o usuário de um dispositivo) deve primeiro instalar o app
no dispositivo antes de chamar esse método.
O exemplo a seguir mostra como você pode usar essas chamadas de API no administrador de um dispositivo totalmente gerenciado e um usuário secundário:
Kotlin
// Set the package to keep. This method assumes that the package is already // installed on the device by managed Google Play. val cachedAppPackageName = "com.example.android.myapp" dpm.setKeepUninstalledPackages(adminName, listOf(cachedAppPackageName)) // ... // The admin of a secondary user installs the app. val success = dpm.installExistingPackage(adminName, cachedAppPackageName)
Java
// Set the package to keep. This method assumes that the package is already // installed on the device by managed Google Play. String cachedAppPackageName = "com.example.android.myapp"; List<String> packages = new ArrayList<String>(); packages.add(cachedAppPackageName); dpm.setKeepUninstalledPackages(adminName, packages); // ... // The admin of a secondary user installs the app. boolean success = dpm.installExistingPackage(adminName, cachedAppPackageName);
Delegar apps
É possível delegar o gerenciamento do armazenamento em cache de outro app. Você pode fazer isso para
separar os recursos da solução ou permitir que os administradores de TI usem
nos próprios apps. O app delegado recebe as mesmas permissões que o administrador
componente. Por exemplo, um delegado do app do administrador de um usuário secundário pode chamar
installExistingPackage()
, mas não é possível chamar setKeepUninstalledPackages()
.
Para fazer uma chamada de delegado
DevicePolicyManager.setDelegatedScopes()
e incluem
DELEGATION_KEEP_UNINSTALLED_PACKAGES
no argumento escopos. O exemplo a seguir mostra como criar outro app
o delegado:
Kotlin
var delegatePackageName = "com.example.tools.kept_app_assist" // Check that the package is installed before delegating. try { context.packageManager.getPackageInfo(delegatePackageName, 0) dpm.setDelegatedScopes( adminName, delegatePackageName, listOf(DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES)) } catch (e: PackageManager.NameNotFoundException) { // The delegate app isn't installed. Send a report to the IT admin ... }
Java
String delegatePackageName = "com.example.tools.kept_app_assist"; // Check that the package is installed before delegating. try { context.getPackageManager().getPackageInfo(delegatePackageName, 0); dpm.setDelegatedScopes( adminName, delegatePackageName, Arrays.asList(DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES)); } catch (PackageManager.NameNotFoundException e) { // The delegate app isn't installed. Send a report to the IT admin ... }
Se tudo correr bem, o app delegado receberá a
ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED
e se torna o delegado. O app pode chamar os métodos neste guia
como se fosse o proprietário do dispositivo ou do perfil. Ao ligar
DevicePolicyManager
, o delegado transmite null
para o administrador.
argumento do componente.
Instalar pacotes de apps
Às vezes é útil instalar um aplicativo personalizado armazenado em cache localmente em uma
dispositivo. Por exemplo, dispositivos dedicados são frequentemente implantados em
ambientes com largura de banda limitada ou áreas sem conectividade com a Internet. Seu
solução de dispositivo dedicado deve considerar a largura de banda dos clientes. Seu
app pode iniciar a instalação de outro pacote de apps (APK) usando o
PackageInstaller
.
Embora qualquer app possa instalar APKs, os administradores em dispositivos totalmente gerenciados podem instalar (ou desinstalar) pacotes sem interação do usuário. O administrador pode gerenciar no dispositivo, um usuário secundário afiliado ou um perfil de trabalho afiliado. Depois terminando a instalação, o sistema publica uma notificação informando que todos os usuários do dispositivo ver. A notificação informa aos usuários do dispositivo que o app foi instalado (ou atualizado) pelo administrador.
Versão do Android | Componente do administrador para instalação e desinstalação |
---|---|
Android 9.0 (nível 28 da API) ou mais recente | Usuários secundários afiliados e perfis de trabalho, ambos em plataformas totalmente gerenciadas dispositivos |
Ter o Android 6.0 (API de nível 23) ou versões mais recentes | Dispositivos totalmente gerenciados |
A forma como você distribui uma ou mais cópias do APK para dispositivos dedicados dependem da distância dos dispositivos e, possivelmente, da distância entre eles são umas das outras. Sua solução precisa seguir as práticas recomendadas de segurança antes de instalar APKs em dispositivos dedicados.
Use PackageInstaller.Session
para criar uma sessão que enfileira um
ou mais APKs para instalação. No exemplo a seguir, recebemos o status
feedback em nossa atividade (modo singleTop), mas você pode usar uma
serviço ou broadcast receiver:
Kotlin
// First, create a package installer session. val packageInstaller = context.packageManager.packageInstaller val params = PackageInstaller.SessionParams( PackageInstaller.SessionParams.MODE_FULL_INSTALL) val sessionId = packageInstaller.createSession(params) val session = packageInstaller.openSession(sessionId) // Add the APK binary to the session. The APK is included in our app binary // and is read from res/raw but file storage is a more typical location. // The I/O streams can't be open when installation begins. session.openWrite("apk", 0, -1).use { output -> getContext().resources.openRawResource(R.raw.app).use { input -> input.copyTo(output, 2048) } } // Create a status receiver to report progress of the installation. // We'll use the current activity. // Here we're requesting status feedback to our Activity but this can be a // service or broadcast receiver. val intent = Intent(context, activity.javaClass) intent.action = "com.android.example.APK_INSTALLATION_ACTION" val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0) val statusReceiver = pendingIntent.intentSender // Start the installation. Because we're an admin of a fully managed device, // there isn't any user interaction. session.commit(statusReceiver)
Java
// First, create a package installer session. PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller(); PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( PackageInstaller.SessionParams.MODE_FULL_INSTALL); int sessionId = packageInstaller.createSession(params); PackageInstaller.Session session = packageInstaller.openSession(sessionId); // Add the APK binary to the session. The APK is included in our app binary // and is read from res/raw but file storage is a more typical location. try ( // These I/O streams can't be open when installation begins. OutputStream output = session.openWrite("apk", 0, -1); InputStream input = getContext().getResources().openRawResource(R.raw.app); ) { byte[] buffer = new byte[2048]; int n; while ((n = input.read(buffer)) >= 0) { output.write(buffer, 0, n); } } // Create a status receiver to report progress of the installation. // We'll use the current activity. // Here we're requesting status feedback to our Activity but this can be a // service or broadcast receiver. Intent intent = new Intent(context, getActivity().getClass()); intent.setAction("com.android.example.APK_INSTALLATION_ACTION"); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); IntentSender statusReceiver = pendingIntent.getIntentSender(); // Start the installation. Because we're an admin of a fully managed device, // there isn't any user interaction. session.commit(statusReceiver);
A sessão usa intents para enviar feedback de status sobre a instalação. Marca de seleção
campo EXTRA_STATUS
de cada intent para receber
status. Os administradores não recebem
Atualização do status do STATUS_PENDING_USER_ACTION
porque o usuário do dispositivo não precisa aprovar a instalação.
Para desinstalar apps, chame PackageInstaller.uninstall
.
Administradores de dispositivos totalmente gerenciados, usuários e perfis de trabalho podem desinstalar pacotes
sem interação do usuário executando versões compatíveis do Android (consulte
tabela 2).
Congelar atualizações do sistema
Os dispositivos Android recebem atualizações OTA (over-the-air) no sistema e no aplicativo de software. Para congelar a versão do SO em períodos críticos, como feriados ou em outros horários de pico, os dispositivos dedicados podem suspender atualizações do sistema OTA por até 90 dias. Saiba mais em Gerenciar atualizações do sistema.
Configuração remota
As configurações gerenciadas do Android permitem que os administradores de TI configurar remotamente seu aplicativo. Recomendamos que você exponha configurações como listas de permissões, hosts de rede ou URLs de conteúdo para tornar seu app mais útil para a equipe de TI do Google Cloud.
Se o seu aplicativo expõe sua configuração, lembre-se de incluí-las no seu na documentação do Google Cloud. Para saber mais sobre como expor a configuração do app e reagir a mudar as configurações, leia Definir configurações gerenciadas.
Configuração de desenvolvimento
Ao desenvolver uma solução para dispositivos dedicados, útil para definir seu aplicativo como o administrador de um dispositivo totalmente gerenciado sem uma fábrica redefinido. Para configurar o administrador de um dispositivo totalmente gerenciado, siga estas etapas:
- Crie e instale seu app controlador de política de dispositivo (DPC) no dispositivo.
- Verifique se não há contas no dispositivo.
Execute o seguinte comando no shell do Android Debug Bridge (adb). Você é necessário substituir
com.example.dpc/.MyDeviceAdminReceiver
no exemplo por nome do componente de administrador do seu app:adb shell dpm set-device-owner com.example.dpc/.MyDeviceAdminReceiver
Para ajudar os clientes a implantar a solução, você precisará conferir outros tipos de métodos. Recomendamos o registro com QR code para dispositivos dedicados.
Outros recursos
Para saber mais sobre dispositivos dedicados, leia os seguintes documentos: