How to create a Service which continuously monitors app usage information?

Viewed 40215

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.

6 Answers

My Thoughts,

  1. 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.

  2. 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.

  3. 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.

public class MonitoringService extends Service {

    private static final String ACTION_FETCH = "action_fetch";
    private static final int REPEAT_DATALOAD_INTERVAL_MS = 10 * 60 * 1000; // 10 Min

    private static PendingIntent makeSelfPendingIntent(Context context) {
        PendingIntent intent = PendingIntent.getService(
                           context, 0, makeSelfIntent(context), 0);
        return intent;
    }

    private static Intent makeSelfIntent(Context context) {
        Intent intent = new Intent(context, MonitoringService.class);
        intent.setAction(ACTION_FETCH);
        return intent;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (intent != null && intent.getAction() != null) {
            String action = intent.getAction();
            if (action.equals(ACTION_FETCH)) {
                loadDataFromContentProviderDoWhateverYouWantThen();
                setAlarmToRedoLoad();
                stopSelf();

            }
        }
        return Super.onStartCommand(intent, flags, startId);
    }

    private void setAlarmToRedoLoad() {
        AlarmManager alarmManager = (AlarmManager) 
                                     getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP,
                     System.currentTimeMillis() + REPEAT_DATALOAD_INTERVAL_MS,
                     makeSelfPendingIntent(getApplicationContext()));
    }

    private void loadDataFromContentProviderDoWhateverYouWantThen(){
        check this link how to load data from content provider.
        as your games app are content providers. It should be loaded easily.
        then do whatever you want display, upload anything

        http://developer.android.com/guide/topics/providers/content-provider-basics.html
    }

    // Call this method from onCreate of your monitoring app
    public static void start(Context context) {
        Intent intent = makeSelfIntent(context);
        context.startService(intent);
    }

}

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

Use this example code it is for checking if the browser is running

ActivityManager activityManager = (ActivityManager) this.getSystemService( ACTIVITY_SERVICE );
    List<RunningAppProcessInfo> procInfos = actvityManager.getRunningAppProcesses();
    for(int i = 0; i < procInfos.size(); i++){
        if(procInfos.get(i).processName.equals("com.android.browser")) {
            Toast.makeText(getApplicationContext(), "Browser is running", Toast.LENGTH_LONG).show();
        }
    }

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 the onStartCommand() 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.html

Related