用Android自帶統計服務AppUasge一招制敵

Tamic發表於2017-10-12

Tamic/文

Google從 API 21 新增了介面 android.app.usage , 通過這個api我們可以統計到每個app的使用情況,啟動次數,啟動時間等,也可以判斷是否前後臺,比較方便,今天就來深入的學習一下 。

programming-2115930__480.jpg
programming-2115930__480.jpg

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/文





相關文章