最近将我们的构建目标切换到 android 30 以添加对 Android 11 的支持,现在方向和电话呼叫不起作用。
文档提到了本机深度链接和/或 npm 包的使用。 这会在本地完成吗?或者可以选择套餐吗?
https://reactnative.dev/docs/linking
在运行 android 30 时检查是否支持 Linking.canOpenURL 现在返回 false。
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."));
答案在于新的 Android 安全功能:Package Visibility。这与 iOS 的
LSApplicationQueriesSchemes
类似。
针对 Android 11 (SDK 30) 需要您更新
AndroidManifest.xml
并包含您正在查询的应用程序列表。例如。这是我用来在我自己的应用程序中检查 Google 地图导航的代码。它还包括 HTTP 和 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>
对于符合特定条件的应用程序(例如防病毒应用程序、文件管理器或浏览器),您可以使用
QUERY_ALL_PACKAGES
权限来允许查询与早期 Android 版本类似的任何随机包:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
但是,请注意,如果您不符合下面列出的任何应用类型的资格或以未经授权的方式使用 QUERY_ALL_PACKAGES
,您的申请将被 Google Play 拒绝:
使用广泛的包(应用程序)可见性(QUERY_ALL_PACKAGES)权限请参阅
android:host="*"
标签添加
data
,如下所示:<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>
对于
Linking.canOpenURL(url)
返回
true
对于 https://...
URL。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;
})
}
app.json
{
"expo": {
...,
"plugins": [
"./android-manifest.plugin.js"
]
}
}
eas build
expo build
),但请记住它很快就会被弃用
const { withAndroidManifest, createRunOncePlugin } = require('expo/config-plugins');
const queries = {
intent: [
{
action: {
$: {
'android:name': 'android.intent.action.VIEW',
},
},
category: {
$: {
'android:name': 'android.intent.category.BROWSABLE',
},
},
data: {
$: {
'android:scheme': 'https',
'android:host': '*',
},
},
},
],
};
/**
* @param {import('@expo/config-plugins').ExportedConfig} config
*/
const withAndroidManifestService = (config) => {
return withAndroidManifest(config, (config) => {
config.modResults.manifest = {
...config.modResults.manifest,
queries,
};
return config;
});
};
module.exports = createRunOncePlugin(
withAndroidManifestService,
'withAndroidManifestService',
'1.0.0'
);
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
谢谢大家的支持。