| /** |
| * 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 Long.compare(b.getLastTimeUsed(), a.getLastTimeUsed()); |
| } |
| } |
| |
| public static class UsageTimeComparator implements Comparator<UsageStats> { |
| @Override |
| public final int compare(UsageStats a, UsageStats b) { |
| return Long.compare(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 |
| } |
| } |