【问题标题】:How to list all downloaded android apps in a fragment如何在片段中列出所有下载的android应用程序
【发布时间】:2025-12-17 02:35:01
【问题描述】:

我正在尝试制作一个类似于Action Launcher 的应用程序,但我遇到了一些困难。我似乎无法让已安装的应用程序填充到片段中。

它要么崩溃,要么只是没有填充应用程序(应用程序视图)。我目前已将其设置为将所有应用程序加载到一个 ArrayList/List 中,该 ArrayList/List 安装了 90 个应用程序,因此我并不担心。它显示了我最难使用的实际应用程序。我正在尝试动态执行此操作,但它没有按我想要的方式工作。

/* 
 * Assume that 
 * GridView gv;
 * Config cnf = new Config(); //personal class
 * PackageManager pm;
 * pm = getPackageManager();
 * 
 */
public void SelectItem(int possition) {
 switch(possition){
   case 2:
    gv = (GridView) findViewById(R.id.gridView1);
    // ArrayList<Apps> apps = cnf.getApps();

    Intent intent = new Intent(Intent.ACTION_MAIN, null);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    List<ResolveInfo> apps = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
    GridLayout gl = new GridLayout(returnContext());

    gl.setOrientation(GridLayout.VERTICAL);

    for (ResolveInfo appInfo : apps) {
       String label = (String) appInfo.loadLabel(pm);
       TextView name2 = new TextView(returnContext());
       name2.setText(label);
       gl.addView(name2);
       ImageView img = new ImageView(returnContext());
       img.setImageDrawable(appInfo.loadIcon(pm));
       gl.addView(img);
    }
    gv.addView(gl); // I am getting a null reference exception here
  }
}

以及上述代码的 Base XML

  <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <GridView
        android:id="@+id/gridView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:columnWidth="40dp"
        android:gravity="center"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth" >

        <ImageView
            android:id="@+id/appicon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="center_vertical"
            android:layout_marginBottom="2dip"
            android:layout_marginLeft="2dip"
            android:layout_marginRight="6dip"
            android:layout_marginTop="2dip"
            android:scaleType="fitCenter" />

        <TextView
            android:id="@+id/apptitle"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:textSize="20dip" />
    </GridView>

</RelativeLayout>

我假设我的问题在于显而易见的问题(我没有正确设置值。)而不是更大的问题,即我不知道我在做什么并且我搞砸了一些事情(我不知道并且可能有)

我将我的来源上传到GitHub :)

干杯。

【问题讨论】:

    标签: java android xml android-layout android-fragments


    【解决方案1】:

    因为即使是一个简单的建议也绝对没有人提出来,所以我自己像一个优秀的小程序员一样想出来了。

    此解决方案将列出所有已安装的应用程序,包括所有带有Intent.CATEGORY_LAUNCHER 的应用程序,但不包括所有系统应用程序。我承认填充速度很慢,但最终的解决方案是实际使用数据库来帮助加载所有项目。

    Since I have released this solution ongithubI have these licensed under theMIT licence。 所以以下是解决方案。

    public List<Apps> listAllApps() {
        List<Apps> apps = new ArrayList<Apps>();
        List<ApplicationInfo> appinfo = pm.getInstalledApplications(0);
    
        Apps app;
        i = 0;
        List<String> appnames = appNames();
        for (int j = 0; j < appinfo.size(); j++) {
            if (Config.in_array(appnames, appinfo.get(j).packageName)) {
                app = new Apps();
                app.setPackageName(appinfo.get(j).packageName);
                app.setTitle(appinfo.get(j).loadLabel(pm).toString());
                apps.add(app);
                if (appinfo.get(j).packageName.contains("gallery") ||
                    appinfo.get(j).loadLabel(pm).toString().contains("gallery")) {
                        if (appinfo.get(j).name.contains("gallery")) {
                            setGalleryPackage(i, appinfo.get(j).packageName);
                        } else
                            setGalleryPackage(i, appinfo.get(j).packageName);
                        i++;
                    }
                }
            }
            return apps;
        }
    
        public List appNames() {
            final Intent mainIntent = new Intent(Intent.ACTION_MAIN);
            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            List<ResolveInfo> packs = pm.queryIntentActivities(mainIntent, 0);
    
            List<String> appNames = new ArrayList<String>(packs.size());
            for (ResolveInfo ai : packs) {
                appNames.add(ai.activityInfo.packageName.toString());
            }
            return appNames;
        }
    

    要真正将项目添加到屏幕上,我必须将以下内容放在(片段)onCreateView 方法中

    List<Apps> loadedApps = listAllApps();
        Collections.sort(loadedApps, new Comparator<Apps>() {
    
            @Override
            public int compare(Apps lhs, Apps rhs) {
                return lhs.getTitle().compareTo(rhs.getTitle());
            }
        });
        // Config.makeColdToast(loadedApps.size());
    
        for (final Apps a : loadedApps) {
            final TableRow tb = new TableRow(Config.context);
            tb.setId(i + 1000);
            Drawable ico = null;
            try {
                Intent in = pm.getLaunchIntentForPackage(a.getPackageName());
                if (in != null) {
                    ico = pm.getActivityIcon(in);
    
                }
            } catch (NameNotFoundException e) {
            }
            ImageView ima = new ImageView(Config.context);
            ima.setImageDrawable(ico);
            tb.addView(ima, new TableRow.LayoutParams(Config.dpToPx(50), Config.dpToPx(50)));
            TextView name = new TextView(Config.context);
            name.setText(a.getTitle());
            a.setID(i);
            tb.setPadding(Config.dpToPx(25), Config.dpToPx(10), Config.dpToPx(15), Config.dpToPx(10));
            tb.setBackgroundColor(Color.argb(125, 0, 0, 0));
            tb.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    Intent intent = Config.context.getPackageManager().getLaunchIntentForPackage(a.getPackageName());
    
                    if (intent != null) {
                        startActivity(intent);
                    }
                    tb.setBackgroundColor(Color.TRANSPARENT);
                }
    
            });
            tb.setOnLongClickListener(new OnLongClickListener() {
    
                @Override
                public boolean onLongClick(View arg0) {
                    Config.makeColdToast("Long click!");
    
                    return false;
                }
            });
            tb.addView(name, new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
    
            gv.addView(tb, new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            /*
             * This is the gray line...
             */
            TableRow tl = new TableRow(Config.context);
            tl.setBackgroundResource(R.layout.customborder);
            gv.addView(tl);
            i++;
        }
    

    最后是被多次引用的 Apps 类。

    public class Apps {
    
        private String title;
        private String packageName;
        private String versionName;
        private int versionCode;
        private String description;
        private ResolveInfo resolveinfo;
        Intent intent;
    
        private int id;
    
        public String getTitle() {
            return title;
        }
    
        public void setResolveInfo(ResolveInfo ri) {
            this.resolveinfo = ri;
        }
    
        public ResolveInfo getResolveInfo() {
            return this.resolveinfo;
        }
    
        public int getID() {
            return id;
        }
    
        public void setID(int id) {
            this.id = id;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getPackageName() {
                return packageName;
        }
    
        public void setPackageName(String packageName) {
            this.packageName = packageName;
        }
    
        public String getVersionName() {
            return versionName;
        }
    
        public void setVersionName(String versionName) {
            this.versionName = versionName;
        }
    
        public int getVersionCode() {
                return versionCode;
        }
    
        public void setVersionCode(int versionCode) {
            this.versionCode = versionCode;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public class AppViewHolder {
    
            public TextView mTitle;
            public ImageView mIcon;
    
    
            public void setTitle(String title) {
                mTitle.setText(title);
            }
    
            public void setIcon(Drawable img) {
                if (img != null) {
                        mIcon.setImageDrawable(img);
                }
            }
        }
    
        public Drawable mIcon;
    
        public void setIcons(Drawable icon) {
            mIcon = icon;
        }
    
        public Drawable getIcon() {
            return mIcon;
        }
    }
    

    【讨论】: