programar - encender celular sin boton de encendido android
Apagar el dispositivo programáticamente (5)
Estoy escribiendo una aplicación que está diseñada para ejecutarse en un modelo de dispositivo específico (un dispositivo decodificador Android que ejecuta firmware basado en Amlogic). Tengo ambas funciones de raíz y mi aplicación está firmada con el certificado de firmware.
Mi aplicación es el enfoque principal del dispositivo, y sería útil poder iniciar un apagado completo.
No tengo el comando de shutdown
. Tengo el comando de reboot
.
reboot -p
no ayuda. Simplemente congela el dispositivo mientras permanece encendido.
El PowerManager
es un paso mejor, pero establece el dispositivo en modo de suspensión, en lugar de un apagado completo:
PowerManager pm = (PowerManager)getSystemService(Service.POWER_SERVICE);
pm.goToSleep(SystemClock.uptimeMillis());
Estoy abierto a todas las sugerencias, hacky o no. Se espera que la versión de Android se mantenga en 4.2.2
.
Intenciones
Este comando hará que el dispositivo se reinicie. Intent.ACTION_SHUTDOWN
no parece hacer nada. ¿Es esta intención tal vez solo informar un cierre y no iniciarlo?
Intent i = new Intent(Intent.ACTION_REBOOT);
i.putExtra("nowait", 1);
i.putExtra("interval", 1);
i.putExtra("window", 0);
sendBroadcast(i);
La mayor suerte que tuve con esto fue solicitar un cierre por Intención:
Intent i = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
i.putExtra("android.intent.extra.KEY_CONFIRM", true);
startActivity(i);
Hilo de cierre
Eso está un poco más cerca. Definitivamente interesante. ¿Puedes encontrar un ejemplo de usarlo?
Hasta ahora he llegado con esto:
Class<?> sdClass = Class.forName("com.android.server.power.ShutdownThread");
Constructor<?> con = sdClass.getDeclaredConstructors()[0];
con.setAccessible(true);
for (Method m : sdClass.getDeclaredMethods()) {
if (m.getName().matches("shutdown")) {
m.setAccessible(true);
m.invoke(sdClass, PlayerActivity.this, false);
} else if (m.getName().matches("rebootOrShutdown")) {
m.setAccessible(true);
m.invoke(sdClass, PlayerActivity.this, false);
} else if (m.getName().matches("beginShutdownSequence")) {
m.setAccessible(true);
m.invoke(sdClass, PlayerActivity.this, false);
}
}
shutdown
y beginShutdownSequence
crean NullPointerException
s (¿ves por qué?) y rebootOrShutdown
crea una InvocationTargetException
debido a un UnsatisfiedLinkError
... No puede encontrar un método nativo:
java.lang.UnsatisfiedLinkError: Método nativo no encontrado: com.android.server.power.PowerManagerService.nativeShutdown :() V en com.android.server.power.PowerManagerService.nativeShutdown (Método nativo) en com.android.server.power .PowerManagerService.lowLevelShutdown (PowerManagerService.java:2163) en com.android.server.power.ShutdownThread.rebootOrShutdown (ShutdownThread.java:543)
lowLevelShutdown
es la función a la que finalmente llegan todas las funciones, cuando se configuran para apagar (y no reiniciar). Así que descubrir cómo evitar este error de enlace puede ser clave.
En mi caso, no creo que sea posible apagar el dispositivo como me gustaría.
Lo más cerca que logré llegar a mi objetivo fue usando:
Intent i = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
i.putExtra("android.intent.extra.KEY_CONFIRM", true);
startActivity(i);
Aparece un cuadro de diálogo para apagar el dispositivo. Esta es la solución perfecta, pero en mi caso, usarla hace que el dispositivo se bloquee. Es posible que mi dispositivo sea algo especial y que otros dispositivos no tengan estas restricciones.
En cualquier caso, espero que mis pruebas ayuden a otros en su búsqueda.
Funciona para mí en un dispositivo rooteado. Si su dispositivo está enraizado, puede utilizar el siguiente enfoque
Apagar:
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot -p" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
Reiniciar:
El mismo código, simplemente use "reboot"
lugar de "reboot -p"
.
Para usar este código, ¡necesitas un Superusuario! Funciona en 4.0 y superior!
Intent i = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
i.putExtra("android.intent.extra.KEY_CONFIRM", false);
i.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
y poner este permiso en manifiesto:
<uses-permission android:name="android.permission.SHUTDOWN" />
Una actualización: para la nueva versión de Android, en mi caso es Android 8.1, cambiaron el nombre de la acción. Vea abajo:
Intent i = new Intent("com.android.internal.intent.action.REQUEST_SHUTDOWN");
i.putExtra("android.intent.extra.KEY_CONFIRM", false);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
¡Buena suerte!
Runtime.getRuntime().exec(new String[]{ "su", "-c", "reboot -p" });
Funciona, solo con dispositivos rooteados !!