So starten Sie eine Aktivität von einer anderen Anwendung in Android aus

478

Ich möchte ein installiertes Paket von meiner Android-Anwendung aus starten. Ich gehe davon aus, dass es mit Absichten möglich ist, aber ich habe keinen Weg gefunden, dies zu tun. Gibt es einen Link, wo Sie die Informationen finden?

Bastian
quelle
2
Was passiert, wenn ich die zweite App von der ersten öffne und dann direkt auf das Symbol der zweiten App klicke? Ich erhalte zwei Instanzen der App, was unerwünscht ist. Wie verwalte ich sie?
Radhey

Antworten:

707

Wenn Sie die Hauptaktivität nicht kennen, kann der Paketname zum Starten der Anwendung verwendet werden.

Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) { 
    startActivity(launchIntent);//null pointer check in case package name was not found
}
andep
quelle
5
Gibt es einen Grund, warum dies nicht funktionieren würde? Ich habe es zumindest nicht zum Laufen gebracht.
Simon Forsberg
22
Es startet eine neue Absicht. Wie wäre es, wenn Sie die Anwendung im Hintergrund fortsetzen?
Salil Dua
3
@andep: Das hat bei mir gut funktioniert, als ich zwischen zwei Apps getestet habe, die ich selbst erstellt habe. Sobald ich den Paketnamen kenne, funktioniert dies immer oder gibt es eine Möglichkeit, jemanden daran zu hindern, Ihre App zu starten (im Maniefest oder irgendwo)?
Leonard Feehan
2
@Leonard: Mein erster Eindruck, dass es immer funktionieren muss, weil Paketnamen öffentlich sind, damit alle Apps sie vorlesen können. Ich denke, Sie können anhand Ihrer Apps nicht feststellen, von wo aus es aufgerufen wurde, aber Ihre App kann feststellen, dass es nicht über die Hauptaktivität nur über Dienste aufgerufen werden kann.
Andep
1
Ja, dies kann null zurückgeben. "Die aktuelle Implementierung sucht zuerst nach einer Hauptaktivität in der Kategorie CATEGORY_INFOund dann nach einer Hauptaktivität in der Kategorie CATEGORY_LAUNCHER. Gibt null zurück, wenn keine gefunden wird. "
quietmint
239

Ich weiß, dass dies beantwortet wurde, aber hier ist, wie ich etwas Ähnliches implementiert habe:

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

Noch besser, hier ist die Methode:

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

Doppelter Code entfernt:

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
quelle
8
Ich hatte ein Problem beim Starten einer Absicht für ein Facebook- oder Twitter-Profil. Sie wurden in meiner App geöffnet und nicht als neue Aktivität. Das Hinzufügen von FLAG_ACTIVITY_NEW_TASK hat das behoben. Vielen Dank!
Harry
4
Kein Problem! Ich hatte Probleme mit etwas sehr Ähnlichem
Jared Burrows
1
Die Methode funktioniert für mich, aber manchmal ist die neue Anwendung geöffnet und die aufrufende Aktivität steht immer noch im Vordergrund. Irgendwelche Ideen, wie man das behebt?
lgdroid57
Gibt es eine Möglichkeit, dies über die Instant-App zu tun?
Mahdi
Funktioniert nur für Release-Versionen. Wenn Sie versuchen, die Debug-App zu öffnen, ist die Absicht null.
RexSplode
152

Ich habe die Lösung gefunden. In der Manifestdatei der Anwendung habe ich den Paketnamen gefunden: com.package.address und den Namen der Hauptaktivität, die ich starten möchte: MainActivity Der folgende Code startet diese Anwendung:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
Bastian
quelle
8
Ich habe die Ausnahme "Dosis, die Sie Aktivität in Ihrem Manifest.xml deklarieren"
itzhar
Auf diese Weise wird eine Ausnahme zurückgegeben, die besagt, dass ich die Aktivität in meinem Manifest deklarieren muss. Es handelt sich jedoch um eine externe App!
JJ Ab
Wie läuft es im Hintergrund? Bedeutet, dass als zweites aufgerufene Anwendungen nicht auf dem Bildschirm angezeigt werden, sondern die onCreated () -Methode ausführen.
Dr.jacky
Ich erhalte diesen Fehler, wenn ich es über die Sofort-App versuche: Aktivität darf nicht gestartet werden Absicht
Mahdi
@ Bastian, wie man die aktuelle App schließt, von wo aus wir die Absicht aufrufen, eine andere App zu öffnen?
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
quelle
17

Hier ist mein Beispiel für das Starten eines Bar- / QR-Code-Scanners über meine App, wenn jemand dies nützlich findet

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.
quelle
13

Bearbeiten je nach Kommentar

In einigen Versionen - wie in den Kommentaren vorgeschlagen - kann die ausgelöste Ausnahme unterschiedlich sein.

Somit ist die nachstehende Lösung leicht modifiziert

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

Ursprüngliche Antwort

Obwohl gut beantwortet, gibt es eine ziemlich einfache Implementierung, die funktioniert, wenn die App nicht installiert ist. so mach ich es

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

Ersetzen Sie "applicationId" durch das Paket, das Sie öffnen möchten, z. B. com.google.maps usw.

mayank1513
quelle
Die PackageManager.getLaunchIntentForPackage(...)Methode gibt null zurück, wenn der Paketname nicht erkannt wird. Es wirft nicht PackageManager.NameNotFoundException. Siehe hier .
Adil Hussain
Ich habe gerade startActivity(null)einen Android 10-Emulator ausprobiert und er wirft ein NullPointerExceptionund kein PackageManager.NameNotFoundException.
Adil Hussain
In meinem Hinweis 7 funktioniert es genau so, wie es beabsichtigt ist.
mayank1513
Was ist das beabsichtigte Verhalten der startActivity(Intent intent)Methode, wenn sie eine Null erhält, Intentund warum sagen Sie das? In der Dokumentation der Android-Entwickler heißt es nur, dass ein ActivityNotFoundException.
Adil Hussain
Hallo @Adil, können Sie mir bitte bei dieser Frage helfen - 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);

        }

    }
Karima Ingenieur
quelle
Gibt es eine Zeichenbeschränkung für die uri.parse-Methode?
API
7

Wenn Sie eine bestimmte Aktivität einer anderen Anwendung öffnen möchten, können wir diese verwenden.

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()
}

Wenn Sie eine andere Anwendung benötigen, können Sie anstelle von Toast einen Dialog anzeigen. Über den Dialog können Sie den Benutzer zum Play-Store bringen, um die erforderliche Anwendung herunterzuladen.

Vignesh KM
quelle
com.android.settings.fuelgauge.PowerUsageSummaryist nur ein Aktivitäts-Alias von com.android.settings.Settings$PowerUsageSummaryActivityund wurde in Android Pie entfernt , daher habe ich die Bearbeitung zusammengefasst, damit diese Antwort zu Pie passt. Beachten Sie, dass es auch mit älteren Versionen kompatibel ist, siehe AOSP-Commit am 10. November 2011 af9252849fd94c1f2859c56a4010900ea38a607e usw.
Wochenende
3

Wenn Sie die Daten und die Aktion kennen, auf die das installierte Paket reagiert, sollten Sie diese Informationen einfach zu Ihrer Intent-Instanz hinzufügen, bevor Sie sie starten.

Wenn Sie Zugriff auf das AndroidManifest der anderen App haben, können Sie dort alle erforderlichen Informationen anzeigen.

WarrenFaith
quelle
1
Danke für die Antwort. Ja, ich habe das AndroidManifest der anderen Anwendung. Was ich jetzt versuche, ist der folgende Code: Intent intent = new Intent (Intent.ACTION_MAIN); intent.setComponent (neuer ComponentName ("com.package", ". MainActivity")); startActivity (Absicht); aber auf diese Weise funktioniert es nicht. Können Sie mir einen genaueren Link geben, wie es geht?
Bastian
1
Die Anwendung stürzt in der Zeile "startActivity ..." ab: Die Anwendung wurde unerwartet gestoppt. Bitte versuchen Sie es erneut. Wo kann ich den Fehler in LogCat sehen?
Bastian
5
Ich habe den Fehler gefunden: Beim Festlegen der Komponente muss der vollständig qualifizierte Klassenname anstelle nur der Klasse benannt werden: intent.setComponent (neuer Komponentenname ("com.package", "com.package.MainActivity")) anstelle von intent .setComponent (neuer ComponentName ("com.package", ". MainActivity"))
Bastian
1
Gut zu wissen ... Sie finden die LogCat auf Eclipse: Fenster> Ansicht anzeigen> Andere, Android> Logcat
WarrenFaith
@WarrenFaith Ich brauche Unterstützung bei stackoverflow.com/questions/52335402/… Bitte helfen Sie.
Benutzer158
2

Schritte zum Starten neuer Aktivitäten wie folgt:

1. Absicht für Paket erhalten

2.Wenn die Absicht null ist, leiten Sie den Benutzer zum Playstore um

3.Wenn die Absicht nicht null ist, öffnen Sie die Aktivität

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

Es ist möglich, die Aktivität einer App zu starten, indem Sie sie Intent.setClassNamegemäß den Dokumenten verwenden.

Ein Beispiel:

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)

Um es außerhalb der aktuellen App zu öffnen, fügen Sie dieses Flag hinzu, bevor Sie die Absicht starten.

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

Eine verwandte Antwort hier

Phani Rithvij
quelle
Bitte schreiben Sie in C ++.
GeneCode
1
@GeneCode stackoverflow.com/a/22436147/8608146 könnte helfen, ich habe noch nie zuvor mit C ++ - Bibliotheken in Android gearbeitet.
Phani Rithvij
1
private fun openOtherApp() {
        val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
        startActivity(sendIntent)
        finishAffinity()
    }
Mirza Ahmed Baig
quelle