I want to lock screen (actually to trigger long click to show system dialog "turn off the phone?") via click button. Is it possible ? I found some examples like:
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
But they don't work. Maybe I can switch phone off programmatically in other way? I found information that it's impossible so I'm trying to implement it like long click on lock button.
UPD:
I found this:
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot -p" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
But it also doesn't work. I'm testing it on emulator, will it work on real phone?
Thanks everyone for answers in advance !
Here is the most usual way of requesting shutdown:
Intent i = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
i.putExtra("android.intent.extra.KEY_CONFIRM", true);
startActivity(i);
Other methods you mentioned don't work because a regular app does not have the permission to run those (for obvious security reasons).
Related
How to do Android device factory data reset from application level?
I tried to run command with su, but it's not working. I have tried two ways:
1)
public void onClick(DialogInterface dialog, int which) {
try {
Process proc = Runtime.getRuntime().exec(new String[] { "su", "–wipe_data" });
proc.waitFor();
} catch (Exception ex) {}
}
2) when clicking a button, I'm calling device setting application, but I also did't get factory data reset.
startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0);
How to call settings->storage&reset->factory data reset directly from my app?
You should use the Intent.ACTION_MASTER_CLEAR to factory reset from your application. You might need to have appropriate permissions for your app (system/signed) to do this.
In case you don't have the required permissions / it's not possible for your app to get to the appropriate permission level, as an alternate, using am broadcast -a android.intent.action.MASTER_CLEAR from su shell might work.
first question here and I am pretty knew to Android development so excuse me.
For part of my app I would like to add a button that can restart the systemui, I am doing this by the following code.
#Override
public void onClick(View v) {
ActivityManager activityManager = (ActivityManager)getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
activityManager.killBackgroundProcesses("com.android.systemui");
}
I have gave the application SU permission with the following code
public Process p;
{
try {
p = Runtime.getRuntime().exec("su");
} catch (IOException e) {
e.printStackTrace();
}
}
Many thanks in advance.
You should have the permission KILL_BACKGROUND_PROCESSES to be able to call this method.
su doesn't play a role here, because you are using android's framework for this operation. If you use busybox to kill the process, than you need su.
Generally, it is not a good idea to kill SystemUI, though.
SystemUI cannot be killed by using Android framework's features. You should use Runtime.getRuntime().exec("su -c killall com.android.systemui"); if you want to kill SystemUI with root. Note that the sereen will go black until SystemUI is restarted soon.
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.
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.
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".
Runtime.getRuntime().exec(new String[]{ "su", "-c", "reboot -p" });
it works, just with rooted devices!!
To use this code, you need Super User! Works on 4.0 and above!
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" />
An update: for newer Android version, in my case is Android 8.1, they changed the action name. See below:
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!
In newer android versions you aren't allowed to shut down the device from the nonSystem app.
I am developing an Android application and we need to power off the device under certain circumstances.
I have read in many places that you need a rooted phone in order to do so. Then, you can issue the "reboot" command by using Java's API:
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot -p" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
I have actually tried this in a Cyanogenmod 10 device (Samsung Galaxy S3), and it works. However, we do not want a rooted device in order to power it off, since the end user will then be able to do unintended things which are not allowed by our company.
On the other hand, our application is signed by the manufacturer's certificate, in this case Cyanogen's. I have read that by signing your application with the manufacturer's certificate, you should be able to issue privileged commands (as if root). However, even if I install my app as a system app signed with the manufacturer's certificate, the above code does not work:
If I leave the "su" part of the command, the "Superuser Request" screen is displayed, but that's something we are trying to avoid.
If I remove the "su" part (just leaving "reboot -p"), the command is silently ignored.
As a result, we are not being able to poweroff our device with our system app, which is signed with the manifacturer's certificate. So my question is, how am I supposed to do that?
EDITED
And, by the way, just in case someone is not sure about it: the application is properly signed and installed as a system application, because we can actually access some restricted APIs, such as PowerManager.goToSleep()
If you want the device to reboot (power off and on), then try PowerManager.reboot()
PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
powerManager.reboot(null);
android.os.PowerManager:
/**
* Reboot the device. Will not return if the reboot is successful.
* <p>
* Requires the {#link android.Manifest.permission#REBOOT} permission.
* </p>
*
* #param reason code to pass to the kernel (e.g., "recovery") to
* request special boot modes, or null.
*/
public void reboot(String reason) {
try {
mService.reboot(false, reason, true);
} catch (RemoteException e) {
}
}
UPDATE
If you want the device to completely turn off, use PowerManagerService.shutdown():
IPowerManager powerManager = IPowerManager.Stub.asInterface(
ServiceManager.getService(Context.POWER_SERVICE));
try {
powerManager.shutdown(false, false);
} catch (RemoteException e) {
}
com.android.server.power.PowerManagerService:
/**
* Shuts down the device.
*
* #param confirm If true, shows a shutdown confirmation dialog.
* #param wait If true, this call waits for the shutdown to complete and does not return.
*/
#Override // Binder call
public void shutdown(boolean confirm, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
final long ident = Binder.clearCallingIdentity();
try {
shutdownOrRebootInternal(true, confirm, null, wait);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
This was working fine for me:
startActivity(new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN"));
you need this permission ( depends on being system-app ):
<uses-permission android:name="android.permission.SHUTDOWN"/>
source:
https://github.com/sas101/shutdown-android-app/wiki
OK, my mistake.
As I performed some tests, I did not realize that I had removed "android:sharedUserId="android.uid.system" from the manifest.
Once the sharedUserId is included, the following code works without prompting the user to confirm root access:
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot -p" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
I tried to remove "su" (because the system may not provide such a command), but in that case it does not work. Surprisingly, the file system is remounted in read-only mode, so I must remount it again with write permissions.
this is for kotlin
(requireContext().getSystemService(Context.POWER_SERVICE) as PowerManager)
.reboot("reason")
I had caught phone boot event.
On boot complete event I am writing following code
KeyguardManager mKeyguardManager = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
KeyguardLock mLock = mKeyguardManager.newKeyguardLock("MyApp");
mLock.disableKeyguard();
but what happing I can able to see lock and after that screen is getting unlocked. But requirement is that lock should not be visible at all after booting.
My guess is that I need to make modification in framework somewhere in setting file.
But I don't know where to modify.
but what happing I can able to see lock and after that screen is getting unlocked
You did not lock the screen. Hence, you cannot unlock it. disableKeyguard() is only used to reverse the effects of reenableKeyguard().
My guess is that I need to make modification in framework somewhere in setting file.
If by "setting file" you mean "Java, or possibly C/C++, source code", then yes that is probably the case.
But I don't know where to modify.
StackOverflow is not a great resource for assistance with firmware modifications, sorry.
I have did it by commenting following code in KeyguardViewMediator
private void showLocked() {
/* if (DEBUG) Log.d(TAG, "showLocked");
Message msg = mHandler.obtainMessage(SHOW);
mHandler.sendMessage(msg);*/
}