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

转载请注明出处: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;
	//是否是用户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="@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

这个类实现的功能很简单,调用其他类的方法,将获取的信息显示到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();

	}
}

三、运行效果

正在加载应用程序

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

四、温馨提示

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 01:30:11

Android之——获取手机安装的应用程序的相关文章

Android下获取手机和SD卡的总空间和可用空间

获取SD卡的总空间和可用空间 File path = Environment.getExternalStorageDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSize(); long totalBlocks = stat.getBlockCount(); long availableBlocks = stat.getAvailableBlocks(); long tota

Android编程获取手机型号,本机电话号码,sdk版本及firmware版本号(即系统版本号)

Android开发平台中,可通过TelephonyManager 获取本机号码. TelephonyManager phoneMgr=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); txtPhoneNumber.setText(phoneMgr.getLine1Number()); //txtPhoneNumber是一个EditText 用于显示手机号 注: 根据Android的安全机制,在使用Telepho

【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)

众所周知,通过PackageManager可以获取手机端已安装的apk文件的信息,具体代码如下 [java] view plaincopyprint? PackageManager packageManager = this.getPackageManager(); List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(0); 通过以上方法,可以得到手机中安装的所有应用程序,既包括了手动安装的apk包的信

安卓Launcher之获取手机安装的应用列表

Launcher中最主要的就是获取所有应用列表的入口以及图标,一般获取的方法有两种: PackageInfo ResolveInfo 运行获取所有APP的Launcher并且允许进行点击事件,进入到应用 下面通过这两种方法获取到所有应用的列表: 建立基本数据: PakageMod.java public class PakageMod { public String pakageName; public String appName; public Drawable icon; public P

安卓Launcher之获取手机安装的应用列表,安卓launcher

Launcher中最主要的就是获取所有应用列表的入口以及图标,一般获取的方法有两种: PackageInfo ResolveInfo 运行获取所有APP的Launcher并且允许进行点击事件,进入到应用 下面通过这两种方法获取到所有应用的列表: 建立基本数据: PakageMod.java public class PakageMod { public String pakageName; public String appName; public Drawable icon; public P

【Android】获取手机的相关硬件信息

今天在QQ群里聊天,一个哥们在某宝买到了一个运行内存16G的手机,当时我就吓尿了,所以有了写个程序把这个手机的实际内存读出来的想法,于是就有了今天这篇博客. 所有的信息项如下图所示.(由于我的测试机没有插手机卡,所以有的信息会显示为空) 以下就是代码: package com.liu.chad.practicesqlite; import android.app.ActivityManager; import android.content.Context; import android.os.

Android编程获取手机的IMEI

手机在生产时,每部手机均有一个唯一的标识(ID),国际上采用国际移动设备身份码(IMEI, International Mobile Equipment Identity).IMEI是由15位数字组成的"电子串号",它与每台手机一一对应,而且该码是全世界唯一的.每一只手机在组装完成后都将被赋予一个全球唯一的一组号码,这个号码从生产到交付使用都将被制造生产的厂商所记录. 在手机应用开发中,使用IMEI来做身份认证是一个常用的技术手段,在Android SDK中,类android.tele

[Android Pro] 获取手机已经安装的应用 和 获取当前正在运行的所有进程(一个uid对应多个pid)

1: 获取PackageManager 获取全部静态已安装的应用: ? 1 PackageManager pm = getPackageManager(); <br>List<PackageInfo> infos = pm.getInstalledPackages(0); <br><br>icon  : info.applicationInfo.loadIcon(pm)<br>appName : info.applicationInfo.load

Qt For Android 如何获取手机屏幕大小

获取方法 首先看一段程序代码: int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); } a为应用程序,w为对话框:我们获取屏幕大小,需要从变量a这里获取: QScreen *iScreen = a.primaryScreen(); QSize rScreenSize = iScreen->size(); 虽然把屏幕大小获得了,但是我们改变UI大小的程