Come avviare un'attività da un'altra applicazione in Android


479

Voglio lanciare un pacchetto installato dalla mia applicazione Android. Presumo che sia possibile usare gli intenti, ma non ho trovato il modo di farlo. Esiste un link, dove trovare le informazioni?


2
cosa succede se apro la seconda app dalla prima e quindi faccio clic direttamente sull'icona della seconda app, ottengo due istanze dell'app, che è indesiderata. Come gestirla ??
Radhey,

Risposte:


707

Se non si conosce l'attività principale, è possibile utilizzare il nome del pacchetto per avviare l'applicazione.

Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) { 
    startActivity(launchIntent);//null pointer check in case package name was not found
}

5
Qualche motivo per cui questo non funzionerebbe? Almeno non l'ho fatto funzionare.
Simon Forsberg,

22
Inizia un nuovo intento, che ne dici di riprendere l'applicazione in background?
Salil Dua,

3
@andep: Questo ha funzionato bene per me quando ho provato tra due app che ho creato da solo. Una volta che so che il nome del pacchetto funzionerà sempre o c'è un modo per impedire a qualcuno di avviare la tua app (nel maniefest o da qualche parte)?
Leonard Feehan,

2
@Leonard: la mia prima impressione, che deve sempre funzionare, perché i nomi dei pacchetti sono pubblici in modo che qualsiasi app possa leggerli. Dalle tue app penso che non puoi determinare da dove è stata chiamata, ma la tua app può determinare che non può essere chiamata tramite l'attività principale solo tramite i servizi.
Andep

1
Sì, questo può restituire null. "L'implementazione corrente cerca prima l'attività principale nella categoria CATEGORY_INFO, e successivamente un'attività principale nella categoria CATEGORY_LAUNCHER. Restituisce null se nessuno dei due viene trovato. "
quietmint

240

So che è stata data una risposta, ma ecco come ho implementato qualcosa di simile:

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

Ancora meglio, ecco il metodo:

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

Codice duplicato rimosso:

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

8
Stavo riscontrando un problema durante l'avvio di un Intento su un profilo Facebook o Twitter. Si stavano aprendo all'interno della mia app, anziché come nuova attività. L'aggiunta di FLAG_ACTIVITY_NEW_TASK ha risolto il problema. Grazie!
Harry,

4
Nessun problema! Ho avuto problemi con qualcosa di molto simile
Jared Burrows,

1
Il metodo funziona per me, ma a volte la nuova applicazione è aperta e l'attività chiamante è ancora in primo piano. Qualche idea su come risolvere?
lgdroid57

C'è un modo per farlo da Instant-App?
Mahdi,

Funziona solo per le versioni di rilascio. Se stai provando ad aprire l'app di debug, l'intento sarà nullo.
RexSplode,

152

Ho trovato la soluzione Nel file manifest dell'applicazione ho trovato il nome del pacchetto: com.package.address e il nome dell'attività principale che voglio avviare: MainActivity Il seguente codice avvia questa applicazione:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);

8
ho ricevuto l'eccezione "dose dichiarata attività nel tuo Manifest.xml"
itzhar

In questo modo viene restituita un'eccezione che dice che devo dichiarare l'attività nel mio manifest .. ma è un'app esterna!
JJ Ab

Come eseguirlo in background? Significa che le applicazioni seconde chiamate non vengono visualizzate sullo schermo, ma eseguono il suo metodo onCreated ().
Dr.jacky,

Ricevo questo errore quando provo dall'app istantanea: non mi è permesso avviare l'attività Intent
Mahdi

@Bastian come chiudere l'app corrente da dove chiamiamo intento per aprire un'altra app?
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;
}

17

Ecco il mio esempio di avvio della barra / scanner di codici QR dalla mia app se qualcuno lo trova 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();
}

13

Modifica in base al commento

In alcune versioni - come suggerito nei commenti - l'eccezione generata potrebbe essere diversa.

Pertanto la soluzione seguente è leggermente modificata

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

Risposta originale

Sebbene abbia una buona risposta, esiste un'implementazione piuttosto semplice che gestisce se l'app non è installata. Lo faccio così

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

Sostituisci "applicationId" con il pacchetto che vuoi aprire come com.google.maps, ecc.


Il PackageManager.getLaunchIntentForPackage(...)metodo restituisce null se il nome del pacchetto non è riconosciuto. Non getta PackageManager.NameNotFoundException. Vedi qui .
Adil Hussain, l'

Ho appena provato startActivity(null)un emulatore di Android 10 e genera un NullPointerExceptione non un PackageManager.NameNotFoundException.
Adil Hussain,

Sulla mia nota 7 funziona esattamente come è inteso.
Mayank1513

Qual è il comportamento previsto del startActivity(Intent intent)metodo quando viene dato un null Intente cosa te lo fa dire? La documentazione degli sviluppatori Android afferma solo che lancerà un ActivityNotFoundException.
Adil Hussain, il

Hi @Adil si può please help me con questa domanda - 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);

        }

    }

c'è un limite di caratteri al metodo uri.parse?
API

7

Se vuoi aprire un'attività specifica di un'altra applicazione, possiamo usarla.

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

Se hai bisogno di altre applicazioni, invece di mostrare Toast puoi mostrare una finestra di dialogo. Utilizzando la finestra di dialogo è possibile portare l'utente nel Play-Store per scaricare l'applicazione richiesta.


com.android.settings.fuelgauge.PowerUsageSummaryè solo un alias di attivitàcom.android.settings.Settings$PowerUsageSummaryActivity ed è stato rimosso in Android Pie , quindi ho completato la modifica per rendere questa risposta adatta a Pie. Si noti che è anche compatibile con la versione precedente, vedere AOSP commit il 10 novembre 2011 af9252849fd94c1f2859c56a4010900ea38a607e ecc.
Weekend

3

Se conosci i dati e l'azione su cui reagiscono i pacchetti installati, devi semplicemente aggiungere queste informazioni all'istanza di intento prima di avviarle.

Se hai accesso ad AndroidManifest dell'altra app, puoi vedere tutte le informazioni necessarie lì.


1
Grazie per la risposta. Sì, ho AndroidManifest dell'altra applicazione. Quello che provo a fare ora è il seguente codice: Intent intent = new Intent (Intent.ACTION_MAIN); intent.setComponent (new ComponentName ("com.package", ". MainActivity")); startActivity (intento); ma in questo modo non funziona. Puoi darmi un link più preciso, come si fa?
Bastian,

1
L'applicazione si arresta in modo anomalo sulla riga "startActivity ...": l'applicazione si è arrestata in modo imprevisto. Per favore, riprova. Dove posso vedere l'errore in LogCat?
Bastian,

5
Ho trovato l'errore: quando si imposta il componente, il nome della classe completo anziché solo la classe deve essere chiamato: intent.setComponent (new ComponentName ("com.package", "com.package.MainActivity")) invece dell'intento .setComponent (new ComponentName ("com.package", ". MainActivity"))
Bastian

1
Buono a sapersi ... Puoi trovare LogCat su eclipse: Finestra> Visualizza vista> Altro, Android> Logcat
WarrenFaith,

@WarrenFaith Ho bisogno di supporto con stackoverflow.com/questions/52335402/... prega di aiuto.
user158,

2

I passaggi per avviare una nuova attività come segue:

1. Ottenere l'intento per il pacchetto

2.Se l'intento è un utente di reindirizzamento null al Playstore

3.Se l'intento non è un'attività aperta nulla

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

2

È possibile avviare l'attività di un'app utilizzando Intent.setClassNamesecondo i documenti.

Un esempio:

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)

Per aprirlo al di fuori dell'app corrente, aggiungi questo flag prima di iniziare l'intento.

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

Una risposta correlata qui


pls come scrivere in C ++.
GeneCode

1
@GeneCode stackoverflow.com/a/22436147/8608146 potrebbe aiutare Non ho mai lavorato con C ++ librerie in Android prima.
Phani Rithvij,

1
private fun openOtherApp() {
        val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
        startActivity(sendIntent)
        finishAffinity()
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.