DMO
DMO

Reputation: 53

How to find if the email app is present on the device on Android API 30?

My app requires to check if an email app is present so we can hide a button for sending the email.

On API 30, Android has made change to the package manager so we cannot access the activities anymore, unless they have been declared in the <queries> tag.

I have setup the queries node on the AndroidManifest file as follows

 <queries>
        <intent>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.APP_EMAIL" />
        </intent>
    </queries>

When I try to query using the the intent, the method on the package manager returns zero items.

 fun isEmailAppInstalled(context: Context): Boolean {
        val intent = Intent(Intent.ACTION_MAIN)
        intent.addCategory(Intent.CATEGORY_APP_EMAIL)
        return context.packageManager.queryIntentActivities(intent, 0).isNotEmpty()
 }

Upvotes: 5

Views: 2517

Answers (3)

envyM6
envyM6

Reputation: 1237

In your AndroidManifest add:

<queries>
    <intent>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="mailto"/>
    </intent>
</queries>

And alter your code to

val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"))
        intent.addCategory(Intent.CATEGORY_DEFAULT)
        return context.packageManager.queryIntentActivities(intent, 0).isNotEmpty()

Language syntax may need double chekcing/updating as I have tested the solution in Xamarin.Forms and is back compat with API 29 and below too.

Upvotes: 13

Zahid Islam
Zahid Islam

Reputation: 740

According to the new documentation based on API level 30 or higher , if you want to access other apps installed on device you have to declare package visibility by adding the <queries> element in your app's manifest file. What you are doing here. And same time the system makes some apps visible to your app automatically. We can check by

adb shell dumpsys package queries

In the command output, find the forceQueryable section. This section includes the list of packages that the device has made visible to your app automatically.(this part copied from documentation).

enter image description here

So in this case without <queries> tag I can access Email app from my device on API 30 and also 29 by Intent.createChooser.

  fun isEmailAppInstalled(context: Context) {
    /* val intent = Intent(Intent.ACTION_MAIN)
    intent.addCategory(Intent.CATEGORY_APP_EMAIL)
    return context.packageManager.queryIntentActivities(intent, 0).isNotEmpty()*/
    val intent = Intent(Intent.ACTION_MAIN)
    intent.addCategory(Intent.CATEGORY_APP_EMAIL)
    try {
        startActivity(Intent.createChooser(intent, "Choose your Email App"))
    } catch (e: ActivityNotFoundException) {
        Log.i("ZI", "No Email App Found")

    }
}

Upvotes: 0

Sam Chen
Sam Chen

Reputation: 8867

From documentation:

fun composeEmail(addresses: Array<String>, subject: String) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        data = Uri.parse("mailto:")    //<- only email apps should handle this
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
    }

    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Upvotes: 0

Related Questions