Универсальные ссылки Cordova на другую деятельность

Я реализую аутентификацию Firebase в своем приложении Cordova. Приложение для Android интегрирует Cordova в действие, которое не является основным действием/активностью запуска. Из-за этого требуемый плагин зависимости «cordova-universal-links-plugin» не нацелен на правильное действие (он нацелен на основное действие/активность запуска).

Есть ли способ указать целевую активность для универсальных ссылок? Если нет, как я могу найти обходной путь/хак, чтобы решить эту проблему (поскольку плагин больше не поддерживается)?


person Shukant Pal    schedule 22.01.2020    source источник
comment
На самом деле вы должны использовать cordova-plugin-deeplinks, так как исходный устарел и не поддерживается.   -  person Shukant Pal    schedule 23.01.2020


Ответы (1)


Неизвестно, как указать целевую активность для cordova-universal-links-plugin. Вы можете создать обходной путь, запустив сценарии до/после cordova prepare.

Исправление будет работать следующим образом:

  1. Вы должны изменить свои действия в AndroidManifest.xml так, чтобы целевое действие располагалось перед основным действием/действием запуска. Я предполагаю, что целевая активность изначально выглядит так:
<activity android:name=".CordovaActivity">
  <intent-filter android:label="@string/launcher_name">
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>
  1. Теперь вы напишете два сценария NodeJS: before_prepare.js и after_prepare.js.

    а) before_prepare.js: это добавит <action android:name="android.intent.action.VIEW" /> после тега <category /> для вашего целевого действия. Поскольку «CordovaActivity» временно также является основным действием/активностью запуска и предшествует фактическому основному действию, плагин универсальных ссылок должен вместо этого ориентироваться на него.

    б) after_prepare.js: мы хотим, чтобы это выполнялось после того, как плагин применит фильтры намерений универсальных ссылок к вашей целевой активности. Он удалит добавленный вами тег <action />. Это необходимо, так как Android не может разрешить два основных действия.

  2. Добавьте before_prepare.js на уровень вашего проекта config.xml в качестве before_prepare крючка Cordova.

  3. Поскольку Cordova запускает ваши хуки до хуков плагина, вы не можете добавить after_prepare.js в качестве after_prepare хука Cordova. Это связано с тем, что тег <action /> будет удален до того, как плагин универсальных ссылок сможет запуститься. Вместо этого вам придется запускать его после команды cordova prepare. Я рекомендую делать это с помощью скрипта npm (npm run prepare), который запускает after_prepare.js после 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 = '/.../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 */
  }
}
person Shukant Pal    schedule 22.01.2020