Проверьте, установлено ли приложение - Android

Я пытаюсь установить приложения из Google Play. Я понимаю, что при открытии URL-адреса магазина Google Play открывается Google Play, и когда я нажимаю кнопку "Назад", действие возобновляется.

Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(appURL));
marketIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(marketIntent);

Когда я вернулся к деятельности, я попытался назвать это onResume() проверить, установлено ли приложение, но я получаю сообщение об ошибке:

@Override
protected void onResume() {
    super.onResume();
    boolean installed = false;
    while (!installed) {
        installed  =   appInstalledOrNot(APPPACKAGE);
        if (installed) {
             Toast.makeText(this, "App installed", Toast.LENGTH_SHORT).show();
        }
    }
}

private boolean appInstalledOrNot(String uri) {
  PackageManager pm = getPackageManager();
  boolean app_installed = false;
  try {
      pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
      app_installed = true;
  }
  catch (PackageManager.NameNotFoundException e) {
      app_installed = false;
  }
  return app_installed ;
}

Ошибка заключается в следующем:

E / AndroidRuntime (796): java.lang.RuntimeException: невозможно запустить действие ComponentInfo{com.example.appinstaller/com.example.appinstaller.MainActivity}: android.content.ActivityNotFoundException: не найдено действие для обработки Intent { act=android.intent.action.VIEW dat=market://details?id=com.package.name flg=0x40080000 }

Я думаю, что активность onPause(), Есть ли лучший способ реализовать это? Я пытаюсь проверить, закончилось ли приложение.

13 ответов

Решение

Попробуй это:

private boolean isPackageInstalled(String packageName, PackageManager packageManager) {

    boolean found = true;

    try {

        packageManager.getPackageInfo(packageName, 0);
    } catch (PackageManager.NameNotFoundException e) {

        found = false;
    }

    return found;
}

Он пытается получить информацию о пакете, чье имя вы передали. NameNotFoundException был брошен, это означает, что пакет с таким именем не установлен, поэтому мы возвращаемся false,

Обратите внимание, что мы передаем в PackageManager вместо Context, так что метод немного более гибок в использовании и не нарушает закон Деметры. Вы можете использовать метод без доступа к Context Например, если у вас есть PackageManager пример.

Используйте это так:

public void someMethod() {
    // ...

    PackageManager pm = context.getPackageManager();
    boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);

    // ...
}

Начиная с Android 11 (уровень API 30), большинство приложений, установленных пользователем, по умолчанию не отображаются. В своем манифесте вы должны статически объявить, о каких приложениях вы собираетесь получать информацию, как показано ниже:

<manifest>
    <queries>
        <!-- Explicit apps you know in advance about: -->
        <package android:name="com.example.this.app"/>
        <package android:name="com.example.this.other.app"/>
    </queries>
    
    ...
</manifest>

Затем ответ @RobinKanters работает:

private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    try {
        packageManager.getPackageInfo(packageName, 0);
        return true;
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

// ...
// This will return true on Android 11 if the app is installed,
// since we declared it above in the manifest.
isPackageInstalled("com.example.this.app", pm); 
// This will return false on Android 11 even if the app is installed:
isPackageInstalled("another.random.app", pm); 

Узнайте больше здесь:

Ответ Робина Кантерса верный, но он проверяет наличие установленных приложений независимо от их включенного или отключенного состояния.

Мы все знаем, что приложение может быть установлено, но отключено пользователем, поэтому его нельзя использовать.

Это проверяет наличие установленных и включенных приложений:

public static boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    try {
        return packageManager.getApplicationInfo(packageName, 0).enabled;
    }
    catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

Вы можете поместить этот метод в класс, как Utils и вызывайте его везде, используя:

boolean isInstalled = Utils.isPackageInstalled("com.package.name", context.getPackageManager())

Более быстрое решение:

private boolean isPackageInstalled(String packagename, PackageManager packageManager) {
    try {
        packageManager.getPackageGids(packagename);
        return true;
    } catch (NameNotFoundException e) {
        return false;
    }
}

getPackageGids дешевле от getPackageInfoтак работает быстрее.

Run 10000 on API 15
Exists pkg:
getPackageInfo: nanoTime = 930000000
getPackageGids: nanoTime = 350000000
Not exists pkg:
getPackageInfo: nanoTime = 420000000
getPackageGids: nanoTime = 380000000

Run 10000 on API 17
Exists pkg:
getPackageInfo: nanoTime = 2942745517
getPackageGids: nanoTime = 2443716170
Not exists pkg:
getPackageInfo: nanoTime = 2467565849
getPackageGids: nanoTime = 2479833890

Run 10000 on API 22
Exists pkg:
getPackageInfo: nanoTime = 4596551615
getPackageGids: nanoTime = 1864970154
Not exists pkg:
getPackageInfo: nanoTime = 3830033616
getPackageGids: nanoTime = 3789230769

Run 10000 on API 25
Exists pkg:
getPackageInfo: nanoTime = 3436647394
getPackageGids: nanoTime = 2876970397
Not exists pkg:
getPackageInfo: nanoTime = 3252946114
getPackageGids: nanoTime = 3117544269

Примечание: это не будет работать в некоторых виртуальных пространствах. Они могут нарушать API Android и всегда возвращать массив, даже если нет приложения с таким именем пакета.
В этом случае используйте getPackageInfo,

Попробуй это:

public static boolean isAvailable(Context ctx, Intent intent) {
final PackageManager mgr = ctx.getPackageManager();
List<ResolveInfo> list =   mgr.queryIntentActivities(intent,PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}

Вы можете использовать это в Котлине extentions.kt

fun Context.isPackageInstalled(packageName: String): Boolean {
    return try {
        packageManager.getPackageInfo(packageName, 0)
        true
    } catch (e: PackageManager.NameNotFoundException) {
        false
    }
}

Применение

context.isPackageInstalled("com.somepackage.name")

После Android 11 вам необходимо добавить имена пакетов в манифест приложения.

если ты не <queries>в манифесте всегда context.getPackageManager().getApplicationInfoимеет исключение (System.err: android.content.pm.PackageManager$NameNotFoundException)

проверьте ссылку:ссылка

Пример:

      <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <queries>
        <package android:name="com.xxx.yyy" />
    </queries>

    <application></application>

</manifest>

Ява

       public boolean applicationIsInstall(Context context , String packageName){
        try {
            context.getPackageManager().getApplicationInfo(packageName, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }

Колтин

      fun applicationIsInstall(context: Context, packageName: String): Boolean {
    return try {
        context.packageManager.getApplicationInfo(packageName, 0)
        true
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
        false
    }
}

Если вы хотите попробовать его без блока try catch, вы можете использовать следующий метод: создать намерение и установить пакет приложения, которое вы хотите проверить.

val intent = Intent(Intent.ACTION_VIEW)
intent.data = uri
intent.setPackage("com.example.packageofapp")

и вызовите следующий метод, чтобы проверить, установлено ли приложение

fun isInstalled(intent:Intent) :Boolean{
    val list = context.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
    return list.isNotEmpty()
}

Хотя ответ уже опубликован и будет работать до Android 29 или Android 10, но когда приложение ориентировано на Android 11 (уровень API 30) или выше и запрашивает информацию о других приложениях, установленных на устройстве, система по умолчанию фильтрует эту информацию. . Такое поведение фильтрации означает, что ваше приложение не может обнаружить все приложения, установленные на устройстве, что помогает свести к минимуму потенциально конфиденциальную информацию, к которой ваше приложение может получить доступ, но не требует выполнения своих сценариев использования.

Итак, чтобы добиться этого, нам просто нужно добавить<queries>или вам нужно добавить указанное ниже разрешение в файл AndroidManifest.xml –

      <uses-permission
    android:name="android.permission.QUERY_ALL_PACKAGES" />

Это потому, что в Android 11 мало изменений в поведении - https://developer.android.com/training/package-visibility .

Те, кто ищет решение Kotlin, могут использовать этот метод,

Здесь я поделился полным кодом, а также обработал статус включения. Проверьте, установлено ли приложение в Android Kotlin

fun isAppInstalled(packageName: String, context: Context): Boolean {
        return try {
            val packageManager = context.packageManager
            packageManager.getPackageInfo(packageName, 0)
            true
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }
    }
isFakeGPSInstalled = Utils.isPackageInstalled(Utils.PACKAGE_ID_FAKE_GPS, this.getPackageManager());

// метод проверки установленного пакета true/false

  public static boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    boolean found = true;
    try {
      packageManager.getPackageInfo(packageName, 0);
    } catch (PackageManager.NameNotFoundException e) {
      found = false;
    }

    return found;
  }
    private boolean isAppExist() {

    PackageManager pm = getPackageManager();
    try {
        PackageInfo info = pm.getPackageInfo("com.facebook.katana", PackageManager.GET_META_DATA);
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
    return true;
}




if (isFacebookExist()) {showToast(" Facebook is  install.");}
     else {showToast(" Facebook is not install.");}
@Override 
protected void onResume() {
    super.onResume();
    boolean installed = false;

    while (!installed) {
        installed = appInstalledOrNot (APPPACKAGE);
        if (installed) {
            Toast.makeText(this, "App installed", Toast.LENGTH_SHORT).show ();
        }
    }
} 

private boolean appInstalledOrNot (String uri) {
    PackageManager pm = getPackageManager();
    boolean app_installed = false;
    try {
        pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
        app_installed = true;
    } catch (PackageManager.NameNotFoundException e) {
        app_installed = false;
    }
    return app_installed;
}
Другие вопросы по тегам