我正在我的Cordova应用程序中实现Firebase身份验证。 android应用程序将Cordova集成到不是main / launcher活动的活动中。因此,必需的依赖项插件“ cordova-universal-links-plugin”未针对正确的活动(它针对了主/启动器活动)。
是否可以指定通用链接的目标活动?如果没有,我该如何解决/破解此问题(因为不再维护该插件)?
[没有已知的方法来指定cordova-universal-links-plugin
的目标活动。您可以通过在cordova prepare
之前/之后运行脚本来创建解决方法。
此修复程序将按以下方式工作:
AndroidManifest.xml
中重新安排活动,以便在主要/发布者活动之前对目标活动进行排序。我假设目标活动最初看起来像这样:<activity android:name=".CordovaActivity">
<intent-filter android:label="@string/launcher_name">
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
现在,您将编写两个NodeJS脚本:before_prepare.js
和after_prepare.js
。
a)before_prepare.js
:这将为您的目标活动在<action android:name="android.intent.action.VIEW" />
标签之后添加一个<category />
。由于“ CordovaActivity”暂时还是主要的/启动者活动,并且在实际的主要活动之前,因此通用链接插件应改为针对它。
b)after_prepare.js
:我们希望此操作在插件将通用链接意图过滤器应用于目标活动之后运行。它将删除您添加的<action />
标签。这是必要的,因为Android不允许两个主要活动。
将before_prepare.js
作为config.xml
Cordova钩子添加到项目级别before_prepare
。
因为Cordova在插入插件钩子之前先运行钩子,所以不能将after_prepare.js
添加为after_prepare
Cordova钩子。这是因为<action />
标签将在通用链接插件获得运行机会之前被删除。相反,您必须在cordova prepare
命令之后运行它。我建议通过使用在npm run prepare
之后运行after_prepare.js
的npm脚本(cordova prepare
)来执行此操作。
我的实现取决于elementtree
进行XML编辑(Cordova内部也使用它:]
npm install elementtree
before_prepare.js
:
const et = require('elementtree')
const fs = require('fs')
const MANIFEST_FILE = '/.../CordovaProject/platforms/android/app/src/main/AndroidManifest.xml'
/**
* Add main action intent from `SurkartaActivity`.
*
* @param {ElementTree} manifestTree
*/
function addMainAction (manifestTree) {
const intentFilterElement = manifestTree.find("./application/activity[@android:name='.SurakartaActivity']")
.getchildren()[0]
const mainActionElement = et.SubElement(intentFilterElement, 'action')
mainActionElement.set('android:name', 'android.intent.action.MAIN')
}
// Cordova hook executes module.exports
module.exports = function () {
const manifestTree = et.parse(fs.readFileSync(MANIFEST_FILE, 'utf8'))
addMainAction(manifestTree)
console.log(manifestTree.write())
fs.writeFileSync(MANIFEST_FILE, manifestTree.write())
}
after_prepare.js
:
const et = require('elementtree')
const fs = require('fs')
const MANIFEST_FILE = '/Users/shukantpal/CordovaProjects/Surakarta/platforms/android/app/src/main/AndroidManifest.xml'
/**
* Remove main action intent from `SurkartaActivity`.
*
* @param {ElementTree} manifestTree
*/
function stripMainAction (manifestTree) {
const intentFilterElement = manifestTree.find("./application/activity[@android:name='.SurakartaActivity']")
.getchildren()[0]
intentFilterElement.remove(intentFilterElement.getchildren()[1])
}
function hey () {
const manifestTree = et.parse(fs.readFileSync(MANIFEST_FILE, 'utf8'))
stripMainAction(manifestTree)
fs.writeFileSync(MANIFEST_FILE, manifestTree.write())
}
module.exports = hey
// This isn't an Cordova hook, so run it manually
hey()
对现有文件的更改:
config.xml
:
<hook type="before_prepare" src="./path/to/before_prepare.js" />
package.json
:
{
"scripts": {
"prepare": "cordova prepare; node ./path/to/after_prepare.js"
},
"dependencies": {
"elementtree": "@latest" /* npm install elementtree should do this for you */
}
}