安卓开发获取本机所有已安装程序(形成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
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。