Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I track "screen on" time on Android?

Tags:

android

screen

I'm trying to do something (theoretically) simple with my first app, but I need some help getting started. I'd like to build an app that tells me how long the screen on my Nexus 4 has been on today.

Android shows me how long the screen has been on since last charge via Setting > Battery > Screen, but I'm not sure how to parse this data, or how to limit it to the current day. My research so far indicates that batterystats.bin is involved with screen tracking outlined above, and that I might be able to use ACTION_SCREEN_ON and ACTION_SCREEN_OFF for this, but I'm not sure if that's exactly what I'm looking for.

Any ideas?

like image 354
Alex Johnson Avatar asked Feb 10 '14 09:02

Alex Johnson


2 Answers

I know this is a old question but hopefully this will help someone.

Within my service i listen for SCREEN_ON/SCREEN_OFF actions and grab the difference between the two times and save to sharedpreferences within onDestroy callback.

    BroadcastReceiver mybroadcast = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("[BroadcastReceiver]", "MyReceiver");

        if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
            startTimer = System.currentTimeMillis();
        }
        else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
            endTimer = System.currentTimeMillis();
            screenOnTime = endTimer - startTimer;

           if(screenOnTime < TIME_ERROR) {
               times.add(screenOnTime);
           }

        }

    }
};

The service is started on boot and when the package is replaced (I find it helpful for debugging).

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent(context, ScreenOnService.class);
        context.startService(i);
    }
}

And here is my manifest for the broadcast receiver

        <receiver android:name=".BootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <data android:scheme="package" android:path="com.application.test" />
            </intent-filter>
        </receiver>
like image 167
Nick171 Avatar answered Sep 21 '22 02:09

Nick171


Another solution can be to call

UsageStatsManager.queryEvents

with the start of the day as first parameter and the current time as end parameter and then filter the results to check just the

UsageEvents.Event.SCREEN_INTERACTIVE UsageEvents.Event.SCREEN_NON_INTERACTIVE

events

take the timestamp of each of them and sum all the time passed between each

SCREEN_INTERACTIVE -> SCREEN_NON_INTERACTIVE

events, this would easily show how much time the screen was interactive, so screen on and the touch enabled.

There is a possibility that you'll have a SCREEN_INTERACTIVE event that doesn't have any related SCREEN_NON_INTERACTIVE, this is when the

UsageEvents.Event.DEVICE_SHUTDOWN

event happen, luckily this event is in the same list returned by the queryEvents method

remember also to declare and make the user to allow the android.permission.PACKAGE_USAGE_STATS permission as stated here

ps. i haven't used this yet but looking at the documentation it's the right thing to use, probably the one used by the android settings pps. look also to the other events in the same package, they might be helpful to what you want to accomplish

like image 38
Sambuccid Avatar answered Sep 21 '22 02:09

Sambuccid