From 3516800b611a79339a3c188332d13a26e9086b09 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Mon, 21 Jul 2014 15:25:30 -0700 Subject: Second iteration of the UsageStats API Based on feedback from API council, updated the API. Also added support for querying the event log. Change-Id: Ibaa008b9e5bd145acdfe8e20c25c2ed2d96be123 --- tests/UsageStatsTest/AndroidManifest.xml | 2 + tests/UsageStatsTest/res/menu/main.xml | 5 + .../android/tests/usagestats/UsageLogActivity.java | 135 +++++++++++++++++++++ .../tests/usagestats/UsageStatsActivity.java | 52 +++++--- 4 files changed, 179 insertions(+), 15 deletions(-) create mode 100644 tests/UsageStatsTest/res/menu/main.xml create mode 100644 tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java (limited to 'tests/UsageStatsTest') diff --git a/tests/UsageStatsTest/AndroidManifest.xml b/tests/UsageStatsTest/AndroidManifest.xml index fac5810..589674a 100644 --- a/tests/UsageStatsTest/AndroidManifest.xml +++ b/tests/UsageStatsTest/AndroidManifest.xml @@ -13,5 +13,7 @@ + + diff --git a/tests/UsageStatsTest/res/menu/main.xml b/tests/UsageStatsTest/res/menu/main.xml new file mode 100644 index 0000000..e781058 --- /dev/null +++ b/tests/UsageStatsTest/res/menu/main.xml @@ -0,0 +1,5 @@ + + + + diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java new file mode 100644 index 0000000..5d8fc9e --- /dev/null +++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java @@ -0,0 +1,135 @@ +/** + * Copyright (C) 2014 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.tests.usagestats; + +import android.app.ListActivity; +import android.app.usage.UsageEvents; +import android.app.usage.UsageStatsManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import java.util.ArrayList; + +public class UsageLogActivity extends ListActivity implements Runnable { + private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 14; + + private UsageStatsManager mUsageStatsManager; + private Adapter mAdapter; + private Handler mHandler = new Handler(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mUsageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); + mAdapter = new Adapter(); + setListAdapter(mAdapter); + } + + @Override + protected void onResume() { + super.onResume(); + run(); + } + + @Override + protected void onPause() { + super.onPause(); + mHandler.removeCallbacks(this); + } + + @Override + public void run() { + long now = System.currentTimeMillis(); + long beginTime = now - USAGE_STATS_PERIOD; + UsageEvents events = mUsageStatsManager.queryEvents(beginTime, now); + mAdapter.update(events); + mHandler.postDelayed(this, 1000 * 5); + } + + private class Adapter extends BaseAdapter { + + private final ArrayList mEvents = new ArrayList<>(); + + public void update(UsageEvents results) { + mEvents.clear(); + while (results.hasNextEvent()) { + UsageEvents.Event event = new UsageEvents.Event(); + results.getNextEvent(event); + mEvents.add(event); + } + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return mEvents.size(); + } + + @Override + public Object getItem(int position) { + return mEvents.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + final ViewHolder holder; + if (convertView == null) { + convertView = LayoutInflater.from(UsageLogActivity.this) + .inflate(R.layout.row_item, parent, false); + holder = new ViewHolder(); + holder.packageName = (TextView) convertView.findViewById(android.R.id.text1); + holder.state = (TextView) convertView.findViewById(android.R.id.text2); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + + holder.packageName.setText(mEvents.get(position).getComponent().toShortString()); + String state; + switch (mEvents.get(position).getEventType()) { + case UsageEvents.Event.MOVE_TO_FOREGROUND: + state = "Foreground"; + break; + + case UsageEvents.Event.MOVE_TO_BACKGROUND: + state = "Background"; + break; + + default: + state = "Unknown: " + mEvents.get(position).getEventType(); + break; + } + holder.state.setText(state); + return convertView; + } + } + + static class ViewHolder { + public TextView packageName; + public TextView state; + } +} diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java index 73143c5..b6591bd 100644 --- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java +++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java @@ -17,31 +17,34 @@ package com.android.tests.usagestats; import android.app.ListActivity; -import android.app.usage.PackageUsageStats; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; import android.content.Context; +import android.content.Intent; import android.os.Bundle; import android.text.format.DateUtils; +import android.util.ArrayMap; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.ArrayList; -import java.util.Calendar; import java.util.Collections; import java.util.Comparator; public class UsageStatsActivity extends ListActivity { - + private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 14; private UsageStatsManager mUsageStatsManager; private Adapter mAdapter; - private Comparator mComparator = new Comparator() { + private Comparator mComparator = new Comparator() { @Override - public int compare(PackageUsageStats o1, PackageUsageStats o2) { - return Long.compare(o2.getTotalTimeSpent(), o1.getTotalTimeSpent()); + public int compare(UsageStats o1, UsageStats o2) { + return Long.compare(o2.getTotalTimeInForeground(), o1.getTotalTimeInForeground()); } }; @@ -50,35 +53,54 @@ public class UsageStatsActivity extends ListActivity { super.onCreate(savedInstanceState); mUsageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); mAdapter = new Adapter(); - updateAdapter(); setListAdapter(mAdapter); } @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.log: + startActivity(new Intent(this, UsageLogActivity.class)); + return true; + + default: + return super.onOptionsItemSelected(item); + } + } + + @Override protected void onResume() { super.onResume(); updateAdapter(); } private void updateAdapter() { - Calendar cal = Calendar.getInstance(); - cal.add(Calendar.DAY_OF_YEAR, -14); - UsageStats stats = mUsageStatsManager.getRecentStatsSince(cal.getTimeInMillis()); + long now = System.currentTimeMillis(); + long beginTime = now - USAGE_STATS_PERIOD; + ArrayMap stats = mUsageStatsManager.queryAndAggregateUsageStats( + beginTime, now); mAdapter.update(stats); } private class Adapter extends BaseAdapter { - private ArrayList mStats = new ArrayList<>(); + private ArrayList mStats = new ArrayList<>(); - public void update(UsageStats stats) { + public void update(ArrayMap stats) { mStats.clear(); if (stats == null) { return; } - final int packageCount = stats.getPackageCount(); + final int packageCount = stats.size(); for (int i = 0; i < packageCount; i++) { - mStats.add(stats.getPackage(i)); + mStats.add(stats.valueAt(i)); } Collections.sort(mStats, mComparator); @@ -116,7 +138,7 @@ public class UsageStatsActivity extends ListActivity { holder.packageName.setText(mStats.get(position).getPackageName()); holder.usageTime.setText(DateUtils.formatDuration( - mStats.get(position).getTotalTimeSpent())); + mStats.get(position).getTotalTimeInForeground())); return convertView; } } -- cgit v1.1