Problem at Hand:
I have to create a Service
which runs continuously. This service monitors 5 apps say 5 android games installed on your phone. This service needs to get the information of:
1. How many times is the game opened and run?
2. For how much time each game has run.
for example: Say If I have this service installed in my app. And I let it run for a month. I need information of this kind on the screen of the app:
Game Number of times the game is run Duration of Game play
Game 1 20 times played for 15 hours in total
Game 2 16 times played for 25 hours in total
..
..
Game 5 10 times played for 12 hours in total
Possible Approach: When an application loads it comes in the memory. Noting the system clocks time while the application starts. And when the application ends or is put in the background noting the time again.
So say if an application is brought to memory at 9:00 pm and exits to background at 9:30 pm that gives us a gameplay time of 30 mins. Next time the application is played the duration will be added to 30 from the previous play stored in some sort of variable and so on. Each time an application is brought into the memory the counter of it being played should increase by one. Hence giving us the number of times an application is played.
Coding:
I have no idea about Service
in Android as I have never really worked on them. Any tutorials related to my problem at hand will be very helpful.
Secondly, if there is another way in which this could be done. I would like to know that as well. I could really use some code snippet for me to start this project.
My Thoughts,
Develop application that makes some of their data public to other process to access them.
Google "How to use content providers".
Each of your application will need to keep record of all the activity they performed. This data will be public to be accessed.
You dont need to run a service all the time for this then. Whenever your monitoring app gets opened. It just need to fetch that data from all the applications you want and display them accordingly.
For a case you want to submit that data on server periodically in background. Then you need a service. But still you dont need to run it forever. Do something like this.
i) From service fetch data and upload to server.
ii) Stop service and schedule an alarm after some time T1 to start your own service again to do step 1 again.
iii) T1 depends on requirement. How refresh data you want on server.
I can even tell you code pieces pointer if you want for how to implement what i said above. But i suggest you to find that on google and do it yourself first. Post another specific question on StackOverflow if you face any difficulty in that.
Hope this helps. :)
Edit:
Firstly. Its only you who has to code in the end. Take pointer and help from here. Dont expect full code. Check more details below.
A)
You need to make your apps as Content Provider. Check the link below. and follow the examples in it. You will end up in a app whose data will be available to others. Its easy go ahead.
http://developer.android.com/guide/topics/providers/content-providers.html
http://developer.android.com/guide/topics/providers/content-provider-creating.html
http://www.vogella.com/articles/AndroidSQLite/article.html
All your games app needs to make data public to be accessed. Now once you are done with this.
Now you just need to access all the data in your monitoring app and display it.
B)
As i said if you want to do this via service. You dont need to run it forever. Just start service for once, loads the data from content provider and do whatever you want to do. Set an alarm to invoke the service at a later stage to re do the same operation.
I assume if every 10 min your service can fetch data from content provider(Your games app that you want to monitor). It will be like following.
C) make sure you allow user of your monitoring app to stop this service anytime. Dont forget to cancel alarm in that case. so it dont run in background forever.
D) You can also make things broadcast based. Whenever your games app saves data they should broadcast this event and let your service gets invoked after listening that broadcast. loads it then only.
E) As Phill also stated you can go for Google Analytics as well.
How you want to actually do this is now depends on your requirement
Hope this helps. Try it out and let me know what more issue you are facing
Installing Covenant Eyes on your Android device will monitor all Internet traffic on the phone’s pre-installed browser and report additional apps that are being used onto the device.
Use this example code it is for checking if the browser is running
To create a service you have to create a class that extends from Service base class and implement the function in an infinite loop such as
while(true)
in theonStartCommand()
function. don't forget to add your service in the manifest file between<service></service>
tags , a good tutorial is on http://www.vogella.com/articles/AndroidServices/article.htmlAs you wrote that the task is about monitoring 3-rd party applications, there is no solution other than periodically read a list of processes and detecting foreground process. You need a service for this. Unfortunately, Android does not provide means such as broadcast events for foreground process change.
The task requires a lot of code in fact, at least much more than an ordinary answer could comprise. I'm posting a part of it here, but you should address many nuances left behind the scenes, such as synchronization and persisting information between launches. This is just a skeleton.
First, lets code an application object, which is a good place to register all instance related stuff.
MonitorApp
Then lets draft an activity.
MonitorActivity
The activity launches a background worker service, which does actually monitor processes. You could possibly move the service registration from the activity into the application instance. The service itself is something like this:
MonitorService
The service utilizes a helper class for building process lists.
ProcessList
Finally, the manifest.
AndroidManifest.xml
As you may see, it's already a lot of code. It's partially extracted from a working application, but I made fast changes for your needs, so there may be typos, all imports are skipped, etc. Nevertheless, I hope this helps a bit.
ADDENDUM: Lollipop+
Beware: the latest Android versions broke the abovementioned approach. Here is what the official documentation says about getRunningTasks method and others:
I think this is an overkill and could be done in much more selective and convenient way. Not to mention that this seems too theatrical considering many built-in features from Google with privacy concerns. Anyway, we can do nothing with this.
The only workaround is to implement Android accessibility service (more info here and here) and intercept all actions with applications gaining and losing focus from there. The user should enable the service manually! Your application should somehow direct the user to do so.
Following solutions based on the assumption that you own all five apps you are trying to monitor. If it other wise i will provide you another solution.
Let's breakdown the problem now.
You should use
Intent
to broadcast messages about your app running or not. Use activityonPause
andonResume
to broadcast messages.Now call this function from onPause and onResume,
and you can call this like the following way
Or
So why onPause and onResume because gamer is playing game only between these functions calls.
Designing Service
Use
IntentService
and read this if you wanna know why.Storing
ContentProvider
is a good option for storing data, and it is also very powerful; integrate and scale well on Android, but in this case seems like you only want to store some very simple information and as such you can also pick something very simple.Code bellow uses
SharedPreferences
.just call these method from
onHandleIntent
.Last piece of puzzle would be distribution. You can distribute this on a separate app or part of these five apps. Separate apps is the easiest route to take. But if you choose to use this as a part of all five of these apps, read this discussion.
To get the current running application you can use:
You can check this periodically from your running service. You will need also define a required permission in your manifest:
android.permission.GET_TASKS