Android AppUasge统计一招制敌

Tamic/文

http://blog.csdn.net/sk719887916/article/details/71105441

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

http://blog.csdn.net/sk719887916/article/details/71105441

时间: 2024-12-17 03:55:02

Android AppUasge统计一招制敌的相关文章

一招制敌 - 玩转 AngularJS 指令的 Scope (作用域),讲得特别好

学习了AngularJS挺长时间,最近再次回首看看指令这部分的时候,觉得比自己刚开始学习的时候理解的更加深入了,尤其是指令的作用域这部分. 步入正题: 每当一个指令被创建的时候,都会有这样一个选择,是继承自己的父作用域(一般是外部的Controller提供的作用域或者根作用域($rootScope)),还是创建一个新的自己的作用域,当然AngularJS为我们指令的scope参数提供了三种选择,分别是:false,true,{}:默认情况下是false. scope = false 首先我们来看

一招制敌 - 玩转 AngularJS 指令的 Scope (作用域)【转】

学习了AngularJS好长时间,最近再次回首看看指令这部分的时候,觉得比自己刚开始学习的时候理解的更加深入了,尤其是指令的作用域这部分. 当初看的是<AngularJS权威指南>这本书,但是感觉这本书关于这方面讲的不是很细致,另外吐槽一下,这本书中文版印刷的质量不是很好,很多地方都有错误:不过讲的还是可以的,是一本学习AngularJS的好书. 下面我们就来详细分析一下指令的作用域.在这之前希望你对AngularJS的Directive有一定的了解,不然你对下面部分的理解可能会有一点难度.

Android流量统计TrafficStats类

对于Android流量统计来说在2.2版中新加入了TrafficStats类可以轻松获取,其实本身TrafficStats类也是读取Linux提供的文件对象系统类型的文本进行解析. android.net.TrafficStats类中,提供了多种静态方法,可以直接调用获取,返回类型均为 long型,如果返回等于-1代表 UNSUPPORTED 当前设备不支持统计. static long getMobileRxBytes() //获取通过Mobile连接收到的字节总数,不包含WiFi stati

Android Stduio统计项目的代码行数

android studio统计项目的代码行数的步骤如下: 1)按住Ctrl+Shift+A,在弹出的框输入‘find’,然后选择Find in Path.(或者使用快捷键Ctrl+Shift+F) 2)在弹出Find in Path的框中的Text to find输入\n,接着勾选Regular expression(正则表达式),Context选择anywhere, Scope根据你想要统计的范围进行选择,File mask选择*.java.(在这里统计项目的Java的代码行数) 3)下图的

Android流量统计TrafficStats类的使用

转自http://gundumw100.iteye.com/blog/1294167 对于Android流量统计来说在2.2版中新加入了TrafficStats类可以轻松获取,其实本身TrafficStats类也是读取Linux提 供的文件对象系统类型的文本进行解析.android.net.TrafficStats类中,提供了多种静态方法,可以直接调用获取,返回类型均为 long型,如果返回等于-1代表 UNSUPPORTED 当前设备不支持统计. static long getMobileRx

android google 统计导致的文件冲突

android studio 加入google 统计 1. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.3' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' classpath 'com.google.gms:google-services:3.0.0' // NOTE

Android 简单统计文本文件字符数、单词数、行数Demo

做的demo是统计文本文件的字符数.单词数.行数的,首先呢,我们必须要有一个文本文件.所以我们要么创建一个文本文件,并保存,然后再解析:要么就提前把文本文件先放到模拟器上,然后检索到文本名再进行解析.我感觉第二种方法不可行,因为要测试时,肯定要多次测试,每次还要找到文件再修改文件内容,过于麻烦.所以我用的第一种方法,文件内容更改后直接保存即可. 首先是 页面布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res

android 流量统计

1 android通过架构流量统计TrafficStats类可以直接获得 获得总流量受理TrafficStats.getTotalRxBytes(), 获得总传出流量TrafficStats.getTotalTxBytes()); 获取不包括WIFI的手机GPRS接收量TrafficStats.getMobileRxBytes()); 获取不包括Wifi的手机GPRS发送量TrafficStats.getMobileTxBytes()); 统计某一个进程的总接收量TrafficStats.get

android流量统计

android.net.TrafficStats类中,提供了多种静态方法,可以直接调用获取,返回类型均为long型,如果返回等于-1代表 UNSUPPORTED 当前设备不支持统计.    static long  getMobileRxBytes()  //获取通过Mobile连接收到的字节总数,这里Android123提示大家不包含WiFi   static long  getMobileRxPackets()  //获取Mobile连接收到的数据包总数   static long  get