am 8d7be7b7: Update Settings to use new UsageStats API

* commit '8d7be7b738cce9facdd8832aa845ceb79c19ffc6':
  Update Settings to use new UsageStats API
This commit is contained in:
Adam Lesinski
2014-07-18 22:29:04 +00:00
committed by Android Git Automerger
5 changed files with 90 additions and 97 deletions

View File

@@ -27,7 +27,7 @@
android:paddingEnd="6dip" android:paddingEnd="6dip"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<TextView <TextView
android:text="@string/launch_count_label" android:text="@string/last_time_used_label"
android:paddingEnd="6dip" android:paddingEnd="6dip"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -31,7 +31,7 @@
android:paddingStart="12dip" android:paddingStart="12dip"
android:maxLines="1" /> android:maxLines="1" />
<TextView android:id="@+id/launch_count" <TextView android:id="@+id/last_time_used"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"

View File

@@ -441,7 +441,7 @@
<!-- Display options for UsageStats class --> <!-- Display options for UsageStats class -->
<string-array name="usage_stats_display_order_types"> <string-array name="usage_stats_display_order_types">
<item>Usage time</item> <item>Usage time</item>
<item>Launch count</item> <item>Last time used</item>
<item>App name</item> <item>App name</item>
</string-array> </string-array>

View File

@@ -3474,8 +3474,8 @@
<string name="display_order_text">Sort by:</string> <string name="display_order_text">Sort by:</string>
<!-- label for application name --> <!-- label for application name -->
<string name="app_name_label">App</string> <string name="app_name_label">App</string>
<!-- label for launch count --> <!-- label for last time used -->
<string name="launch_count_label">Count</string> <string name="last_time_used_label">Last time used</string>
<!-- label for usage time --> <!-- label for usage time -->
<string name="usage_time_label">Usage time</string> <string name="usage_time_label">Usage time</string>

View File

@@ -16,23 +16,24 @@
package com.android.settings; package com.android.settings;
import com.android.internal.app.IUsageStats;
import com.android.settings.R;
import android.app.Activity; import android.app.Activity;
import android.app.usage.PackageUsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager; import java.text.DateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -48,116 +49,109 @@ import android.widget.AdapterView.OnItemSelectedListener;
* Activity to display package usage statistics. * Activity to display package usage statistics.
*/ */
public class UsageStats extends Activity implements OnItemSelectedListener { public class UsageStats extends Activity implements OnItemSelectedListener {
private static final String TAG="UsageStatsActivity"; private static final String TAG = "UsageStatsActivity";
private static final boolean localLOGV = false; private static final boolean localLOGV = false;
private Spinner mTypeSpinner; private UsageStatsManager mUsageStatsManager;
private ListView mListView;
private IUsageStats mUsageStatsService;
private LayoutInflater mInflater; private LayoutInflater mInflater;
private UsageStatsAdapter mAdapter; private UsageStatsAdapter mAdapter;
private PackageManager mPm; private PackageManager mPm;
public static class AppNameComparator public static class AppNameComparator implements Comparator<PackageUsageStats> {
implements Comparator<android.app.UsageStats.PackageStats> { private Map<String, String> mAppLabelList;
Map<String, CharSequence> mAppLabelList;
AppNameComparator(Map<String, CharSequence> appList) { AppNameComparator(Map<String, String> appList) {
mAppLabelList = appList; mAppLabelList = appList;
} }
public final int compare(android.app.UsageStats.PackageStats a,
android.app.UsageStats.PackageStats b) { @Override
String alabel = mAppLabelList.get(a.getPackageName()).toString(); public final int compare(PackageUsageStats a, PackageUsageStats b) {
String blabel = mAppLabelList.get(b.getPackageName()).toString(); String alabel = mAppLabelList.get(a.getPackageName());
String blabel = mAppLabelList.get(b.getPackageName());
return alabel.compareTo(blabel); return alabel.compareTo(blabel);
} }
} }
public static class LaunchCountComparator public static class LastTimeUsedComparator implements Comparator<PackageUsageStats> {
implements Comparator<android.app.UsageStats.PackageStats> { @Override
public final int compare(android.app.UsageStats.PackageStats a, public final int compare(PackageUsageStats a, PackageUsageStats b) {
android.app.UsageStats.PackageStats b) {
// return by descending order // return by descending order
return b.getLaunchCount() - a.getLaunchCount(); return (int)(b.getLastTimeUsed() - a.getLastTimeUsed());
} }
} }
public static class UsageTimeComparator public static class UsageTimeComparator implements Comparator<PackageUsageStats> {
implements Comparator<android.app.UsageStats.PackageStats> { @Override
public final int compare(android.app.UsageStats.PackageStats a, public final int compare(PackageUsageStats a, PackageUsageStats b) {
android.app.UsageStats.PackageStats b) { return (int)(b.getTotalTimeSpent() - a.getTotalTimeSpent());
long ret = a.getUsageTime(0)-b.getUsageTime(0);
if (ret == 0) {
return 0;
}
if (ret < 0) {
return 1;
}
return -1;
} }
} }
// View Holder used when displaying views // View Holder used when displaying views
static class AppViewHolder { static class AppViewHolder {
TextView pkgName; TextView pkgName;
TextView launchCount; TextView lastTimeUsed;
TextView usageTime; TextView usageTime;
} }
class UsageStatsAdapter extends BaseAdapter { class UsageStatsAdapter extends BaseAdapter {
// Constants defining order for display order // Constants defining order for display order
private static final int _DISPLAY_ORDER_USAGE_TIME = 0; private static final int _DISPLAY_ORDER_USAGE_TIME = 0;
private static final int _DISPLAY_ORDER_LAUNCH_COUNT = 1; private static final int _DISPLAY_ORDER_LAST_TIME_USED = 1;
private static final int _DISPLAY_ORDER_APP_NAME = 2; private static final int _DISPLAY_ORDER_APP_NAME = 2;
private int mDisplayOrder = _DISPLAY_ORDER_USAGE_TIME; private int mDisplayOrder = _DISPLAY_ORDER_USAGE_TIME;
private List<android.app.UsageStats.PackageStats> mUsageStats; private LastTimeUsedComparator mLastTimeUsedComparator = new LastTimeUsedComparator();
private LaunchCountComparator mLaunchCountComparator; private UsageTimeComparator mUsageTimeComparator = new UsageTimeComparator();
private UsageTimeComparator mUsageTimeComparator;
private AppNameComparator mAppLabelComparator; private AppNameComparator mAppLabelComparator;
private HashMap<String, CharSequence> mAppLabelMap; private final ArrayMap<String, String> mAppLabelMap = new ArrayMap<>();
private final ArrayList<PackageUsageStats> mPackageStats = new ArrayList<>();
UsageStatsAdapter() { UsageStatsAdapter() {
mUsageStats = new ArrayList<android.app.UsageStats.PackageStats>(); Calendar cal = Calendar.getInstance();
mAppLabelMap = new HashMap<String, CharSequence>(); cal.add(Calendar.DAY_OF_YEAR, -5);
android.app.UsageStats.PackageStats[] stats;
try { final android.app.usage.UsageStats stats =
stats = mUsageStatsService.getAllPkgUsageStats(getPackageName()); mUsageStatsManager.getRecentStatsSince(cal.getTimeInMillis());
} catch (RemoteException e) { if (stats == null) {
Log.e(TAG, "Failed initializing usage stats service");
return; return;
} }
if (stats == null) {
return; final int pkgCount = stats.getPackageCount();
} for (int i = 0; i < pkgCount; i++) {
for (android.app.UsageStats.PackageStats ps : stats) { final PackageUsageStats pkgStats = stats.getPackage(i);
mUsageStats.add(ps);
// load application labels for each application // load application labels for each application
CharSequence label; try {
try { ApplicationInfo appInfo = mPm.getApplicationInfo(pkgStats.getPackageName(), 0);
ApplicationInfo appInfo = mPm.getApplicationInfo(ps.getPackageName(), 0); String label = appInfo.loadLabel(mPm).toString();
label = appInfo.loadLabel(mPm); mAppLabelMap.put(pkgStats.getPackageName(), label);
mPackageStats.add(pkgStats);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
label = ps.getPackageName(); // This package may be gone.
} }
mAppLabelMap.put(ps.getPackageName(), label);
} }
// Sort list // Sort list
mLaunchCountComparator = new LaunchCountComparator();
mUsageTimeComparator = new UsageTimeComparator();
mAppLabelComparator = new AppNameComparator(mAppLabelMap); mAppLabelComparator = new AppNameComparator(mAppLabelMap);
sortList(); sortList();
} }
@Override
public int getCount() { public int getCount() {
return mUsageStats.size(); return mPackageStats.size();
} }
@Override
public Object getItem(int position) { public Object getItem(int position) {
return mUsageStats.get(position); return mPackageStats.get(position);
} }
@Override
public long getItemId(int position) { public long getItemId(int position) {
return position; return position;
} }
@Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls // A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row. // to findViewById() on each row.
@@ -173,7 +167,7 @@ public class UsageStats extends Activity implements OnItemSelectedListener {
// we want to bind data to. // we want to bind data to.
holder = new AppViewHolder(); holder = new AppViewHolder();
holder.pkgName = (TextView) convertView.findViewById(R.id.package_name); holder.pkgName = (TextView) convertView.findViewById(R.id.package_name);
holder.launchCount = (TextView) convertView.findViewById(R.id.launch_count); holder.lastTimeUsed = (TextView) convertView.findViewById(R.id.last_time_used);
holder.usageTime = (TextView) convertView.findViewById(R.id.usage_time); holder.usageTime = (TextView) convertView.findViewById(R.id.usage_time);
convertView.setTag(holder); convertView.setTag(holder);
} else { } else {
@@ -183,12 +177,14 @@ public class UsageStats extends Activity implements OnItemSelectedListener {
} }
// Bind the data efficiently with the holder // Bind the data efficiently with the holder
android.app.UsageStats.PackageStats pkgStats = mUsageStats.get(position); PackageUsageStats pkgStats = mPackageStats.get(position);
if (pkgStats != null) { if (pkgStats != null) {
CharSequence label = mAppLabelMap.get(pkgStats.getPackageName()); String label = mAppLabelMap.get(pkgStats.getPackageName());
holder.pkgName.setText(label); holder.pkgName.setText(label);
holder.launchCount.setText(String.valueOf(pkgStats.getLaunchCount())); holder.lastTimeUsed.setText(DateUtils.formatSameDayTime(pkgStats.getLastTimeUsed(),
holder.usageTime.setText(String.valueOf(pkgStats.getUsageTime(0))+" ms"); System.currentTimeMillis(), DateFormat.MEDIUM, DateFormat.MEDIUM));
holder.usageTime.setText(
DateUtils.formatElapsedTime(pkgStats.getTotalTimeSpent() / 1000));
} else { } else {
Log.w(TAG, "No usage stats info for package:" + position); Log.w(TAG, "No usage stats info for package:" + position);
} }
@@ -206,45 +202,42 @@ public class UsageStats extends Activity implements OnItemSelectedListener {
private void sortList() { private void sortList() {
if (mDisplayOrder == _DISPLAY_ORDER_USAGE_TIME) { if (mDisplayOrder == _DISPLAY_ORDER_USAGE_TIME) {
if (localLOGV) Log.i(TAG, "Sorting by usage time"); if (localLOGV) Log.i(TAG, "Sorting by usage time");
Collections.sort(mUsageStats, mUsageTimeComparator); Collections.sort(mPackageStats, mUsageTimeComparator);
} else if (mDisplayOrder == _DISPLAY_ORDER_LAUNCH_COUNT) { } else if (mDisplayOrder == _DISPLAY_ORDER_LAST_TIME_USED) {
if (localLOGV) Log.i(TAG, "Sorting launch count"); if (localLOGV) Log.i(TAG, "Sorting by last time used");
Collections.sort(mUsageStats, mLaunchCountComparator); Collections.sort(mPackageStats, mLastTimeUsedComparator);
} else if (mDisplayOrder == _DISPLAY_ORDER_APP_NAME) { } else if (mDisplayOrder == _DISPLAY_ORDER_APP_NAME) {
if (localLOGV) Log.i(TAG, "Sorting by application name"); if (localLOGV) Log.i(TAG, "Sorting by application name");
Collections.sort(mUsageStats, mAppLabelComparator); Collections.sort(mPackageStats, mAppLabelComparator);
} }
notifyDataSetChanged(); notifyDataSetChanged();
} }
} }
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override
protected void onCreate(Bundle icicle) { protected void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
mUsageStatsService = IUsageStats.Stub.asInterface(ServiceManager.getService("usagestats")); setContentView(R.layout.usage_stats);
if (mUsageStatsService == null) {
Log.e(TAG, "Failed to retrieve usagestats service"); mUsageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
return;
}
mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mPm = getPackageManager(); mPm = getPackageManager();
Spinner typeSpinner = (Spinner) findViewById(R.id.typeSpinner);
typeSpinner.setOnItemSelectedListener(this);
setContentView(R.layout.usage_stats); ListView listView = (ListView) findViewById(R.id.pkg_list);
mTypeSpinner = (Spinner) findViewById(R.id.typeSpinner);
mTypeSpinner.setOnItemSelectedListener(this);
mListView = (ListView) findViewById(R.id.pkg_list);
// Initialize the inflater
mAdapter = new UsageStatsAdapter(); mAdapter = new UsageStatsAdapter();
mListView.setAdapter(mAdapter); listView.setAdapter(mAdapter);
} }
public void onItemSelected(AdapterView<?> parent, View view, int position, @Override
long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mAdapter.sortList(position); mAdapter.sortList(position);
} }
@Override
public void onNothingSelected(AdapterView<?> parent) { public void onNothingSelected(AdapterView<?> parent) {
// do nothing // do nothing
} }