I program an application, which is connected to bluetooth device and used in a car (in the background) and navigation (or something else) in the foreground.
But on android 7+ (maybe also 6), application go to sleep after some time. When I'm trying to take picture from camera the "sleep mode" is immediately and my app is sleeping now (no bluetooth connection, no notifications) - just dead app.
I must go to recent apps -> click on my app and this make the "wake up". Bluetooth is now connecting to device again.
But I can't still check if the app is sleeping or not. So, how to keep app awake also in background?
I read some about WakeLock, but it looks like it's not working, cause app still sleeping. BUút maybe I'm using it wrong.
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wk = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MyWakeLock");
wk.acquire();
and onDestroy
wk.release();
Thanks
From Android API 23 onward, Google has introduced Doze mode and App Standby in order to conserve battery power. When a device enters doze mode or an app enters App Standby, all tasks done by an app is deferred. We had an issue with an Alarm which was not firing because of the same. If you read upon docs, you will find that using a Wake Lock is not gonna help either.
Doze restrictions The following restrictions apply to your apps while
in Doze:
Network access is suspended.
The system ignores wake locks.
Standard AlarmManager alarms (including setExact() and setWindow()) are
deferred to the next maintenance window. If you need to set alarms
that fire while in Doze, use setAndAllowWhileIdle() or
setExactAndAllowWhileIdle(). Alarms set with setAlarmClock() continue
to fire normally — the system exits Doze shortly before those alarms
fire.
The system does not perform Wi-Fi scans.
The system does not allow sync adapters to run. The system does not allow JobScheduler to run
So if you want to bypass all these, your app must have a process in the foreground. Once again from the same doc -
The app has a process currently in the foreground (either as an
activity or foreground service, or in use by another activity or
foreground service).
In your case run a service and raise it's priority to foreground.
for wakelock to work, u should add this line to your androidmanifest file at the beginning. but as Ajay said, u should use a service so that the service works in background and do the job but if you want to keep the screen on that's something else which i think it is not the case here.
<uses-permission android:name="android.permission.WAKE_LOCK" />
xml layout file under layout type:
android:keepScreenOn="true">
why don't you use service? WakeLock basically keeps the screen on which is not an efficient mechanism
https://developer.android.com/training/scheduling/wakelock.html
Related
Context
We are developing an android app that is supposed to do the following:
the user installs the app, registers and closes the app
once or twice a year an admin sends a Firebase data message with priority high to the user containing a geo fence
the FCM message starts a JobService that locates where the phone is
if the phone is inside the given area an Activity is started and user interaction starts
if the phone is outside the area the service is stopped and the user is never disturbed
I developed the app based on the Firebase push example found here
The problem
The application works fine on my older phones but on my new test phone (android 8.1.0, LineageOS 15.1) we have a problem when the phone is in sleep mode. In this case the FCM message arrives instantly but the service is first started once the phone is unlocked. So the message is stuck between 2. and 3.
We need the app to respond at once - not when the user decides to use his phone 2 hours later.
I assume the problem is due to the Doze mode introduced with android 6. I tried to solve it by adding the app to the whitelist in settings->battery->battery optimization but this did not solve the problem.
Questions
Is it Doze mode that delays my app between 2. and 3.? If so why is it not solved when the app is in the whitelist?
Is there any other way to start the location service at once? This post suggests that a foreground service can do it but this requires that a notification is shown which breaks with 5.
Is there another way to start my service at once besides whitelist and foreground service?
Yes! you are right this may be due to the Doze and App Standby features introduced in API 23 Marshmallow.
As mentioned in the documentation, the system do ignore wakelocks and system doesn't allow JobScheduler to run, which effectively prevents your app from running the Job.
An easy and effective workaround would be to run Location detecting routine inside a normal background service and start it using startService() when you receive FCM push.
Note that you might still need to white-list your app because as mentioned in another post here, only a whitelisted app can use the network and hold partial wake locks.
Is it Doze mode that delays my app between 2. and 3.?
From the documentation Doze mode affect Network access and blocks JobScheduler.
If so why is it not solved when the app is in the whitelist?
Also from the documentation: An app that is whitelisted can use the network and hold partial wake locks during Doze and App Standby. However, other restrictions still apply to the whitelisted app, just as they do to other apps.
So the blocking of JobScheduler still applies.
Is there any other way to start the location service at once? This
post suggests that a foreground service can do it but this requires
that a notification is shown which breaks with 5.
Ignore Battery Optimizations (for Internet access) in combination with an AlarmManager with setAndAllowWhileIdle() or setExactAndAllowWhileIdle() should work.
Be careful with Ignore Battery Optimizations
Google Play policies prohibit apps from requesting direct exemption from Power Management features in Android 6.0+ (Doze and App Standby) unless the core function of the app is adversely affected.
I think an important question here is: Do you really need to execute the JobScheduler immediately.
If a user leaves a device unplugged and stationary for a period of time, with the screen off, the device enters Doze mode.
If the device is in Doze mode, it means the user is not using it.
if the phone is inside the given area an Activity is started and user interaction starts
This is the step Doze blocks
We need the app to respond at once - not when the user decides to use his phone 2 hours later.
If the device is in Doze it means the user is not interacting with it. Even if you show the Activity the user is not using the phone, he will see it when he starts using it 2 hours later :)
I still didn't try that,
but you might use a WakefulBroadcastReceiver:
https://developer.android.com/training/scheduling/wakelock.html
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html
According with this links, you should declare your receiver as:
public class YourReceiver extends WakefulBroadcastReceiver {
Probably your receiver is already a WakefulBroadcastReceiver because notifications are showing..
In the receiver, you start the service (your service has to be an IntentService) using:
startWakefulService(context, your service);
Finally, remember to release the wake lock in the service:
#Override
protected void onHandleIntent(Intent intent) {
<Your_broadcast_receiver_class>.completeWakefulIntent(intent);
}
I hope it helped
I have an android application that uses Geofence and I'm having a hard time overcoming Doze mode. My manifest has the WAKE_LOCK permission and seven setNotificationResponsiveness to 0 for each region. I even changed PendingIntent to BroadcastReceiver but the app literally sleeps or is dead after a while with the deleted smartphone screen. I've already tried using LocationRequest
LocationRequest.setFastestInterval(1000);
LocationRequest.setInterval(2000);
Even so, I did not succeed. Has anyone managed to keep the application running with the Doze?
I faced the issues in My Chatting application and Location Tracking applications, While in doze mode we will not get any push, or we will not get any network connection or location details and most of the background operation will be blocked because of battery optimization, We can solve by 2 ways.
Priority push message(I used in my chatting application) - If you send normal push it will not reach the app until the mobile come to normal, If you send priority push it will reach the app you can do some process within few seconds, but this also have some limitation.
Foreground service, - For your scenario this is the best solution, You should have on service and that service should run as Foreground service so that you can get the Location information all time even in Doze mode.
WAKE_LOCK permission in the manifest is not enough for use a Wake Lock , you need to acquire and release the lock in your code, but starting with Android 6 Doze mode it goes to deep sleep also with an acquired wake_lock.
The way that works for me also with Doze mode :
In the Main Activity onStop I acquire a Partial WakeLock and I start a Service with STARTFOREGROUND_ACTION intent, the Service calls startForeground and shows a Notification.
On Activity onResume the WakeLock is released, the Service stops with STOPFOREGROUND_ACTION intent and the Service itself calls stopForeground & stopSelf.
I ended up putting my application to receive push messages. Apparently the app is no longer being killed by the operating system.
I made the device which monitors person's health in sleep time and it connects to a smartphone via BLE.
It's working great with the iOS app.
But since Doze mode came on Android world.
It's really hard to deal with it because my device is working in his sleep time.
The main feature is that it detects particular danger and notify to the user while he is sleeping with the device. I need a network connection when it occurs.
Many articles tell me that I can use a network even in the doze mode if my app is in the whitelist. But it does not seem true after I tested Doze mode.
Am I right?
I can ensure that I can find my app in the lists, when I fire
adb shell dumpsys deviceidle
What is the best approach that I can take to make my app working correctly?
foreground services
alarm manager with SetExactAndAllowWhileIdle.
GCM (it means push, right?)
anything else
Any tips will help me.
Thanks.
Edit
Unfortunately, I tested with using GCM but it only wakes my app in short time. It means I have to send GCM as many as I want to keep it awake. I don't think I can use it.
Many articles tell me that I can use a network even in the doze mode if my app is in the whitelist. But it does not seem true after I tested Doze mode. Am I right?
You are not right. One of the restrictions of doze that are lifted when your app is on the whitelist, is the ability to use the network when doze is active.
An app that is whitelisted can use the network and hold partial wake locks during Doze and App Standby. However, other restrictions still apply to the whitelisted app, just as they do to other apps. For example, the whitelisted app’s jobs and syncs are deferred (on API level 23 and below), and its regular AlarmManager alarms do not fire.
From here.
In other words: you should be able to use the network in doze if you are on the whitelist.
What is the best approach that I can take to make my app working correctly?
Considering your app is a health monitor and thus should be able to do its work constantly or at least very regularly, you could put the functionality in a foreground service. Foreground services are not effected by doze.
You should be aware that you should have a good reason to use a foreground service since the user is aware of them, but I think you have one with the health monitoring etc.
Note: You should only use a foreground service for tasks the user expects the system to execute immediately or without interruption. Such cases include uploading a photo to social media, or playing music even while the music-player app is not in the foreground. You should not start a foreground service simply to prevent the system from determining that your app is idle.
From here.
I m new to android world n m trying to make an app that wakes up my device from standy mode at a particular time.
I tried a few places where they mentioned about wakelock but this thing just prevents the device from going into standy mode.
I basically want my device to wake up from standby mode.
Like take the example of alarm clock... once set i can leave it and at that time from standby mode I get to see that the phone is active.
I even tried developer site for android... but it wasn't much helpful!
Any help would be highly appreciated!
You have to use Alarm Manager to schedule a repeated alarm (use RTC_WAKEUP for type parameter).
Then your code will execute even if the device is sleep. but notice that the registered alarm will removed once the device is restarted so you have a re-schedule the alarm again (by listening to boot broadcast)
I am writing a Android client app which keeps receiving push notifications from a server using HTTP long-polling(Comet).
I don't want to always keep WakeLock since it will drain battery, but I need to make sure the device can receive notification even when it is in sleep mode.
And I found this question:
Android: Sleep stages/levels on an Android device?
where "CommonsWare" mentioned that an incoming packet on a non-Wifi socket will wake up the device.
So my solution looks like this:
Client ------------------------- Server
---- Request----->
release WakeLock (Allow device to sleep)
<----Notification-- (Hopes it can wake up the device)
require WakeLock
process the notification
---- Request----->
release WakeLock
....
But there is a little time window between receiving the notification and requiring the wakelock, so my question is, how long will the device keep this awake state? Is it possible for the device to back to sleep during this time window?
The device will be awake for long enough to execute some short code in the BroadcastReceiver. I have not been able to find an exact number of millis, but the idea is that in your receiver, you should grab whatever WakeLock you need to proceed with your own processing.
However exact management of the WakeLock can be tricky. I recommend using #CommonsWare's WakefulIntentService:
https://github.com/commonsguy/cwac-wakeful