12

I have used the following codes to exclude facebook app from my app chooser:

 List<Intent> targetedShareIntents = new ArrayList<Intent>();
    Intent intent = new Intent(android.content.Intent.ACTION_SEND);
    intent.setType("image/*");
    List<ResolveInfo> resInfo = getActivity().getPackageManager().queryIntentActivities(intent, 0);
    if (!resInfo.isEmpty()) {
        for (ResolveInfo resolveInfo : resInfo) {
            String packageName = resolveInfo.activityInfo.packageName;
            Intent targetedShareIntent = new Intent(android.content.Intent.ACTION_SEND);
            targetedShareIntent.setType("image/*");
            targetedShareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "tooter.nl");
            if (!TextUtils.equals(packageName, "com.facebook.katana")) {


                targetedShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, st);
                targetedShareIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
                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);
    }

Facebook app was removed when I used the code. But the sad part was, even Twitter app was also removed from the app chooser and other unnecessary apps like "Android system" was listed on the chooser . What should i do ? Is something missing or wrong with this code ?

mrnobody
  • 409
  • 2
  • 8
  • 16

7 Answers7

16

Check my answer below. It will exclude only facebook application from sharing.

 void shareOnOtherSocialMedia() {

    List<Intent> shareIntentsLists = new ArrayList<Intent>();
    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.setType("image/*");
    List<ResolveInfo> resInfos = getPackageManager().queryIntentActivities(shareIntent, 0);
    if (!resInfos.isEmpty()) {
      for (ResolveInfo resInfo : resInfos) {
        String packageName = resInfo.activityInfo.packageName;
        if (!packageName.toLowerCase().contains("facebook")) {
          Intent intent = new Intent();
          intent.setComponent(new ComponentName(packageName, resInfo.activityInfo.name));
          intent.setAction(Intent.ACTION_SEND);
          intent.setType("image/*");
          intent.setPackage(packageName);
          shareIntentsLists.add(intent);
        }
      }
      if (!shareIntentsLists.isEmpty()) {
        Intent chooserIntent = Intent.createChooser(shareIntentsLists.remove(0), "Choose app to share");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, shareIntentsLists.toArray(new Parcelable[]{}));
        startActivity(chooserIntent);
      } else
        Log.e("Error", "No Apps can perform your task");

    }
  }
}

And call the above function wherever you want. Let me know for queries.

Swaminathan V
  • 4,663
  • 2
  • 22
  • 32
6

For Android API 24 and above, you can use this:

val components = arrayOf(ComponentName(applicationContext, YourActivity::class.java))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
   startActivity(Intent.createChooser(intent, null).putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS,components))

For the rest, you can have this solution I wrote about (which allows you to have a condition which to exclude

Here's a more generalized solution, to be able to choose which to exclude for all Android versions:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val targetIntent = Intent(Intent.ACTION_SEND)
        targetIntent.type = "text/plain"
        targetIntent.putExtra(Intent.EXTRA_SUBJECT, "subject")
        targetIntent.putExtra(Intent.EXTRA_TEXT, "text")
        val excludedAppsPackageNames = hashSetOf( "com.pushbullet.android","com.android.bluetooth","com.google.android.apps.docs","com.google.android.gm")
        getIntentChooser(this, targetIntent, "choose!", object : ComponentNameFilter {
            override fun shouldBeFilteredOut(componentName: ComponentName): Boolean = excludedAppsPackageNames.contains(componentName.packageName)
        })?.let { startActivity(it) }
    }

    interface ComponentNameFilter {
        fun shouldBeFilteredOut(componentName: ComponentName): Boolean
    }

    private fun getIntentChooser(context: Context, intent: Intent, chooserTitle: CharSequence? = null, filter: ComponentNameFilter): Intent? {
        val resolveInfos = context.packageManager.queryIntentActivities(intent, 0)
//        Log.d("AppLog", "found apps to handle the intent:")
        val excludedComponentNames = HashSet<ComponentName>()
        resolveInfos.forEach {
            val activityInfo = it.activityInfo
            val componentName = ComponentName(activityInfo.packageName, activityInfo.name)
//            Log.d("AppLog", "componentName:$componentName")
            if (filter.shouldBeFilteredOut(componentName))
                excludedComponentNames.add(componentName)
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return Intent.createChooser(intent, chooserTitle).putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames.toTypedArray())
        }
        if (resolveInfos.isNotEmpty()) {
            val targetIntents: MutableList<Intent> = ArrayList()
            for (resolveInfo in resolveInfos) {
                val activityInfo = resolveInfo.activityInfo
                if (excludedComponentNames.contains(ComponentName(activityInfo.packageName, activityInfo.name)))
                    continue
                val targetIntent = Intent(intent)
                targetIntent.setPackage(activityInfo.packageName)
                targetIntent.component = ComponentName(activityInfo.packageName, activityInfo.name)
                // wrap with LabeledIntent to show correct name and icon
                val labeledIntent = LabeledIntent(targetIntent, activityInfo.packageName, resolveInfo.labelRes, resolveInfo.icon)
                // add filtered intent to a list
                targetIntents.add(labeledIntent)
            }
            val chooserIntent: Intent?
            // deal with M list seperate problem
            chooserIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                // create chooser with empty intent in M could fix the empty cells problem
                Intent.createChooser(Intent(), chooserTitle)
            } else {
                // create chooser with one target intent below M
                Intent.createChooser(targetIntents.removeAt(0), chooserTitle)
            }
            if (chooserIntent == null) {
                return null
            }
            // add initial intents
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toTypedArray<Parcelable>())
            return chooserIntent
        }
        return null
    }
}
android developer
  • 114,585
  • 152
  • 739
  • 1,270
6

I had to exclude facebook apps as they had a broken share intent (something about user originality) using Intent#EXTRA_EXCLUDE_COMPONENTS I resorted to this:

        Intent intent = new Intent(Intent.ACTION_SEND);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            intent.setTypeAndNormalize("text/plain");
        } else {
            intent.setType("text/plain");
        }
        intent.putExtra(Intent.EXTRA_TEXT, "Text to share");

        Intent chooser = Intent.createChooser(intent, "Share Text");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

            ArrayList<ComponentName> targets = new ArrayList<>();

            // remove facebook which has a broken share intent
            for (ResolveInfo candidate : requireActivity().getPackageManager().queryIntentActivities(intent, 0)) {
                String packageName = candidate.activityInfo.packageName;
                if (packageName.toLowerCase().contains("facebook")) {
                    targets.add(new ComponentName(packageName, candidate.activityInfo.name));
                }
            }
            chooser.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, targets.toArray(new ComponentName[0]));
        }

        startActivity(chooser);

This only works for android N and above

Richard Muvirimi
  • 639
  • 9
  • 14
5

Android N (API 24) introduces blacklist Intent.EXTRA_EXCLUDE_COMPONENTS, which is better and simpler than whitelist Intent.EXTRA_INITIAL_INTENTS.

liudongmiao
  • 455
  • 4
  • 7
  • Thank you for this verification, as I was wondering why Intent.EXTRA_EXCLUDE_COMPONENTS wasnt working. –  Sep 13 '19 at 16:59
2

Updated Kotlin answer based on Ragu Swaminathan's answer

fun share() {

        val shareIntent = Intent()
        shareIntent.action = Intent.ACTION_SEND
        shareIntent.type = "text/plain"
        val resInfoList = activity?.packageManager?.queryIntentActivities(shareIntent, 0)

        val shareIntentList = arrayListOf<Intent>()

        if (resInfoList?.isNotEmpty() == true) {
            for (resInfo in resInfoList) {
                val packageName = resInfo.activityInfo.packageName
                if (!packageName.toLowerCase().contains("discord")) {
                    val intent = Intent()
                    intent.component = ComponentName(packageName, resInfo.activityInfo.name)
                    intent.action = Intent.ACTION_SEND
                    intent.type = "text/plain"
                    intent.`package` = packageName
                    intent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
                    shareIntentList.add(intent)
                }
            }
        }

        if (shareIntentList.isEmpty()) {
            Toast.makeText(activity, "No apps to share!", Toast.LENGTH_LONG).show()
        } else {
            val chooserIntent = Intent.createChooser(Intent(), "Choose app to share")
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, shareIntentList.toTypedArray())
            activity?.startActivity(chooserIntent)
        }
    }
T. Colligan
  • 161
  • 1
  • 9
0

Thanks to Ragu Swaminathan's answer, it works perfectly to exclude specific application in an IntentChooser. However, because the 'shareIntentLists' is added in front of the 'chooserIntent', some empty spaces may occur if the size of list is not multiple of 4. To solve this, try:

Intent chooserIntent = Intent.createChooser(new Intent(), "Choose app to share");
空気嫁
  • 186
  • 5
0

After updating targetSdkVersion to 31 the older solution will stop working. This below solution will work for all android version

In Manifest file AndroidManidest.xml

(In Android api 31 by default queryIntentActivities() will return empty list to get the desired result from queryIntentActivities you need to add the below query parameter in manifest file.)

<manifest>
   <queries>
      <intent>
         <!--Change the action and data depending on you share intent-->
         <action android:name="android.intent.action.SEND" /> 
         <data android:mimeType="text/*"/>

      </intent>
   </queries>
</manifest>

In the activity file share function

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain");

shareIntent.putExtra(Intent.EXTRA_TEXT, "Link");
shareIntent.putExtra(Intent.EXTRA_SUBJECT,"Description")

ArrayList<ComponentName> excludedComponents = new ArrayList<ComponentName>();
PackageManager packageManager = context.getPackageManager();
for (ResolveInfo resolveInfo : packageManager.queryIntentActivities(shareIntent, 0)){
String packageName = resolveInfo.activityInfo.packageName;
//change facebook with whichever app you want to exclude or you can directly search for the specific package name
   if (packageName.contains("facebook")){
   excludedComponents.add(new 
   ComponentName(packageName,resolveInfo.activityInfo.name));
   }
}

Intent intentChooser = Intent.createChooser(shareIntent, "Share");
intentChooser.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponents.toArray(new Parcelable[]{}));
startActivity(intentChooser);
Priyankchoudhary
  • 786
  • 9
  • 12