Android之——获取手机安装的应用程序

莫道桑榆晚,为霞尚满天。这篇文章主要讲述Android之——获取手机安装的应用程序相关的知识,希望能为你提供帮助。

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47114331

前几篇有关android的博文中。向大家介绍了几个项目中经常使用的有用功能。那么在这篇博文中。我将向大家介绍怎样获取Android手机中已经安装的手机应用程序,有用过金山手机卫士或者360手机卫士的童鞋都知道。这些软件都能够获取到当前手机中安装的应用程序。
那么,这些功能是怎样实现的呢?就让我们一起来看看这些功能详细是怎样实现的吧。
一、原理
原理非常easy,我们通过Android中提供的PackageManager类,来获取手机中安装的应用程序信息,将这些信息封装成一个对象,这个对象包括应用程序的图标、名称、版本、包名、是否是用户应用程序等信息。然后将这些对象封装成一个对象集合。再将这个集合显示到界面的listView上。形成一个应用程序列表。呈现给用户的便是一个手机中安装的应用程序列表了。
原理是不是非常easy呢?以下,就让我们一起来实现这些功能吧。

二、实现
1、创建应用程序的实体类AppInfo为了更加面向对象化和体现面向对象的封装性。我将获取到的每个应用程序信息封装成了一个java对象,这个对象包括应用程序的图标、名称、版本、包名、是否是用户应用程序等信息。
详细实现代码例如以下:

package cn.lyz.mobilesafe.domain; import android.graphics.drawable.Drawable; /** * 获取的应用基本信息实体类 * @author liuyazhuang * */ public class AppInfo { //图标 private Drawable app_icon; //应用名称 private String app_name; //应用版本 private String app_version; //应用包名 private String packagename; //是否是用户app private boolean isUserApp; public AppInfo() { super(); // TODO Auto-generated constructor stub } public AppInfo(Drawable app_icon, String app_name, String app_version, String packagename) { super(); this.app_icon = app_icon; this.app_name = app_name; this.app_version = app_version; this.packagename = packagename; } public AppInfo(Drawable app_icon, String app_name, String app_version, String packagename, boolean isUserApp) { super(); this.app_icon = app_icon; this.app_name = app_name; this.app_version = app_version; this.packagename = packagename; this.isUserApp = isUserApp; } public Drawable getApp_icon() { return app_icon; } public void setApp_icon(Drawable app_icon) { this.app_icon = app_icon; } public String getApp_name() { return app_name; } public void setApp_name(String app_name) { this.app_name = app_name; } public String getApp_version() { return app_version; } public void setApp_version(String app_version) { this.app_version = app_version; } public String getPackagename() { return packagename; } public void setPackagename(String packagename) { this.packagename = packagename; } public boolean isUserApp() { return isUserApp; } public void setUserApp(boolean isUserApp) { this.isUserApp = isUserApp; } @Override public String toString() { return " AppInfo [app_icon=" + app_icon + " , app_name=" + app_name + " , app_version=" + app_version + " , packagename=" + packagename + " , isUserApp=" + isUserApp + " ]" ; } }


2、获取手机应用程序的业务类AppInfoService这个类主要实现获取手机中安装的应用程序的主要业务功能。封装了怎样获取手机安装的应用程序的方法。
详细实现代码例如以下:

package cn.lyz.mobilesafe.engine; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import cn.lyz.mobilesafe.domain.AppInfo; /** * 获取手机应用程序 * @author liuyazhuang * */ public class AppInfoService { private Context context; private PackageManager pm; public AppInfoService(Context context) { // TODO Auto-generated constructor stub this.context = context; pm = context.getPackageManager(); } /** * 得到手机中全部的应用程序信息 * @return */ public List< AppInfo> getAppInfos(){ //创建要返回的集合对象 List< AppInfo> appInfos = new ArrayList< AppInfo> (); //获取手机中全部安装的应用集合 List< ApplicationInfo> applicationInfos = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES); //遍历全部的应用集合 for(ApplicationInfo info : applicationInfos){AppInfo appInfo = new AppInfo(); //获取应用程序的图标 Drawable app_icon = info.loadIcon(pm); appInfo.setApp_icon(app_icon); //获取应用的名称 String app_name = info.loadLabel(pm).toString(); appInfo.setApp_name(app_name); //获取应用的包名 String packageName = info.packageName; appInfo.setPackagename(packageName); try { //获取应用的版本 PackageInfo packageInfo = pm.getPackageInfo(packageName, 0); String app_version = packageInfo.versionName; appInfo.setApp_version(app_version); } catch (NameNotFoundException e) { e.printStackTrace(); } //推断应用程序是否是用户程序 boolean isUserApp = filterApp(info); appInfo.setUserApp(isUserApp); appInfos.add(appInfo); } return appInfos; } //推断应用程序是否是用户程序 public boolean filterApp(ApplicationInfo info) { //原来是系统应用,用户手动升级 if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { return true; //用户自己安装的应用程序 } else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { return true; } return false; } }


3、样式文件styles.xml在res/values文件夹下新建styles.xml文件来定义应用程序的样式信息。我在这个文件里主要定义个两个样式。
详细代码例如以下:

< style name=" view_divide_line_style" > < item name=" android:layout_width" > fill_parent< /item> < item name=" android:layout_height" > 1dip< /item> < item name=" android:layout_marginTop" > 5dip< /item> < item name=" android:background" > @drawable/devide_line< /item> < /style>

< style name=" text_title_style" > < item name=" android:layout_width" > fill_parent< /item> < item name=" android:layout_height" > wrap_content< /item> < item name=" android:gravity" > center< /item> < item name=" android:textColor" > #42E700< /item> < item name=" android:textSize" > 25sp< /item> < /style>


4、主布局文件applationinstall.xml详细实现代码例如以下:

< ?
xml version=" 1.0" encoding=" utf-8" ?> < LinearLayout xmlns:android=" http://schemas.android.com/apk/res/android" android:layout_width=" fill_parent" android:layout_height=" fill_parent" android:orientation=" vertical" > < TextView android:id=" @+id/tv_title" style=" @style/text_title_style" android:text=" 所有程序" /> < View style=" @style/view_divide_line_style" /> < FrameLayout android:layout_width=" fill_parent" android:layout_height=" fill_parent" > < !-- android:cacheColorHint=" #00000000" 缓存的颜色默认是黄色 android:divider=" #00ffffff" 切割线 android:dividerHeight=" 3.0dip" 切割线的宽度 --> < ListView android:id=" @+id/lv_appmanage" android:layout_width=" fill_parent" android:layout_height=" fill_parent" android:cacheColorHint=" #00000000" android:divider=" #fff" android:fastScrollEnabled=" true" android:dividerHeight=" 1.0dip" android:paddingLeft=" 3.0dip" android:paddingRight=" 3.0dip" /> < RelativeLayout android:id=" @+id/rl_loading" android:layout_width=" fill_parent" android:layout_height=" fill_parent" > < LinearLayout android:layout_width=" wrap_content" android:layout_height=" wrap_content" android:orientation=" vertical" android:layout_centerInParent=" true" > < ProgressBar android:id=" @+id/pb" android:layout_width=" wrap_content" android:layout_height=" wrap_content" android:layout_gravity=" center" /> < TextView android:layout_width=" wrap_content" android:layout_height=" wrap_content" android:layout_marginTop=" 10dip" android:text=" 正在载入应用程序。。" android:textColor=" #fff" android:textSize=" 22sp" /> < /LinearLayout> < /RelativeLayout> < /FrameLayout> < /LinearLayout>


5、ListView中每一项条目布局applationinstall_item.xml详细实现代码例如以下

< ?xml version=" 1.0" encoding=" utf-8" ?
> < RelativeLayout xmlns:android=" http://schemas.android.com/apk/res/android" android:layout_width=" fill_parent" android:layout_height=" wrap_content" android:orientation=" horizontal" android:paddingBottom=" 8.0dip" android:paddingLeft=" 6.0dip" android:paddingRight=" 5.0dip" android:paddingTop=" 8.0dip" > < ImageView android:id=" @+id/iv_appicon" android:layout_width=" wrap_content" android:layout_height=" wrap_content" android:layout_centerVertical=" true" android:src=https://www.songbingjia.com/android/" @drawable/ic_launcher" /> < TextView android:id=" @+id/tv_appname" android:layout_width=" wrap_content" android:layout_height=" wrap_content" android:layout_centerVertical=" true" android:layout_marginLeft=" 4.0dip" android:layout_toRightOf=" @id/iv_appicon" android:textColor=" #fff" android:text=" 我最摇摆" android:textSize=" 16.0dip" /> < TextView android:id=" @+id/tv_appversion" android:layout_width=" wrap_content" android:layout_height=" wrap_content" android:layout_alignParentRight=" true" android:layout_centerVertical=" true" android:layout_marginLeft=" 4.0dip" android:textColor=" #fff" android:layout_marginRight=" 10dp" android:text=" 1.0" android:textSize=" 16.0dip" /> < /RelativeLayout>


6、自己定义ListView适配器AppManagerAdapter这个类继承自BaseAdapter主要作为List显示数据的适配器,在这个类中通过布局载入器LayoutInflater来载入条目布局。找到布局上的控件来设置对应的信息。

详细实现代码例如以下:

package cn.lyz.mobilesafe.adapter; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import cn.lyz.mobilesafe.R; import cn.lyz.mobilesafe.domain.AppInfo; /** * App管理的Adapter类 * @author liuyazhuang * */ public class AppManagerAdapter extends BaseAdapter { private Context context; //布局载入器 private LayoutInflater mInflater; private List< AppInfo> appInfos; //动态改变appInfos public void setAppInfos(List< AppInfo> appInfos) { this.appInfos = appInfos; } public AppManagerAdapter(Context context,List< AppInfo> appInfos) { this.context = context; this.appInfos = appInfos; mInflater = LayoutInflater.from(context); } public int getCount() { return appInfos.size(); } public Object getItem(int position) { return appInfos.get(position); } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { //1 得到控件 //2 得到数据 //3 绑定数据 View view = null; if(convertView != null){ view = convertView; }else{ view = mInflater.inflate(R.layout.applationinstall_item, null); }//获取布局控件 ImageView iv_appicon = (ImageView) view.findViewById(R.id.iv_appicon); TextView tv_appname = (TextView) view.findViewById(R.id.tv_appname); TextView tv_appversion = (TextView) view.findViewById(R.id.tv_appversion); //获取position位置上的AppInfo对象 AppInfo appInfo = appInfos.get(position); iv_appicon.setImageDrawable(appInfo.getApp_icon()); tv_appname.setText(appInfo.getApp_name()); tv_appversion.setText(appInfo.getApp_version()); return view; }}


7、程序显示界面AppManagerActivity这个类实现的功能非常easy,调用其它类的方法,将获取的信息显示到ListView上。
详细的实现是在onCreate方法中找到布局上的控件。并在一个线程程序中调用AppInfoService中的方法获取手机中安装的应用程序,并将获取的结果通过Handler与Message机制传递到主线程,主线程将这些数据显示到UI视图上。
详细实现代码例如以下:

package cn.lyz.mobilesafe.activity; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.ListView; import android.widget.PopupWindow; import android.widget.RelativeLayout; import android.widget.TextView; import cn.lyz.mobilesafe.R; import cn.lyz.mobilesafe.adapter.AppManagerAdapter; import cn.lyz.mobilesafe.domain.AppInfo; import cn.lyz.mobilesafe.engine.AppInfoService; /** * APP管理的Manager类 * @author liuyazhuang * */ public class AppManagerActivity extends Activity{ protected static final int SUCCESS_GET_APPLICAITON = 0; //布局中的各个控件 private RelativeLayout rl_loading; private ListView lv_appmanage; private TextView tv_title; //包管理器 private PackageManager pm; //获取手机应用信息的业务类 private AppInfoService appInfoService; //手机应用app信息集合 private List< AppInfo> appInfos; //用户应用程序信息集合 private List< AppInfo> userAppInfos; //是否是全部的app程序,默觉得true private boolean isAllApp = true; //AppManagerAdapter适配器对象 private AppManagerAdapter mAdapter; private PopupWindow mPopupWindow; //mHandler方法 private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { switch (msg.what) { case SUCCESS_GET_APPLICAITON: //给listview去绑定数据。隐藏载入的控件 mAdapter = new AppManagerAdapter(getApplicationContext(), appInfos); //设置数据 lv_appmanage.setAdapter(mAdapter); //隐藏RelativeLayout rl_loading.setVisibility(View.GONE); //View.VISIBLE (控件显示)View.INVISIBLE(控件隐藏但占领空间)View.GONE(控件隐藏不占领空间) break; default: break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.applationinstall); //获取布局中的控件 rl_loading = (RelativeLayout) findViewById(R.id.rl_loading); lv_appmanage = (ListView) findViewById(R.id.lv_appmanage); tv_title = (TextView) findViewById(R.id.tv_title); //实例化AppInfoService对象 appInfoService = new AppInfoService(this); //包管理器 pm = getPackageManager(); //在子线程中获取手机安装的应用程序信息 new Thread(){ public void run() { appInfos = appInfoService.getAppInfos(); userAppInfos = new ArrayList< AppInfo> (); for(AppInfo appInfo:appInfos){ if(appInfo.isUserApp()){ userAppInfos.add(appInfo); } } Message msg = new Message(); msg.what = SUCCESS_GET_APPLICAITON; mHandler.sendMessage(msg); }; }.start(); } }

补充:推断应用程序是否是用户程序
//推断应用程序是否是用户程序 public boolean filterApp(ApplicationInfo info) { //原来是系统应用。用户手动升级 if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { return true; //用户自己安装的应用程序 } else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { return true; } return false; }


三、执行效果
正在载入应用程序

Android之——获取手机安装的应用程序
获取到手机中安装的应用程序

Android之——获取手机安装的应用程序

文章图片

四、温馨提示
【Android之——获取手机安装的应用程序】本实例中。为了方面,我把一些文字直接写在了布局文件里和相关的类中。大家在真实的项目中要把这些文字写在strings.xml文件里,在外部引用这些资源,切记,这是作为一个Android程序猿最主要的开发常识和规范,我在这里仅仅是为了方便直接写在了类和布局文件里。






    推荐阅读