Activity Recognition PendingIntent stop been called in the middle of the night - android

my application collects periodically Activity Recognition's Detected activity data.
I implemented it exactly as described in the documentation , but with one minute interval.
as long as the user is logged in - the application registered with a PendingIntent to receive updates from google play process..
please not lecture me about battery usage, network, and performance problem derived from request updates each minute, unless it have something to do with my problem:
the problem: in some devices (in Nexus 5 it happens the most), for a 5-6 hours in the middle of the night - the IntentService stopped been called.
I'm not sure, but suspects it have something to do with Google optimizations and the significant motion sensor not detecting any motion entering the activity recognition mechanism to be in sort of idle mode, as described in the documentation that can happened.
it's important to my app to know what is the current activity each minute approximately even if it stay the same, or idle for a long time..
my question:
how can I know if the periodically activity recognition stopped been called because of the significant motion sensor or from any other reason?
it there a way to force somehow the Google play process to perform activity updates without stop it for a time it assumes not needed?

Per ActivityRecognitionClient.requestActivityUpdates:
To conserve battery, activity reporting may stop when the device is 'STILL' for an extended period of time. It will resume once the device moves again. This only happens on devices that support the Sensor.TYPE_SIGNIFICANT_MOTION hardware.
As you suspected. There's no reason you cannot save the last value using the many data storage techniques - a simple SharedPreference might be enough for your case.
If you are directly triggering actions based on the IntentService being called (a bad idea since other apps may cause it to trigger extremely quickly) rather than only on changes in activity, then you should decouple those actions and instead set an alarm or trigger a periodic sync adapter for whatever specific time interval you need, reading the current value from the last activity you received.

Related

How to determine the time that the device was not being used for?

My application should detect whether the user was sleeping to start itself with a welcome message when the user wakes up and powers up his phone for the first time in the morning, afternoon, or whenever he wakes up, by pressing the power putton and entering the pattern on the homescreen or pin or whatever.
I want to do this by measuring the time the device was used the last time. I presume 8 hours of sleep, so if 8 hours passed since the last switching off, the next time the mobile phone is being switched on, the application starts(respectively a function inside).
The screen going on because of an alarm or anything but user interaction should not count.
I looked at logcat and it gave me the useful information I/PowerManagerService: Going to sleep due to power button. So a PowerManagerServiceListener could be a way. I found https://developer.android.com/reference/android/os/PowerManager.html but it is for actively keeping the display on, not for passively reporting it.
Another candidate is KeyguardViewMediator: onStartedGoingToSleep(2) and KeyguardServiceDelegate: onScreenTurnedOff().
Sure, I could create a polling application, that looks through logcat, but that sounds like a strongly battery draining approach.
Which performance friendly way is there to accomplish what I want?
According to your description, you are interested in a granularity of hours. Then you can schedule a repeating alarm every hour (see Scheduling Repeating Alarms), save the time in a Shared Preference, receive a BOOT_COMPLETED broadcast, compare the times and decide what to do.
However, I guess a lot of users don't turn their devices off, so I would try to find out if the assumption your approach is based on is valid.
You can also try getDetectedActivity() from Snapshot Awareness API and check if DetectedActivity is for example STILL at some specified interval.

Android Activity Recognition updates are not regular

Related to this question.
I am experiencing that Activity Recognition updates are not delivered on a regular basis. The power saving mode on my phone is disabled and I set the fastest possible detection interval (0), yet sometimes intents are not delivered for more than 10-20 seconds. It seems the delays mostly happen during an activity transition (e.g., still -> in vehicle), but this is just a hypothesis.
In my application I need be able to set a strict upper bound for the interval between intents, has anyone achieved something like that?
This may come a little late. However yes this is normal. I have noticed that there is a delay during a transition from activity A to activity B (e.g. from still to walking) while there is generally no delay when the activity is constant. I guess this is because the sensor tries to collect as much evidence as possible in case of activity change (e.g. to avoid returning false positives). I doubt there is any way to change that.

How to make efficient android periodic background service

I'm trying to develop an Android app that among other things, uses location services to get user location and sends it to a remote server. The user can turn this feature on and off according to his own will, but as long as it's turned on, it will get user location periodically (maybe each 30 seconds, don't know it for sure yet). Also, while it is turned on, it must keep tracking the user even if the application is closed.
So far I've considered 2 options:
Option 1 - Use Service, call startForeground to make sure Android don't kill it (the sticky notification is not an issue to me) and use a LocationListener with the said interval, but this seems rather inefficient as the service would be doing nothing most of the time, I mean, the listener would be called each 30 seconds, send the location to the server and the service itself would spend the next 29.9 seconds or whatever just waiting for the next location.
Option 2 - Doing some research, I've seen some approaches using AlarmManager to trigger some background service (like seen in this post), but I'm concerned that using alarms that often (every 30 seconds) might not be good for the battery and system general performance (in a code snippet in this page of Android's Developer guide there's a comment saying that "hopefully your alarm will have a frequency lower than 30 MINUTES").
Maybe there's another option that I still haven't thought about, or maybe there's a way to put the service from option 1 to sleep for some time or something like that. Bottom line, I'm looking for the approach that doesn't impacts on performance, consumes the minimum amount of battery and has the least chance of being killed by Android.
Any help and/or suggestions are welcome.

Which is better for repeated user notifications: A series of broadcasts, a started service or a bound service?

I'm currently developing an android application that will repeatedly ask a question to the user in randomly determined time intervals. This means it will wake up the device if nessecary, pop up an Activity, make a sound or vibration and let the user choose one of the options.
The user will be able to turn the series of pop ups on or off. The user will also be able to temporarily turn it off for a self-determined period of time. Lastly the user will be able to specify designated times of the day in which the series of pop ups will turn on or off automatically.
I already know how to schedule Activities and BroadcastReceivers with AlarmManager. I also know how to wake the device up by looking at the source code for the alarm clock on android.
My question is how to best implement it with the Android framework. When the pop up series start my application needs to randomly determine in which interval the next pop up will occur. When the time has come for the notification to be displayed. The Activity will pop up (already implemented) and immedeately the next pop up time will be randomly calculated. When the user has not answered the question in the pop up when it is already time for the next pop up, the application must know that. The application must also be able to determine when is has to start and stop its pop ups as specified by the user. At all these points something must be called.
I'm wondering if I could best do all this with a BroadcastReceiver receiving a series of different actions by Intent. Or should I use a Service doing all the work. And if I use a service is it best to send it different commands through onStartCommand() or should I rather bind to it and call the methods through the Binder?
I found the source for the alarm clock rather confusing on this matter and I'm unsure which method is the best. They all seem to have their strong and weak points.
Services can have 'states', but the system may decide to destroy it to free memory, thus losing this data. Scheduled BroadcastReceivers will be remembered by the AlarmManager, but they are 'stateless'.
With bound Services you can communicate both ways, but it takes some time to accuire the Binder. Started services can be given quick commands through onStartCommand(), but cannot directly communicate with Activities.
The decision remains hard...
The decision remains hard...
There is only one answer: use AlarmManager with a BroadcastReceiver. Nothing else can reliably wake up the phone. That BroadcastReceiver, in turn, should acquire a WakeLock and start up your activity. The activity can use android:keepScreenOn to keep the device awake while the activity is in the foreground; the activity should release the WakeLock acquired by the BroadcastReceiver in onCreate() after the call to setContentView(). The activity can schedule the next alarm based upon user input or lack thereof.

Android background service and AlarmManager

I am coding an android application that gets the user position every 5 minutes, stores it in the database and sends it to a server.
I have read many ways of doing it, I was going to do the following:
User starts the application
The main UI activity starts a service.
The service runs in background and keeps turning on and off the gps, and creating new
threads that will save to database,and send the data to the server.
But I have seen that it can be done with a "Remote service" (http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html) or with an AlarmManager that schedules starting this service every 5 minutes.
The service will need to be running always: it is important that after every interval (5 minutes), it is executed.
I think I need some clarity here.
Thank you for your help,
I am coding an android application that gets the user position every 5 minutes, stores it in the database and sends it to a server.
Please allow the user to choose the location provider. Not everybody has GPS on their device. Not everybody has GPS enabled. And, not everybody will want the power hit of GPS being turned on every five minutes.
Please allow the user to choose the polling period, including "never poll -- I'll refresh the information manually from the activity". Also, please honor the background data setting (deprecated as of ICS).
I think I need some clarity here.
If the polling is supposed to go on even if the activity is not in the foreground, use AlarmManager. However, most recipes for using AlarmManager will have the real work (in your case, GPS fix and network I/O) be handled by an IntentService. This will not work in your case, because GPS is asynchronous -- you cannot just get a fix whenever you feel like it. It will take a long time, possibly forever, to get a fix, so you have to deal with the delay and eventually timing out the operation. Writing a Service to do this is possible, but tricky, particularly if you are aiming to collect this information even if the device falls asleep.
If, however, the polling is only supposed to go on while the activity is in the foreground and the device is on, I wouldn't bother with a Service at all. Just have the activity use postDelayed() to set up an every-five-minutes scheduled bit of code to run, then have it do the work.

Categories

Resources