Android 11以上 判断另一个应用页面是否存在,queryIntentActivities返回错误的解决

一、常用的方法

(一)根据包名判断应用是否存在

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;
    }

 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>