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

前几篇有关Android的博文中,向大家介绍了几个项目中常用的实用功能,那么在这篇博文中,我将向大家介绍如何获取Android手机中已经安装的手机应用程序,实用过金山手机卫士或者360手机卫士的童鞋都知道,这些软件都可以获取到当前手机中安装的应用程序。那么,这些功能是如何实现的呢?就让我们一起来看看这些功能具体是如何实现的吧。

一、原理

原理很简单,我们通过Android中提供的PackageManager类,来获取手机中安装的应用程序信息,将这些信息封装成一个对象,这个对象包含应用程序的图标、名称、版本号、包名、是否是用户应用程序等信息,然后将这些对象封装成一个对象集合,再将这个集合显示到界面的listView上,形成一个应用程序列表。呈现给用户的便是一个手机中安装的应用程序列表了。

原理是不是很简单呢?下面,就让我们一起来实现这些功能吧。

二、实现

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;//是否是用户appprivate 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;}@Overridepublic 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 stubthis.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="@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;//动态改变appInfospublic 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

这个类实现的功能很简单,调用其他类的方法,将获取的信息显示到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程序,默认为trueprivate 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);//隐藏RelativeLayoutrl_loading.setVisibility(View.GONE);//View.VISIBLE (控件显示)View.INVISIBLE(控件隐藏  但占据空间)  View.GONE(控件隐藏  不占据空间)break;default:break;}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.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;    }

三、运行效果

正在加载应用程序

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

四、温馨提示

本实例中,为了方面,我把一些文字直接写在了布局文件中和相关的类中,大家在真实的项目中要把这些文字写在strings.xml文件中,在外部引用这些资源,切记,这是作为一个Android程序员最基本的开发常识和规范,我在这里只是为了方便直接写在了类和布局文件中。

更多相关文章

  1. Android(安卓)获取应用的安装时间及更新时间
  2. Android仿IOS上拉下拉弹性效果
  3. Android(安卓)Studio插件Android(安卓)Code Generator的使用
  4. Android通过代码获取ROOT权限
  5. 最近开发Android的一些总结
  6. Android(安卓)如何更改包名
  7. 【IMOOC学习笔记】多种多样的App主界面Tab实现方法(一)
  8. TextView和EditText中添加图片(ImageSpan)
  9. Android开发指南(35) —— Toast Notifications

随机推荐

  1. 伦敦开发者构建了一个基于 Android(安卓)
  2. 巧用事件分发机制,和我一起hold住android
  3. android 可以精确到秒级的时间选择器
  4. 韩国监管机构撤销对Android反竞争指控
  5. 关于eclipse中关联各版本Android.jar对应
  6. 思考Android架構(一):What & Why《Android
  7. Android使用Sqlite存储数据用法示例
  8. Android(安卓)淡入淡出动画
  9. :开源社区是个好地方:第一个android小程序
  10. [置顶] 一路16有你,一起17前行。Keep不止,A