首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

用Android自带统计服务AppUasge一招制敌

2024-12-13 来源:花图问答

Tamic/文

Google从 API 21 新增了接口 android.app.usage , 通过这个api我们可以统计到每个app的使用情况,启动次数,启动时间等,也可以判断是否前后台,比较方便,今天就来深入的学习一下 。

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 
    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的使用情况。更多技巧请继续关注。

及时阅读文章可以关注我的号:

开发者技术前线
显示全文