Android 下获取各个包的信息
此博客始发于: http://blog.csdn.net/lys211
转载请保留标识。
自己在写东西的时候需要获取到手机上所有包的安装时间、使用次数、使用时长、最后一次启动的时间等等信息。
百度谷歌良久,终于完成。
android里是有获取这些数据所需要的包的,分别是:
com.android.internal.app.IUsageStats
com.android.internal.os.PkgUsageStats
但是上面这个好东西被google对外隐藏了,直接用是用不了的。
想查看它们的详细实现,可以参考:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/1.5_r4/com/
如果是在sdk下写的代码,在没有完成framework.jar的情况下,推荐使用反射来调用,参考以下方法:
Class<?> ServiceManager = Class.forName("android.os.ServiceManager");
Method getService = ServiceManager.getMethod("getService", java.lang.String.class);
Object objRemoteService = getService.invoke(null, "usagestats");
Class<?> cStub = Class.forName("com.android.internal.app.IUsageStats$Stub");
Method asInterface = cStub.getMethod("asInterface", android.os.IBinder.class);
private Object objIUsageStats = asInterface.invoke(null, objRemoteService);
private Method getPkgUsageStats = objIUsageStats.getClass().getMethod("getPkgUsageStats", ComponentName.class);
private Class<?> cPkgUsageStats = Class.forName("com.android.internal.os.PkgUsageStats");
注:如果有完整的framework.jar,在项目中导入这个framework.jar,就可以直接使用这些隐藏的api了。
之后使用以下方法:
int aLaunchCount = cPkgUsageStats.getDeclaredField("launchCount").getInt(oStats);//总登录次数
long aUseTime = cPkgUsageStats.getDeclaredField("usageTime").getLong(oStats);//上次使用的时长
String apkgString = (String)cPkgUsageStats.getDeclaredField("packageName").get(oStats);//app的包名
Map<String, Long > componentResumeMap = (Map<String, Long>) cPkgUsageStats.getDeclaredField("componentResumeTimes").get(oStats);//此app所有activity的最后登录时间。
获取某个app最后使用的时候,可以这样拿:
private long getLatestResumeTime(Map<String, Long > componentResumeTimeMap){///
Log.i(LAPP_USAGE_REFLECT_TAG, " getLatestResumeTime ");
long resumeTime = 0;
long keyTime = 0;
for(String key : componentResumeTimeMap.keySet()){
keyTime = componentResumeTimeMap.get(key);
Log.i(LAPP_USAGE_REFLECT_TAG, " get map data: "+ resumeTime + " | " + keyTime + " | " + key.toString() );
if(keyTime > resumeTime){
resumeTime = keyTime;
}
}
return resumeTime;
}
这样编译没问题.
但是有的时候在模拟器运行或者在手机上运行时会报错,权限问题:
android.permission.PACKAGE_USAGE_STATS
于是在AndroidManifest.xml里加上这句,加上了这句,有的eclipse会有这里有个error警告,导致无法编译。
说明这个权限一般不给使用,为了正常编译,可以使用以下方法:
Windows -> Preference -> Android -> Lint Error Checking -> ID -> Correctness , 在这列里找到 ProtectedPremission,在右下角Severity里将这个ProtectedPremission的报警等级降下来,降为Warning就可以了,可以编译了。
编译完在手机上还是无法安装,还是提示的权限问题...
此时,想要继续下支就只能把手机root了(当然如果你是在源码环境下开发的话,当我什么都没说)。
二阶段:
root 掉手机后,其实还是无法运行,因为 android.permission.PACKAGE_USAGE_STATS 这个权限是要求system app才可以使用,
所以将你的app提升为系统app后,再安装就可以正确获取到包信息了。//将app提升为system app的方法会另外说明。
来一张获取信息的截图:
最后,如果你不是想获取到以上的包信息,我想 PackageManager 这个类就完全够用了。