利用RxJava获取手机已安装的App的图片、应用名称和版本号
2016-11-14 20:28
393 查看
先上效果图:
获取手机已安装的App列表利用Android系统API就可以办到,这里为什么要引入RxJava?现在我们假设一下有下面几个需求:
1、我们不需要所有的App,只需要用户安装的第三方App,即过滤到系统App;
2、我们自定义一个AppInfo类,该类中保存了App_Icon、App_Name、App_VersionName等属性,而Android系统提供的API我们只能获取ApplicationInfo,这样就存在一个类型转换;
3、获取Application信息,过滤数据这些操作都是相对耗时的操作,我们需要在工作线程进行操作,获取数据后,我们又需要切换到UI线程进行结果的显示,这又涉及到线程的切换。
基于上面的需求,我们用传统的java代码来实现,相对来说比较麻烦,既然RxJava现在这么火,我们就利用RxJava来实现上面的几个需求。本文所涉及的RxJava操作符主要包括filter、map两个操作符。
一、定义一个AppInfo类,用来保存我们需要显示的信息
二、定义一个Adapter
三、显示页面
显示页面主要是一个RecyclerView列表,用来展示手机中已经安装的App列表。布局什么的就不多说了,直接上代码:
通过getInstalledApp方法,我们可以获取到系统的安装的应用的PackageInfo,在getAllApp刚发中,通过subscriber.onNext(info)发送PackageInfo;由于PackageInfo中包含了所有的App信息,而这并不是我们需要的,我们只需要用户安装的App就可以,这样就要求过滤掉系统App,RxJava提供了一个filter操作符来进行过滤操作,通过map操作我们就可以把系统应用过滤掉;另外,我们需要将获得的PackageInfo转换为我们定义的AppInfo类型,而RxJava只需要一个map操作符就能完成转换,这样就可以把获取的App信息保存到AppInfo类中。
通过上面的过滤和变换之后,我们就可以得到AppInfo,然后在onNext方法中通过mData.add(appInfo)把结果添加进List集合中,onCompleted方法中通知Adapter进行更新mAdapter.notifyDataSetChanged()。
看似复杂的一系列需求,得益于RxJava优秀API设计,使得数据的过滤、变换等操作变得十分简单,同时RxJava的流式API设计,即使我们的逻辑很复杂的情况下,RxJava能够依然保持我们代码逻辑的简洁和易懂。
获取手机已安装的App列表利用Android系统API就可以办到,这里为什么要引入RxJava?现在我们假设一下有下面几个需求:
1、我们不需要所有的App,只需要用户安装的第三方App,即过滤到系统App;
2、我们自定义一个AppInfo类,该类中保存了App_Icon、App_Name、App_VersionName等属性,而Android系统提供的API我们只能获取ApplicationInfo,这样就存在一个类型转换;
3、获取Application信息,过滤数据这些操作都是相对耗时的操作,我们需要在工作线程进行操作,获取数据后,我们又需要切换到UI线程进行结果的显示,这又涉及到线程的切换。
基于上面的需求,我们用传统的java代码来实现,相对来说比较麻烦,既然RxJava现在这么火,我们就利用RxJava来实现上面的几个需求。本文所涉及的RxJava操作符主要包括filter、map两个操作符。
一、定义一个AppInfo类,用来保存我们需要显示的信息
public class AppInfo { private Drawable appIcon; private String appName; private String appVersionName; public Drawable getAppIcon() { return appIcon; } public void setAppIcon(Drawable appIcon) { this.appIcon = appIcon; } public String getAppVersionName() { return appVersionName; } public void setAppVersionName(String appVersionName) { this.appVersionName = appVersionName; } public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } }
二、定义一个Adapter
public class AppInfoAdapter extends RecyclerView.Adapter<AppInfoAdapter.AppInfoViewHolder> { private List<AppInfo> mData; public AppInfoAdapter(List<AppInfo> data) { mData = data; } @Override public AppInfoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_app_info, parent, false); return new AppInfoViewHolder(rootView); } @Override public void onBindViewHolder(AppInfoViewHolder holder, int position) { AppInfo appInfo = mData.get(position); if (appInfo == null) { return; } if (appInfo.getAppIcon() != null) { holder.appIcon.setImageDrawable(appInfo.getAppIcon()); } if (!TextUtils.isEmpty(appInfo.getAppName())) { holder.appName.setText(appInfo.getAppName()); } if (!TextUtils.isEmpty(appInfo.getAppVersionName())) { holder.appVersionCode.setText(appInfo.getAppVersionName()); } } @Override public int getItemCount() { return mData == null ? 0 : mData.size(); } public class AppInfoViewHolder extends RecyclerView.ViewHolder { private ImageView appIcon; private TextView appName; private TextView appVersionCode; public AppInfoViewHolder(View itemView) { super(itemView); appIcon = (ImageView) itemView.findViewById(R.id.app_icon); appName = (TextView) itemView.findViewById(R.id.app_name); appVersionCode = (TextView) itemView.findViewById(R.id.app_version_code); } } }
三、显示页面
显示页面主要是一个RecyclerView列表,用来展示手机中已经安装的App列表。布局什么的就不多说了,直接上代码:
private void getAllApp() { Observable.create(new Observable.OnSubscribe<PackageInfo>() { @Override public void call(Subscriber<? super PackageInfo> subscriber) { List<PackageInfo> packageInfoList = getInstalledApp(getPackageManager()); for (PackageInfo info : packageInfoList) { subscriber.onNext(info); } subscriber.onCompleted(); } }) .map(new Func1<PackageInfo, AppInfo>() { @Override public AppInfo call(PackageInfo packageInfo) { AppInfo appInfo = new AppInfo(); appInfo.setAppIcon(packageInfo.applicationInfo.loadIcon(getPackageManager())); appInfo.setAppName(packageInfo.applicationInfo.loadLabel(getPackageManager()).toString()); appInfo.setAppVersionName(packageInfo.versionName); return appInfo; } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<AppInfo>() { @Override public void onCompleted() { mAdapter.notifyDataSetChanged(); } @Override public void onError(Throwable e) { Log.d(TAG, "onError: " + e.toString()); } @Override public void onNext(AppInfo appInfo) { mData.add(appInfo); } }); } private void getThirdPartyApp() { Observable.create(new Observable.OnSubscribe<PackageInfo>() { @Override public void call(Subscriber<? super PackageInfo> subscriber) { List<PackageInfo> packageInfoList = getInstalledApp(getPackageManager()); for (PackageInfo info : packageInfoList) { subscriber.onNext(info); } subscriber.onCompleted(); } }) .filter(new Func1<PackageInfo, Boolean>() { @Override public Boolean call(PackageInfo packageInfo) { //过滤系统应用 return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0; } }) .map(new Func1<PackageInfo, AppInfo>() { @Override public AppInfo call(PackageInfo packageInfo) { AppInfo appInfo = new AppInfo(); appInfo.setAppIcon(packageInfo.applicationInfo.loadIcon(getPackageManager())); appInfo.setAppName(packageInfo.applicationInfo.loadLabel(getPackageManager()).toString()); appInfo.setAppVersionName(packageInfo.versionName); return appInfo; } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<AppInfo>() { @Override public void onCompleted() { mAdapter.notifyDataSetChanged(); } @Override public void onError(Throwable e) { Log.d(TAG, "onError: " + e.toString()); } @Override public void onNext(AppInfo appInfo) { mData.add(appInfo); } }); } private List<PackageInfo> getInstalledApp(PackageManager pm) { return pm.getInstalledPackages(0); }
通过getInstalledApp方法,我们可以获取到系统的安装的应用的PackageInfo,在getAllApp刚发中,通过subscriber.onNext(info)发送PackageInfo;由于PackageInfo中包含了所有的App信息,而这并不是我们需要的,我们只需要用户安装的App就可以,这样就要求过滤掉系统App,RxJava提供了一个filter操作符来进行过滤操作,通过map操作我们就可以把系统应用过滤掉;另外,我们需要将获得的PackageInfo转换为我们定义的AppInfo类型,而RxJava只需要一个map操作符就能完成转换,这样就可以把获取的App信息保存到AppInfo类中。
通过上面的过滤和变换之后,我们就可以得到AppInfo,然后在onNext方法中通过mData.add(appInfo)把结果添加进List集合中,onCompleted方法中通知Adapter进行更新mAdapter.notifyDataSetChanged()。
看似复杂的一系列需求,得益于RxJava优秀API设计,使得数据的过滤、变换等操作变得十分简单,同时RxJava的流式API设计,即使我们的逻辑很复杂的情况下,RxJava能够依然保持我们代码逻辑的简洁和易懂。
相关文章推荐
- 利用RxJava获取手机已安装的App的图片、应用名称和版本号
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等) 收藏
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)
- 获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)
- Android获取已安装应用信息(图标,名称,版本号,包)
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等) 收藏
- Android获取已安装应用信息(图标,名称,版本号,包)
- 获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)
- Android获取已安装应用信息(图标,名称,版本号,包)
- Android获取已安装应用信息(图标,名称,版本号,包)
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)
- Android获取已安装应用信息(图标,名称,版本号,包)
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等
- Android获取已安装应用信息(图标,名称,版本号,包)
- 获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)
- Android获取已安装应用信息(图标,名称,版本号,包)
- Android获取已安装应用信息(图标,名称,版本号,包)(转载)
- Android获取已安装应用信息(图标,名称,版本号,包)