3

I'm making an app that tracks user activity in the background using ActivityRecognition API, and if the user remains in the same place for specified period of time(e.g. 1 hour), then system pushes notification telling user to take a walk. I have implemented activity recognition, but only for the cases when the app is opened. Obviously, the Google API Client needs to keep connected in order to send activity updates. My questions is - for activity tracking in background, what would be a better solution:

1) To implement AlarmManager in the main activity (or separate activity) that once in 30 seconds wakes the activity, connects Google API Client to Play Services, then sends PendingIntent to IntentService for activity analysis

2) Create a separate Service (not IntentService) to continuously run on background (separate thread), that will keep API Client connected, and send activity updates to IntentService. Hence, the system would have 2 services: 1) Service to keep API client connected to Play Services and send regular activity updates to IntentService for analysis; 2) IntentService for receiving activity updates form Service, and analyse the data.

3) Some other solution (offered by you guys)

Comments: My tutor suggested me to use AlarmManager, but you usually use it for things like network updates, hence the interval is generally more than 10 minutes whereas I need 30 sec - 1 min. So I am hesitant to use it.

I also have seen many similar questions on here before, but I haven't found any clear answer.

ar_shabazov
  • 398
  • 1
  • 4
  • 13
  • Have you considered using Geofences or monitoring the Accelerometer with a wakelock? – Veener Sep 18 '16 at 00:08
  • Question similar to http://stackoverflow.com/questions/28380527/detect-phone-movement-when-screen-is-off – Veener Sep 18 '16 at 00:09

2 Answers2

7

Actually, a connected GoogleApiClient is only required for requesting and removing activity updates - you do not need a connected GoogleApiClient to receive activity updates.

The requestActivityUpdates() documentation actually specifically mentions working in the background:

A common use case is that an application wants to monitor activities in the background and perform an action when a specific activity is detected. To do this without needing a service that is always on in the background consuming resources, detected activities are delivered via an intent. The application specifies a PendingIntent callback (typically an IntentService) which will be called with an intent when activities are detected. The intent recipient can extract the ActivityRecognitionResult using extractResult(android.content.Intent). See the documentation of PendingIntent for more details.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • So if I connect Google Client in the main activity, and from there implement method for continuously sending PendingIntents to IntentService with activity data, does that mean it will still keep sending the data to IntentService, even after the main activity itself is destroyed? Also how should the recipient of data be implemented: as a normal activity with some broadcast receiver, or maybe I should extract the result in the IntentService itself? Sorry I read too many post on stack overflow relating to similar issues, and the wide variety of answers got me really confused at this point. – ar_shabazov Sep 18 '16 at 06:27
  • @Gideon - yep, you'll continue to receive activity updates even after the main activity is destroyed. Following the advice right from the docs and using `extractResult` in your `IntentService` will be the right choice the vast majority of the time. – ianhanniballake Sep 18 '16 at 15:39
  • One more question, after creating client object and requesting activity updates, then if we quit the app, thus destroying client object, and open it again to remove the activity updates, does the new client object that we create and supply to the system in the remove activity updates method need to be the same object that we created for requesting updates, in another words, does the client object need to have some sort of id so that the system will remove updates for specific client object; or does it not matter to the system, as long as we provide any client object? – ar_shabazov Sep 19 '16 at 00:24
  • 1
    There's only one global activity recognition request per app, so any client is fine for removing (and as per the `request` documentation, any subsequent calls to `request` simply replace any existing request) – ianhanniballake Sep 19 '16 at 00:28
  • Thank you very much Ian, you are life saver, and sorry for not so bright questions, I am still a newbie in Android – ar_shabazov Sep 19 '16 at 00:34
  • Everyone starts somewhere :-) Make sure to read over the documentation carefully - you'll note that most of the answer here was pulled directly from the documentation – ianhanniballake Sep 19 '16 at 01:46
  • Do we still get the activity updates even after the App has been killed. My use case is to register for an activity update from the App. Since then, the App could be killed by user but when the intended Activity update happens, I should get the callback. – Dibzmania Mar 19 '19 at 05:19
1

I would recommend a different approach. The problem with the Google Activity recognition API is that you cannot be confident about it reporting a certain event until its confidence level is >75. To have a confidence level of >75, you need to increase the detection level, which in turn can consume a lot of battery. I’d recommend trying some free SDKs like Atooma, tranql or Neura (you can find them online). These give you much better insights about your users and, in some cases, consume only around 1% of your battery life

johndaly
  • 115
  • 7