Esta guía de soluciones ayuda a los desarrolladores y a los integradores de sistemas a mejorar de Google Cloud. Sigue nuestras instrucciones para encontrar soluciones para dispositivos exclusivos los comportamientos del modelo. Este libro de cocina funciona mejor para los desarrolladores que ya tienen una para dispositivos. Si es la primera vez que lo haces, consulta la sección Dispositivos exclusivos. descripción general.
Apps de Home personalizadas
Estas recetas son útiles si estás desarrollando una app para reemplazar la app de Home de Android y el Selector.
Sé la app de Home
Puedes configurar tu app como la de inicio del dispositivo para que se inicie. automáticamente cuando se inicia el dispositivo. También puedes habilitar la página principal botón que lleve la app de la lista de entidades permitidas al primer plano con bloqueo el modo de tarea.
Todas las apps de inicio controlan la categoría de intent CATEGORY_HOME
. Esta
es la forma en que el sistema reconoce una app de inicio. Establece una para ser la app de inicio predeterminada
de las actividades de tu app como el controlador de intents de la pantalla principal preferido, llamando
DevicePolicyManager.addPersistentPreferredActivity()
como se muestra en el siguiente ejemplo:
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);
Aún debes declarar el filtro de intents. del archivo de manifiesto de tu app, como se muestra en el siguiente fragmento XML:
<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>
Por lo general, no quieres que la app de selector aparezca en la pantalla Recientes.
Sin embargo, no es necesario que agregues excludeFromRecents
a
la declaración de actividad porque el Launcher de Android oculta el que se inició inicialmente
cuando el sistema se ejecuta
en el modo de tareas bloqueadas.
Mostrar tareas separadas
FLAG_ACTIVITY_NEW_TASK
puede ser una marca útil para
apps de tipo selector, ya que cada tarea nueva aparece como un elemento separado en la
Pantalla Overview. Para obtener más información sobre las tareas de la pantalla Recientes, lee Recientes
Pantalla.
Kioscos públicos
Estas recetas son excelentes para dispositivos sin supervisión en espacios públicos, pero también ayudan a muchos usuarios de dispositivos dedicados a enfocarse en sus tareas.
Bloquea el dispositivo
Para asegurarte de que los dispositivos se usen según su uso previsto, puedes agregar para las restricciones de usuario que se indican en la tabla 1.
Restricción de usuarios | Descripción |
---|---|
DISALLOW_FACTORY_RESET |
Impide que un usuario restablezca el dispositivo a la configuración predeterminada de fábrica. Los administradores de dispositivos completamente administrados y el usuario principal pueden establecer esto restricción. |
DISALLOW_SAFE_BOOT |
Impide que un usuario inicie el dispositivo en modo seguro en los que el sistema no iniciará automáticamente tu app. Los administradores de en dispositivos administrados, y el usuario principal puede establecer esta restricción. |
DISALLOW_MOUNT_PHYSICAL_MEDIA |
Impide que el usuario del dispositivo active los volúmenes de almacenamiento que podría necesitar. conectarla al dispositivo. Los administradores de dispositivos completamente administrados y el usuario principal pueden establecer esta restricción. |
DISALLOW_ADJUST_VOLUME |
Silencia el dispositivo y evita que su usuario cambie el sonido la configuración de volumen y vibración. Verifica que el kiosco no necesite audio para la reproducción de contenido multimedia o las funciones de accesibilidad. Los administradores de entornos completamente dispositivos, el usuario principal, los usuarios secundarios y los perfiles de trabajo pueden establecer restricción. |
DISALLOW_ADD_USER |
Impide que el usuario del dispositivo agregue nuevos usuarios, como usuarios secundarios o usuarios restringidos. El sistema agrega automáticamente esta restricción de usuario a completamente administrados, pero es posible que se haya borrado. Los administradores de en dispositivos administrados, y el usuario principal puede establecer esta restricción. |
En el siguiente fragmento, se muestra cómo puedes establecer las restricciones:
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);
Te recomendamos que quites estas restricciones cuando tu app esté en modo de administrador
de que un administrador de TI pudiera seguir usando estas funciones para el mantenimiento de los dispositivos. Para borrar
la restricción, llama
DevicePolicyManager.clearUserRestriction()
Suprimir diálogos de error
En algunos entornos, como para las demostraciones minoristas o la información pública
es posible que no quieras mostrar diálogos de error a los usuarios. En Android 9.0 (API
nivel 28) o versiones posteriores, puedes suprimir los diálogos de error del sistema para
apps que no responden agregando
Usuario de DISALLOW_SYSTEM_ERROR_DIALOGS
restricción. El sistema reinicia las apps que no responden como si el usuario las cerrara
la aplicación desde el cuadro de diálogo. En el siguiente ejemplo, se muestra cómo puedes hacerlo:
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); }
Si un administrador del usuario principal o secundario establece esta restricción, el sistema suprime los diálogos de error solo para ese usuario. Si un administrador de un dominio completamente El dispositivo establece esta restricción y el sistema elimina los diálogos para todos los usuarios.
Cómo mantener encendida la pantalla
Si estás creando un kiosco, puedes impedir que un dispositivo vaya a
Sleep cuando está ejecutando la actividad de la app. Agrega
la marca de diseño FLAG_KEEP_SCREEN_ON
como se muestra en el siguiente ejemplo:
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); }
Verifica si el dispositivo está conectado a una CA, USB o conexión inalámbrica
cargador. Regístrate para recibir transmisiones de cambio de batería y usar BatteryManager
de salida para descubrir el estado de carga. Incluso puedes enviar alertas remotas a un departamento de TI
administrador si el dispositivo se desconecta. Para obtener instrucciones paso a paso, lee
Cómo supervisar el nivel de batería y la carga
Estado.
También puedes configurar el STAY_ON_WHILE_PLUGGED_IN
configuración global para mantener el dispositivo activo mientras está conectado a una fuente de alimentación.
Los administradores de dispositivos completamente administrados, en Android 6.0 (nivel de API 23) o versiones posteriores, pueden
llama a DevicePolicyManager.setGlobalSetting()
como se muestra
en el siguiente ejemplo:
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));
Paquetes de aplicación
Esta sección contiene recetas para instalar apps de manera eficiente en dispositivos dedicados.
Cómo almacenar paquetes de apps en caché
Si todos los usuarios de un dispositivo compartido comparten un conjunto común de apps, de evitar la descarga de aplicaciones siempre que sea posible. Para optimizar la experiencia a través de dispositivos compartidos con un conjunto fijo de usuarios, como dispositivos para los trabajadores por turno, en Android 9.0 (nivel de API 28) o versiones posteriores, puedes almacenar necesarios (APK) necesarios para las sesiones multiusuario.
La instalación de un APK almacenado en caché (que ya está instalado en el dispositivo) ocurre en dos etapas:
- El componente de administrador de un dispositivo completamente administrado (o un delegado;consulta esta página siguiente) establece la lista de APK que se conservarán en el dispositivo.
- Los componentes administradores de los usuarios secundarios afiliados (o sus delegados) pueden instalar el APK almacenado en caché en nombre del usuario. Los administradores del entorno de ejecución dispositivo, el usuario principal o un perfil de trabajo afiliado (o su delegados) también pueden instalar la app almacenada en caché si es necesario.
Para configurar la lista de APK que se conservarán en el dispositivo, el administrador llama
DevicePolicyManager.setKeepUninstalledPackages()
(es útil si no verificas que el APK esté instalado en el dispositivo)
instalar una app justo antes de que la necesite un usuario. Para obtener una lista de
paquetes previamente establecidos, puedes llamar
DevicePolicyManager.getKeepUninstalledPackages()
Después de llamar a setKeepUninstalledPackages()
con cambios o cuando una instancia
se borra el usuario, el sistema borra los APK almacenados en caché que ya no son necesarios.
Para instalar un APK almacenado en caché, llama a
DevicePolicyManager.installExistingPackage()
Este método solo puede instalar una app que el sistema ya haya almacenado en caché; tu
solución para dispositivos exclusivos (o el usuario de un dispositivo) primero debe instalar la aplicación en
el dispositivo antes de que puedas llamar a este método.
En el siguiente ejemplo, se muestra cómo podrías usar estas llamadas a la API en el administrador Un dispositivo completamente administrado y un usuario secundario:
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);
Delega apps
Puedes delegar otra app para que administre el almacenamiento en caché. Puedes hacer esto para
separar las funciones de la solución o ofrecer la posibilidad de que los administradores de TI usen
sus propias aplicaciones. La app delegada obtiene los mismos permisos que el administrador.
este componente. Por ejemplo, el delegado de una app del administrador de un usuario secundario puede llamar
installExistingPackage()
, pero no puede llamar a setKeepUninstalledPackages()
.
Sigue estos pasos para realizar una llamada delegada.
DevicePolicyManager.setDelegatedScopes()
e incluir
DELEGATION_KEEP_UNINSTALLED_PACKAGES
en el argumento de los permisos. En el siguiente ejemplo, se muestra cómo crear otra app
el 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 ... }
Si todo sale bien, la app delegada recibe el
ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED
y se convierte en el delegado. La app puede llamar a los métodos de esta guía
como si fuera el propietario del dispositivo o del perfil. Al realizar llamadas
DevicePolicyManager
, el delegado pasa null
al administrador
componente.
Instala paquetes de aplicación
A veces resulta útil instalar una app personalizada almacenada en caché local en una aplicación
dispositivo. Por ejemplo, los dispositivos dedicados se implementan frecuentemente en
en entornos con ancho de banda limitado
o en áreas sin conectividad a Internet. Tu
de la solución para dispositivos exclusivos debe tener en cuenta el ancho de banda de los clientes. Tu
puede iniciar la instalación de otro paquete de aplicación (APK) con el
PackageInstaller
.
Si bien cualquier app puede instalar APK, los administradores en dispositivos completamente administrados también instalar (o desinstalar) paquetes sin la interacción del usuario. El administrador podría gestionar el dispositivo, un usuario secundario afiliado o un perfil de trabajo afiliado Después del tras finalizar la instalación, el sistema publica una notificación que informa a todos los usuarios del dispositivo ver. La notificación informa a los usuarios del dispositivo que se instaló la app (o (actualizado) por su administrador.
Versión de Android | Componente de administrador para la instalación y desinstalación |
---|---|
Android 9.0 (nivel de API 28) o una versión posterior | Usuarios secundarios afiliados y perfiles de trabajo, ambos en cuentas completamente administradas dispositivos |
Android 6.0 (nivel de API 23) o una versión posterior | Dispositivos completamente administrados |
La manera en la que distribuyes una o más copias del APK en dispositivos exclusivos dependen de qué tan remotos estén los dispositivos y, posiblemente, de qué tan lejos están entre sí. Tu solución debe seguir las prácticas recomendadas de seguridad antes de instalar los APK en dispositivos exclusivos.
Puedes usar PackageInstaller.Session
para crear una sesión que ponga en cola uno.
o más APK para la instalación. En el siguiente ejemplo, recibimos el estado
comentarios en nuestra actividad (modo singleTop), pero puedes usar un
servicio o receptor de emisión:
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);
La sesión envía comentarios sobre el estado de la instalación mediante intents. Cheque
el campo EXTRA_STATUS
de cada intent para obtener la
estado. Recuerda que los administradores no reciben el
Actualización de estado del STATUS_PENDING_USER_ACTION
porque el usuario del dispositivo no necesita aprobar la instalación.
Para desinstalar apps, puedes llamar a PackageInstaller.uninstall
.
Los administradores de dispositivos completamente administrados, usuarios y perfiles de trabajo pueden desinstalar paquetes
sin interacción del usuario al ejecutar versiones de Android compatibles (consulta
tabla 2).
Inmovilizar las actualizaciones del sistema
Los dispositivos Android reciben actualizaciones inalámbricas del sistema y la aplicación software. Para congelar la versión del SO durante períodos críticos, como días festivos o otras horas de mayor actividad, los dispositivos exclusivos pueden suspender las actualizaciones del sistema inalámbrico durante 90 días. Para obtener más información, consulta Cómo administrar actualizaciones del sistema.
Configuración remota
Los parámetros de configuración administrados de Android permiten que los administradores de TI realicen las siguientes acciones: configurar tu app de forma remota. Puedes exponer parámetros de configuración, como listas de entidades permitidas, hosts de red o URLs de contenido para que tu app sea más útil para el equipo de TI de Google Workspace for Education.
Si tu app expone su configuración, recuerda incluir la configuración en tu en la documentación de Google Cloud. Si quieres obtener más información para exponer la configuración de tu app y reaccionar a cambios en la configuración, lee Establece parámetros de configuración administrados.
Configuración de desarrollo
Mientras desarrollas tu solución para dispositivos exclusivos, útil para establecer tu app como administrador de un dispositivo completamente administrado sin una configuración de fábrica restablecer. Para establecer el administrador de un dispositivo completamente administrado, sigue estos pasos:
- Compila e instala la app de controlador de política de dispositivo (DPC) en el dispositivo.
- Verifica que no haya cuentas en el dispositivo.
Ejecuta el siguiente comando en el shell de Android Debug Bridge (adb). Tú debes reemplazar
com.example.dpc/.MyDeviceAdminReceiver
en el ejemplo por nombre del componente de administración de tu aplicación:adb shell dpm set-device-owner com.example.dpc/.MyDeviceAdminReceiver
Para ayudar a los clientes a implementar tu solución, deberás revisar otras opciones de inscripción. métodos. Recomendamos la inscripción en código QR para o dispositivos exclusivos.
Recursos adicionales
Para obtener más información sobre los dispositivos exclusivos, lee los siguientes documentos: