一、常用的方法
(一)根据包名判断应用是否存在
public boolean checkApplication(String packageName) {
if (packageName == null || "".equals(packageName)){
return false;
}
try {
ApplicationInfo info = getPackageManager().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
return true;
} catch (NameNotFoundException e) {
return false;
}
}
(二)判断Activity是否存在
if (getPackageManager().resolveActivity(intent, 0) == null) {
// 说明系统中不存在这个activity
}
if(intent.resolveActivity(getPackageManager()) == null) {
// 说明系统中不存在这个activity
}
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, 0);
if (list.size() == 0) {
// 说明系统中不存在这个activity
}
以上针对android 30的应用,不管怎么调试都不管用,费解啊,就这么盯了一天过去了,然后无意中看到了下面这个配置。
经查询,这是Android11引入的包可见性的概念。在Android11中,我们不能直接获取到软件包是否已经安装了,就是说我们安装了一个应用,按照以往的调用 getInstalledApplications() 或 getInstalledPackages()方法不会返回目标应用的包名,必须在当前应用的清单文件中添加目标应用的包名。这个概念可参考文章,Android 11包可见性。
这样我只需要在manefest中声明<queries>,以往的代码不变:
我的app的build.gradle配置如下:
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 31
buildToolsVersion '30.0.3'
defaultConfig {
applicationId "com.test.aapplication"
minSdkVersion 28
targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
....
跳转代码如下(也可以使用隐式跳转):
Intent accountIntent = new Intent();
accountIntent.setClassName("com.test.bapplication","com.test.bapplication.MainActivity");
if (isActionOrIntentExisting(this, null, accountIntent)) {
startActivityForResult(accountIntent, 105);
} else {
Log.e(TAG, "startOtherApplication: OtherApplication apk is not exist" );
}
判断类是否可见的代码如下:
/**
* check action or Intent exists
*
* @param context
* @param action
* @param intent
* @return
*/
public static boolean isActionOrIntentExisting(@NonNull Context context, @Nullable String action, @Nullable Intent intent) {
final PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> resolveInfo = null;
if (action != null) {
Log.d(TAG, "actionOrIntentExisting: intent = " + action);
final Intent checkIntent = new Intent(action);
resolveInfo = packageManager.queryIntentActivities(checkIntent,
PackageManager.MATCH_ALL);
}
if (intent != null) {
Log.d(TAG, "actionOrIntentExisting: intent = " + intent.toString());
resolveInfo = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
//resolveInfo = packageManager.queryIntentActivities(intent,0);
}
Log.d(TAG, "resolveInfo.size = " + resolveInfo.size());
if (resolveInfo.size() > 0) {
for (int i = 0; i < resolveInfo.size(); i++) {
Log.d(TAG, " resolveInfo.get(" + i + ") = " + resolveInfo.toString());
}
Log.d(TAG, " actionOrIntentExisting return true");
return true;
}
Log.d(TAG, " actionOrIntentExisting return false");
return false;
}