Як запустити активність з іншого додатка в Android


478

Я хочу запустити встановлений пакет із свого додатка Android. Я припускаю, що це можливо за допомогою намірів, але я не знайшов способу зробити це. Чи є посилання, де знайти інформацію?


2
що трапиться, якщо я відкрию другий додаток з першого, а потім натискаю безпосередньо значок другого додатка, я отримую два екземпляри програми, які не бажано. як керувати ним ??
Радхей

Відповіді:


707

Якщо ви не знаєте основної діяльності, то ім'я пакета можна використовувати для запуску програми.

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

5
Будь-яка причина, чому це не працює? Я принаймні не працював.
Саймон Форсберг

22
Він запускає новий Намір, як щодо відновлення програми, яка знаходиться у фоновому режимі?
Саліл Дуа

3
@andep: Це спрацювало для мене, коли я тестував між двома програмами, які я створив сам. Як тільки я знаю, ім'я пакету буде завжди спрацьовувати, чи існує спосіб запобігти запусканню вашої програми (у maniefest чи десь)?
Леонард Фіхан

2
@Leonard: Моє перше враження, що воно завжди має працювати, оскільки назви пакетів є загальнодоступними, тому будь-які програми можуть їх читати. З ваших додатків, я думаю, ви не можете визначити, звідки його викликали, але ваш додаток може визначити, що не можна телефонувати через основну діяльність просто через сервіси.
andep

1
Так, це може повернути нуль. «В даний час виглядає реалізація першої для основної діяльності в категорії CATEGORY_INFO, а потім для основної діяльності в категорії CATEGORY_LAUNCHER. Повертає NULL , якщо ні один не знайдені. »
quietmint

239

Я знаю, що на це відповіли, але ось як я реалізував щось подібне:

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

Ще краще, ось метод:

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

Видалений повторний код:

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
У мене виникла проблема під час запуску намірів у профілі Facebook чи Twitter. Вони відкривалися всередині мого додатку, а не як нова діяльність. Додавання виправленого FLAG_ACTIVITY_NEW_TASK. Дякую!
Гаррі

4
Нема проблем! У мене виникли проблеми з чимось дуже подібним
Джаред Берроз

1
Метод працює для мене, але іноді новий додаток відкрито, і активність виклику все ще залишається на першому плані. Будь-які ідеї, як виправити?
lgdroid57

Чи можливо це зробити з миттєвого додатка?
Махді

Працює лише для версій версій. Якщо ви намагаєтесь відкрити програму для налагодження, ціль буде нульовою.
RexSplode

152

Я знайшов рішення. У файлі маніфесту програми я знайшов назву пакета: com.package.address та назву основної діяльності, яку я хочу запустити: MainActivity Цей додаток запускає наступний код:

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

8
Я отримав виняток "доза ви заявляєте про активність у своєму Manifest.xml"
itzhar

Цей спосіб повертає виняток, який говорить, що мені потрібно оголосити активність у своєму маніфесті .. але його зовнішнє додаток!
JJ Ab

Як запустити його у фоновому режимі? Значення, що називаються другими програмами, не відображаються на екрані, але запускають його метод onCreate ().
Dr.jacky

Я отримую цю помилку, коли я намагаюся використовувати миттєвий додаток: Не дозволяється запускати діяльність Намір
Махді

@Bastian як закрити поточний додаток, звідки ми викликаємо наміри відкрити інший додаток?
Арнольд Браун

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

Ось мій приклад запуску сканера бар / QR-код із мого додатка, якщо хтось вважає це корисним

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

Редагувати залежно від коментаря

У деяких версіях - як це пропонується в коментарях - виняток може бути різним.

При цьому розчин нижче трохи змінений

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

Оригінальний відповідь

Хоча відповіли добре, є досить проста реалізація, яка обробляє, якщо додаток не встановлено. Я це роблю так

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

Замініть "applicationId" на пакет, який ви хочете відкрити, наприклад com.google.maps тощо.


У PackageManager.getLaunchIntentForPackage(...)метод повертає нульове значення , якщо ім'я пакета не розпізнається. Це не кидає PackageManager.NameNotFoundException. Дивіться тут .
Аділ

Я просто спробував startActivity(null)на емуляторі Android 10, і він кидає а, NullPointerExceptionа не PackageManager.NameNotFoundException.
Аділ Хуссейн

У моїй примітці 7 це працює саме так, як і задумано.
mayank1513

Яка цільова поведінка startActivity(Intent intent)методу, коли йому дано нуль Intentі що змушує вас це сказати? Андроїда розробників документації тільки стверджує , що вона буде кидатися ActivityNotFoundException.
Аділ Хуссейн

Привіт @Adil можете ви допомогти мені з цим питанням - 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);

        }

    }

чи існує обмеження символів для методу uri.parse?
API

7

Якщо ви хочете відкрити конкретну діяльність іншої програми, ми можемо скористатися цим.

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

Якщо вам потрібна інша програма, замість того, щоб показувати Toast, ви можете показати діалогове вікно. За допомогою діалогового вікна ви можете підвести користувача до Play-Store, щоб завантажити потрібну програму.


com.android.settings.fuelgauge.PowerUsageSummaryце лише псевдонім діяльності com.android.settings.Settings$PowerUsageSummaryActivity, і його було видалено в Android Pie , тому я підсумував редагування, щоб відповісти на цю відповідь Пиріг. Зауважте, що він також сумісний із старішою версією, див. Прихильність AOSP 10 листопада 2011 року af9252849fd94c1f2859c56a4010900ea38a607e тощо
вихідні

3

Якщо ви знаєте дані та дії, на які реагує встановлений пакет, ви просто повинні додати цю інформацію до свого примірника, перш ніж запускати їх.

Якщо у вас є доступ до AndroidManifest іншого додатка, ви можете побачити всю необхідну інформацію там.


1
Дякую за відповідь. Так, у мене є AndroidManifest іншого додатка. Я зараз намагаюся зробити такий код: Намір наміру = новий Намір (Intent.ACTION_MAIN); intent.setComponent (новий ComponentName ("com.package", ". MainActivity")); startActivity (наміри); але таким чином це не працює. Чи можете ви дати мені більш точне посилання, як це зробити?
Бастіан

1
Додаток виходить з ладу в рядку "startActivity ...": додаток несподівано зупинився. Заклики спробуйте ще раз. Де я можу побачити помилку в LogCat?
Бастіан

5
Я виявив помилку: під час встановлення компонента, повністю кваліфіковане ім'я класу замість просто класу має бути названо: intent.setComponent (новий ComponentName ("com.package", "com.package.MainActivity")) замість наміру .setComponent (new ComponentName ("com.package", ". MainActivity"))
Бастіан

1
Приємно знати ... Ви можете знайти LogCat на затемненні: Вікно> Показати перегляд> Інше, Android> Logcat
WarrenFaith

@WarrenFaith Мені потрібна підтримка з stackoverflow.com/questions/52335402/… Будь ласка, допоможіть.
користувач158

2

Кроки для запуску нової діяльності наступним чином:

1.Отримайте намір пакету

2.Якщо наміром є нульовий переспрямований користувач до магазину

3.Якщо намір не є нульовою відкритою діяльністю

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

Запустити діяльність програми можна за допомогою Intent.setClassName згідно з документами.

Приклад:

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)

Щоб відкрити його поза поточним додатком, додайте цей прапор перед початком наміру.

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

Пов'язаний відповідь тут


pls, як писати на C ++.
GeneCode

1
@GeneCode stackoverflow.com/a/22436147/8608146 може допомогти я ніколи не працював з C ++ ЛІЕСА в андроїд раніше.
Фані Рітвій

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.