2011-11-10 8 views
1

何が起きているのか分かりません。私はgetInstalledPackages()を使用して、インストールされているすべてのユーザーとそのアクセス許可の一覧を取得します。ここで私はそれを行う方法です:AsyncTaskとgetInstalledPackages()が失敗する

private PackageManager pm; 

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     pm = getPackageManager(); 
     getListData(); 
} 

private void getListData() 
    { 

     backTask = new BackTask(); 
     backTask.execute(); 
    } 

protected class BackTask extends AsyncTask<Context, String, ArrayList<App>> 
    { 
.... 
     @Override 
     protected ArrayList<App> doInBackground(Context... param) 
     { 

       try { 

         //get a list of installed apps. 
          List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS); 

          for (PackageInfo packageInfo : packages) { 
           ApplicationInfo application = packageInfo.applicationInfo; 
.... 
} 

私はユーザーの操作に基づいて表示されるリストを更新する必要があります。問題はAsyncTaskで、この行に表示されます:

List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS); 

時にはパッケージは時にインストールされているすべてのアプリケーションが含まれていEMPTYです。例えば、3回のうち3回目が空であるとします。このコードをAsyncTaskから取り出してgetListData()に置くと、毎回問題なく動作します。問題は、操作がバックスレッドではないため、少しフリーズしてしまうことです。 AsyncTaskとは何ですか?私は何か間違っているのですか?

答えて

0

同様のSOの質問hereをチェックしてください、CommonsWareは、このメソッドはUIスレッドに関与する必要があると主張します。私が見る限り、これは唯一の合理的な説明です。私は別の説明を提案しています

+0

私の他の答えを確認してください、私はそれがUIスレッドで実行する必要はないと思う:http://stackoverflow.com/questions/3455781/packagemanager-getinstalledpackages-returns-empty-list – darken

0

IPCバッファがフル稼働し、新しいAndroidのバージョンでTransactionTooLargeExceptionがスローされている間、以前のAndroidのバージョン(サブAPI15)にちょうど空のリストが返されます。

も参照してください。 PackageManager.getInstalledPackages() returns empty list

1

を基本的には、この例外はアンドロイド5.1に固定した(あるいは少なくともそれは私がどこかで読んだものだ)が、前の5.1のために、自分で何かをする必要があります。

あなたはこの例外のクラッシュを回避し、私はここに示されてきたように、シェルを使用してインストール済みのアプリケーションの完全なリストを取得することができます。

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

ここでは、コードです:

は、
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; 
    } 
関連する問題