zoukankan      html  css  js  c++  java
  • 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="@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;
        }

    三、执行效果

    正在载入应用程序

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

    四、温馨提示

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

  • 相关阅读:
    UWP&WP8.1 基础控件——Grid
    UWP&WP8.1 基础控件——Border
    UWP&WP8.1 基础控件——Image
    UWP&WP8.1 基础控件—Button
    UWP&WP8.1 基础控件—TextBlock和TextBox
    UWP &WP8.1 依赖属性和用户控件 依赖属性简单使用 uwp添加UserControl
    UWP_开源小程序 水印添加器
    UWP&WP8.1 附加属性 和WebView的NavigateToString方法XAML绑定方法
    Sql Server 中锁的概念
    MSSQL 查询表空间
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6747820.html
Copyright © 2011-2022 走看看