Comment lancer une activité à partir d'une autre application dans Android

479

Je souhaite lancer un package installé à partir de mon application Android. Je suppose qu'il est possible d'utiliser des intentions, mais je n'ai pas trouvé de moyen de le faire. Existe-t-il un lien, où trouver les informations?

Bastian
la source
2
que se passe-t-il si j'ouvre la deuxième application à partir de la première, puis que je clique directement sur l'icône de la deuxième application, j'obtiens deux instances de l'application, ce qui n'est pas souhaité. comment la gérer ??
Radhey

Réponses:

707

Si vous ne connaissez pas l'activité principale, le nom du package peut être utilisé pour lancer l'application.

Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) { 
    startActivity(launchIntent);//null pointer check in case package name was not found
}
andep
la source
5
Une raison pour laquelle cela ne fonctionnerait pas? Je ne l'ai pas fait fonctionner au moins.
Simon Forsberg
22
Il démarre une nouvelle intention, que diriez-vous de reprendre l'application qui est en arrière-plan?
Salil Dua
3
@andep: Cela a bien fonctionné pour moi lorsque j'ai testé entre deux applications que j'ai créées moi-même. Une fois que je connais le nom du package, cela fonctionnera-t-il toujours, ou existe-t-il un moyen d'empêcher quelqu'un de lancer votre application (dans le maniefest ou quelque part)?
Leonard Feehan
2
@Leonard: Ma première impression, que cela doit toujours fonctionner, car les noms de packages sont publics afin que toutes les applications puissent les lire. À partir de vos applications, je pense que vous ne pouvez pas déterminer d'où elle a été appelée, mais votre application peut déterminer qu'elle ne peut pas être appelée via l'activité principale uniquement via les services.
andep
1
Oui, cela peut retourner null. "L'implémentation actuelle recherche d'abord une activité principale dans la catégorie CATEGORY_INFO, puis une activité principale dans la catégorie CATEGORY_LAUNCHER. Renvoie null si aucune n'est trouvée. "
quietmint
240

Je sais que cela a été répondu, mais voici comment j'ai mis en œuvre quelque chose de similaire:

Intent intent = getPackageManager().getLaunchIntentForPackage("com.package.name");
if (intent != null) {
    // We found the activity now start the activity
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
} else {
    // Bring user to the market or let them choose an app?
    intent = new Intent(Intent.ACTION_VIEW);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setData(Uri.parse("market://details?id=" + "com.package.name"));
    startActivity(intent);
}

Encore mieux, voici la méthode:

public void startNewActivity(Context context, String packageName) {
    Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    if (intent != null) {
        // We found the activity now start the activity
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    } else {
        // Bring user to the market or let them choose an app?
        intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setData(Uri.parse("market://details?id=" + packageName));
        context.startActivity(intent);
    }
}

Suppression du code en double:

public void startNewActivity(Context context, String packageName) {
    Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    if (intent == null) {
        // Bring user to the market or let them choose an app?
        intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("market://details?id=" + packageName));
    }
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
}
Jared Burrows
la source
8
J'avais un problème lors du démarrage d'une intention sur un profil Facebook ou Twitter. Ils s'ouvraient à l'intérieur de mon application, plutôt que comme une nouvelle activité. L'ajout de FLAG_ACTIVITY_NEW_TASK a corrigé ce problème. Merci!
Harry
4
Aucun problème! J'avais des problèmes avec quelque chose de très similaire
Jared Burrows
1
La méthode fonctionne pour moi, mais parfois la nouvelle application est ouverte et l'activité appelante est toujours au premier plan. Des idées pour réparer?
lgdroid57
Existe-t-il un moyen de le faire à partir de l'application instantanée?
Mahdi
Fonctionne uniquement pour les versions de sortie. Si vous essayez d'ouvrir l'application de débogage, l'intention sera nulle.
RexSplode
152

J'ai trouvé la solution. Dans le fichier manifeste de l'application, j'ai trouvé le nom du package: com.package.address et le nom de l'activité principale que je veux lancer: MainActivity Le code suivant démarre cette application:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
Bastian
la source
8
J'ai une exception 'dose que vous déclarez activité dans votre Manifest.xml'
itzhar
De cette façon, renvoie une exception qui dit que je dois déclarer l'activité dans mon manifeste .. mais c'est une application externe!
JJ Ab
Comment l'exécuter en arrière-plan? Signifie que les deuxièmes applications appelées ne s'affichent pas à l'écran, mais exécutez sa méthode onCreated ().
Dr.jacky
J'obtiens cette erreur lorsque j'essaie depuis l'application instantanée: pas autorisé à démarrer l'activité Intention
Mahdi
@Bastian comment fermer l'application actuelle d'où nous appelons l'intention d'ouvrir une autre application?
Arnold Brown
18
// in onCreate method
String appName = "Gmail";
String packageName = "com.google.android.gm";
openApp(context, appName, packageName);

public static void openApp(Context context, String appName, String packageName) {
    if (isAppInstalled(context, packageName))
        if (isAppEnabled(context, packageName))
            context.startActivity(context.getPackageManager().getLaunchIntentForPackage(packageName));
        else Toast.makeText(context, appName + " app is not enabled.", Toast.LENGTH_SHORT).show();
    else Toast.makeText(context, appName + " app is not installed.", Toast.LENGTH_SHORT).show();
}

private static boolean isAppInstalled(Context context, String packageName) {
    PackageManager pm = context.getPackageManager();
    try {
        pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
        return true;
    } catch (PackageManager.NameNotFoundException ignored) {
    }
    return false;
}

private static boolean isAppEnabled(Context context, String packageName) {
    boolean appStatus = false;
    try {
        ApplicationInfo ai = context.getPackageManager().getApplicationInfo(packageName, 0);
        if (ai != null) {
            appStatus = ai.enabled;
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    return appStatus;
}
Ahamadullah Saikat
la source
17

Voici mon exemple de lancement d'un scanner de code barre / QR depuis mon application si quelqu'un le trouve utile

Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.setPackage("com.google.zxing.client.android");

try 
{
    startActivityForResult(intent, SCAN_REQUEST_CODE);
} 
catch (ActivityNotFoundException e) 
{
    //implement prompt dialog asking user to download the package
    AlertDialog.Builder downloadDialog = new AlertDialog.Builder(this);
    downloadDialog.setTitle(stringTitle);
    downloadDialog.setMessage(stringMessage);
    downloadDialog.setPositiveButton("yes",
            new DialogInterface.OnClickListener() 
            {
                public void onClick(DialogInterface dialogInterface, int i) 
                {
                    Uri uri = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
                    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                    try
                    {
                        myActivity.this.startActivity(intent);
                    }
                    catch (ActivityNotFoundException e)
                    {
                        Dialogs.this.showAlert("ERROR", "Google Play Market not found!");
                    }
                }
            });
    downloadDialog.setNegativeButton("no",
            new DialogInterface.OnClickListener() 
            {
                public void onClick(DialogInterface dialog, int i) 
                {
                    dialog.dismiss();
                }
            });
    downloadDialog.show();
}
Tine M.
la source
13

Modifier en fonction du commentaire

Dans certaines versions - comme suggéré dans les commentaires - l'exception levée peut être différente.

Ainsi la solution ci-dessous est légèrement modifiée

Intent launchIntent = null;
try{
   launchIntent = getPackageManager().getLaunchIntentForPackage("applicationId");
} catch (Exception ignored) {}

if(launchIntent == null){
    startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")));
} else {
    startActivity(launchIntent);
}

Réponse originale

Bien que bien répondu, il existe une implémentation assez simple qui gère si l'application n'est pas installée. Je le fais comme ça

try{
    startActivity(getPackageManager().getLaunchIntentForPackage("applicationId"));
} catch (PackageManager.NameNotFoundException e) {
    startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")));
}

Remplacez "applicationId" par le package que vous souhaitez ouvrir, tel que com.google.maps, etc.

mayank1513
la source
La PackageManager.getLaunchIntentForPackage(...)méthode renvoie null si le nom du package n'est pas reconnu. Il ne jette pas PackageManager.NameNotFoundException. Voyez ici .
Adil Hussain
Je viens d'essayer startActivity(null)un émulateur Android 10 et il lance un NullPointerExceptionet non un PackageManager.NameNotFoundException.
Adil Hussain
Sur ma note 7, cela fonctionne exactement comme prévu.
Mayank1513
Quel est le comportement prévu de la startActivity(Intent intent)méthode lorsqu'elle reçoit une valeur nulle Intentet qu'est-ce qui vous fait dire cela? La documentation des développeurs Android indique seulement qu'elle lancera un ActivityNotFoundException.
Adil Hussain
Salut @Adil pouvez-vous m'aider avec cette question - stackoverflow.com/q/59615815/9640177
mayank1513
7
// check for the app if it exist in the phone it will lunch it otherwise, it will search for the app in google play app in the phone and to avoid any crash, if no google play app installed in the phone, it will search for the app in the google play store using the browser : 

 public void onLunchAnotherApp() {

        final String appPackageName = getApplicationContext().getPackageName();

        Intent intent = getPackageManager().getLaunchIntentForPackage(appPackageName);
        if (intent != null) {

            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);

        } else {

            onGoToAnotherInAppStore(intent, appPackageName);

        }

    }

    public void onGoToAnotherInAppStore(Intent intent, String appPackageName) {

        try {

            intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("market://details?id=" + appPackageName));
            startActivity(intent);

        } catch (android.content.ActivityNotFoundException anfe) {

            intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("http://play.google.com/store/apps/details?id=" + appPackageName));
            startActivity(intent);

        }

    }
Ingénieur Karima
la source
y a-t-il une limite de caractères à la méthode uri.parse?
API
7

Si vous souhaitez ouvrir une activité spécifique d'une autre application, nous pouvons l'utiliser.

Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try 
{
    startActivity(intent)
}catch(ActivityNotFoundException e){
    Toast.makeText(context,"Activity Not Found",Toast.LENGTH_SHORT).show()
}

Si vous avez besoin d'une autre application, au lieu d'afficher Toast, vous pouvez afficher une boîte de dialogue. En utilisant la boîte de dialogue, vous pouvez amener l'utilisateur sur Play-Store pour télécharger l'application requise.

Vignesh KM
la source
com.android.settings.fuelgauge.PowerUsageSummaryest juste un alias d' activité de com.android.settings.Settings$PowerUsageSummaryActivity, et il a été supprimé dans Android Pie , j'ai donc sommé la modification pour que cette réponse convienne à Pie. Notez qu'il est également compatible avec une version plus ancienne, voir Validation AOSP le 10 novembre 2011 af9252849fd94c1f2859c56a4010900ea38a607e etc
Week
3

Si vous connaissez les données et l'action sur laquelle le package installé réagit, vous devez simplement ajouter ces informations à votre instance d'intention avant de la démarrer.

Si vous avez accès au manifeste Android de l'autre application, vous pouvez y voir toutes les informations nécessaires.

WarrenFaith
la source
1
Merci pour la réponse. Oui, j'ai le AndroidManifest de l'autre application. Ce que j'essaie de faire maintenant, c'est le code suivant: Intent intention = new Intent (Intent.ACTION_MAIN); intent.setComponent (new ComponentName ("com.package", ". MainActivity")); startActivity (intention); mais de cette façon, cela ne fonctionne pas. Pouvez-vous me donner un lien plus précis, comment faire?
Bastian
1
L'application se bloque sur la ligne "startActivity ...": l'application s'est arrêtée de manière inattendue. Veuillez réessayer. Où puis-je voir l'erreur dans LogCat?
Bastian
5
J'ai trouvé l'erreur: lors de la définition du composant, le nom de classe complet au lieu de la classe doit être nommé: intent.setComponent (new ComponentName ("com.package", "com.package.MainActivity")) au lieu de l'intention .setComponent (new ComponentName ("com.package", ". MainActivity"))
Bastian
1
Bon à savoir ... Vous pouvez trouver le LogCat sur Eclipse: Fenêtre> Afficher la vue> Autre, Android> Logcat
WarrenFaith
@WarrenFaith J'ai besoin d'assistance avec stackoverflow.com/questions/52335402/… S'il vous plaît, aidez- moi .
user158
2

Étapes pour lancer une nouvelle activité comme suit:

1.Obtenez l'intention du colis

2.Si l'intention est nulle, redirigez l'utilisateur vers Playstore

3.Si l'intention n'est pas une activité ouverte nulle

public void launchNewActivity(Context context, String packageName) {
    Intent intent = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.CUPCAKE) {
        intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    }
    if (intent == null) {
        try {
            intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("market://details?id=" + packageName));
            context.startActivity(intent);
        } catch (android.content.ActivityNotFoundException anfe) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + packageName)));
        }
    } else {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }
}
Sharath kumar
la source
2

Il est possible de démarrer l'activité d'une application en utilisant Intent.setClassNameselon les documents.

Un exemple:

val activityName = "com.google.android.apps.muzei.MuzeiActivity" // target activity name
val packageName = "net.nurik.roman.muzei" // target package's name
val intent = Intent().setClassName(packageName, activityName)
startActivity(intent)

Pour l'ouvrir en dehors de l'application actuelle, ajoutez ce drapeau avant de démarrer l'intention.

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

Une réponse connexe ici

Phani Rithvij
la source
pls comment écrire en C ++.
GeneCode
1
@GeneCode stackoverflow.com/a/22436147/8608146 pourrait aider Je n'ai jamais travaillé avec des bibliothèques c ++ dans Android auparavant.
Phani Rithvij
1
private fun openOtherApp() {
        val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
        startActivity(sendIntent)
        finishAffinity()
    }
Mirza Ahmed Baig
la source