I want to send device to sleep or turn the screen off. I have investigated and found this topic: Turn off screen on Android
Basically, the are three ways to do it, but I have found problems for the three:
a) Choice 1:
PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
manager.goToSleep(int amountOfTime);
Problem: It causes FC. I have read I need DEVICE_POWER permissions, but it can't be granted for normal apps.
b) Choice 2:
PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Your Tag");
wl.acquire();
wl.release();
Problem: This does not work for me. I don't know why. It does not give me a FC, but it is innocuous.
c) Choice 3:
WindowManager.LayoutParams params = getWindow().getAttributes();
params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);
Problem: I can get it to work but when try to turn on device it does strange things, like don't like to return, or if my apps is in front, automatically goes to sleep just after pressing on button. This looks more like a tip or workaround than normal solution.
Can anyone tell me any good method to send device to sleep or turn screen off that can run without problems? It sound rare to me that a simple functionality like this has not a good way to use it (or at lest well documented)
I answer myself. It is possible to turn off the device, but the application has to implement the device administrator feature via API: Device Administration
In this API there is a locknow() function that do what I want.
Anyway, this is for extending the android hardware and security features and it is very unlikely that anyone wants to control the device in that way.
What I wanted is the ability to lock the device from a simple gesture. As I dont want to make my own device manager class I check if the free application "lockScreen" is installed and launch it. It is a shortcut and an easy way to do what I want. This app must be register as device manager so it has implemented this class. It is possible to get it free from the market.
My application already does this fine, I found this in my PowerManager.class
/**
* Force the device to go to sleep. Overrides all the wake locks that are
* held.
*
* #param time is used to order this correctly with the wake lock calls.
* The time should be in the {#link SystemClock#uptimeMillis
* SystemClock.uptimeMillis()} time base.
*/
public void goToSleep(long time)
{
try {
mService.goToSleep(time);
} catch (RemoteException e) {
}
}
Related
I have created an application that generates a tracklog of the Android devices location. A GPS coordinate is recorded at regular intervals and stored on the device for later download. Currently, when the phone goes on standby, the program stops recording points. Is there a method that would allow the application to continue documenting location while the unit is on standby? Thanks in advance.
According to android documentation, if your app targets API level 26 or higher, the system imposes restrictions on running background services when the app itself isn't in the foreground. Also for accessing location in the background you may need additional permissions
You can run a foreground service with showing an ongoing notification if you want to run a service which is always alive in the background. Or you can schedule tasks using WorkManager.
I found two solutions.
1.) Use Wakelock
public void wakeLock() {
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MyApp::MyWakelockTag");
wakeLock.acquire();
}
with the following added to the manifest XML file,
<uses-permission android:name="android.permission.WAKE_LOCK"/>
or, 2.) use WindowManager to keep the device awake,
public void noSleep() {
if (bNoSleep == true){
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} else if (bNoSleep != true){
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
I've chosen the latter as a user selectable feature accessible via checkbox in the main workspace. I've also set this to engage automatically when a tracklog is initiated with the user having the option to disable this and allow standby/sleep to occur. I did implement a wakelock, but had some issues with it that may be related to a custom ROM on some of my Android devices. This is why I went ultimately went w/the windowmanager solution.
I was having problem whit android media player because when I turn off the screen the system goes to sleep mode and stop it and I didnt want that because nobody wants to listen music and have the screen on (who do that?).
I noticed that the problem was on the battery optimizations because if the mobile was plug to power cable it keeps the music playin even if it goes to sleep mode.
I tried with a lot of posibilities to fix it (reading android documentation and trying every thing I was finding in the net) but what works was this code:
public void doPower() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String packageName = getActivity().getPackageName();
PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
try {
//some device doesn't has activity to handle this intent
//so add try catch
Intent intent = new Intent();
intent.setAction(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
} catch (Exception e) {
}
}
}
}
The problem here is: The app at the beginning shows an alert asking the user to disable the battery optimizations and I dont want that, because some users may thinks "this is a bad thing" or "why its asking this?" Because an app like spotify doesnt do it.
How can I avoid the alert message? If I cant, how can I add something else to the message? (something like this: "So you will able to listen the radio with the screen turn off")
Thanks in advance and best regards.
You can't avoid that dialog and asking to avoid battery optimizations is absolutely not needed.
What is needed is a wakelock, as described in the MediaPlayer Using wake locks documentation:
When designing applications that play media in the background, the device may go to sleep while your service is running. Because the Android system tries to conserve battery while the device is sleeping, the system tries to shut off any of the phone's features that are not necessary, including the CPU and the WiFi hardware. However, if your service is playing or streaming music, you want to prevent the system from interfering with your playback.
In order to ensure that your service continues to run under those conditions, you have to use "wake locks." A wake lock is a way to signal to the system that your application is using some feature that should stay available even if the phone is idle.
If you're using MediaPlayer, this only requires you use the setWakeMode() method:
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
(Note the additional note on the documentation page about holding a wifi lock if you're streaming your media from the network.)
I am running service background to execute some tasks with some interval using AlaramManager (setExactAndAllowWhileIdle). If its connected the power charger its running. But if its unplugged device power after some i am loosing the network to my application.
Alaram is waking up the service even device is idle.But my app don't have network.
As per https://developer.android.com/training/monitoring-device-state/doze-standby.html# its restricting the network when phone is idle.I tested the same with applying phone idle ($ adb shell dumpsys battery unplug)
But is there any possible to get network access to my application even phone is idle mode.
Application is not of play store. Its really appropriated for suggestion.
I've used PowerManager.isDeviceIdleMode() in your running service to detect whether you're in Doze and if so just invoke setAlarmClock() method with 250 millis (for example) and random broadcast just to wake the device up, it'll completely wake up from doze and thus will get network access as usual. THe down side is that you lose the battery saving that comes with doze.. :D Please mark this as useful should it actually be usefull in your case.
Once your service (set up with setExactAndAllowWhileIdle()) you can go :
private boolean isDeviceInDozeMode() {
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
return pm.isDeviceIdleMode();
So now you know that you're in DOZE or not.
Then you can just set up AlarmClock and set it with setAlarmClock(AlarmClockInfo a, PendingIntent p)
And you're out of Doze with normal network access.
NOTE: Please remember that using setExactAndAllowWhileIdle doesn't mean that your alarm will go off at specified time, it will go off sooner than normal set() method, but not exact (as the method name would suggest). Generally my way isn't perfect in terms of scheduling, but it does exit DOZE programmatically once it's detected on device.
Let me know should you need more update.
I tried many options but none of them works, But finally this works to me.It might help for others.
we can always ask the user to let your app ignore battery optimization functionality using
PowerManager powerManager = (PowerManager)
getSystemService(Context.POWER_SERVICE);
Intent intent=new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
if (powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
}
else {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
and in the manifest
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"></uses-permission>
But remember this might make your app not approved by Google Play
https://developer.android.com/training/monitoring-device-state/doze-standby.html#whitelisting-cases
I am trying to make the watch vibrate at specific moments that are not at regular intervals.
I have no problem doing it when the watch's screen is on but it is not working when the watch screen dims out.
I have read a few questions on here and android developer's pages on WakeLocks and I think it's what I need... However it does not work for me. Below is my code, am I doing something wrong?
First, in my Manifest file, I have:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Here is parts of my code:
PowerManager.WakeLock wakeLock;
#Override
public void onCreate(SurfaceHolder holder) {
super.onCreate(holder);
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
}
private void vibrate(int duration) {
wakeLock.acquire();
Vibrator v = (Vibrator) getBaseContext().getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(duration);
wakeLock.release();
}
The screen doesn't turn on and the watch doesn't vibrate... What am I doing wrong?
Thank you!
If your watch doesn't vibrate when you get a notification or you're not seeing notifications at all, check your watch after each step to see if notifications start working. try the troubleshooting steps below:
Make sure that your watch isn't in Cinema mode.
Make sure that you're getting notifications on your phone.
Make sure that you haven't turned off (block) notifications for specific apps.
Make sure that app notifications and system notifications on your phone are turned on.
Check that your phone is connected to the Internet.
Make sure that your watch is paired with your phone or tablet.
Try restating your phone and your watch.
Check that these apps are up to date: Google Play Services, Google, Android Wear.
Try to awake device by using the flag FLAG_KEEP_SCREEN_ON.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
The advantage of this approach is that unlike wake locks, it doesn't require special permission, and the platform correctly manages the user moving between applications, without your app needing to worry about releasing unused resources.
Another way to implement this is in your application's layout XML file, by using the android:keepScreenOn attribute:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
...
</RelativeLayout>
Using android:keepScreenOn="true" is equivalent to using FLAG_KEEP_SCREEN_ON. You can use whichever approach is best for your app.
You need to keep the wake lock acquired for as long as you want the watch to stay interactive (and vibration to continue -- you must be in interactive to vibrate), but you seem to be releasing the wake lock immediately after acquiring it.
Acquiring wake locks can be risky, so if you're running that code from a watch face service (not clear from your snippet), start a transparent activity when acquiring your wake lock and release it when the activity dies -- this way, you are using the activity lifecycle as a means to stop the vibration and release a wake lock. This is something I implemented in the ustwo Timer Watch Faces (the watch face starts flashing and vibrating in interactive mode when the timer expires), and it's worked well.
Also, remember that to make vibration work, you need to declare the vibrate permission in the manifest:
<uses-permission android:name="android.permission.VIBRATE" />
How do I unlock phone screen when some event happens?I tried the following code but it does not unlock the screeen . By unlock I mean bypass PIN or pattern
Am using following code and its get triggered when a sms is received.
private void unlockScreen(Context context){
Log.d("dialog", "unlocking screen now");
PowerManager powermanager = ((PowerManager)context.getSystemService(Context.POWER_SERVICE));
WakeLock wakeLock = powermanager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
wakeLock.acquire();
Window wind = DialogActivity.this.getWindow();
wind.addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
wind.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);
wind.addFlags(LayoutParams.FLAG_TURN_SCREEN_ON);
}
Screen is powered on but the user has to enter PIN/pattern.How do I get over it?
Straight from the android API Site for disableKeyguard():
Disable the keyguard from showing. If the keyguard is currently
showing, hide it. The keyguard will be prevented from showing again
until reenableKeyguard() is called. A good place to call this is from
onResume() Note: This call has no effect while any DevicePolicyManager
is enabled that requires a password.
Based off that bolded statement I would probably say that you cannot do that without a password. The only way passed that is if you had yourself(app) added to the phone as a device admin, then you could control that from your device admin application of removing the password, wiping it etc.
Source : KeyguardManager.KeyguardLock & DevicePolicyManager
EDIT
I found the source code of the LockPatternUtils (I know it is from older version, but I doubt it has changed much) that is in part pattern locks and it has DevicePolicyManager all over it. I believe it has an internal service running as root in the system that does all the work. So without being a device admin, you do not even have authority to unlock the phone when it has a security setting for it.