Skip to content

Instantly share code, notes, and snippets.

@Benjiko99
Last active December 24, 2021 10:49
Show Gist options
  • Save Benjiko99/a9a9abbd41e40bbfc5ce515a9c37634f to your computer and use it in GitHub Desktop.
Save Benjiko99/a9a9abbd41e40bbfc5ce515a9c37634f to your computer and use it in GitHub Desktop.
Intent Chooser for Email apps
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<!-- Let's us query installed apps so we can open them (required on Android 11) -->
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
<data android:mimeType="*/*" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="*/*" />
</intent>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="*/*" />
</intent>
</queries>
</manifest>
import android.content.Context
import android.content.Intent
import android.content.pm.LabeledIntent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.net.Uri
object IntentChooser {
val VIEW_EMAIL = Intent(Intent.ACTION_VIEW, Uri.parse("mailto:"))
/**
* Shows an intent chooser for apps that can handle the [targetIntent].
*/
fun showAppsSuitableForIntent(
context: Context,
targetIntent: Intent,
chooserTitle: String,
onNoSuitableApps: () -> Unit
) {
val packageManager = context.packageManager
val suitableApps = packageManager.queryIntentActivities(targetIntent, PackageManager.MATCH_DEFAULT_ONLY)
if (suitableApps.isEmpty()) {
onNoSuitableApps()
return
}
val firstAppInfo = suitableApps.first().activityInfo
val firstAppIntent = packageManager.getLaunchIntentForPackage(firstAppInfo.packageName)
val chooserIntent = Intent.createChooser(firstAppIntent, chooserTitle)
val remainingApps = suitableApps.subList(1, suitableApps.size)
val appIntents = remainingApps.toLabeledIntents(packageManager)
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, appIntents)
context.startActivity(chooserIntent)
}
private fun List<ResolveInfo>.toLabeledIntents(packageManager: PackageManager): Array<LabeledIntent> {
return this.map { labeledIntent(it, packageManager) }.toTypedArray()
}
private fun labeledIntent(
info: ResolveInfo,
packageManager: PackageManager
): LabeledIntent {
val sourcePackage = info.activityInfo.packageName
val originalIntent = packageManager.getLaunchIntentForPackage(sourcePackage)
val label = info.loadLabel(packageManager)
return LabeledIntent(originalIntent, sourcePackage, label, info.icon)
}
}
fun showEmailAppChooser() {
IntentChooser.showAppsSuitableForIntent(
requireContext(),
IntentChooser.VIEW_EMAIL,
getString(R.string.email_chooser_title)
) {
Toast.makeText(requireContext(), R.string.no_email_apps_found, Toast.LENGTH_SHORT).show()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment