Відкрийте іншу програму від власної (наміри)


136

Я знаю, як оновити власні програми, і я знаю, як відкривати програми за допомогою попередньо визначеного Uri (наприклад, для sms чи електронної пошти)

Мені потрібно знати, як я можу створити Намір відкрити MyTracks або будь-яку іншу програму, яку я не знаю, які наміри вони слухають.

Я отримав цю інформацію від DDMS, але я не мав успіху перетворити цю інтенцію, яку я можу використовувати. Це береться під час відкриття MyTracks вручну.

Спасибі за вашу допомогу

05-06 11:22:24.945: INFO/ActivityManager(76): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.google.android.maps.mytracks/com.google.android.apps.mytracks.MyTracks bnds=[243,338][317,417] }
05-06 11:22:25.005: INFO/ActivityManager(76): Start proc com.google.android.maps.mytracks for activity com.google.android.maps.mytracks/com.google.android.apps.mytracks.MyTracks: pid=1176 uid=10063 gids={3003, 1015}
05-06 11:22:26.995: INFO/ActivityManager(76): Displayed activity com.google.android.maps.mytracks/com.google.android.apps.mytracks.MyTracks: 1996 ms (total 1996 ms)

Відповіді:


141

По-перше, поняття «додаток» в Android трохи розширене.

Додаток - технічно процес - може мати декілька видів діяльності, послуг, постачальників вмісту та / або слухачів трансляції. Якщо принаймні одна з них запущена, програма запущена і працює (процес).

Отже, ви повинні визначити, як ви хочете "запустити додаток".

Гаразд ... ось що можна спробувати:

  1. Створіть наміри за допомогою action=MAINтаcategory=LAUNCHER
  2. Отримайте PackageManagerз поточного контексту, використовуючиcontext.getPackageManager
  3. packageManager.queryIntentActivity(<intent>, 0)де намір є category=LAUNCHER, action=MAINабо packageManager.resolveActivity(<intent>, 0)отримати першу діяльність з основною / пусковий
  4. Отримайте те, що ActivityInfoвас цікавить
  5. З ActivityInfo, дістаньте packageNameіname
  6. І, нарешті, створити іншу мету з з category=LAUNCHER, action=MAIN, componentName = new ComponentName(packageName, name)іsetFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
  7. Нарешті, context.startActivity(newIntent)

Що робити, якщо я хотів відкрити три окремі програми?
Si8

7
Спільноти вікі відповідь нижче , тим краще, якщо ви знаєте ім'я пакета stackoverflow.com/a/7596063/379115
Martin Белчер - AtWrk

Як можна передавати дані між додатком, що викликає, та запущеним додатком? Я знайшов "Intent.putExtra ()", але я не знаю, як отримати додаткові дані в запущеному додатку.
Брам

onCreate=> Bundle extras = getIntent().getExtras()=> if(extras != null) { extras.getString("blah") }і т. д.
Гаурав Вайш

2
getPackageManager().getLaunchIntentForPackage()вже робить все для вас github.com/android/platform_frameworks_base/blob/master/core/…
грудня

231

Я працюю так,

/** Open another app.
 * @param context current Context, like Activity, App, or Service
 * @param packageName the full package name of the app to open
 * @return true if likely successful, false if unsuccessful
 */
public static boolean openApp(Context context, String packageName) {
    PackageManager manager = context.getPackageManager();
    try {
        Intent i = manager.getLaunchIntentForPackage(packageName);
        if (i == null) {
            return false;
            //throw new ActivityNotFoundException();
        }
        i.addCategory(Intent.CATEGORY_LAUNCHER);
        context.startActivity(i);
        return true;
    } catch (ActivityNotFoundException e) {
        return false;
    }
}

Приклад використання:

openApp(this, "com.google.android.maps.mytracks");

Сподіваюся, це комусь допоможе.


5
тому що getLaunchIntentForPackage ("назва пакета програми") може спричинити виняток.
xtr

Це чудова відповідь, просто спіймати виняток і робити все, що потрібно, сповістити користувача тощо
IT-Dan

5
Не бути стикером, але немає причин виділяти новий Намір у першому рядку, якщо ви використовуєте результат getLaunchIntentForPackageдзвінка.
Кріс Лейсі

2
getLaunchIntentForPackage()вже додає категорію, див. джерело: github.com/android/platform_frameworks_base/blob/master/core/…
квітня

96
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.setComponent(ComponentName.unflattenFromString("com.google.android.maps.mytracks/com.google.android.apps.mytracks.MyTracks"));
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    startActivity(intent);

Редагувати:

як запропоновано в коментарях, додайте попередньо один рядок startActivity(intent);

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

18
але для цього потрібно знати назву діяльності
njzk2

Я спробував це і отримав помилку, рекомендуючи використовувати прапор FLAG_ACTIVITY_NEW_TASK. Я додав цей рядок перед запуском StartActivity і він працював: intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
david-hoze

1
@ njzk2 знайти назву пакета для чогось у Google Play дуже просто; це прямо там, в URL-адресі. Наприклад: play.google.com/store/apps/…
Да-Джин

@iceybobby Так, назву пакета легко знайти, але як ви знайдете назву класу для запуску?
фрікхед

@phreakhead Ви маєте рацію. Я думаю, що я використав рішення у цій відповіді: stackoverflow.com/a/8944286/1224186, тому ім'я діяльності не потрібно, і тому я вважаю, що моя відповідь на njzk2 тут не корисна.
Да-Джин

39

Якщо у вас вже є ім'я пакета, який ви хочете активувати, ви можете використовувати такий код, який є трохи більш загальним:

PackageManager pm = context.getPackageManager();
Intent appStartIntent = pm.getLaunchIntentForPackage(appPackageName);
if (null != appStartIntent)
{
    context.startActivity(appStartIntent);
}

Я виявив, що він працює краще для тих випадків, коли основна діяльність не була знайдена звичайним методом початку ОСНОВНОЇ діяльності.


Найкраща відповідь для мене :-) корисно для мене. Дякую
Jalpesh Khakhi

Це ідеально для мене. Дуже дякую Музикант:)
Алекс

13

Це код моєї бази рішення щодо рішення MasterGaurav:

private void  launchComponent(String packageName, String name){
    Intent launch_intent = new Intent("android.intent.action.MAIN");
    launch_intent.addCategory("android.intent.category.LAUNCHER");
    launch_intent.setComponent(new ComponentName(packageName, name));
    launch_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    activity.startActivity(launch_intent);
}

public void startApplication(String application_name){
    try{
        Intent intent = new Intent("android.intent.action.MAIN");
        intent.addCategory("android.intent.category.LAUNCHER");

        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        List<ResolveInfo> resolveinfo_list = activity.getPackageManager().queryIntentActivities(intent, 0);

        for(ResolveInfo info:resolveinfo_list){
            if(info.activityInfo.packageName.equalsIgnoreCase(application_name)){
                launchComponent(info.activityInfo.packageName, info.activityInfo.name);
                break;
            }
        }
    }
    catch (ActivityNotFoundException e) {
        Toast.makeText(activity.getApplicationContext(), "There was a problem loading the application: "+application_name,Toast.LENGTH_SHORT).show();
    }
}

10

Використовуючи рішення від inversus, я розширив фрагмент з функцією, яка буде викликана, коли потрібна програма не встановлена ​​на даний момент. Так це працює так: Запустіть додаток за назвою пакета. Якщо його не знайдено, відкрийте Android ринок - Google грає для цього пакету .

public void startApplication(String packageName)
{
    try
    {
        Intent intent = new Intent("android.intent.action.MAIN");
        intent.addCategory("android.intent.category.LAUNCHER");

        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        List<ResolveInfo> resolveInfoList = getPackageManager().queryIntentActivities(intent, 0);

        for(ResolveInfo info : resolveInfoList)
            if(info.activityInfo.packageName.equalsIgnoreCase(packageName))
            {
                launchComponent(info.activityInfo.packageName, info.activityInfo.name);
                return;
            }

        // No match, so application is not installed
        showInMarket(packageName);
    }
    catch (Exception e) 
    {
        showInMarket(packageName);
    }
}

private void launchComponent(String packageName, String name)
{
    Intent intent = new Intent("android.intent.action.MAIN");
    intent.addCategory("android.intent.category.LAUNCHER");
    intent.setComponent(new ComponentName(packageName, name));
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    startActivity(intent);
}

private void showInMarket(String packageName)
{
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageName));
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}

І використовується так:

startApplication("org.teepee.bazant");

6

Використовуй це :

    PackageManager pm = getPackageManager();
    Intent intent = pm.getLaunchIntentForPackage("com.package.name");
    startActivity(intent);

Маєте якусь ідею? відкрийте test.apk замість встановленого в магазині пристроїв всередині існуючої програми. підказки при натисканні кнопки на ланч test.apk програми, які зберігалися в існуючому проекті. Дякую заздалегідь.
Селім Раза

6

Відкрийте програму, якщо вона існує, або відкрийте програму Play Store, щоб встановити її:

private void open() {
    openApplication(getActivity(), "com.app.package.here");
}

public void openApplication(Context context, String packageN) {
    Intent i = context.getPackageManager().getLaunchIntentForPackage(packageN);
    if (i != null) {
        i.addCategory(Intent.CATEGORY_LAUNCHER);
        context.startActivity(i);
    } else {
        try {
            context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageN)));
        }
        catch (android.content.ActivityNotFoundException anfe) {
            context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + packageN)));
        }
    }
}

має бути якщо (i! = null)
vallllll

4

Щоб запустити іншу активність у програмі з моєї програми. Для мене це добре працює.

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

Intent intent = new Intent();
intent.setClassName("com.xyz.myapplication", "com.xyz.myapplication.SplashScreenActivity");
startActivity(intent);

Будь ласка, не пишіть декілька відповідей, які майже однакові на одне і те ж питання. Скористайтеся посиланням "редагувати" під відповіддю та змініть оригінал.
AdrianHHH

3

// Це працює на Android Lollipop 5.0.2

public static boolean launchApp(Context context, String packageName) {

    final PackageManager manager = context.getPackageManager();
    final Intent appLauncherIntent = new Intent(Intent.ACTION_MAIN);
    appLauncherIntent.addCategory(Intent.CATEGORY_LAUNCHER);

    List<ResolveInfo> resolveInfos = manager.queryIntentActivities(appLauncherIntent, 0);
    if ((null != resolveInfos) && (!resolveInfos.isEmpty())) {
        for (ResolveInfo rInfo : resolveInfos) {
            String className = rInfo.activityInfo.name.trim();
            String targetPackageName = rInfo.activityInfo.packageName.trim();
            Log.d("AppsLauncher", "Class Name = " + className + " Target Package Name = " + targetPackageName + " Package Name = " + packageName);
            if (packageName.trim().equals(targetPackageName)) {
                Intent intent = new Intent();
                intent.setClassName(targetPackageName, className);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
                Log.d("AppsLauncher", "Launching Package '" + packageName + "' with Activity '" + className + "'");
                return true;
            }
        }
    }
    return false;
}

2

Оскільки програмам заборонено змінювати багато налаштувань телефону, ви можете відкрити налаштування, як і іншу програму.

Подивіться на вихід LogCat після того, як ви фактично змінили налаштування вручну:

INFO/ActivityManager(1306): Starting activity: Intent { act=android.intent.action.MAIN cmp=com.android.settings/.DevelopmentSettings } from pid 1924

Потім використовуйте це, щоб відобразити сторінку налаштувань у вашому додатку:

String SettingsPage = "com.android.settings/.DevelopmentSettings";

try
{
Intent intent = new Intent(Intent.ACTION_MAIN);             
intent.setComponent(ComponentName.unflattenFromString(SettingsPage));             
intent.addCategory(Intent.CATEGORY_LAUNCHER );             
startActivity(intent); 
}
catch (ActivityNotFoundException e)
{
 log it
}

2

Для рівня API 3+ і більше, ніж один рядок коду:

Intent intent = context.getPackageManager().getLaunchIntentForPackage("name.of.package");

Повернення наміру запуску CATEGORY_INFO (програми без активності запуску, наприклад, шпалери, часто використовують це для надання деякої інформації про додаток) і, якщо такої немає, повертає CATEGORY_LAUNCH пакета, якщо він існує.


2

Якщо ви намагаєтесь запустити СЕРВІС, а не активність, це працювало для мене:

Intent intent = new Intent();
intent.setClassName("com.example.otherapplication", "com.example.otherapplication.ServiceName");
context.startService(intent);

Якщо ви використовуєте метод intent.setComponent (...), як зазначено в інших відповідях, ви можете отримати попередження "Неявні наміри за допомогою startService are not safe".


2

Крім того, ви також можете відкрити намір зі свого додатка в іншому додатку за допомогою:

Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

де uriє посилання на інший додаток


2

Використовуйте наступне:

String packagename = "com.example.app";
startActivity(getPackageManager().getLaunchIntentForPackage(packagename));

2

Запустіть програму з іншої програми на Android

  Intent launchIntent = getActivity.getPackageManager().getLaunchIntentForPackage("com.ionicframework.uengage");
        startActivity(launchIntent);

2

Якщо ви хочете відкрити іншу програму, але вона не встановлена, ви можете надіслати її в Google App Store для завантаження

  1. Спочатку створіть, наприклад, метод openOtherApp

    public static boolean openOtherApp(Context context, String packageName) {
        PackageManager manager = context.getPackageManager();
         try {
            Intent intent = manager.getLaunchIntentForPackage(packageName);
            if (intent == null) {
                //the app is not installed
                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 (ActivityNotFoundException e) {
                    //throw new ActivityNotFoundException();
                    return false;
                }
    
             }
             intent.addCategory(Intent.CATEGORY_LAUNCHER);
             context.startActivity(intent);
             return true;
        } catch (ActivityNotFoundException e) {
            return false;
        }
    
    }

2.- Використання

openOtherApp(getApplicationContext(), "com.packageappname");

0

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

    String  packageN = "aman4india.com.pincodedirectory";

            Intent i = getPackageManager().getLaunchIntentForPackage(packageN);
            if (i != null) {
                i.addCategory(Intent.CATEGORY_LAUNCHER);
                startActivity(i);
            } else {
                try {
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageN)));
                }
                catch (android.content.ActivityNotFoundException anfe) {
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + packageN)));
                }
            }


-3
Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setComponent(new ComponentName("package_name","package_name.class_name"));
        intent.putExtra("grace", "Hi");
        startActivity(intent);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.