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;
}
三、执行效果
正在载入应用程序
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" height="340" width="433">
获取到手机中安装的应用程序
四、温馨提示
本实例中。为了方面,我把一些文字直接写在了布局文件里和相关的类中。大家在真实的项目中要把这些文字写在strings.xml文件里,在外部引用这些资源,切记,这是作为一个Android程序猿最主要的开发常识和规范,我在这里仅仅是为了方便直接写在了类和布局文件里。
Android之——获取手机安装的应用程序的更多相关文章
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)
众所周知,通过PackageManager可以获取手机端已安装的apk文件的信息,具体代码如下 PackageManager packageManager = this.getPackageManag ...
- 安卓Launcher之获取手机安装的应用列表,安卓launcher
Launcher中最主要的就是获取所有应用列表的入口以及图标,一般获取的方法有两种: PackageInfo ResolveInfo 运行获取所有APP的Launcher并且允许进行点击事件,进入到应 ...
- Android中获取正在运行的应用程序-----ActivityManager.RunningAppProcessInfo类详解
今天继续讲解关于ActivityManager的使用,通过前面一节的学习,我们学会了如何利用ActivityManager获取系统里 正在运行的进程.本文要讲解的知识点是利用这些进程信息获取系统里正在 ...
- android如何获取手机型号和版本号
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView ...
- Android编程获取手机的IMEI
手机在生产时,每部手机均有一个唯一的标识(ID),国际上采用国际移动设备身份码(IMEI, International Mobile Equipment Identity).IMEI是由15位数字组成 ...
- Android中获取手机电量信息
有些时候我们需要在我们的应用上为用户展示当前手机的电量,这时候我们就需要用到广播了,我们都知道在动态注册广播的时候,我们需要传入一个BroadcastReceiver类对象,还有一个意图过滤器Inte ...
- 如何获取离线安装Chrome扩展程序的包
最近工作环境限制,有些机器文件只能拿进去,不能拿出来.网络也是内部网络,没法下载东西.工作中常用的一些Chrome扩展应用也没法使用,对于我这类工具爱好者,打击够大.后来想想,既然扩展应用能开发打包上 ...
- Android获取手机安装的浏览器列表
最近碰到一个同事询问如何查询本地安装的浏览器列表,其使用的代码如下: public static List<ResolveInfo> getBrowserList(Context cont ...
- [Android Pro] 获取手机已经安装的应用 和 获取当前正在运行的所有进程(一个uid对应多个pid)
1: 获取PackageManager 获取全部静态已安装的应用: PackageManager pm = getPackageManager(); List<PackageInfo> i ...
随机推荐
- 利用php设置url转发 - 解决空间不提供子目录绑定功能的问题
由于很多新手都是使用的虚拟空间都是最便宜的那种,这空间一般不支持子目录绑定.但是很多朋友又想设置几个不同的二级域名访问不同的网站程序.于是大家找到了域名url转发,但是由于国家政策的原因,许多服务商暂 ...
- JS实现上下左右对称的九九乘法表
JS实现上下左右对称的九九乘法表 css样式 <style> table{ table-layout:fixed; border-collapse:collapse; } td{ padd ...
- Excel2010数据透视表1
“透视”作为一个动词,意思是旋转.如果将数据看成是一个物体,数据透视表允许旋转数据汇总,从不同角度或观点来看它.数据透视表能够轻松地移动字段,交换字段位置,设置创建项目的特定组. 如果给出一个陌生的物 ...
- echarts 图表建立步骤
需要引用的文件 <script src="web/mobile/js/jquery-1.8.3.min.js"></script> <script s ...
- solr 启动过程分析
http://www.cnblogs.com/likehua/p/4353608.html#top
- (13)python 正则表达式
匹配单个字符 f. o f和o之间是任意字符 例如:fbo123 .. 任意两个字符 \.用来匹配. 边界匹配 the 表示包含the的任何字符串 ^from 表示以from开头的所 ...
- HDU 1029 Ignatius and the Princess IV(数论)
#include <bits/stdc++.h> using namespace std; int main(){ int n; while(~scanf("%d",& ...
- requests库使用socks5代理
备查: #!usr/bin/env python # coding=utf-8 import requests proxies = {'https': 'https://127.0.0.1:1080' ...
- cogs p服务点设置
5. P服务点设置 ★★ 输入文件:djsc.in 输出文件:djsc.out 简单对比时间限制:2 s 内存限制:128 MB 问题描述为了进一步普及九年义务教育,政府要在某乡镇建立 ...
- 【数论】【最大公约数】【枚举约数】CODEVS 1012 最大公约数和最小公倍数问题 2001年NOIP全国联赛普及组
对于一对数(p,q),若它们的gcd为x0,lcm为y0, 则:p*q/x0=y0,即q=x0*y0/p, 由于p.q是正整数,所以p.q都必须是x0*y0的约数. 所以O(sqrt(x0*y0))地 ...