在 recyclerView 中通过 PackageManager 获取应用程序包的问题

Problems with getting application packages via PackageManager in a recyclerView

我正在尝试创建一个带有通过 recyclerview 实现的应用程序抽屉的 andorid 启动器 - 基本上我只想列出设备上所有已安装的应用程序。

目前,当我 运行 activity 它崩溃时,我不太清楚为什么。我认为问题是我没有从 phone 中正确提取应用程序包,因此 onBindViewHolder 崩溃了,因为我给了它空对象引用,但我不确定包的问题到底在哪里经理是。

这是持有recyclerview的activity,AppDrawer.java:

public class AppDrawer extends AppCompatActivity {


    RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.app_drawer);

        recyclerView = findViewById(R.id.appsList);

        // add this
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        AppAdapter adapter = new AppAdapter(this);

        // replace this line by this two. (you should not call adapter method directly).
        // adapter.onCreateViewHolder(recyclerView, 0);    
        recyclerView.setAdapter(adapter);
        // notify the adapter that the data has changed
        //recyclerView.notifyDataSetChanged();
    }
}

这是AppAdapter.java:

public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> {
    private List<AppObject> appsList;

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView textView;
        public ImageView img;

        //This is the subclass ViewHolder which simply
        //'holds the views' for us to show on each row
        public ViewHolder(View itemView) {
            super(itemView);

            //Finds the views from our row.xml
            textView = (TextView) itemView.findViewById(R.id.text);
            img = (ImageView) itemView.findViewById(R.id.image);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick (View v) {
            int pos = getAdapterPosition();
            Context context = v.getContext();

            Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(appsList.get(pos).getName());
            context.startActivity(launchIntent);
            Toast.makeText(v.getContext(), appsList.get(pos).getName(), Toast.LENGTH_LONG).show();

        }
    }



    public AppAdapter(Context c) {

        //This is where we build our list of app details, using the app
        //object we created to store the label, package name and icon

        PackageManager pm = c.getPackageManager();
        appsList = new ArrayList<AppObject>();

        Intent i = new Intent(Intent.ACTION_MAIN, null);
        i.addCategory(Intent.CATEGORY_LAUNCHER);

        List<ResolveInfo> allApps = pm.queryIntentActivities(i, 0);
        for(ResolveInfo ri:allApps) {
            AppObject app = new AppObject(ri.loadLabel(pm).toString(), ri.activityInfo.packageName, ri.activityInfo.loadIcon(pm), false);
//            app.getName() = ri.loadLabel(pm);
//            app.getPackageName() = ri.activityInfo.packageName;
//            app.getImage() = ri.activityInfo.loadIcon(pm);
            appsList.add(app);
        }

    }

    @Override
    public void onBindViewHolder(AppAdapter.ViewHolder viewHolder, int i) {

        //Here we use the information in the list we created to define the views

        String appLabel = appsList.get(i).getName();
        String appPackage = appsList.get(i).getPackageName();
        Drawable appIcon = appsList.get(i).getImage();

        TextView textView = viewHolder.textView;
        textView.setText(appLabel);
        ImageView imageView = viewHolder.img;
        imageView.setImageDrawable(appIcon);
    }


    @Override
    public int getItemCount() {

        //This method needs to be overridden so that Androids knows how many items
        //will be making it into the list

        return appsList.size();
    }


    @Override
    public AppAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        //This is what adds the code we've written in here to our target view
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());

        View view = inflater.inflate(R.layout.app_drawer_item, parent, false);

        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }
}

AppObject.java:

public class AppObject {
    private String  name,
                    packageName;
    private Drawable image;
    private Boolean isAppInDrawer;

    public AppObject(String packageName, String name, Drawable image, Boolean isAppInDrawer) {
        this.name = name;
        this.image = image;
        this.packageName = packageName;
        this.isAppInDrawer = isAppInDrawer;
    }

    public String getPackageName() {
        return packageName;
    }
    public String getName() {
        return name;
    }
    public Drawable getImage() {
        return image;
    }
    public Boolean getIsAppInDrawer() {return isAppInDrawer;}

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setImage(Drawable image) {
        this.image = image;
    }
    public void setIsAppInDrawer(Boolean appInDrawer) {
        this.isAppInDrawer = appInDrawer;
    }
}

这是我尝试 运行 代码时收到的错误消息:



I/Surface: opservice is null false
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@365f0dd
E/OpApplicationPackageManagerInjector: Application package com.oneplus.iconpack.square not found
E/OpApplicationPackageManagerInjector: Application package com.oneplus.iconpack.square not found
I/chatty: uid=10302(com.example.launcherapplication) identical 36 lines
E/OpApplicationPackageManagerInjector: Application package com.oneplus.iconpack.square not found
W/cherapplicatio: resources.arsc in APK '/data/app/com.oneplus.gallery-u0eFcDkuFtHGko86_UqHPA==/base.apk' is compressed.
E/OpApplicationPackageManagerInjector: Application package com.oneplus.iconpack.square not found
I/chatty: uid=10302(com.example.launcherapplication) identical 24 lines
E/OpApplicationPackageManagerInjector: Application package com.oneplus.iconpack.square not found
W/cherapplicatio: resources.arsc in APK '/data/app/com.facebook.orca-omRvfq_ufIlgi54ffkzO9g==/base.apk' is compressed.
E/OpApplicationPackageManagerInjector: Application package com.oneplus.iconpack.square not found
I/chatty: uid=10302(com.example.launcherapplication) identical 58 lines
E/OpApplicationPackageManagerInjector: Application package com.oneplus.iconpack.square not found
V/ViewRootImpl: The specified message queue synchronization  barrier token has not been posted or has already been removed
I/Surface: opservice is null false
D/DecorView: onWindowFocusChangedFromViewRoot hasFocus: true, DecorView@ef5993e[AppDrawer]
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.launcherapplication, PID: 15904
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
        at com.example.launcherapplication.AppAdapter.onBindViewHolder(AppAdapter.java:82)
        at com.example.launcherapplication.AppAdapter.onBindViewHolder(AppAdapter.java:18)
//FILLER ERROR MESSAGES//
E/AndroidRuntime:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
I/Process: Sending signal. PID: 15904 SIG: 9


不要在 OnBindViewHolder 中创建新的 TextView,而是直接调用 viewHolder 的 textview 并确保您的 findViewById() 调用正确的 ID。(基于您的 logCat 错误)

 @Override
    public void onBindViewHolder(AppAdapter.ViewHolder viewHolder, int i) {

       viewHolder.textView.setText(appLabel);
       viewHolder.img.setImageDrawable(appIcon);}