最近工作中使用到根据手机已安装应用的使用频次,然后向用户推荐这些最近使用的app。
演示效果:
整体做法:
1.通过packageManager获取手机上已安装应用
2.通过UsageStatsManager查询用户使用应用频次统计
3.按照使用频次对应用进行排序
判断用户是否开启应用使用统计权限和查询已安装应用权限
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
然后跳转到权限打开页面:
询问权限
public static boolean hasEnable(Context context) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
long ts = System.currentTimeMillis();
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Service.USAGE_STATS_SERVICE);
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, 0, ts);
if (queryUsageStats == null || queryUsageStats.isEmpty()) {
return false;
}
}
return true;
}
通过packageManager获取手机上已安装应用
获取手机已安装应用
public static ArrayList<AppInfo> getAllAppInfo(Context ctx, boolean isFilterSystem) {
ArrayList<AppInfo> appBeanList = new ArrayList<>();
AppInfo bean = null;
PackageManager packageManager = ctx.getPackageManager();
List<PackageInfo> list = packageManager.getInstalledPackages(0);
for (PackageInfo p : list) {
bean = new AppInfo(packageManager.getApplicationLabel(p.applicationInfo).toString(),
0, p.packageName, p.applicationInfo.loadIcon(packageManager));
int flags = p.applicationInfo.flags;
// 判断是否是属于系统的apk
if ((flags & ApplicationInfo.FLAG_SYSTEM) != 0&&isFilterSystem) {
} else {
appBeanList.add(bean);
}
}
return appBeanList;
}
获取app使用频次
@SuppressLint("WrongConstant")
public static List<UsageStats> getUsagList(Context context) {
UsageStatsManager manager = (UsageStatsManager) context.getSystemService("usagestats");
long endTime = 0, startTime = 0;
endTime = System.currentTimeMillis();
startTime = getZeroClockTimestamp(endTime);
List<UsageStats> usageStats = manager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, startTime, endTime);
return usageStats;
}
通过获取UsageStats类的mLaunchCount属性,对app进行排序:
/**
* 根据使用频次推荐app
*/
private fun addRecommendApp(
stats: UsageStats,
localApps: MutableList<AppInfo>,
appInfoList: List<AppInfo>
) {
try {
val count = stats.javaClass.getDeclaredField("mLaunchCount").getInt(stats)
if (count != 0) {
for (i in appInfoList.indices) {
if (stats.packageName == appInfoList[i].packageName) {
appInfoList[i].launchCount = count
localApps.add(appInfoList[i])
}
}
}
} catch (e: IllegalAccessException) {
e.printStackTrace()
} catch (e: NoSuchFieldException) {
e.printStackTrace()
}
}
按使用频次排序
private fun getPackages() {
datas.clear()
val allAppInfo = AppHelper.getAllAppInfo(this, true)
val usagList = AppHelper.getUsagList(applicationContext)
usagList.forEach {
if (!AppHelper.isSystemApp(applicationContext, it.packageName)) {
addRecommendApp(it, datas, allAppInfo)
}
}
datas.sort()
adapter.setDatas(datas)
}
使用的实体类:
class AppInfo(val name: String, var launchCount: Int, val packageName: String, val icon: Drawable): Comparable<Any?> {
override operator fun compareTo(o: Any?): Int {
return if (o is AppInfo) {
if (launchCount > o.launchCount) -1 else 1
} else 0
}
}
功能实现的主要代码就是如上了,这里屏蔽了系统app,因为不过滤系统app实在是太多了。另外,adapter的代码没有贴。
网友评论