In one of our projects, we wanted to know the applications users select when sharing content from our app for analytics. The possible value that could be sent to the analytics platform was Facebook, Twitter or Other (there were other possible values, but we'll leave it like this to keep things simple).
This was working well on iOS, but on Android we were always sending "Other" because getting that information was (probably?) not feasible when it first got implemented. I decided to try and see if I could find a solution to this. The solution I found is not bulletproof, but it's still better than always sending "Other" as the chosen app. Here are the steps if you ever need to get that information.
The first step is to create a Broadcast Receiver derived class and override the onReceive function:
class ChooserBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// TODO Get the selected app...
}
}
Then, we implement the onReceive function. This function receives an Intent object as an argument. From that, we can retrieve the component info of the app the user selected.
val selectedComponent = intent?.extras?.get(EXTRA_CHOSEN_COMPONENT).toString()
The returned value is a String that is similar to ComponentInfo{com.facebook.katana/com.facebook.composer.shareintent.ImplicitShareIntentHandlerDefaultAlias}. With that, we can simply check if it contains a certain String to determine which app was selected. This is the result:
class ChooserBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val selectedComponent = intent?.extras?.get(EXTRA_CHOSEN_COMPONENT).toString()
val selectedApp = when {
selectedComponent.contains("facebook", true) -> "Facebook"
selectedComponent.contains("twitter", true) -> "Twitter"
else -> "Other"
}
// Send the value to the analytics platform...
}
}
Next, we declare our ChooserBroadcastReceiver in the AndroidManifest.xml file inside the application tag.
<manifest ... >
<application ... >
<receiver
android:name=".your.package.ChooserBroadcastReceiver"
android:exported="false" />
</application>
</manifest>
Finally, let's say we have an Activity that allows the user to share some text, we can create a share intent with our ChooserBroadcastReceiver. I will not explain the code as it's beyond the scope of this article, but you can go to https://developer.android.com/training/sharing/send for more information.
class SharableActivity : AppCompatActivity() {
fun shareText() {
val receiverIntent = Intent(baseContext, ChooserBroadcastReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(this, 0, receiverIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val shareIntent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_TEXT, "This is my text to share.")
type = "text/plain"
}
startActivity(Intent.createChooser(shareIntent, null, pendingIntent.intentSender))
}
}
And voilà! The onReceive function of our ChooserBroadcastReceiver will be called when the user selects an app from the share intent and we can send the right value to the analytics platform!