Android 以编程方式关闭设备

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24693682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:36:08  来源:igfitidea点击:

Turn off device programmatically

android

提问by Knossos

I am writing an App that is designed to run on one specific device model (an Android set-top device that runs Amlogic based firmware). I have both root capability and my App is signed with the firmware certificate.

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

My App is the main focus of the device, and it would be helpful to be able to initiate a complete power-off.

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

I do not have the shutdowncommand. I do have the rebootcommand.

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

reboot -pdoes not help. It simply freezes the device while remaining powered on.

reboot -p没有帮助。它只是在保持通电的同时冻结设备。

The PowerManageris one step better, but it sets the device into sleep mode, instead of a complete shutdown:

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

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

I am open to all suggestions - hacky or otherwise. The version of Android is expected to remain at 4.2.2.

我对所有建议持开放态度 - hacky 或其他。Android 版本预计将保持在4.2.2.



Intents

意图

This command will cause the device to reboot. Intent.ACTION_SHUTDOWNdoes not appear to do anything. Is this Intent perhaps only to report a shutdown, and not to initiate one?

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

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

The most luck I had with this was to request a shutdown by Intent:

我最幸运的是通过 Intent 请求关闭:

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


Shutdown Thread

关机线程

That is a bit closer. Definitely interesting. Can you find an example of using it?

那更近了一点。绝对有趣。你能找到一个使用它的例子吗?

So far I have come up with this:

到目前为止,我想出了这个:

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

shutdownand beginShutdownSequencecreate NullPointerExceptions (do you see why?) and rebootOrShutdowncreates an InvocationTargetExceptiondue to an UnsatisfiedLinkError... It cannot find a native method:

shutdownbeginShutdownSequence创建NullPointerExceptions(你明白为什么吗?)并rebootOrShutdown创建一个InvocationTargetException由于UnsatisfiedLinkError......它找不到本机方法:

java.lang.UnsatisfiedLinkError: Native method not found: com.android.server.power.PowerManagerService.nativeShutdown:()V at com.android.server.power.PowerManagerService.nativeShutdown(Native Method) at com.android.server.power.PowerManagerService.lowLevelShutdown(PowerManagerService.java:2163) at com.android.server.power.ShutdownThread.rebootOrShutdown(ShutdownThread.java:543) at com.android.server.power.ShutdownThread.run(ShutdownThread.java:393)

java.lang.UnsatisfiedLinkError:未找到本机方法:com.android.server.power.PowerManagerService.nativeShutdown:()V at com.android.server.power.PowerManagerService.nativeShutdown(Native Method) 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)

lowLevelShutdownis the function that all the functions eventually reach, when configured to shutdown (and not reboot). So figuring out how to avoid this link error may be key.

lowLevelShutdown是所有功能最终达到的功能,当配置为关闭(而不是重新启动)时。因此,弄清楚如何避免此链接错误可能是关键。

采纳答案by Knossos

In my case, I do not think it is possible to shut the device down how I would like to.

就我而言,我认为无法按照自己的意愿关闭设备。

The closest that I managed to get to my target was using:

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

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

That brings up a dialog to turn the device off. This is the perfect solution, but in my case, using it causes the device to crash. It may be that my device is somewhat special, and other devices will not have these restrictions.

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

In any case, I hope that my testing will help others in their quest.

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

回答by Yogesh Rathi

It work for me on rooted device. If your device is rooted then you can use below approach

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

Shutdown:

关掉:

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

Restart:

重新开始:

Same code, just use "reboot"instead of "reboot -p".

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

回答by Rodrigo Gontijo

To use this code, you need Super User! Works on 4.0 and above!

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

and put this permission on manifest:

并将此权限放在清单上:

<uses-permission android:name="android.permission.SHUTDOWN" /> 

回答by Perestroico

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

it works, just with rooted devices!!

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

回答by Silver

An update: for newer Android version, in my case is Android 8.1, they changed the action name. See below:

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

Good luck!

祝你好运!

回答by ?imon Vyhnis

In newer android versions you aren't allowed to shut down the device from the nonSystem app.

在较新的 android 版本中,您不允许从非系统应用程序关闭设备。