Android Launcher页面最近任务开发
1、需要导入Framework.jar
2、AS会报错但是能编译成功,想让MainActivity中的代码正常编译运行,就需要修改依赖模块AndroidSDK和framework.jar的先后顺序,只要让framework.jar加载的优先级高于AndroidSDK。参考此文章:Android开发之依赖framework.jar包引用系统隐藏的属性和方法_AFinalStone的博客-CSDN博客
/**
* 通过FrameWork层获取最近任务
* @return a list of the recents tasks.
*/
public static List<ActivityManager.RecentTaskInfo> getRecentTasks(int numTasks, int userId) {
try {
return ActivityManager.getService().getRecentTasks(numTasks,
RECENT_IGNORE_UNAVAILABLE, userId).getList();
} catch (RemoteException e) {
Log.e(TAG, "Failed to get recent tasks", e);
return new ArrayList<>();
}
}
/**
* 获取最近任务列表具体信息
* @param context
* @return 返回最近任务列表
*/
@RequiresApi(api = Build.VERSION_CODES.M) public static List<AppInfoBean> get(Context context,int numTasks) { List<AppInfoBean> list = new ArrayList<>(); final PackageManager pm = context.getPackageManager(); //此方法要调用Framework层的方法,获取最近任务列表 List<ActivityManager.RecentTaskInfo> recents = getRecentTasks(numTasks, UserHandle.myUserId()); try { for (int i = 0; i < recents.size(); i++) { //通过RecentTaskInfo转换ResolveInfo 获取包名、应用名、icon final ActivityManager.RecentTaskInfo info = recents.get(i); Intent intent = new Intent(info.baseIntent); if (info.origActivity != null) { intent.setComponent(info.origActivity); } //这句话我暂时还不时很清晰 intent.setFlags((intent.getFlags() & ~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) | Intent.FLAG_ACTIVITY_NEW_TASK); // 获取指定应用程序activity的信息 final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); //屏蔽不显示的应用 if (resolveInfo != null) { final ActivityInfo activityInfo = resolveInfo.activityInfo; final String title = activityInfo.loadLabel(pm).toString(); final String pkName = resolveInfo.activityInfo.packageName; AppInfoBean infoBean = new AppInfoBean(); Drawable icon = activityInfo.loadIcon(pm); infoBean.setAppIcon(icon); infoBean.setAppName(title); infoBean.setPkgName(pkName); list.add(infoBean); } } return list; } catch (Exception e) { e.printStackTrace(); return null; } }
App信息类 public class AppInfoBea { private String appName; private Drawable appIcon; private String pkgName ; public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public Drawable getAppIcon() { return appIcon; } public void setAppIcon(Drawable appIcon) { this.appIcon = appIcon; } public String getPkgName() { return pkgName; } public void setPkgName(String pkgName) { this.pkgName = pkgName; } @Override public String toString() { return "AppInfoBean{" + "appName='" + appName + '\'' + ", pkgName='" + pkgName + '\'' +'}'; } }
有可能获取最近任务列表是个耗时的操作所以写了一个异步类来获取数据
public class MyAsyncTask extends AsyncTask<String, String, List<AppInfoBean>> {
private Context mContext;
private List<AppInfoBean> mData;
private OnResponseListener<List<AppInfoBean>> listener;
public MyAsyncTask(Context context) {
mContext = context;
}
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected List<AppInfoBean> doInBackground(String... strings) {
mData = AppsUtil.get(mContext,10);
Log.d("task", "doInBackground: "+mData.size());
return mData;
}
@Override
protected void onPostExecute(List<AppInfoBean> appInfoBeans) {
super.onPostExecute(appInfoBeans);
if (listener != null) {
listener.onResponse(appInfoBeans);
}
}
public void setListener(OnResponseListener<List<AppInfoBean>> listener) {
this.listener = listener;
}
//定义回调接口
public interface OnResponseListener<T> {
void onResponse(T t);
}
}
最后在你可以在activity的onResume()来执行这一步操作,这样每次打开主页都是最新的任务列表。但是每次可见的时候都要重新获取数据,消耗内存,暂时没想到更好的方法,也希望各路大神指点。 @Override protected void onResume() { MyAsyncTask myAsyncTask=new MyAsyncTask(context); myAsyncTask.setListener(new MyAsyncTask.OnResponseListener<List<AppInfoBean>>() { @Override public void onResponse(List<AppInfoBean> appInfoBeans) { Log.d("task", "onResponse: "); //在这里初始化你的recycleview的adapter } }); myAsyncTask.execute(); }