0

I am getting a ClassCastException for the pid variable that I am trying to show on screen. I know that the item at the onclick position is a string that is casting to RunningAppProcessInfo which is causing the exception, but I cant figure out how I can get the pid without using it though.

Here is my code

  ActivityManager activityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
  List<RunningAppProcessInfo> list = activityManager.getRunningAppProcesses();

  ArrayList<String> info = new ArrayList<>();
  for (ActivityManager.RunningAppProcessInfo p : list) {
      info.add(p.processName);
  }

  ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, info);
  ListView listView = (ListView) findViewById(R.id.list);
  listView.setAdapter(adapter);

  listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
          int  uid = ((RunningAppProcessInfo)parent.getItemAtPosition(position)).pid;
          Toast.makeText(getApplicationContext(),uid,Toast.LENGTH_LONG).show();
        }
  });
gt53
  • 13
  • 5

2 Answers2

0

Well, no. The way you've initialized your adapter, the item is going to be the process name, not the process ID. It certainly won't be an instance of RunningAppProcessInfo. If you want your items to be process IDs, redefine your adapter as follows:

ArrayList<Integer> info = new ArrayList<>();
for (ActivityManager.RunningAppProcessInfo p : list) {
    info.add(p.pid); // not p.processName
}

ArrayAdapter<Integer> adapter = new ArrayAdapter<>(this,
   android.R.layout.simple_list_item_1, info);

and then retrieve it with:

int uid = (Integer) parent.getItemAtPosition(position);

If you need both, you'll have to define your own class that holds both the process name and the ID:

class Info {
    final String processName;
    final int pid;
    Info(String processName, int pid) {
        this.processName = processName;
        this.pid = pid;
    }
    @Override
    public String toString() {
        return processName;
    }
}
ArrayList<Info> info = new ArrayList<>();
for (ActivityManager.RunningAppProcessInfo p : list) {
    info.add(new Info(p.processName, p.pid));
}

ArrayAdapter<Info> adapter = new ArrayAdapter<>(this,
   android.R.layout.simple_list_item_1, info);

and retrieve it with:

int uid = ((Info)parent.getItemAtPosition(position)).pid;

You might be tempted to write:

ArrayList<RunningAppProcessInfo> info = new ArrayList<>();
for (ActivityManager.RunningAppProcessInfo p : list) {
    info.add(p);
}

ArrayAdapter<RunningAppProcessInfo> adapter = new ArrayAdapter<>(this,
   android.R.layout.simple_list_item_1, info);

and keep your original retrieval code, but unfortunately, RunningAppProcessInfo doesn't have a usable toString() method for the adapter to use, so you're going to have to write a container class one way or another.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
0

parent.getItemAtPosition(position) will actually return the item of list you provided in the ArrayAdapter constructor, so it is a String, and then of course you will get a classCastException when you try to cast this String to a RunningAppProcessInfo.

My suggestion is to use a custom adapter instead of ArrayAdapter directly. Here is a sample code I wrote for your reference:

public class ProcessSampleAdapter extends BaseAdapter {

private Context mContext;
private List<ActivityManager.RunningAppProcessInfo> mAppProcInfos;

public ProcessSampleAdapter(Context context, List<ActivityManager.RunningAppProcessInfo> list) {
    mContext = context;
    mAppProcInfos = list;
}

@Override
public int getCount() {
    return mAppProcInfos.size();
}

@Override
public Object getItem(int position) {
    return mAppProcInfos.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup root) {
    convertView = LayoutInflater.from(mContext).inflate(android.R.layout.simple_list_item_1, null);

    TextView textV = (TextView)convertView;
    textV.setText(mAppProcInfos.get(position).processName);

    return convertView;
}

}

And by the way, since uid is an int, so don't serve it to makeToast method directly, otherwise instead of showing uid, it will try to look for a String resource with id of uid.