'On React-native, on Android, canOpenURL fails & OpenURL throw an error: Could not open URL
On a React-Native
mobile app Linking.canOpenURL
and Linking.openURL
fail if the URL refers to an app screen, while it works when referring to an HTTPS URL. I suspect it is a problem with Android permissions. I have not tried it on iOS. Any idea what I am missing?
My Code:
// const url = "https://google.com"; // works
const url = "casualjob://"; // does NOT work
Linking.canOpenURL(url)
.then( (supported) => {
// execution reaches this point -> supported: false
console.log("canOpenURL - ", "supported:", supported, );
});
Linking.openURL(url)
.then(() => {
console.log("openURL -URL was opened successfully");
})
.catch((err) => {
// execution reaches this point -> Error: Could not open URL 'casualjob://': No Activity found to handle Intent { act=android.intent.action.VIEW dat=casualjob:// flg=0x10000000
console.error("openURL - failed - err:", err, )
});
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.casualjob">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme"
android:requestLegacyExternalStorage="true"
>
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="@string/facebook_client_token"/>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="casualjob"/>
<data android:scheme="http" android:host="buildwebsitepro.com.au/casualjob"/>
<data android:scheme="https" android:host="buildwebsitepro.com.au/casualjob"/>
</intent-filter>
</activity>
</application>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="casualjob"/>
</intent>
</queries>
</manifest>
Solution 1:[1]
For Deeplink integration refer this plugin react-native-deep-linking
Your URL should be like this
const url = "https://buildwebsitepro.com.au"
after that you need to first initialise event for Dee-link For Android
Linking.getInitialURL()
.then(ev => {
if (ev && ev !== '') {
handleUrl({url: ev});
}
})
.catch(err => console.log('An error occurred', err));
function handleUrl({url}: {url: string | null}) {
const deepLinkURL = url;
if (deepLinkURL) {
Linking.canOpenURL(deepLinkURL).then(supported => {
if (supported) {
DeepLinking.evaluateUrl(deepLinkURL);
}
});
}
}
You need to change MenifestFile like below
<data android:host="casualjob" android:scheme="buildwebsitepro" />
Finally Register Routes
DeepLinking.addRoute('/test/:id', (response) => {
// example://test/23
console.log(response.id); // 23
});
Solution 2:[2]
I discovered that the problem was a conflict between the <data>
definitions. Following is an extract showing the required modifications.
AndroidManifest.xml:
<manifest ...>
...
<application ...>
...
<activity ...>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="casualjob"/>
<!-- It seems that the following 2 data statements are conflicting with the one above. So, I removed them. -->
<!-- <data android:scheme="http" android:host="buildwebsitepro.com.au/casualjob"/>
<data android:scheme="https" android:host="buildwebsitepro.com.au/casualjob"/> -->
</intent-filter>
</activity>
</application>
</manifest>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Mobile Team iOS-RN |
Solution 2 | Bilal Abdeen |