Как получить список установленных приложений для Android и выбрать одно для запуска

326

В начале этой недели я задавал аналогичный вопрос, но до сих пор не понимаю, как получить список всех установленных приложений, а затем выбрать одно для запуска.

Я пробовал:

Intent intent = new Intent(ACTION_MAIN);
intent.addCategory(CATEGORY_LAUNCHER);

и это только показывает приложение, которое предустановлено или может запускать ACTION_MAINтип Intent.

Я также знаю, что могу использовать PackageManagerдля получения всех установленных приложений, но как мне использовать это для запуска определенного приложения?

2Real
источник
Как вы можете получить только информацию о выбранном приложении в списке?
Pedrum

Ответы:

277

Ниже приведен код для получения списка действий / приложений, установленных на Android:

Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> pkgAppsList = context.getPackageManager().queryIntentActivities( mainIntent, 0);

Вы получите все необходимые данные ResolveInfoдля запуска приложения. Вы можете проверить ResolveInfoJavadoc здесь .

Каран
источник
3
Как я могу начать один из них? Я получил информацию ActivityInfo внутри ResolveInfo, но мне не удается запустить его.
Spidey
1
Неважно, нашел это. Я должен создать новое намерение, используя полное имя класса (пакет + класс).
Spidey
Как вы можете получить только информацию о выбранном приложении в списке?
Pedrum
1
Я хотел понять политику магазина android / play относительно того, что мое приложение читает и хранит список всех приложений и, возможно, связывается с сервером. Есть ли какие-либо рекомендации?
dowjones123
1
@ dowjones123 Вы случайно не нашли рекомендации по этому поводу?
RmK
415

Вот более чистый способ использования PackageManager

final PackageManager pm = getPackageManager();
//get a list of installed apps.
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);

for (ApplicationInfo packageInfo : packages) {
    Log.d(TAG, "Installed package :" + packageInfo.packageName);
    Log.d(TAG, "Source dir : " + packageInfo.sourceDir);
    Log.d(TAG, "Launch Activity :" + pm.getLaunchIntentForPackage(packageInfo.packageName)); 
}
// the getLaunchIntentForPackage returns an intent that you can use with startActivity() 

Более подробная информация здесь http://qtcstation.com/2011/02/how-to-launch-another-app-from-your-app/

Нельсон Рамирес
источник
Работает гр8. Но когда попробовал это на Android 4.0.3, ничего не печатается !! Любая подсказка ??
Саураб Верма
Убедитесь, что вы не отфильтровываете сообщения журнала отладки.
QED
Этот код работает, однако, есть ли у вас какие-либо идеи о том, как поместить эти списки приложений в ListView?
androidBoomer
@androidBoomer я делаю то же самое. Прочитайте это здесь - vogella.com/tutorials/AndroidListView/article.html
Дэвид Т.
@DavidT. Я уже понял это. Сейчас я работаю над тем, как получить доступ к этим установленным приложениям, чтобы создать ярлык внутри моего приложения. Это возможно?
androidBoomer
61

Еще один способ фильтрации системных приложений (работает на примере king9981):

/**
 * Return whether the given PackageInfo represents a system package or not.
 * User-installed packages (Market or otherwise) should not be denoted as
 * system packages.
 * 
 * @param pkgInfo
 * @return
 */
private boolean isSystemPackage(PackageInfo pkgInfo) {
    return ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
}
Кеннет Эванс
источник
4
Это лучший ответ для фильтрации системных приложений.
Бьорн
5
Но я фильтрую приложения, такие как настройки, карты или ..., как их перечислить
Ata
7
Часть «? True: false» в вашем операторе возврата избыточна
k2col
упростить возврат ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)! = 0);
Бхавеш Рангани
как отфильтровать платные приложения?
Пемба Таманг
55

Вот хороший пример:

class PInfo {
    private String appname = "";
    private String pname = "";
    private String versionName = "";
    private int versionCode = 0;
    private Drawable icon;
    private void prettyPrint() {
        Log.v(appname + "\t" + pname + "\t" + versionName + "\t" + versionCode);
    }
}

private ArrayList<PInfo> getPackages() {
    ArrayList<PInfo> apps = getInstalledApps(false); /* false = no system packages */
    final int max = apps.size();
    for (int i=0; i<max; i++) {
        apps.get(i).prettyPrint();
    }
    return apps;
}

private ArrayList<PInfo> getInstalledApps(boolean getSysPackages) {
    ArrayList<PInfo> res = new ArrayList<PInfo>();        
    List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);
    for(int i=0;i<packs.size();i++) {
        PackageInfo p = packs.get(i);
        if ((!getSysPackages) && (p.versionName == null)) {
            continue ;
        }
        PInfo newInfo = new PInfo();
        newInfo.appname = p.applicationInfo.loadLabel(getPackageManager()).toString();
        newInfo.pname = p.packageName;
        newInfo.versionName = p.versionName;
        newInfo.versionCode = p.versionCode;
        newInfo.icon = p.applicationInfo.loadIcon(getPackageManager());
        res.add(newInfo);
    }
    return res; 
}
king9981
источник
1
Как вы выполняете один из тех, если вам нужно? Я имею в виду, вы можете получить намерение?
Тон
Отлично. Спасибо за Ваш ответ. Я использовал ваш ответ в своем заявлении, и у меня небольшая проблема с размером значка. большинство из них нормальные, а некоторые очень большие или маленькие. Как я могу это исправить. Есть ли у вас какие-либо идеи? спасибо
Мейсам Валуян
37

Получение списка установленных несистемных приложений

public static void installedApps()
{
    List<PackageInfo> packList = getPackageManager().getInstalledPackages(0);
    for (int i=0; i < packList.size(); i++)
    {
        PackageInfo packInfo = packList.get(i);
        if (  (packInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
        {
            String appName = packInfo.applicationInfo.loadLabel(getPackageManager()).toString();
            Log.e("App № " + Integer.toString(i), appName);
        }
    }
}
XXX
источник
19

Чтобы отфильтровать приложения, основанные на sytem:

private boolean isSystemPackage(ResolveInfo ri) {
    return (ri.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
SamCsharpAs3
источник
18

Чтобы получить все установленные приложения, вы можете использовать диспетчер пакетов.

    List<PackageInfo> apps = getPackageManager().getInstalledPackages(0);

Для запуска вы можете использовать имя пакета

Intent launchApp = getPackageManager().getLaunchIntentForPackage(“package name”)
startActivity(launchApp);

Для более подробной информации вы можете прочитать этот блог http://codebucket.co.in/android-get-list-of-all-installed-apps/

Эрвинд
источник
Это ближе к делу. Мы можем установить правильную проверку, выяснив наше необходимое приложение.
Номан
13

Вы можете найти список установленных приложений на Android-устройстве, используя следующий код: «packageInfo» содержит информацию об установленных приложениях на устройстве. мы можем получить Intent для приложения, установленного из объекта packageinfo и, используя startactivity (намерение), можем запустить приложение. это зависит от вас, как вы организуете пользовательский интерфейс Listview или Gridview. поэтому при щелчке по событию вы можете получить объект намерения и запустить намерение действия.

final PackageManager pm = getPackageManager();

List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);


for (ApplicationInfo packageInfo : packages) 

{
 if(pm.getLaunchIntentForPackage(packageInfo.packageName)!= null &&   

                   !pm.getLaunchIntentForPackage(packageInfo.packageName).equals(""))


{

    System.out.println("Package Name :" + packageInfo.packageName);

    System.out.println("Launch Intent For Package :"   +  
                  pm.getLaunchIntentForPackage(packageInfo.packageName));

    System.out.println("Application Label :"   + pm.getApplicationLabel(packageInfo));

    System.out.println("Application Label :"   + 
                           pm.getApplicationIcon(packageInfo.packageName).toString());

    System.out.println("i : "+i);

    /*if(i==2)

    {
         startActivity(pm.getLaunchIntentForPackage(packageInfo.packageName));

     break;

    }*/

    i++;

}
}
Прашант Агравал
источник
13

У меня было требование отфильтровать системные приложения, которые пользователь на самом деле не использует (например, «com.qualcomm.service», «update services» и т. Д.). В конечном итоге я добавил еще одно условие для фильтрации списка приложений. Я только что проверил, имеет ли приложение «намерение запуска».

Итак, результирующий код выглядит так ...

PackageManager pm = getPackageManager();
        List<ApplicationInfo> apps = pm.getInstalledApplications(PackageManager.GET_GIDS);

        for (ApplicationInfo app : apps) {
            if(pm.getLaunchIntentForPackage(app.packageName) != null) {
                // apps with launcher intent
                if((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
                    // updated system apps

                } else if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                    // system apps

                } else {
                    // user installed apps

                }
                appsList.add(app);
            }

        }
joecizac
источник
Спасибо. Функция getLaunchIntentForPackage очень полезна для отображения приложений в
ящике
10

Если в одном пакете несколько пусковых установок, в коде есть проблема. Например: на LG Optimus Facebook для LG, MySpace для LG, Twitter для LG содержит одно имя пакета SNS, и если вы используете выше, SNS будет повторяться. После нескольких часов исследований я пришел с кодом ниже. Кажется, работает хорошо.

private List<String> getInstalledComponentList()
            throws NameNotFoundException {
        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        List<ResolveInfo> ril = getPackageManager().queryIntentActivities(mainIntent, 0);
        List<String> componentList = new ArrayList<String>();
        String name = null;

        for (ResolveInfo ri : ril) {
            if (ri.activityInfo != null) {
                Resources res = getPackageManager().getResourcesForApplication(ri.activityInfo.applicationInfo);
                if (ri.activityInfo.labelRes != 0) {
                    name = res.getString(ri.activityInfo.labelRes);
                } else {
                    name = ri.activityInfo.applicationInfo.loadLabel(
                            getPackageManager()).toString();
                }
                componentList.add(name);
            }
        }
        return componentList;
    }
kakopappa
источник
7

@Jas: у меня больше нет этого кода, но я нашел что-то близкое Я сделал это для поиска «компонентов» моего приложения, это просто действия с определенной категорией.

private List<String> getInstalledComponentList() {
    Intent componentSearchIntent = new Intent();
    componentSearchIntent.addCategory(Constants.COMPONENTS_INTENT_CATEGORY);
    componentSearchIntent.setAction(Constants.COMPONENTS_INTENT_ACTION_DEFAULT);
    List<ResolveInfo> ril = getPackageManager().queryIntentActivities(componentSearchIntent, PackageManager.MATCH_DEFAULT_ONLY);
    List<String> componentList = new ArrayList<String>();
    Log.d(LOG_TAG, "Search for installed components found " + ril.size() + " matches.");
    for (ResolveInfo ri : ril) {
        if (ri.activityInfo != null) {
            componentList.add(ri.activityInfo.packageName);// + ri.activityInfo.name);
            Log.d(LOG_TAG, "Found installed: " + componentList.get(componentList.size()-1));
        }
    }
    return componentList;
}

Я прокомментировал ту часть, где он получает название активности, но это довольно просто.

Паучок
источник
6

Чистое решение, успешно фильтрующее системные приложения

Идея этого решения заключается в том, что основная активность каждого системного приложения не имеет собственного значка активности . Этот метод дает мне отличный результат:

 public static Set<PackageInfo> getInstalledApps(Context ctx) {
    final PackageManager packageManager = ctx.getPackageManager();

    final List<PackageInfo> allInstalledPackages = packageManager.getInstalledPackages(PackageManager.GET_META_DATA);
    final Set<PackageInfo> filteredPackages = new HashSet();

    Drawable defaultActivityIcon = packageManager.getDefaultActivityIcon();

    for(PackageInfo each : allInstalledPackages) {
        if(ctx.getPackageName().equals(each.packageName)) {
            continue;  // skip own app
        }

        try {
            // add only apps with application icon
            Intent intentOfStartActivity = packageManager.getLaunchIntentForPackage(each.packageName);
            if(intentOfStartActivity == null)
                continue;

            Drawable applicationIcon = packageManager.getActivityIcon(intentOfStartActivity);
            if(applicationIcon != null && !defaultActivityIcon.equals(applicationIcon)) {
                filteredPackages.add(each);
            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.i("MyTag", "Unknown package name " + each.packageName);
        }
    }

    return filteredPackages;
}
funcoder
источник
3
private static boolean isThisASystemPackage(Context context, PackageInfo  packageInfo ) {
        try {
            PackageInfo sys = context.getPackageManager().getPackageInfo("android", PackageManager.GET_SIGNATURES);
            return (packageInfo != null && packageInfo.signatures != null &&
                    sys.signatures[0].equals(packageInfo.signatures[0]));
        } catch (NameNotFoundException e) {
            return false;
        }
    }
user1546570
источник
2

У меня есть другое решение:

ArrayList<AppInfo> myAppsToUpdate;

    // How to get the system and the user apps.
    public ArrayList<AppInfo> getAppsToUpdate() {

        PackageManager pm = App.getContext().getPackageManager();
        List<ApplicationInfo> installedApps = pm.getInstalledApplications(0);
        myAppsToUpdate = new ArrayList<AppInfo>();
        for (ApplicationInfo aInfo : installedApps) {

            if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                // System apps 
            } else {
                // Users apps
                AppInfo appInfo = new AppInfo();
                appInfo.setAppName(aInfo.loadLabel(pm).toString());
                appInfo.setPackageName(aInfo.packageName);
                appInfo.setLaunchActivity(pm.getLaunchIntentForPackage(aInfo.packageName).toString());
                try {
                    PackageInfo info = pm.getPackageInfo(aInfo.packageName, 0);
                    appInfo.setVersionName(info.versionName.toString());
                    appInfo.setVersionCode("" + info.versionCode);
                    myAppsToUpdate.add(appInfo);
                } catch (NameNotFoundException e) {
                    Log.e("ERROR", "we could not get the user's apps");
                }

            }
        }
        return myAppsToUpdate;
    }
Виктор Руис.
источник
2

Получить все приложения:

    PackageManager pm = getContext().getPackageManager();
    List<ApplicationInfo> apps = pm.getInstalledApplications(0);

Проверьте, установлено ли приложение, затем откройте:

if((app.flags & (ApplicationInfo.FLAG_UPDATED_SYSTEM_APP | ApplicationInfo.FLAG_SYSTEM)) > 0) {
                String app_package = app.packageName;
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(app_package);
context.startActivity(launchIntent);
Чандра Агарвала
источник
0

Вы можете использовать это:

PackageManager pm = getApplicationContext().getPackageManager();
                List<ResolveInfo> activityList = pm.queryIntentActivities(shareIntent, 0);
                for (final ResolveInfo app : activityList) 
                {
                   if ((app.activityInfo.name).contains("facebook")) 
                   {
                     // facebook  
                   }

                   if ((app.activityInfo.name).contains("android.gm")) 
                   {
                     // gmail  
                   }

                   if ((app.activityInfo.name).contains("mms")) 
                   {
                     // android messaging app
                   }

                   if ((app.activityInfo.name).contains("com.android.bluetooth")) 
                   {
                     // android bluetooth  
                   }
                }
Акшай Паливал
источник
0
public static List<ApplicationInfo> getApplications(Context context) {
    return context.getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA);
}
Реза
источник