Выключить устройство программно
Я пишу приложение, предназначенное для работы на одной конкретной модели устройства (Android-устройство Android, на котором выполняется прошивка на базе Amlogic). У меня есть и возможность root, и мое приложение подписано с сертификатом прошивки.
Мое приложение является основным фокусом устройства, и было бы полезно иметь возможность инициировать полное отключение питания.
У меня нет команды shutdown
. У меня есть команда reboot
.
reboot -p
не помогает. Он просто замораживает устройство, оставаясь включенным.
PowerManager
на один шаг лучше, но он переключает устройство в спящий режим, а не на полное завершение работы:
PowerManager pm = (PowerManager)getSystemService(Service.POWER_SERVICE);
pm.goToSleep(SystemClock.uptimeMillis());
Я открыт для всех предложений - хакерских или иных. Ожидается, что версия Android останется на уровне 4.2.2
.
Intents
Эта команда приведет к перезагрузке устройства. Intent.ACTION_SHUTDOWN
, похоже, ничего не делает. Возможно, это намерение только сообщить о завершении работы, а не инициировать его?
Intent i = new Intent(Intent.ACTION_REBOOT);
i.putExtra("nowait", 1);
i.putExtra("interval", 1);
i.putExtra("window", 0);
sendBroadcast(i);
Самая удача, с которой я столкнулась, заключалась в том, чтобы запросить остановку по намерению:
Intent i = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
i.putExtra("android.intent.extra.KEY_CONFIRM", true);
startActivity(i);
Отключить поток
Это немного ближе. Определенно интересно. Можете ли вы найти пример его использования?
До сих пор я придумал следующее:
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
и beginShutdownSequence
create NullPointerException
(вы видите, почему?) и rebootOrShutdown
создает InvocationTargetException
из-за UnsatisfiedLinkError
... Он не может найти собственный метод:
java.lang.UnsatisfiedLinkError: собственный метод не найден: com.android.server.power.PowerManagerService.nativeShutdown:() V at com.android.server.power.PowerManagerService.nativeShutdown(Native Метод) при com.android.server.power.PowerManagerService.lowLevelShutdown(PowerManagerService.java:2163) в com.android.server.power.ShutdownThread.rebootOrShutdown(ShutdownThread.java:543) в com.android.server.power.ShutdownThread.run(ShutdownThread.java:393)
lowLevelShutdown
- это функция, которую в конечном итоге достигают все функции, когда она настроена на выключение (и не перезагрузка). Поэтому выяснение того, как избежать этой ошибки ссылки, может быть ключевым.
Ответы
Ответ 1
В моем случае, я не думаю, что можно отключить устройство, как бы я хотел.
Самое близкое, что мне удалось добраться до моей цели, было:
Intent i = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
i.putExtra("android.intent.extra.KEY_CONFIRM", true);
startActivity(i);
Появится диалоговое окно, чтобы выключить устройство. Это идеальное решение, но в моем случае его использование приводит к сбою устройства. Возможно, мое устройство несколько особенное, и другие устройства не будут иметь этих ограничений.
В любом случае, я надеюсь, что мое тестирование поможет другим в их поисках.
Ответ 2
Runtime.getRuntime().exec(new String[]{ "su", "-c", "reboot -p" });
он работает, только с укоренившимися устройствами!
Ответ 3
Он работает для меня на корневом устройстве.
Если ваше устройство внедрено, вы можете использовать подход ниже
Shutdown:
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot -p" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
Restart:
В этом же коде просто используйте "reboot"
вместо "reboot -p"
.
Ответ 4
Чтобы использовать этот код, вам нужен Суперпользователь! Работает на 4.0 и выше!
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);
и поставьте это разрешение на манифест:
<uses-permission android:name="android.permission.SHUTDOWN" />