Android 7.1.1
developers/samples/android/system/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/AppUsageStatisticsFragment.java
packages/apps/Settings/src/com/android/settings/UsageStatsActivity.java
/** * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.android.settings; import android.app.Activity; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.Spinner; import android.widget.TextView; import java.text.DateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; /** * Activity to display package usage statistics. */ public class UsageStatsActivity extends Activity implements OnItemSelectedListener { private static final String TAG = "UsageStatsActivity"; private static final boolean localLOGV = false; private UsageStatsManager mUsageStatsManager; private LayoutInflater mInflater; private UsageStatsAdapter mAdapter; private PackageManager mPm; public static class AppNameComparator implements Comparator<UsageStats> { private Map<String, String> mAppLabelList; AppNameComparator(Map<String, String> appList) { mAppLabelList = appList; } @Override public final int compare(UsageStats a, UsageStats b) { String alabel = mAppLabelList.get(a.getPackageName()); String blabel = mAppLabelList.get(b.getPackageName()); return alabel.compareTo(blabel); } } public static class LastTimeUsedComparator implements Comparator<UsageStats> { @Override public final int compare(UsageStats a, UsageStats b) { // return by descending order return (int)(b.getLastTimeUsed() - a.getLastTimeUsed()); } } public static class UsageTimeComparator implements Comparator<UsageStats> { @Override public final int compare(UsageStats a, UsageStats b) { return (int)(b.getTotalTimeInForeground() - a.getTotalTimeInForeground()); } } // View Holder used when displaying views static class AppViewHolder { TextView pkgName; TextView lastTimeUsed; TextView usageTime; } class UsageStatsAdapter extends BaseAdapter { // Constants defining order for display order private static final int _DISPLAY_ORDER_USAGE_TIME = 0; private static final int _DISPLAY_ORDER_LAST_TIME_USED = 1; private static final int _DISPLAY_ORDER_APP_NAME = 2; private int mDisplayOrder = _DISPLAY_ORDER_USAGE_TIME; private LastTimeUsedComparator mLastTimeUsedComparator = new LastTimeUsedComparator(); private UsageTimeComparator mUsageTimeComparator = new UsageTimeComparator(); private AppNameComparator mAppLabelComparator; private final ArrayMap<String, String> mAppLabelMap = new ArrayMap<>(); private final ArrayList<UsageStats> mPackageStats = new ArrayList<>(); UsageStatsAdapter() { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_YEAR, -5); final List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, cal.getTimeInMillis(), System.currentTimeMillis()); if (stats == null) { return; } ArrayMap<String, UsageStats> map = new ArrayMap<>(); final int statCount = stats.size(); for (int i = 0; i < statCount; i++) { final android.app.usage.UsageStats pkgStats = stats.get(i); // load application labels for each application try { ApplicationInfo appInfo = mPm.getApplicationInfo(pkgStats.getPackageName(), 0); String label = appInfo.loadLabel(mPm).toString(); mAppLabelMap.put(pkgStats.getPackageName(), label); UsageStats existingStats = map.get(pkgStats.getPackageName()); if (existingStats == null) { map.put(pkgStats.getPackageName(), pkgStats); } else { existingStats.add(pkgStats); } } catch (NameNotFoundException e) { // This package may be gone. } } mPackageStats.addAll(map.values()); // Sort list mAppLabelComparator = new AppNameComparator(mAppLabelMap); sortList(); } @Override public int getCount() { return mPackageStats.size(); } @Override public Object getItem(int position) { return mPackageStats.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // A ViewHolder keeps references to children views to avoid unneccessary calls // to findViewById() on each row. AppViewHolder holder; // When convertView is not null, we can reuse it directly, there is no need // to reinflate it. We only inflate a new View when the convertView supplied // by ListView is null. if (convertView == null) { convertView = mInflater.inflate(R.layout.usage_stats_item, null); // Creates a ViewHolder and store references to the two children views // we want to bind data to. holder = new AppViewHolder(); holder.pkgName = (TextView) convertView.findViewById(R.id.package_name); holder.lastTimeUsed = (TextView) convertView.findViewById(R.id.last_time_used); holder.usageTime = (TextView) convertView.findViewById(R.id.usage_time); convertView.setTag(holder); } else { // Get the ViewHolder back to get fast access to the TextView // and the ImageView. holder = (AppViewHolder) convertView.getTag(); } // Bind the data efficiently with the holder UsageStats pkgStats = mPackageStats.get(position); if (pkgStats != null) { String label = mAppLabelMap.get(pkgStats.getPackageName()); holder.pkgName.setText(label); holder.lastTimeUsed.setText(DateUtils.formatSameDayTime(pkgStats.getLastTimeUsed(), System.currentTimeMillis(), DateFormat.MEDIUM, DateFormat.MEDIUM)); holder.usageTime.setText( DateUtils.formatElapsedTime(pkgStats.getTotalTimeInForeground() / 1000)); } else { Log.w(TAG, "No usage stats info for package:" + position); } return convertView; } void sortList(int sortOrder) { if (mDisplayOrder == sortOrder) { // do nothing return; } mDisplayOrder= sortOrder; sortList(); } private void sortList() { if (mDisplayOrder == _DISPLAY_ORDER_USAGE_TIME) { if (localLOGV) Log.i(TAG, "Sorting by usage time"); Collections.sort(mPackageStats, mUsageTimeComparator); } else if (mDisplayOrder == _DISPLAY_ORDER_LAST_TIME_USED) { if (localLOGV) Log.i(TAG, "Sorting by last time used"); Collections.sort(mPackageStats, mLastTimeUsedComparator); } else if (mDisplayOrder == _DISPLAY_ORDER_APP_NAME) { if (localLOGV) Log.i(TAG, "Sorting by application name"); Collections.sort(mPackageStats, mAppLabelComparator); } notifyDataSetChanged(); } } /** Called when the activity is first created. */ @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.usage_stats); mUsageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); mPm = getPackageManager(); Spinner typeSpinner = (Spinner) findViewById(R.id.typeSpinner); typeSpinner.setOnItemSelectedListener(this); ListView listView = (ListView) findViewById(R.id.pkg_list); mAdapter = new UsageStatsAdapter(); listView.setAdapter(mAdapter); } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { mAdapter.sortList(position); } @Override public void onNothingSelected(AdapterView<?> parent) { // do nothing } }
ENV:Android 4.4.4
1.
packages/apps/Settings/src/com/android/settings/UsageStats.java
import com.android.internal.app.IUsageStats; import com.android.settings.R; import android.app.Activity; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; import com.android.internal.os.PkgUsageStats; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.Spinner; import android.widget.TextView; import android.widget.AdapterView.OnItemSelectedListener; /** * Activity to display package usage statistics. */ public class UsageStats extends Activity implements OnItemSelectedListener { private static final String TAG="UsageStatsActivity"; private static final boolean localLOGV = false; private Spinner mTypeSpinner; private ListView mListView; private IUsageStats mUsageStatsService; private LayoutInflater mInflater; private UsageStatsAdapter mAdapter; private PackageManager mPm; public static class AppNameComparator implements Comparator<PkgUsageStats> { Map<String, CharSequence> mAppLabelList; AppNameComparator(Map<String, CharSequence> appList) { mAppLabelList = appList; } public final int compare(PkgUsageStats a, PkgUsageStats b) { String alabel = mAppLabelList.get(a.packageName).toString(); String blabel = mAppLabelList.get(b.packageName).toString(); return alabel.compareTo(blabel); } } public static class LaunchCountComparator implements Comparator<PkgUsageStats> { public final int compare(PkgUsageStats a, PkgUsageStats b) { // return by descending order return b.launchCount - a.launchCount; } } public static class UsageTimeComparator implements Comparator<PkgUsageStats> { public final int compare(PkgUsageStats a, PkgUsageStats b) { long ret = a.usageTime-b.usageTime; if (ret == 0) { return 0; } if (ret < 0) { return 1; } return -1; } } // View Holder used when displaying views static class AppViewHolder { TextView pkgName; TextView launchCount; TextView usageTime; } class UsageStatsAdapter extends BaseAdapter { // Constants defining order for display order private static final int _DISPLAY_ORDER_USAGE_TIME = 0; private static final int _DISPLAY_ORDER_LAUNCH_COUNT = 1; private static final int _DISPLAY_ORDER_APP_NAME = 2; private int mDisplayOrder = _DISPLAY_ORDER_USAGE_TIME; private List<PkgUsageStats> mUsageStats; private LaunchCountComparator mLaunchCountComparator; private UsageTimeComparator mUsageTimeComparator; private AppNameComparator mAppLabelComparator; private HashMap<String, CharSequence> mAppLabelMap; UsageStatsAdapter() { mUsageStats = new ArrayList<PkgUsageStats>(); mAppLabelMap = new HashMap<String, CharSequence>(); PkgUsageStats[] stats; try { stats = mUsageStatsService.getAllPkgUsageStats(); } catch (RemoteException e) { Log.e(TAG, "Failed initializing usage stats service"); return; } if (stats == null) { return; } for (PkgUsageStats ps : stats) { mUsageStats.add(ps); // load application labels for each application CharSequence label; try { ApplicationInfo appInfo = mPm.getApplicationInfo(ps.packageName, 0); label = appInfo.loadLabel(mPm); } catch (NameNotFoundException e) { label = ps.packageName; } mAppLabelMap.put(ps.packageName, label); } // Sort list mLaunchCountComparator = new LaunchCountComparator(); mUsageTimeComparator = new UsageTimeComparator(); mAppLabelComparator = new AppNameComparator(mAppLabelMap); sortList(); } public int getCount() { return mUsageStats.size(); } public Object getItem(int position) { return mUsageStats.get(position); } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { // A ViewHolder keeps references to children views to avoid unneccessary calls // to findViewById() on each row. AppViewHolder holder; // When convertView is not null, we can reuse it directly, there is no need // to reinflate it. We only inflate a new View when the convertView supplied // by ListView is null. if (convertView == null) { convertView = mInflater.inflate(R.layout.usage_stats_item, null); // Creates a ViewHolder and store references to the two children views // we want to bind data to. holder = new AppViewHolder(); holder.pkgName = (TextView) convertView.findViewById(R.id.package_name); holder.launchCount = (TextView) convertView.findViewById(R.id.launch_count); holder.usageTime = (TextView) convertView.findViewById(R.id.usage_time); convertView.setTag(holder); } else { // Get the ViewHolder back to get fast access to the TextView // and the ImageView. holder = (AppViewHolder) convertView.getTag(); } // Bind the data efficiently with the holder PkgUsageStats pkgStats = mUsageStats.get(position); if (pkgStats != null) { CharSequence label = mAppLabelMap.get(pkgStats.packageName); holder.pkgName.setText(label); holder.launchCount.setText(String.valueOf(pkgStats.launchCount)); holder.usageTime.setText(String.valueOf(pkgStats.usageTime)+" ms"); } else { Log.w(TAG, "No usage stats info for package:" + position); } return convertView; } void sortList(int sortOrder) { if (mDisplayOrder == sortOrder) { // do nothing return; } mDisplayOrder= sortOrder; sortList(); } private void sortList() { if (mDisplayOrder == _DISPLAY_ORDER_USAGE_TIME) { if (localLOGV) Log.i(TAG, "Sorting by usage time"); Collections.sort(mUsageStats, mUsageTimeComparator); } else if (mDisplayOrder == _DISPLAY_ORDER_LAUNCH_COUNT) { if (localLOGV) Log.i(TAG, "Sorting launch count"); Collections.sort(mUsageStats, mLaunchCountComparator); } else if (mDisplayOrder == _DISPLAY_ORDER_APP_NAME) { if (localLOGV) Log.i(TAG, "Sorting by application name"); Collections.sort(mUsageStats, mAppLabelComparator); } notifyDataSetChanged(); } } /** Called when the activity is first created. */ protected void onCreate(Bundle icicle) { super.onCreate(icicle); mUsageStatsService = IUsageStats.Stub.asInterface(ServiceManager.getService("usagestats")); if (mUsageStatsService == null) { Log.e(TAG, "Failed to retrieve usagestats service"); return; } mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); mPm = getPackageManager(); setContentView(R.layout.usage_stats); mTypeSpinner = (Spinner) findViewById(R.id.typeSpinner); mTypeSpinner.setOnItemSelectedListener(this); mListView = (ListView) findViewById(R.id.pkg_list); // Initialize the inflater mAdapter = new UsageStatsAdapter(); mListView.setAdapter(mAdapter); } public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { mAdapter.sortList(position); } public void onNothingSelected(AdapterView<?> parent) { // do nothing } }
2.
frameworks/base/core/java/com/android/internal/app/IUsageStats.aidl
package com.android.internal.app; import android.content.ComponentName; import com.android.internal.os.PkgUsageStats; interface IUsageStats { void noteResumeComponent(in ComponentName componentName); void notePauseComponent(in ComponentName componentName); void noteLaunchTime(in ComponentName componentName, int millis); PkgUsageStats getPkgUsageStats(in ComponentName componentName); PkgUsageStats[] getAllPkgUsageStats(); }
3.
frameworks/base/core/java/com/android/internal/os/PkgUsageStats.java
package com.android.internal.os; import android.os.Parcel; import android.os.Parcelable; import java.util.HashMap; import java.util.Map; /** * implementation of PkgUsageStats associated with an * application package. * @hide */ public class PkgUsageStats implements Parcelable { public String packageName; public int launchCount; public long usageTime; public Map<String, Long> componentResumeTimes; public static final Parcelable.Creator<PkgUsageStats> CREATOR = new Parcelable.Creator<PkgUsageStats>() { public PkgUsageStats createFromParcel(Parcel in) { return new PkgUsageStats(in); } public PkgUsageStats[] newArray(int size) { return new PkgUsageStats[size]; } }; public String toString() { return "PkgUsageStats{" + Integer.toHexString(System.identityHashCode(this)) + " " + packageName + "}"; } public PkgUsageStats(String pkgName, int count, long time, Map<String, Long> lastResumeTimes) { packageName = pkgName; launchCount = count; usageTime = time; componentResumeTimes = new HashMap<String, Long>(lastResumeTimes); } public PkgUsageStats(Parcel source) { packageName = source.readString(); launchCount = source.readInt(); usageTime = source.readLong(); final int N = source.readInt(); componentResumeTimes = new HashMap<String, Long>(N); for (int i = 0; i < N; i++) { String component = source.readString(); long lastResumeTime = source.readLong(); componentResumeTimes.put(component, lastResumeTime); } } public PkgUsageStats(PkgUsageStats pStats) { packageName = pStats.packageName; launchCount = pStats.launchCount; usageTime = pStats.usageTime; componentResumeTimes = new HashMap<String, Long>(pStats.componentResumeTimes); } public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int parcelableFlags) { dest.writeString(packageName); dest.writeInt(launchCount); dest.writeLong(usageTime); dest.writeInt(componentResumeTimes.size()); for (Map.Entry<String, Long> ent : componentResumeTimes.entrySet()) { dest.writeString(ent.getKey()); dest.writeLong(ent.getValue()); } } }
4.
frameworks/base/core/java/com/android/internal/os/PkgUsageStats.aidl
package com.android.internal.os; parcelable PkgUsageStats;
Android 8.0.0
时间: 2024-11-12 20:59:18