Como iniciar uma atividade de outro aplicativo no Android

479

Quero iniciar um pacote instalado no meu aplicativo Android. Presumo que seja possível usar intenções, mas não encontrei uma maneira de fazê-lo. Existe um link onde encontrar as informações?

Bastian
fonte
2
o que acontece se eu abrir o segundo aplicativo a partir do primeiro e clicar diretamente no ícone do segundo aplicativo, recebo duas instâncias do aplicativo, que são indesejadas. como gerenciá-lo?
Radhey

Respostas:

707

Se você não conhece a atividade principal, o nome do pacote pode ser usado para iniciar o aplicativo.

Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) { 
    startActivity(launchIntent);//null pointer check in case package name was not found
}
andep
fonte
5
Alguma razão para isso não funcionar? Eu não consegui funcionar pelo menos.
Simon Forsberg
22
Ele inicia uma nova Intent, que tal retomar o aplicativo que está em segundo plano?
Salil Dua 29/07
3
@andep: Isso funcionou bem para mim quando testei entre dois aplicativos que eu mesmo criei. Depois que eu souber o nome do pacote, isso sempre funcionará ou existe uma maneira de impedir que alguém inicie seu aplicativo (no mais perigoso ou em algum outro lugar)?
precisa saber é o seguinte
2
@ Leonard: Minha primeira impressão, que deve sempre funcionar, porque os nomes dos pacotes são públicos para que qualquer aplicativo possa lê-los. Nos seus aplicativos, acho que você não pode determinar de onde foi chamado, mas seu aplicativo pode determinar que não pode ser chamado pela atividade principal apenas por meio de serviços.
andep
1
Sim, isso pode retornar nulo. "A atual aparência de implementação primeiros para uma atividade principal na categoria CATEGORY_INFO, e ao lado de uma atividade principal na categoria CATEGORY_LAUNCHER. Retorna NULL se não são encontrados. "
quietmint
240

Eu sei que isso foi respondido, mas aqui está como eu implementei algo semelhante:

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

Melhor ainda, aqui está o método:

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

Código duplicado removido:

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
fonte
8
Eu estava tendo um problema ao iniciar um Intent para um perfil do Facebook ou Twitter. Eles estavam abrindo dentro do meu aplicativo, e não como uma nova atividade. Adicionar o FLAG_ACTIVITY_NEW_TASK corrigiu isso. Obrigado!
Harry
4
Sem problemas! Eu estava tendo problemas com algo muito semelhante
Jared Burrows
1
O método funciona para mim, mas às vezes o novo aplicativo está aberto e a atividade de chamada ainda é o primeiro plano. Alguma idéia de como consertar?
Lgdroid57
Existe alguma maneira de fazer isso no aplicativo instantâneo?
Mahdi
Funciona apenas para versões de lançamento. Se você estiver tentando abrir o aplicativo de depuração, a intenção será nula.
RexSplode 23/05
152

Eu encontrei a solução. No arquivo de manifesto do aplicativo, encontrei o nome do pacote: com.package.address e o nome da atividade principal que desejo iniciar: MainActivity O código a seguir inicia esse aplicativo:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
Bastian
fonte
8
eu tenho exceção 'dose que declarar atividade em sua Manifest.xml'
itzhar
Dessa forma, retorna uma exceção que diz que preciso declarar a atividade no meu manifesto .. mas é um aplicativo externo!
JJ Ab
Como executá-lo em segundo plano? Significa que o segundo aplicativo chamado não aparece na tela, mas executa o método onCreated ().
precisa saber é o seguinte
Eu recebo este erro quando eu tento de aplicação instantânea: Não é permitido para começar a atividade Intenção
Mahdi
@Bastian como fechar o aplicativo atual de onde chamamos a intenção de abrir outro aplicativo?
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
fonte
17

Aqui está o meu exemplo de como iniciar o scanner de código de barras / QR do meu aplicativo, se alguém achar útil

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

Editar dependendo do comentário

Em algumas versões - como sugerido nos comentários - a exceção lançada pode ser diferente.

Assim, a solução abaixo é ligeiramente modificada

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

Resposta original

Embora tenha respondido bem, há uma implementação bastante simples que lida com o aplicativo não instalado. Eu faço assim

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

Substitua "applicationId" pelo pacote que você deseja abrir, como com.google.maps etc.

mayank1513
fonte
O PackageManager.getLaunchIntentForPackage(...)método retornará nulo se o nome do pacote não for reconhecido. Não joga PackageManager.NameNotFoundException. Veja aqui .
Adil Hussain
Eu apenas tentei startActivity(null)em um emulador do Android 10 e ele lança um NullPointerExceptione não um PackageManager.NameNotFoundException.
Adil Hussain
Na minha nota 7, ele funciona exatamente da maneira que se destina.
mayank1513 7/01
Qual é o comportamento pretendido do startActivity(Intent intent)método quando ele recebe um nulo Intente o que faz você dizer isso? A documentação dos desenvolvedores do Android afirma apenas que ele lançará um ActivityNotFoundException.
Adil Hussain
Oi @Adil você pode por favor me ajudar com esta pergunta - 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 Engineer
fonte
existe um limite de caracteres para o método uri.parse?
API
7

Se você deseja abrir uma atividade específica de outro aplicativo, podemos usá-lo.

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 você precisar de outro aplicativo, em vez de mostrar o Toast, poderá mostrar uma caixa de diálogo. Usando o diálogo, você pode levar o usuário à Play-Store para baixar o aplicativo necessário.

Vignesh KM
fonte
com.android.settings.fuelgauge.PowerUsageSummaryé apenas um alias de atividade de com.android.settings.Settings$PowerUsageSummaryActivitye foi removido no Android Pie . Por isso, reuni a edição para tornar essa resposta adequada ao Pie. Observe que também é compatível com a versão mais antiga, consulte Confirmação do AOSP em 10/11/2011, af9252849fd94c1f2859c56a4010900ea38a607e etc.
Weekend
3

Se você conhece os dados e a ação na qual o pacote instalado reage, basta adicionar essas informações à sua instância de intenção antes de iniciá-las.

Se você tiver acesso ao AndroidManifest do outro aplicativo, poderá ver todas as informações necessárias lá.

WarrenFaith
fonte
1
Obrigado pela resposta. Sim, eu tenho o AndroidManifest do outro aplicativo. O que tento fazer agora é o seguinte código: Intent intent = new Intent (Intent.ACTION_MAIN); intent.setComponent (new ComponentName ("com.package", ". MainActivity")); startActivity (intenção); mas desta forma não está funcionando. Você pode me dar um link mais preciso, como fazê-lo?
Bastian
1
O aplicativo falha na linha "startActivity ...": o aplicativo foi interrompido inesperadamente. Fundamentos, tente novamente. Onde posso ver o erro no LogCat?
Bastian
5
Encontrei o erro: ao definir o componente, o nome completo da classe, em vez de apenas a classe, deve ser nomeado: intent.setComponent (new ComponentName ("com.package", "com.package.MainActivity")) em vez de intent .setComponent (new ComponentName ("com.package", ". MainActivity"))
Bastian
1
É bom saber ... Você pode encontrar o LogCat no eclipse: Janela> Mostrar visualização> Outros, Android> Logcat
WarrenFaith
@WarrenFaith Preciso de suporte com stackoverflow.com/questions/52335402/… Por favor, ajude.
user158
2

Etapas para iniciar nova atividade da seguinte maneira:

1. Obter intenção para o pacote

2.Se a intenção é nulo, redirecione o usuário para o playstore

3.Se a intenção não for uma atividade aberta nula

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

É possível iniciar a atividade de um aplicativo usando de Intent.setClassNameacordo com os documentos.

Um exemplo:

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)

Para abri-lo fora do aplicativo atual, adicione esse sinalizador antes de iniciar a intenção.

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

Uma resposta relacionada aqui

Phani Rithvij
fonte
pls como escrever em C ++.
GeneCode 23/02
1
@GeneCode stackoverflow.com/a/22436147/8608146 pode ajudar Eu nunca trabalhei com bibliotecas c ++ no android antes.
Phani Rithvij
1
private fun openOtherApp() {
        val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
        startActivity(sendIntent)
        finishAffinity()
    }
Mirza Ahmed Baig
fonte