Подтвердить что ты не робот

Выключить устройство программно

Я пишу приложение, предназначенное для работы на одной конкретной модели устройства (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 - это функция, которую в конечном итоге достигают все функции, когда она настроена на выключение (и не перезагрузка). Поэтому выяснение того, как избежать этой ошибки ссылки, может быть ключевым.

4b9b3361

Ответ 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" />