如何查找我Android设备上是否存在特定的软件包?

77

我怎样才能找到我Android设备上是否安装了某个特定的软件包或应用程序,例如:com.android.abc

10个回答

162

使用以下任意一个方法,加上包名即可调用。

import android.content.pm.PackageManager;

// ...

    public boolean isPackageExisted(String targetPackage){
        List<ApplicationInfo> packages;
        PackageManager pm;

        pm = getPackageManager();        
        packages = pm.getInstalledApplications(0);
        for (ApplicationInfo packageInfo : packages) {
            if(packageInfo.packageName.equals(targetPackage))
                return true;
        }
        return false;
    }

 import android.content.pm.PackageManager;

 public boolean isPackageExisted(String targetPackage){
   PackageManager pm=getPackageManager();
   try {
     PackageInfo info=pm.getPackageInfo(targetPackage,PackageManager.GET_META_DATA);
   } catch (PackageManager.NameNotFoundException e) {
     return false;
   }  
   return true;
 }

谢谢Rasel,我就是在找这个。非常感谢你。 - brig
我需要导入什么才能让它工作?我得到了“无法解析符号'PackageManager'”的错误。 - Oscar Swanros
第二种方法更快。 - Alex
这需要任何权限吗?我仍然得到false! - Emon Hossain Munna
根据Android版本的不同,您现在需要在清单文件中声明与之交互的包:https://developer.android.com/guide/topics/manifest/queries-element。@EmonHossainMunna - Markus

14

不使用try-catch块或迭代一堆包:

public static boolean isPackageInstalled(Context context, String packageName) {
    final PackageManager packageManager = context.getPackageManager();
    Intent intent = packageManager.getLaunchIntentForPackage(packageName);
    if (intent == null) {
        return false;
    }
    List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

12

Kotlin

fun isPackageExist(context: Context, target: String): Boolean {
     return context.packageManager.getInstalledApplications(0).find { info -> info.packageName == target } != null
}

编辑:扩展函数

fun Context.isPackageExist(target: String): Boolean {
     return packageManager.getInstalledApplications(0).find { info -> info.packageName == target } != null
}

4
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;

4
我们可以像这样检查:
 if(getPackageManager().hasSystemFeature("android.software.webview") == true && isPackageExisted("com.google.android.webview")) {
            if (Constant.isNetworkConnected(Activity.this)) {
                 //Your Intent 
            } else {
                Toast.makeText(getApplicationContext(), resources.getString(R.string.internet_error), Toast.LENGTH_SHORT).show();
            }
        }   else
            {
                Constant.showDialog(Activity.this,"Please install the webview");
            }
    }

创建用于包检查的方法!此方法由“Kavi”提供。 https://dev59.com/12w15IYBdhLWcg3wMpAY#30708227

public boolean isPackageExisted(String targetPackage) {
    List<ApplicationInfo> packages;
    PackageManager pm;

    pm = getPackageManager();
    packages = pm.getInstalledApplications(0);
    for (ApplicationInfo packageInfo : packages) {
        if(packageInfo.packageName.equals(targetPackage))
        {
            return true;
        }
}
return false;

}


3

2
您可以使用pm.getPackageUid()来代替遍历pm.getInstalledApplications()。
 boolean isPackageInstalled;
 PackageManager pm = getPackageManager();   
 int flags = 0; 
        try 
        {   
              pm.getPackageUid(packageName,flags);               
              isPackageInstalled = true;    
        }   
        catch (final PackageManager.NameNotFoundException nnfe) 
        {   
            isPackageInstalled = false; 
        }                   
 return isPackageInstalled;

getPackageUid - 自 API 级别 24 添加。 - Goran Horia Mihail

2
由于一些设备报告“getInstalledPackages”可能会导致TransactionTooLargeException(请查看此处此处此处),我认为你应该像下面我所做的那样设置备用方案。
这个问题本来应该在Android 5.1上修复(阅读此处),但仍有人报告了此问题。
public static List<String> getInstalledPackages(final Context context) {
    List<String> result = new ArrayList<>();
    final PackageManager pm = context.getPackageManager();
    try {
        List<PackageInfo> apps = pm.getInstalledPackages(0);
        for (PackageInfo packageInfo : apps)
            result.add(packageInfo.packageName);
        return result;
    } catch (Exception ignored) {
        //we don't care why it didn't succeed. We'll do it using an alternative way instead
    }
    // use fallback:
    BufferedReader bufferedReader = null;
    try {
        Process 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);
            result.add(packageName);
        }
        closeQuietly(bufferedReader);
        process.waitFor();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        closeQuietly(bufferedReader);
    }
    return result;
}

public static void closeQuietly(final Closeable closeable) {
    if (closeable == null)
        return;
    try {
        closeable.close();
    } catch (final IOException e) {
    }
}

2
如果你只想使用adb:
adb shell "pm list packages"|cut -f 2 -d ":"

它会列出所有已安装的软件包。

0
根据Android 11中的包可见性过滤更改,您需要将此权限添加到清单中才能列出已安装的应用程序: 但是Google不建议使用这种方式。相反,您应该使用标签:
<manifest ...>
    <queries>
        <package android:name="com.app.package" />
        ...
    </queries>
    ...
</manifest>

而在您的代码中:

fun isAppInstalled(context: Context, packageId: String): Boolean {
    return try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            context.packageManager
                .getApplicationInfo(packageId, PackageManager.ApplicationInfoFlags.of(0))
        } else {
            context.packageManager.getApplicationInfo(packageId, 0)
        }
        true
    } catch (e: PackageManager.NameNotFoundException) {
        false
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接