Tracking user idle time within the app in Android

2019-02-20 15:22发布

问题:

As far as I know, there is no system API for me to get user idle time. When I say user idle time, I mean user have some interaction on the touch screen within my app. Therefore, I want to track it by my self. The way come up to my mind is to extends Activity and override onuserinteraction method to save the last user active time.

But the challenge is that my app have multiple processes. I am not sure the following way is the correct and efficient way.

I want to use SharedPreference with MODE_WORLD_WRITEABLE flag to store the user last active time. To avoid the performance issue, I also cache the last active time within the activity in each activity. And I only save the new time to SharedPrefernces if the diff time > 1 second.

Is this way efficient compared to using aidl? Actually, is aidl also share variable using file? If yes, I think the two ways should have similar performance, right? Thanks.

回答1:

Instead writing it down every time, from everywhere, make this a global function in your App:

public class MyApp extends Application {
    private static SharedPreferences sPreference;

    private static final long MIN_SAVE_TIME = 1000;
    private static final String PREF_KEY_LAST_ACTIVE = "last_active";
    private static final String PREF_ID_TIME_TRACK = "time_track";

    public static void saveTimeStamp(){
        if(getElapsedTime() > MIN_SAVE_TIME){
            sPreference.edit().putLong(PREF_KEY_LAST_ACTIVE, timeNow()).commit();
        }
    }

    public static long getElapsedTime(){
        return timeNow() - sPreference.getLong(PREF_KEY_LAST_ACTIVE,0);
    }

    private static long timeNow(){
        return Calendar.getInstance().getTimeInMillis();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        sPreference = getSharedPreferences(PREF_ID_TIME_TRACK,MODE_PRIVATE);
    }
}

Add Application class to manifest: <application android:name="com.example.MyApp"

Place saving functionality in an abstract Activity class:

public abstract class TimedActivity extends Activity {

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
        MyApp.saveTimeStamp();
    }

    public long getElapsed(){
        return MyApp.getElapsedTime();
    }

}

Now, extend all your activities from this class, all of them will be auto-save time, and will be able to use getElapsed().