Tamic/文
Google從 API 21 新增了介面 android.app.usage , 通過這個api我們可以統計到每個app的使用情況,啟動次數,啟動時間等,也可以判斷是否前後臺,比較方便,今天就來深入的學習一下 。
Google從 API 21 新增了介面 android.app.usage , 通過這個api我們可以統計到每個app的使用情況,啟動次數,啟動時間等,也可以判斷是否執行在前後臺,比較方便,也可以用作埋點,統計框架中,今天就來深入的學習一下。
獲取前後臺
5.0以前做法是這樣的:
public String getForegroundApp(Context context) {
List<RunningAppProcesInfo> lr=context.getRunningAppProcesses();
if (lr == null) {
return null;
}
for (RunningAppProcessInfo ra : lr) {
if (ra.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE || ra.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { return ra.processName;
}
}
return null;
}
複製程式碼
突然從5.0就不能用了。這就有點eggs pain, 很多人通過檢查當前自己應用的介面做標記, 在可見和不可見的生命週期中分別做記錄,來判斷是否前臺。 getRecentTasks( ) 也廢棄使用了,我們在清單註冊getTask許可權已經被收回了,那怎麼辦,android api其實已經想好了替代品,那就是 AppUsageStatistics
需要使用者授權才可以,好,就學學姿勢吧。
5.0以後用AppUsageStatistics來獲取
private String getForegroundApp() {
long ts = System.currentTimeMillis();
List<UsageStats> queryUsageStats =
usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST,ts-2000, ts);
if (queryUsageStats == null || queryUsageStats.isEmpty()) {
return null;
}
UsageStats recentStats = null;
for (UsageStats usageStats : queryUsageStats) {
if(recentStats == null || recentStats.getLastTimeUsed() < usageStats.getLastTimeUsed()) {
recentStats = usageStats;
}
}
return recentStats.getPackageName;
}
複製程式碼
看是不是 很簡單,或許你都沒聽過吧!好 follow me!
AppUasgeStatistics
1 首先清單申請許可權
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.appusagestatistics"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
<application android:allowBackup="true"
android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:theme="@style/Theme.AppCompat.Light">
<activity android:name=".AppUsageStatisticsActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
複製程式碼
2 獲取UsageStatsManager
接著通過context GET到UsageStatsManager。
UsageStatsManager mUsageStatsManager = (UsageStatsManager) getActivity() .getSystemService("usagestats"); //Context.USAGE_STATS_SERVICE
複製程式碼
3 使用
我通過這個api獲取一下每個app的使用情況, intervalType是統計的週期,是統計區間,UsageStatsManager 內部提供四個原則,有:年,月,周,日。
DAILY("Daily", UsageStatsManager.INTERVAL_DAILY),
WEEKLY("Weekly", UsageStatsManager.INTERVAL_WEEKLY),
MONTHLY("Monthly", UsageStatsManager.INTERVAL_MONTHLY),
YEARLY("Yearly", UsageStatsManager.INTERVAL_YEARLY);
複製程式碼
為了擴充我定義一個CustomUsageStats, UsageStats是谷歌提供一個統計類,裡面可以獲取app的使用情況。
public class CustomUsageStats {
public UsageStats usageStats;
public Drawable appIcon;
}
複製程式碼
下面這段程式碼就是獲取每個app的使用情況的。
public List<UsageStats> getUsageStatistics(int intervalType) { // Get the app statistics since one year ago from the current time.
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
List<UsageStats> queryUsageStats = mUsageStatsManager
.queryUsageStats(intervalType, cal.getTimeInMillis(),
System.currentTimeMillis()); if (queryUsageStats.size() == 0) {
Log.i(TAG, "The user may not allow the access to apps usage. ");
Toast.makeText(getActivity(),
getString(R.string.explanation_access_to_appusage_is_not_enabled),
Toast.LENGTH_LONG).show();
mOpenUsageSettingButton.setVisibility(View.VISIBLE);
mOpenUsageSettingButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
}
});
} return queryUsageStats;
}
複製程式碼
當然上面程式碼只是獲取app的使用情況,來寫個列表,用介面卡用來展現app的包名,最後使用的時間,以及圖示icon。
public class UsageListAdapter extends RecyclerView.Adapter<UsageListAdapter.ViewHolder> {
private List<CustomUsageStats> mCustomUsageStatsList = new ArrayList<>();
private DateFormat mDateFormat = new SimpleDateFormat();
/**
* Provide a reference to the type of views that you are using (custom ViewHolder)
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView mPackageName;
private final TextView mLastTimeUsed;
private final ImageView mAppIcon;
public ViewHolder(View v) {
super(v);
mPackageName = (TextView) v.findViewById(R.id.textview_package_name);
mLastTimeUsed = (TextView) v.findViewById(R.id.textview_last_time_used);
mAppIcon = (ImageView) v.findViewById(R.id.app_icon);
}
public TextView getLastTimeUsed() {
return mLastTimeUsed;
}
public TextView getPackageName() {
return mPackageName;
}
public ImageView getAppIcon() {
return mAppIcon;
}
}
public UsageListAdapter() {
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.usage_row, viewGroup, false); return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
viewHolder.getPackageName().setText(
mCustomUsageStatsList.get(position).usageStats.getPackageName()); long lastTimeUsed = mCustomUsageStatsList.get(position).usageStats.getLastTimeUsed();
viewHolder.getLastTimeUsed().setText(mDateFormat.format(new Date(lastTimeUsed)));
viewHolder.getAppIcon().setImageDrawable(mCustomUsageStatsList.get(position).appIcon);
}
@Override
public int getItemCount() {
return mCustomUsageStatsList.size();
}
public void setCustomUsageStatsList(List<CustomUsageStats> customUsageStats) {
mCustomUsageStatsList = customUsageStats;
}
}
複製程式碼
後記
這個api不是說想用就能用,必須使用者授權了才能統計到。所以我們在做移動端埋點時可以加入這個api,方便我們更精確的蒐集app的使用情況。更多技巧請繼續關注。
Tamic/文