Как получить список установленных приложений для android и выбрать один для запуска
Я задал аналогичный вопрос на этой неделе, но я все еще не понимаю, как получить список всех установленных приложений, а затем выбрать один для запуска.
Я пробовал:
Intent intent = new Intent(ACTION_MAIN);
intent.addCategory(CATEGORY_LAUNCHER);
и это только показывает приложение, которое предварительно установлено или может запустить тип намерения ACTION_MAIN.
Я также знаю, что могу использовать PackageManager для получения всех установленных приложений, но как я могу использовать это для запуска конкретного приложения?
17 ответов:
Ниже приведен код, чтобы получить список действий / приложений, установленных на Android:
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); List<ResolveInfo> pkgAppsList = context.getPackageManager().queryIntentActivities( mainIntent, 0);вы получите все необходимые данные в
ResolveInfoдля запуска приложения. Вы можете проверитьResolveInfoдокументация здесь.
вот более чистый способ с помощью 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/
другой способ фильтрации в системных приложениях (работает с примером выше):
/** * Return whether the given PackgeInfo 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); }
вот хороший пример:
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; }
получение списка установленных несистемных приложений
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); } } }
для фильтрации по системным приложениям:
private boolean isSystemPackage(ResolveInfo ri) { return (ri.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; }
чтобы получить все установленные приложения, вы можете использовать Диспетчер пакетов..
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/
вы можете найти список установленных приложений в Android устройстве с помощью кода ниже, "packageInfo" содержит информацию об установленных приложениях в устройствах. мы можем повторить намерение для приложения, установленного из объект packageinfo и с помощью startactivity (intent) можно запустить приложение. это зависит от вас, как вы организуете пользовательский интерфейс либо Listview или таблицы. так что на событие щелчка на основе позиции, вы можете повторить намерение цель объекта и начала действия.
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++; } }
Если есть несколько пусковых установок в одном пакете выше код имеет проблему. Например: на 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; }
@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; }Я прокомментировал часть, где он получает имя активности, но это довольно просто.
У меня было требование отфильтровать системные приложения, которые пользователь на самом деле не использует(например. "com.компания Qualcomm.сервис", "службы обновления" и др.). В конечном счете я добавил еще одно условие, чтобы отфильтровать список приложений. Я только что проверил, есть ли у приложения "намерение запуска".
Итак, результирующий код выглядит следующим образом...
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); } }
чистое решение, которое успешно фильтрует системные приложения
идея этого решения заключается в том, что основная деятельность каждого системного приложения не имеет пользовательский значок активности. Этот метод дает мне отличный результат:
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; }
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; } }
получить все приложения:
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);
У меня есть другое решение:
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; }
вы можете использовать это :
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 } }
public static List<ApplicationInfo> getApplications(Context context) { return context.getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA); }
Comments