Jak uruchomić działanie z innej aplikacji w systemie Android

478

Chcę uruchomić zainstalowany pakiet z mojej aplikacji na Androida. Zakładam, że jest to możliwe przy użyciu intencji, ale nie znalazłem sposobu, aby to zrobić. Czy jest link, gdzie można znaleźć informacje?

Bastian
źródło
2
co się stanie, jeśli otworzę drugą aplikację od pierwszej, a następnie kliknę bezpośrednio ikonę drugiej aplikacji, otrzymam dwa wystąpienia aplikacji, co jest niepożądane. jak to zarządzać?
Radhey,

Odpowiedzi:

707

Jeśli nie znasz głównej aktywności, możesz użyć nazwy pakietu do uruchomienia aplikacji.

Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) { 
    startActivity(launchIntent);//null pointer check in case package name was not found
}
andep
źródło
5
Jest jakiś powód, dla którego to nie działałoby? Przynajmniej nie udało mi się.
Simon Forsberg,
22
Rozpoczyna nową intencję, co powiesz na wznowienie aplikacji działającej w tle?
Salil Dua
3
@ andep: Działa to dla mnie dobrze, gdy testowałem między dwiema aplikacjami, które sam stworzyłem. Kiedy się dowiem, że nazwa pakietu będzie zawsze działać, czy istnieje sposób, aby ktoś nie uruchomił Twojej aplikacji (na maniefest czy gdzieś)?
Leonard Feehan
2
@Leonard: Moje pierwsze wrażenie, że musi zawsze działać, ponieważ nazwy pakietów są publiczne, aby każda aplikacja mogła je odczytać. Z twoich aplikacji myślę, że nie możesz ustalić, skąd się nazywa, ale twoja aplikacja może stwierdzić, że nie można wywoływać za pośrednictwem głównej czynności tylko za pośrednictwem usług.
andep
1
Tak, to może zwrócić wartość null. „Bieżąca implementacja najpierw szuka głównej aktywności w kategorii CATEGORY_INFO, a następnie głównej aktywności w kategorii CATEGORY_LAUNCHER. Zwraca wartość null, jeśli żadna z nich nie zostanie znaleziona.
quietmint
239

Wiem, że udzielono odpowiedzi, ale oto jak zaimplementowałem coś podobnego:

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

Jeszcze lepiej, oto metoda:

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

Usunięto duplikat kodu:

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
źródło
8
Miałem problem z uruchomieniem profilu Intent na Facebooku lub Twitterze. Otwierali się w mojej aplikacji, a nie jako nowa aktywność. Dodanie FLAG_ACTIVITY_NEW_TASK naprawiło to. Dzięki!
Harry
4
Nie ma problemu! Miałem problem z czymś bardzo podobnym
Jared Burrows
1
Ta metoda działa dla mnie, ale czasami nowa aplikacja jest otwarta, a działanie wywołujące jest nadal na pierwszym planie. Wszelkie pomysły, jak to naprawić?
lgdroid57
Czy można to zrobić za pomocą aplikacji instant?
Mahdi
Działa tylko w wersjach wydanych. Jeśli próbujesz otworzyć aplikację do debugowania, zamiar będzie zerowy.
RexSplode
152

Znalazłem rozwiązanie. W pliku manifestu aplikacji znalazłem nazwę pakietu: com.package.address i nazwę głównego działania, które chcę uruchomić: MainActivity Następujący kod uruchamia tę aplikację:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
Bastian
źródło
8
mam wyjątek „dawka, którą deklarujesz aktywność w Manifest.xml”
itzhar
W ten sposób zwraca wyjątek, który mówi, że muszę zadeklarować aktywność w moim manifeście ... ale jest to aplikacja zewnętrzna!
JJ Ab
Jak uruchomić go w tle? Oznacza, że ​​drugie wywołane aplikacje nie są wyświetlane na ekranie, ale uruchamiają metodę onCreated ().
Dr.jacky
Występuje ten błąd, gdy próbuję z aplikacji błyskawicznej: Nie wolno rozpocząć działania Intent
Mahdi
@Bastian jak zamknąć bieżącą aplikację, z której nazywamy zamiar otwarcia innej aplikacji?
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
źródło
17

Oto mój przykład uruchamiania skanera kodów kreskowych / QR z mojej aplikacji, jeśli ktoś uzna to za przydatne

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.
źródło
13

Edytuj w zależności od komentarza

W niektórych wersjach - jak sugerowano w komentarzach - zgłoszony wyjątek może być inny.

Dlatego poniższe rozwiązanie zostało nieznacznie zmodyfikowane

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

Oryginalna odpowiedź

Chociaż dobrze odpowiedział, istnieje dość prosta implementacja, która obsługuje, jeśli aplikacja nie jest zainstalowana. Robię to w ten sposób

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

Zamień „applicationId” na pakiet, który chcesz otworzyć, taki jak com.google.maps itp.

mayank1513
źródło
Że PackageManager.getLaunchIntentForPackage(...)metoda zwraca null, jeśli nazwa pakiet nie jest rozpoznawany. Nie rzuca się PackageManager.NameNotFoundException. Zobacz tutaj .
Adil Hussain
Właśnie próbowałem startActivity(null)na emulatorze Androida 10 i rzuca a, NullPointerExceptiona nie a PackageManager.NameNotFoundException.
Adil Hussain
W mojej notatce 7 działa dokładnie tak, jak jest przeznaczone.
mayank1513
Jakie jest zamierzone zachowanie startActivity(Intent intent)metody, gdy ma ona wartość zerową Intenti co sprawia, że ​​tak mówisz? Android deweloperów dokumentacja stanowi jedynie, że będzie rzucać ActivityNotFoundException.
Adil Hussain
Cześć @Adil, czy możesz mi pomóc z tym pytaniem - 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);

        }

    }
Inżynier Karima
źródło
czy istnieje limit znaków dla metody uri.parse?
API
7

Jeśli chcesz otworzyć określoną aktywność innej aplikacji, możemy z tego skorzystać.

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

Jeśli potrzebujesz innej aplikacji, zamiast Pokazywać Toast możesz wyświetlić okno dialogowe. Za pomocą okna dialogowego możesz doprowadzić użytkownika do Play-Store w celu pobrania wymaganej aplikacji.

Vignesh KM
źródło
com.android.settings.fuelgauge.PowerUsageSummaryjest tylko aktywność-alias z com.android.settings.Settings$PowerUsageSummaryActivityi został usunięty w Android Pie , więc summitted edit, aby ta odpowiedź garnitur Pie. Zauważ, że jest również kompatybilny ze starszą wersją, zobacz zatwierdzenie AOSP w dniu 10 listopada 2011 af9252849fd94c1f2859c56a4010900ea38a607e itp.
Weekend
3

Jeśli znasz dane i działania, na które zareaguje zainstalowany pakiet, po prostu dodaj te informacje do instancji użytkownika przed jego uruchomieniem.

Jeśli masz dostęp do AndroidManifest drugiej aplikacji, możesz tam zobaczyć wszystkie potrzebne informacje.

WarrenFaith
źródło
1
Dziękuję za odpowiedź. Tak, mam AndroidManifest drugiej aplikacji. To, co próbuję teraz zrobić, to następujący kod: Intent intent = new Intent (Intent.ACTION_MAIN); intent.setComponent (new ComponentName („com.package”, „. MainActivity”)); startActivity (intencja); ale w ten sposób nie działa. Czy możesz podać mi dokładniejszy link, jak to zrobić?
Bastian
1
Aplikacja ulega awarii w linii „startActivity ...”: Aplikacja niespodziewanie przestała działać. Zarzuty spróbuj ponownie. Gdzie mogę zobaczyć błąd w LogCat?
Bastian
5
Znalazłem błąd: podczas ustawiania komponentu należy nazwać w pełni kwalifikowaną nazwę klasy zamiast samej klasy: intent.setComponent (nowa nazwa komponentu („com.package”, „com.package.MainActivity”)) zamiast zamiaru .setComponent (new ComponentName („com.package”, „. MainActivity”))
Bastian
1
Dobrze wiedzieć ... LogCat można znaleźć w Eclipse: Okno> Pokaż widok> Inne, Android>
Logcat
@WarrenFaith Potrzebuję wsparcia z stackoverflow.com/questions/52335402/... Proszę o pomoc.
user158
2

Kroki, aby rozpocząć nową aktywność w następujący sposób:

1.Zamierz zamiar paczki

2.Jeśli intencją jest zerowe przekierowanie użytkownika do playstore

3.Jeśli zamiar nie jest aktywnością zerową otwartą

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
źródło
2

Możliwe jest rozpoczęcie działania aplikacji przy użyciu Intent.setClassNamezgodnie z dokumentacją.

Przykład:

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)

Aby otworzyć go poza bieżącą aplikacją, dodaj tę flagę przed rozpoczęciem zamiaru.

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

Powiązana odpowiedź tutaj

Phani Rithvij
źródło
proszę pisać w C ++.
GeneCode
1
@GeneCode stackoverflow.com/a/22436147/8608146 może pomóc nigdy wcześniej nie pracować z bibliotekami c ++ w systemie Android.
Phani Rithvij
1
private fun openOtherApp() {
        val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
        startActivity(sendIntent)
        finishAffinity()
    }
Mirza Ahmed Baig
źródło