以编程方式关闭设备

时间:2014-07-11 08:49:58

标签: android

我正在编写一个旨在在一个特定设备模型(运行基于Amlogic的固件的Android机顶设备)上运行的应用程序。我有两个root功能,我的应用程序已使用固件证书签名。

我的应用程序是该设备的主要关注点,能够启动完全关闭电源会很有帮助。

我没有shutdown命令。我有reboot命令。

reboot -p无济于事。它只是在打开电源的同时冻结设备。

PowerManager更好一步,但它将设备设置为睡眠模式,而不是完全关闭:

PowerManager pm = (PowerManager)getSystemService(Service.POWER_SERVICE);
pm.goToSleep(SystemClock.uptimeMillis());

我对所有建议持开放态度 - 黑客或其他。 Android的版本预计会保持在4.2.2


意图

此命令将导致设备重新启动。 Intent.ACTION_SHUTDOWN似乎没有做任何事情。这个Intent可能只是报告关闭,而不是启动一个吗?

Intent i = new Intent(Intent.ACTION_REBOOT);
i.putExtra("nowait", 1);
i.putExtra("interval", 1);
i.putExtra("window", 0);
sendBroadcast(i);

我最幸运的是要求Intent关闭:

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);
    }
}

shutdownbeginShutdownSequence创建NullPointerException s(你知道为什么吗?),rebootOrShutdownInvocationTargetException而创建UnsatisfiedLinkError。 ..它无法找到原生方法:

  

java.lang.UnsatisfiedLinkError:找不到本机方法:   com.android.server.power.PowerManagerService.nativeShutdown :()V at   com.android.server.power.PowerManagerService.nativeShutdown(母语   方法)at   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是所有功能最终到达的功能,配置为关闭(而不是重启)。因此,弄清楚如何避免这种链接错误可能是关键。

6 个答案:

答案 0 :(得分:17)

在我的情况下,我认为不可能按照我的意愿关闭设备。

我设法达到目标的最接近的是:

Intent i = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
i.putExtra("android.intent.extra.KEY_CONFIRM", true);
startActivity(i);

会弹出一个关闭设备的对话框。这是一个完美的解决方案,但在我的情况下,使用它会导致设备崩溃。可能是我的设备有些特殊,其他设备也没有这些限制。

无论如何,我希望我的测试能帮助其他人完成任务。

答案 1 :(得分:6)

它适用于root设备。 如果您的设备已植根,则可以使用以下方法

<强>关机:

tabControl1.SelectedIndex == 0   //for tabPage1

<强>重新启动:

相同的代码,只需使用try { Process proc = Runtime.getRuntime() .exec(new String[]{ "su", "-c", "reboot -p" }); proc.waitFor(); } catch (Exception ex) { ex.printStackTrace(); } 代替"reboot"

答案 2 :(得分:5)

Runtime.getRuntime().exec(new String[]{ "su", "-c", "reboot -p" });

它可以工作,只需使用root设备!!

答案 3 :(得分:5)

要使用此代码,您需要超级用户!适用于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" /> 

答案 4 :(得分:0)

更新:对于较新的Android版本,在我的情况下为Android 8.1,他们更改了动作名称。见下文:

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);

祝你好运!

答案 5 :(得分:0)

在较新的android版本中,不允许您从nonSystem应用关闭设备。