不同 activity 上的 Cordova 通用链接
Cordova universal links on a different activity
我正在我的 Cordova 应用程序中实施 Firebase 身份验证。 android 应用程序将 Cordova 集成到 activity 而不是 main/launcher activity。因此,所需的依赖插件 "cordova-universal-links-plugin" 没有以正确的 activity 为目标(它以 main/launcher activity 为目标)。
有没有办法为通用链接指定目标 activity?如果没有,我如何制作 workaround/hack 来解决这个问题(因为插件不再维护)?
没有为 cordova-universal-links-plugin
指定目标 activity 的已知方法。您可以通过 运行ning 脚本 before/after cordova prepare
.
创建解决方法
修复将像这样工作:
- 您必须重新安排
AndroidManifest.xml
中的活动,以便目标 activity 排在 main/launcher activity 之前。我假设目标 activity 最初看起来像这样:
<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
:这将在目标 activity 的 <category />
标签后添加一个 <action android:name="android.intent.action.VIEW" />
。由于 "CordovaActivity" 暂时也是一个 main/launcher activity & 在实际主要 activity 之前,通用链接插件应该以它为目标。
b) after_prepare.js
:我们希望在插件将 universal-links intent-filters 应用到您的目标 activity 之后 运行。它将删除您添加的 <action />
标签。这是必要的,因为 Android 不能允许两个主要活动。
将 before_prepare.js
作为 before_prepare
Cordova 挂钩添加到您的项目级别 config.xml
。
因为 Cordova 运行 是插件挂钩之前的挂钩,所以您不能将 after_prepare.js
添加为 after_prepare
Cordova 挂钩。那是因为 <action />
标签会在通用链接插件有机会 运行 之前被删除。相反,您必须在 cordova prepare
命令之后 运行 它。我建议使用 cordova prepare
.
之后 运行s after_prepare.js
的 npm 脚本 (npm run 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 = '/.../CordovaProject/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 */
}
}
我正在我的 Cordova 应用程序中实施 Firebase 身份验证。 android 应用程序将 Cordova 集成到 activity 而不是 main/launcher activity。因此,所需的依赖插件 "cordova-universal-links-plugin" 没有以正确的 activity 为目标(它以 main/launcher activity 为目标)。
有没有办法为通用链接指定目标 activity?如果没有,我如何制作 workaround/hack 来解决这个问题(因为插件不再维护)?
没有为 cordova-universal-links-plugin
指定目标 activity 的已知方法。您可以通过 运行ning 脚本 before/after cordova prepare
.
修复将像这样工作:
- 您必须重新安排
AndroidManifest.xml
中的活动,以便目标 activity 排在 main/launcher activity 之前。我假设目标 activity 最初看起来像这样:
<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
:这将在目标 activity 的<category />
标签后添加一个<action android:name="android.intent.action.VIEW" />
。由于 "CordovaActivity" 暂时也是一个 main/launcher activity & 在实际主要 activity 之前,通用链接插件应该以它为目标。b)
after_prepare.js
:我们希望在插件将 universal-links intent-filters 应用到您的目标 activity 之后 运行。它将删除您添加的<action />
标签。这是必要的,因为 Android 不能允许两个主要活动。将
before_prepare.js
作为before_prepare
Cordova 挂钩添加到您的项目级别config.xml
。因为 Cordova 运行 是插件挂钩之前的挂钩,所以您不能将
after_prepare.js
添加为after_prepare
Cordova 挂钩。那是因为<action />
标签会在通用链接插件有机会 运行 之前被删除。相反,您必须在cordova prepare
命令之后 运行 它。我建议使用cordova prepare
. 之后 运行s
after_prepare.js
的 npm 脚本 (npm run 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 = '/.../CordovaProject/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 */
}
}