Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
311 views
in Technique[技术] by (71.8m points)

android - Turn off device programmatically

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.

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 shutdown command. I do have the reboot command.

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

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

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.


Intents

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

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

shutdown and beginShutdownSequence create NullPointerExceptions (do you see why?) and rebootOrShutdown creates an InvocationTargetException due to an UnsatisfiedLinkError... It cannot find a native method:

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)

lowLevelShutdown is 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...