安卓开发获取本机所有已安装程序(形成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


技术分享

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。