当前位置: 代码迷 >> Android >> 安卓开发获取本机全部已安装程序(形成ListView)
  详细解决方案

安卓开发获取本机全部已安装程序(形成ListView)

热度:22   发布时间:2016-04-28 02:16:04.0
安卓开发获取本机所有已安装程序(形成ListView)

  项目刚好需要用到这个,查询汇总了很多资料最后终于顺利解决,也积累了不少查资料的技巧,现在把思路整理一下,希望能对想做类似功能的朋友有帮,希望结交热爱移动开发的朋友。 下面切入正题!

 

  之前自己写代码一个很坏的习惯就是类的互相解耦之间做的很差,一堆代码都是堆在一起的,从没考虑到规划接口,工具类。


   这里首先创建一个保存一个APP所有信息的类,包括名字,图标,版本号等。

//AllAppInfo类class AllAppInfo {      private int versionCode = 0;  //版本号         private String appname = "";// 程序名称       private String packagename = "";    //包名称       private Drawable appicon ;//图标       private long lastInstal;//最后一次安装时间       private ProviderInfo[] provider;//供应商       private String InstalPath;//安装路径       private int flag ;  //判断是不是系统应用      public int getVersionCode() {        return versionCode;    }        public void setAppicon(PackageManager packageManager) {	// TODO Auto-generated method stub	}public void setVersionCode(int versionCode) {        this.versionCode = versionCode;    }        public String getAppname() {        return appname;    }        public void setAppname(String appname) {        this.appname = appname;    }        public String getPackagename() {        return packagename;    }        public void setPackagename(String packagename) {        this.packagename = packagename;    }                public Drawable getAppicon() {        return appicon;    }        public void setAppicon(Drawable appicon) {        this.appicon = appicon;    }    /**    * @return the lastInstal    */    public long getLastInstal() {        return lastInstal;    }    /**    * @param firstInstallTime the lastInstal to set    */    public void setLastInstal(long firstInstallTime) {        this.lastInstal = firstInstallTime;    }    /**    * @return the provider    */    public ProviderInfo[] getProvider() {        return provider;    }    /**    * @param providers the provider to set    */    public void setProvider(ProviderInfo[] providers) {        this.provider = providers;    }    /**    * @return the instalPath    */    public String getInstalPath() {        return InstalPath;    }    /**    * @param instalPath the instalPath to set    */    public void setInstalPath(String instalPath) {        InstalPath = instalPath;    }       public void setFlags(int flag)  {	  this.flag = flag ;  }    public int getFlags()  {	  return this.flag ;  }}  

写之前这个类看似写了很多多余的东西,但是程序的健壮性大大增加,将来需要深入开发这个APP列表的话一个setter加一个getter直接搞定,代码逻辑一目了然。继续。

这里继续创建一个Get函数,返回一个集合保存所有需要查询的内容


//Get函数    private ArrayList<AllAppInfo> Get(){      ArrayList<AllAppInfo> appList = new ArrayList<AllAppInfo>();         List<PackageInfo> packageInfos=getPackageManager().getInstalledPackages(0);      for (int i = 0; i < packageInfos.size(); i++) {          PackageInfo pInfo=packageInfos.get(i);          AllAppInfo allAppInfo=new AllAppInfo();          allAppInfo.setAppname(pInfo.applicationInfo.loadLabel(getPackageManager()).toString());//应用程序的名称           allAppInfo.setPackagename(pInfo.packageName);//应用程序的包           allAppInfo.setVersionCode(pInfo.versionCode);//版本号           allAppInfo.setFlags(pInfo.applicationInfo.flags);   //uid号        allAppInfo.setLastInstal(pInfo.firstInstallTime);          //allAppInfo.setProvider(pInfo.providers);           allAppInfo.setAppicon( pInfo.applicationInfo.loadIcon(getPackageManager()) );        allAppInfo.setInstalPath(pInfo.applicationInfo.sourceDir);          appList.add(allAppInfo);      }      return appList;      }      

以上两步做完之后整个模块基本就成了,剩下的就是配置一下界面适配器。


import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.pm.ApplicationInfo;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.content.pm.PackageManager.NameNotFoundException;import android.content.pm.ProviderInfo;import android.content.pm.ResolveInfo;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.view.View;import android.widget.Adapter;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ImageView;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.SimpleAdapter.ViewBinder;public class AboutMore extends Activity {  		private ListView listview ;	private List<Map<String, Object>> listitem ;	private String[] systemApp = {"设置","录音机","时钟"} ;	/** Called when the activity is first created. */      @Override      public void onCreate(Bundle savedInstanceState)    {          super.onCreate(savedInstanceState);          setContentView(R.layout.aboutmore_layout);  		 listitem = new ArrayList<Map<String,Object>>();      //  Get();           ArrayList<AllAppInfo> list=this.Get();          for (Iterator<AllAppInfo> iterator = list.iterator(); iterator.hasNext();)         {              AllAppInfo allAppInfo = (AllAppInfo) iterator.next();              System.out.println(allAppInfo.getAppname()+" |"+allAppInfo.getPackagename()+"| "+allAppInfo.getVersionCode()+"|"+allAppInfo.getLastInstal()+"|"+allAppInfo.getInstalPath());              if((allAppInfo.getFlags() & ApplicationInfo.FLAG_SYSTEM)>0)  //如果判定为系统应用            {            	int flag = 0 ;            	for(int i = 0 ;i<systemApp.length ;i++)            	{            		if( systemApp[i].equals(allAppInfo.getAppname()) )            		{            			flag = 1 ;            		}            	}            	if(flag == 0)            		continue ;            		            }           // System.out.println(allAppInfo.getAppname()+" |"+allAppInfo.getPackagename()+"| "+allAppInfo.getVersionCode()+"|"+allAppInfo.getLastInstal()+"|"+allAppInfo.getInstalPath());              Map<String, Object> showitem = new HashMap<String, Object>();            showitem.put("logo",allAppInfo.getAppicon() );              showitem.put("appName",allAppInfo.getAppname());              showitem.put("packagename",allAppInfo.getPackagename() ) ;            listitem.add(showitem);          }          		SimpleAdapter myAdapter = new SimpleAdapter(getApplicationContext(), listitem, R.layout.aboutmore_item_layout, new String[]{"logo","appName"}, new int[]{R.id.logo,R.id.app_name});		myAdapter.setViewBinder(new ViewBinder()		 {	           public boolean setViewValue(View view,Object data,String textRepresentation)	           {	                 if(view instanceof ImageView && data instanceof Drawable)	                 {	                      ImageView iv=(ImageView)view;	                      iv.setImageDrawable((Drawable)data);	                     return true;	                   }	                 else return false;	            }	     } );		listview = (ListView) findViewById(R.id.listview) ;    //实例化listview		listview.setAdapter(myAdapter);                           //为listview添加适配器				//下面开始添加列表的事件监听				listview.setOnItemClickListener(new OnItemClickListener() {			@Override			public void onItemClick(AdapterView<?> parent, View view,					int position, long id) {				// TODO Auto-generated method stub			    String packagename = listitem.get(position).get("packagename").toString() ;				doStartApplicationWithPackageName(packagename);			}		});    }   }

这里在上面代码的最后调用了一个方法,通过程序的包开启调用,以下的代码转自一篇博客。博客地址http://blog.csdn.net/mad1989/article/details/38090513,写的很棒。


*     * 通过包的名字调用其他程序     * 来自:http://blog.csdn.net/mad1989/article/details/38090513     */	private void doStartApplicationWithPackageName(String packagename) {		// 通过包名获取此APP详细信息,包括Activities、services、versioncode、name等等		PackageInfo packageinfo = null;		try {			packageinfo = getPackageManager().getPackageInfo(packagename, 0);		} catch (NameNotFoundException e) {			e.printStackTrace();		}		if (packageinfo == null) {			return;		}		// 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent		Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);		resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);		resolveIntent.setPackage(packageinfo.packageName);		// 通过getPackageManager()的queryIntentActivities方法遍历		List<ResolveInfo> resolveinfoList = getPackageManager()				.queryIntentActivities(resolveIntent, 0);		ResolveInfo resolveinfo = resolveinfoList.iterator().next();		if (resolveinfo != null) {			// packagename = 参数packname			String packageName = resolveinfo.activityInfo.packageName;			// 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packagename.mainActivityname]			String className = resolveinfo.activityInfo.name;			// LAUNCHER Intent			Intent intent = new Intent(Intent.ACTION_MAIN);			intent.addCategory(Intent.CATEGORY_LAUNCHER);			// 设置ComponentName参数1:packagename参数2:MainActivity路径			ComponentName cn = new ComponentName(packageName, className);			intent.setComponent(cn);			startActivity(intent);		}


最后晒上一张效果图。  PS:自己在获取APP图标的代码上花费了很多时间,现在特别说明一下。如下这样完成AllAppInfo类的setAppicon方法就可以顺利在需要的时候取出来用了

 allAppInfo.setAppicon( pInfo.applicationInfo.loadIcon(getPackageManager()) );  //通过getPackageManager



  相关解决方案