una studio personalizar para nombre iconos icono icon descargar como changer cambiar app aplicacion android android-intent

android - studio - icon changer



Filtrado personalizado del selector de intenciones basado en el nombre del paquete de Android instalado (6)

Aquí hay una solución que armé. Lo uso para tener diferentes datos de intención para cada selección en el selector, pero también puede eliminar fácilmente un intento de la lista. Espero que esto ayude:

List<Intent> targetedShareIntents = new ArrayList<Intent>(); Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND); shareIntent.setType("text/plain"); List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(shareIntent, 0); if (!resInfo.isEmpty()) { for (ResolveInfo resolveInfo : resInfo) { String packageName = resolveInfo.activityInfo.packageName; Intent targetedShareIntent = new Intent(android.content.Intent.ACTION_SEND); targetedShareIntent.setType("text/plain"); targetedShareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "subject to be shared"); if (TextUtils.equals(packageName, "com.facebook.katana")) { targetedShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "http://link-to-be-shared.com"); } else { targetedShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "text message to shared"); } targetedShareIntent.setPackage(packageName); targetedShareIntents.add(targetedShareIntent); } Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select app to share"); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()])); startActivity(chooserIntent); }

EDITAR

Mientras uso este método, obtengo nombres de algunas aplicaciones como sistema Android. Si alguien obtiene este error, por favor agregue las siguientes líneas antes de targetedShareIntents.add(targetedShareIntent);

targetedShareIntent.setClassName( resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);

fuente: intención de compartir Android Twitter: ¿Cómo compartir solo por Tweet o Mensaje directo?

Me gustaría aprovechar el selector de intenciones incorporado para mostrar una lista filtrada personalizada de aplicaciones para que el usuario pueda seleccionarlas e iniciarlas.

Sé cómo obtener una lista de paquetes instalados:

final Intent myIntent = new Intent(android.content.Intent.ACTION_MAIN); List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(myIntent, 0);

En este punto, quiero filtrar la lista en función de una cadena específica (o variación de cadenas) contenida dentro del nombre del paquete, que también puedo descifrar cómo hacerlo.

Pero aquí es donde me quedo atascado. Hasta donde yo sé, Intent.createChooser() toma solo un único objetivo como parámetro. Esperaba que hubiera una sobrecarga que tomara una lista de intenciones basada en nombres de paquetes y clases o algo así. Pero no veo nada como eso. ¿Extrañé eso en alguna parte?

Entonces, la pregunta es, ¿es posible hacer esto con un selector incorporado, o tengo que construir el mío con AlertDialog Builder? Espero evitar lo posterior.

Gracias por adelantado.


El único parámetro adicional para el selector es Intent.EXTRA_INITIAL_INTENTS . Su descripción es:

A Parcelable [] de Intent o LabeledIntent establece objetos con putExtra (String, Parcelable []) de actividades adicionales para colocarlos al principio de la lista de opciones, cuando se muestran al usuario con ACTION_CHOOSER.

No he encontrado ninguna forma en las fuentes de Android para excluir otras actividades de la lista, por lo que parece que no hay forma de hacer lo que desea hacer con el selector.

EDITAR : Eso es realmente fácil de descubrir. Solo revisa el código fuente de ChooserActivity y ResolverActivity . Estas clases son bastante pequeñas.


Esta solución se basa en esta publicación https://rogerkeays.com/how-to-remove-the-facebook-android-sharing-intent

// get available share intents final String packageToBeFiltered = "com.example.com" List<Intent> targets = new ArrayList<Intent>(); Intent template = new Intent(Intent.ACTION_SEND); template.setType("text/plain"); List<ResolveInfo> candidates = this.getPackageManager().queryIntentActivities(template, 0); // filter package here for (ResolveInfo candidate : candidates) { String packageName = candidate.activityInfo.packageName; if (!packageName.equals(packageToBeFiltered)) { Intent target = new Intent(android.content.Intent.ACTION_SEND); target.setType("text/plain"); target.putExtra(Intent.EXTRA_TEXT, "Text to share")); target.setPackage(packageName); targets.add(target); } } if (!targets.isEmpty()) { Intent chooser = Intent.createChooser(targets.get(0), "Share dialog title goes here")); chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targets.toArray(new Parcelable[]{})); startActivity(chooser); }


Hice una pequeña modificación para tener una lista de las aplicaciones con las que desea compartir el nombre. Es casi lo que ya has publicado, pero agregando las aplicaciones para compartir por nombre

String[] nameOfAppsToShareWith = new String[] { "facebook", "twitter", "gmail" }; String[] blacklist = new String[]{"com.any.package", "net.other.package"}; // your share intent Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, "some text"); intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "a subject"); // ... anything else you want to add invoke custom chooser startActivity(generateCustomChooserIntent(intent, blacklist)); private Intent generateCustomChooserIntent(Intent prototype, String[] forbiddenChoices) { List<Intent> targetedShareIntents = new ArrayList<Intent>(); List<HashMap<String, String>> intentMetaInfo = new ArrayList<HashMap<String, String>>(); Intent chooserIntent; Intent dummy = new Intent(prototype.getAction()); dummy.setType(prototype.getType()); List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(dummy,0); if (!resInfo.isEmpty()) { for (ResolveInfo resolveInfo : resInfo) { if (resolveInfo.activityInfo == null || Arrays.asList(forbiddenChoices).contains( resolveInfo.activityInfo.packageName)) continue; //Get all the posible sharers HashMap<String, String> info = new HashMap<String, String>(); info.put("packageName", resolveInfo.activityInfo.packageName); info.put("className", resolveInfo.activityInfo.name); String appName = String.valueOf(resolveInfo.activityInfo .loadLabel(getPackageManager())); info.put("simpleName", appName); //Add only what we want if (Arrays.asList(nameOfAppsToShareWith).contains( appName.toLowerCase())) { intentMetaInfo.add(info); } } if (!intentMetaInfo.isEmpty()) { // sorting for nice readability Collections.sort(intentMetaInfo, new Comparator<HashMap<String, String>>() { @Override public int compare( HashMap<String, String> map, HashMap<String, String> map2) { return map.get("simpleName").compareTo( map2.get("simpleName")); } }); // create the custom intent list for (HashMap<String, String> metaInfo : intentMetaInfo) { Intent targetedShareIntent = (Intent) prototype.clone(); targetedShareIntent.setPackage(metaInfo.get("packageName")); targetedShareIntent.setClassName( metaInfo.get("packageName"), metaInfo.get("className")); targetedShareIntents.add(targetedShareIntent); } String shareVia = getString(R.string.offer_share_via); String shareTitle = shareVia.substring(0, 1).toUpperCase() + shareVia.substring(1); chooserIntent = Intent.createChooser(targetedShareIntents .remove(targetedShareIntents.size() - 1), shareTitle); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[] {})); return chooserIntent; } } return Intent.createChooser(prototype, getString(R.string.offer_share_via)); }

Es casi la misma solución que Makibo publicó pero con un pequeño complemento para hacer una forma fácil de elegir las aplicaciones con las que quieres compartir simplemente agregando el nombre para que no tengas ningún problema en caso de que cambien el nombre del paquete o algo así esta. Siempre y cuando no cambien el nombre.


Intentaba hacer lo mismo pero con ShareActionProvider. El método en la publicación de gumbercules no funcionó bien con ShareActionProvider, así que copié y modifiqué las clases relacionadas con ShareActionProvider para permitir el filtrado personalizado de las sugerencias de ShareActionProvider.

El único cambio es en el método ActivityChooserModel.loadActivitiesIfNeeded (). En mi caso, quería filtrar el paquete de YouTube.

public static final String YOUTUBE_PACKAGE = "com.google.android.youtube"; private boolean loadActivitiesIfNeeded() { if (mReloadActivities && mIntent != null) { mReloadActivities = false; mActivities.clear(); List<ResolveInfo> resolveInfos = mContext.getPackageManager() .queryIntentActivities(mIntent, 0); final int resolveInfoCount = resolveInfos.size(); for (int i = 0; i < resolveInfoCount; i++) { ResolveInfo resolveInfo = resolveInfos.get(i); // Filter out the YouTube package from the suggestions list if (!resolveInfo.activityInfo.packageName.equals(YOUTUBE_PACKAGE)) { mActivities.add(new ActivityResolveInfo(resolveInfo)); } } return true; } return false; }

Código en https://github.com/danghiskhan/FilteredShareActionProvider


Mi implementación del selector abierto personalizado.

caracteristicas:

  • las aplicaciones se ordenan en orden alfabético
  • manejo de la aplicación predeterminada definida por el usuario
  • no manejando ningún caso de aplicaciones
  • filtrándose

public static Intent createOpenFileIntent(Context context, String pathToFile) { File file = new File(pathToFile); String extension = extensionFromName(file.getName()); String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); if (mimeType == null) { //If android doesn''t know extension we can check our own list. mimeType = KNOWN_MIME_TYPES.get(DataViewHelper.extensionFromName(file.getName())); } Intent openIntent = new Intent(); openIntent.setAction(android.content.Intent.ACTION_VIEW); openIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); openIntent.setDataAndType(Uri.fromFile(file), mimeType); // 1. Check if there is a default app opener for this type of content. final PackageManager packageManager = context.getPackageManager(); ResolveInfo defaultAppInfo = packageManager.resolveActivity(openIntent, PackageManager.MATCH_DEFAULT_ONLY); if (!defaultAppInfo.activityInfo.name.endsWith("ResolverActivity")) { return openIntent; } // 2. Retrieve all apps for our intent. If there are no apps - return usual already created intent. List<Intent> targetedOpenIntents = new ArrayList<Intent>(); List<ResolveInfo> appInfoList = packageManager.queryIntentActivities(openIntent, PackageManager.MATCH_DEFAULT_ONLY); if (appInfoList.isEmpty()) { return openIntent; } // 3. Sort in alphabetical order, filter itself and create intent with the rest of the apps. Collections.sort(appInfoList, new Comparator<ResolveInfo>() { @Override public int compare(ResolveInfo first, ResolveInfo second) { String firstName = packageManager.getApplicationLabel(first.activityInfo.applicationInfo).toString(); String secondName = packageManager.getApplicationLabel(second.activityInfo.applicationInfo).toString(); return firstName.compareToIgnoreCase(secondName); } }); for (ResolveInfo appInfo : appInfoList) { String packageName = appInfo.activityInfo.packageName; if (packageName.equals(context.getPackageName())) { continue; } Intent targetedOpenIntent = new Intent(android.content.Intent.ACTION_VIEW) .setDataAndType(Uri.fromFile(file), mimeType) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .setPackage(packageName); targetedOpenIntents.add(targetedOpenIntent); } Intent chooserIntent = Intent.createChooser(targetedOpenIntents.remove(targetedOpenIntents.size() - 1), context.getString(R.string.context_menu_open_in)) .putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedOpenIntents.toArray(new Parcelable[] {})); return chooserIntent; } public static String extensionFromName(String fileName) { int dotPosition = fileName.lastIndexOf(''.''); // If extension not present or empty if (dotPosition == -1 || dotPosition == fileName.length() - 1) { return ""; } else { return fileName.substring(dotPosition + 1).toLowerCase(Locale.getDefault()); } }