AsyncTask and getInstalledPackages() fail

天涯浪子 提交于 2019-11-29 12:37:13
yorkw

Check out a similar SO question here, CommonsWare argues that this method need to be involved in UI thread, As far as I can see, this is the only reasonable explanation.

Basically, this exception was fixed on Android 5.1 (or at least that's what I've read somewhere), but for pre-5.1, you need to do something on your own.

You can avoid having a crash of this exception and get a full list of the installed apps by using the shell, as I've shown here:

https://code.google.com/p/android/issues/detail?id=172058

Here's the code:

  public static List<PackageInfo> getInstalledPackages(Context context,int flags)
    {
    final PackageManager pm=context.getPackageManager();
    //if it's Android 5.1, no need to do any special work
    if(VERSION.SDK_INT>=VERSION_CODES.LOLLIPOP_MR1)
      return pm.getInstalledPackages(flags);
    //else, protect against exception, and use a fallback if needed:
    try
      {
      return pm.getInstalledPackages(flags);
      }
    catch(Exception ignored)
      {
      //we don't care why it didn't succeed. We'll do it using an alternative way instead
      }
    // use fallback:
    Process process;
    List<PackageInfo> result=new ArrayList<>();
    BufferedReader bufferedReader=null;
    try
      {
      process=Runtime.getRuntime().exec("pm list packages");
      bufferedReader=new BufferedReader(new InputStreamReader(process.getInputStream()));
      String line;
      while((line=bufferedReader.readLine())!=null)
        {
        final String packageName=line.substring(line.indexOf(':')+1);
        final PackageInfo packageInfo=pm.getPackageInfo(packageName,flags);
        result.add(packageInfo);
        }
      process.waitFor();
      }
    catch(Exception e)
      {
      e.printStackTrace();
      }
    finally
      {
      if(bufferedReader!=null)
        try
          {
          bufferedReader.close();
          }
        catch(IOException e)
          {
          e.printStackTrace();
          }
      }
    return result;
    }
darken

I'm proposing a different explanation:

The IPC buffer runs full and on earlier Android versions (sub API15) just an empty list is returned while on newer Android versions a TransactionTooLargeException is thrown.

Also see: PackageManager.getInstalledPackages() returns empty list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!