34

Recently switched our build targets to android 30 to add support for Android 11, now directions and call for phone are not working.

The documentation mentions deep linking natively and or the use of an npm package. Would this be done natively? Or is the package an option?

https://reactnative.dev/docs/linking

Linking.canOpenURL is now returning false when checking if it is supported when running android 30.

Linking.canOpenURL(url)
.then((supported: boolean) => (supported ? Linking.openURL(url) : Alert.alert("Error", "There was an error attempting to opening the location.")))
.catch(() => Alert.alert("Error", "There was an error attempting to opening the location."));
Before The Empire
  • 463
  • 1
  • 5
  • 15

5 Answers5

56

The answer lies in a new Android security feature: Package Visibility. This works similar to iOS' LSApplicationQueriesSchemes.

Targeting Android 11 (SDK 30) requires you to update your AndroidManifest.xml and include a list of applications you're querying for. E.g. here's the code I'm using to check for Google Maps navigation in my own app. It also includes permissions for HTTP and HTTPS:

<manifest package="com.example.game">
  <queries>
    <intent>
      <action android:name="android.intent.action.VIEW" />
      <data android:scheme="http"/>
    </intent>
    <intent>
      <action android:name="android.intent.action.VIEW" />
      <data android:scheme="https"/>
    </intent>
    <intent>
      <action android:name="android.intent.action.VIEW" />
      <data android:scheme="geo" />
    </intent>
    <intent>
      <action android:name="android.intent.action.VIEW" />
      <data android:scheme="google.navigation" />
    </intent>
  </queries>
  ...
</manifest>

For applications matching certain criterias (such as Antivirus apps, file managers, or browser) you can use the QUERY_ALL_PACKAGES permission to allow querying any random package similar to earlier Android versions:

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

However, be aware that your application will be rejected from Google Play if you don't qualify as any of the app types listed below or uses the QUERY_ALL_PACKAGES in an unauthorized way:

Permitted use involves apps that must discover any and all installed apps on the device, for awareness or interoperability purposes may have eligibility for the permission. Permitted use includes device search, antivirus apps, file managers, and browsers. Apps granted access to this permission must comply with the User Data policies, including the Prominent Disclosure and Consent requirements, and may not extend its use to undisclosed or invalid purposes.

See Use of the broad package (App) visibility (QUERY_ALL_PACKAGES) permission

André
  • 2,101
  • 20
  • 23
  • How about Phone app and emails? – Ankit Jayaprakash Jun 16 '21 at 13:03
  • 1
    @AnkitJayaprakash you need to figure out the URL schemes of the apps you're looking for and add them to the intent list. They should be documented for the specific apps you're looking for. For common intents check out https://developer.android.com/guide/components/intents-common. The phone dialer, for example, uses android:name="android.intent.action.DIAL" and android:scheme="tel". – André Jun 25 '21 at 14:07
  • anyone knows how to do this for non bare (expo) workflow? – nanakondor Nov 01 '21 at 02:36
  • bare applications designed not to work with configurations files and it works pure javascript base. So I don't think it's not possible with the expo thing. Probably they will do a release related to android 11 soon and then you can upgrade your expo SDK to latest one. – Vidurajith Darshana Nov 24 '21 at 06:27
33

In my case I needed to add a android:host="*" to the data tag like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          package="com.acme">
...
    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" android:host="*" />
        </intent>
    </queries>
</manifest>

For Linking.canOpenURL(url) to return true for https://... URLs.

Gabri
  • 341
  • 3
  • 3
6

Take care if you decide to use

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

google says:

Permitted use involves apps that must discover any and all installed apps on the device, for awareness or interoperability purposes may have eligibility for the permission. Permitted use includes device search, antivirus apps, file managers, and browsers. Apps granted access to this permission must comply with the User Data policies, including the Prominent Disclosure and Consent requirements, and may not extend its use to undisclosed or invalid purposes.

on policy update from Google Play

Felipe Santos
  • 61
  • 1
  • 2
2

If you're using expo you can add this (https://github.com/chirag04/react-native-mail/pull/175/files) to your manifest file by doing the next:

  1. Create a new file at root folder named 'android-manifest.plugin.js' with the next code on it.
const { withAndroidManifest } = require("@expo/config-plugins")

module.exports = function androiManifestPlugin(config) {
  return withAndroidManifest(config, async config => {
    let androidManifest = config.modResults.manifest

    androidManifest["queries"].push({
        "intent": [{
            "action": [{
                "$": {
                    "android:name": "android.intent.action.SEND_MULTIPLE"
                }
            }],
            "data": [{
                "$": {
                    "android:mimeType": "*/*"
                }
            }]
        }]
    });

    return config;
  })
}
  1. Add the plugin above to your expo config file app.json
{
  "expo": {
    ...,
    "plugins": [
      "./android-manifest.plugin.js"
    ]
  }
}
  1. Rebuild by using a eas build or you can use classic (expo build) but remember it will be deprecated soon

That's it. Your apk should have the normal manifest plus the section that was mentioned in the link above. You can also use this approach to set your manifest as your wish. You can also verify that your manifest was successfully modified by using this tool (How to view AndroidManifest.xml from APK file?)

  • thanks, i need to try that, i still on sdk 45 and expo build, but as managed i have no other choice, for the moment i don't use canOpenURL and force openURL, and at least it show phone number in dialer – devseo Sep 23 '22 at 08:17
-3

By adding this in manifest resolved the issue

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

Thank you everyone for your support.

Ankit Jayaprakash
  • 1,040
  • 3
  • 15
  • 31