136 votes

Vérifier si l'application est installée - Android

J'essaie d'installer des applications à partir de Google Play. Je peux comprendre qu'en ouvrant l'URL du magasin Google Play, cela ouvre le Google Play et lorsque j'appuie sur le bouton retour, l'activité reprend.

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

Quand je suis retourné à l'activité, j'ai essayé d'appeler ceci onResume() pour vérifier si l'application est installée, mais je reçois une erreur :

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

L'erreur est la suivante :

E/AndroidRuntime(796) : java.lang.RuntimeException : Impossible de démarrer l'activité ComponentInfo{com.example.appinstaller/com.example.appinstaller.MainActivity} : Android.content.ActivityNotFoundException : Aucune activité trouvée pour gérer l'intention { act=Android.intent.action.VIEW dat=market://details?id=com.package.name flg=0x40080000 }

Je suppose que l'activité est onPause() . Existe-t-il une meilleure façon de l'implémenter ? J'essaie de vérifier si l'application a fini de s'installer.

365voto

Robin Kanters Points 1114

Essayez ça :

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

Il tente de récupérer des informations sur le paquet dont vous avez indiqué le nom. Si ce n'est pas le cas, si un NameNotFoundException a été lancé, cela signifie qu'aucun paquet portant ce nom n'est installé, nous retournons donc false .

Notez que nous passons dans un PackageManager au lieu d'un Context de manière à ce que la méthode soit légèrement plus flexible et ne viole pas le principe de l'égalité des chances. loi de Déméter . Vous pouvez utiliser cette méthode sans avoir accès à un Context pour autant que vous ayez une PackageManager instance.

Utilisez-le comme ça :

public void someMethod() {
    // ...

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

    // ...
}

Note : A partir d'Android 11 (API 30), vous devrez peut-être déclarer <queries> dans votre manifeste, en fonction du paquet que vous recherchez. Consultez les docs pour plus d'informations.

76voto

now Points 1998

Depuis Android 11 (niveau API 30), la plupart des applications installées par l'utilisateur ne sont pas visibles par défaut. Dans votre manifeste, vous devez déclarer de manière statique les applications sur lesquelles vous allez obtenir des informations, comme dans l'exemple suivant :

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

Ensuite, @RobinKanters'. réponse travaux :

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

Pour en savoir plus, cliquez ici :

45voto

AndroidGuy Points 447

La réponse de Robin Kanters est correcte, mais elle vérifie les applications installées, quel que soit leur état d'activation ou de désactivation.

Nous savons tous qu'une application peut être installée mais désactivée par l'utilisateur, donc inutilisable.

Cette vérification porte sur l'installation de ET des applications :

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

Vous pouvez placer cette méthode dans une classe comme Utils et l'appeler partout en utilisant :

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

11voto

Enyby Points 344

Une solution plus rapide :

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

getPackageGids est moins coûteux que getPackageInfo pour qu'il fonctionne plus rapidement.

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

Note : Ceci ne fonctionnera pas dans certains espaces virtuels. Ils peuvent violer l'API Android et toujours retourner un tableau, même s'il n'y a pas d'application avec ce nom de paquet.
Dans ce cas, utilisez getPackageInfo .

5voto

Gopi Cg Points 284

Essayez ça :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X