【问题标题】:Turn off device programmatically以编程方式关闭设备
【发布时间】:2014-07-11 08:49:57
【问题描述】:

我正在编写一个应用程序,该应用程序旨在在一个特定的设备型号(运行基于 Amlogic 的固件的 Android 机顶设备)上运行。我拥有 root 权限,并且我的应用程序使用固件证书进行了签名。

我的应用程序是设备的主要焦点,能够启动完全关机会很有帮助。

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

reboot -p 没有帮助。它只是在保持开机状态时冻结设备。

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

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

我对所有建议持开放态度- hacky 或其他。 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 创建 NullPointerExceptions(你明白为什么吗?)和 rebootOrShutdown 由于 UnsatisfiedLinkError 创建一个 InvocationTargetException... 它找不到本机方法:

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

【问题讨论】:

  • 这对您有帮助吗? stackoverflow.com/questions/10411650/…
  • 没有。缺少关闭命令。重新启动会冻结设备。电源管理器没有实际关闭设备的选项。只能休眠并重新启动。
  • 请看下面Manty和cmets的回答,好像有shutdown命令。
  • 你需要root权限,你可以点击@hungr发布的链接..
  • @Manty:该答案使用“关机”。如前所述,我没有可用的。该链接的所有结果都不适合我。

标签: android


【解决方案1】:

就我而言,我认为不可能按照我的意愿关闭设备。

我最接近目标的是使用:

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

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

无论如何,我希望我的测试能帮助其他人的探索。

【讨论】:

  • 有什么方法可以防止设备通过按电源按钮关机或重启。我还需要将设备限制为静音模式。
  • 你真的应该为此提出一个新问题。
  • @rup35h:你有两个问题。谷歌了一下。如果您没有找到答案,请发布两个新的 Stack Overflow 问题。这样您就有更好的机会获得支持和回答: 1. 解释您想要这些东西的原因。 2. 非常注意拼写和语法。
  • @unforgettableid 真的有必要戳一个 2 岁的问题评论吗?我怀疑他是否仍在寻找这些问题的答案。
  • 此解决方案需要android.permission.SHUTDOWN 权限,并且该权限仅适用于系统应用程序,另请参阅stackoverflow.com/a/14065879/1545993
【解决方案2】:

它在有根设备上对我有用。 如果您的设备已植根,则可以使用以下方法

关机:

try {
    Process proc = Runtime.getRuntime()
                    .exec(new String[]{ "su", "-c", "reboot -p" });
    proc.waitFor();
} catch (Exception ex) {
    ex.printStackTrace();
}

重启:

相同的代码,只需使用"reboot" 而不是"reboot -p"

【讨论】:

  • 我得到 java.io.IOException: Permission denied 但我的设备已植根,有什么想法吗?
  • 我需要做"su", "0", "reboot", "-p"
【解决方案3】:
Runtime.getRuntime().exec(new String[]{ "su", "-c", "reboot -p" });

它可以工作,只需要有根设备!

【讨论】:

  • 我需要执行“su”、“0”、“rebo​​ot”、“-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" /> 

【讨论】:

  • 这要求应用程序成为我的系统应用程序。相反,运行 reboot -p 子进程不需要这种情况。
  • 是的,它可以工作,但使用意图是更好的代码!适用于任何安卓系统!
  • 我收到错误:Permission Denial: starting Intent { act=com.android.internal.intent.action.REQUEST_SHUTDOWN flg=0x10000000 cmp=android/com.android.internal.app.ShutdownActivity (has extras) } from ProcessRecord{***/u0a194} (pid=13671, uid=10194) requires android.permission.SHUTDOWN 它可能是什么?我的应用程序是设备所有者,所以我不应该对权限有任何问题。
  • @AlbertoM 你把权限放在清单中了吗?这似乎是问题所在……请为答案投票!
  • 是的,我提供了许可并使用了您的相同代码。您最近是否尝试运行此代码?如果您的代码对我没有帮助,您为什么要要求投票?
【解决方案5】:

更新:对于较新的 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);

祝你好运!

【讨论】:

  • 这不再起作用了。我收到错误:权限拒绝:启动 Intent xxx 需要 android.permission.SHUTDOWN
【解决方案6】:

在较新的 android 版本中,您不能通过非系统应用关闭设备。

【讨论】:

  • 我预计我的 DeviceOwner 应用程序会被识别为系统应用程序,但显然这组答案没有任何作用(在非 root 设备上)。
猜你喜欢
  • 1970-01-01
  • 2013-02-24
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
  • 2011-11-15
相关资源
最近更新 更多