【问题标题】:Ionic/Cordova: Add intent-filter using config.xmlIonic/Cordova:使用 config.xml 添加意图过滤器
【发布时间】:2015-03-27 18:00:21
【问题描述】:

我正在使用 Ionic 框架(基于 Cordova)开发一个移动应用程序。

在 Android 中,我注册我的应用程序以打开 *.txt 文件。 我在platforms/android/AndroidManifest.xml 中添加了intent-filter,它可以工作。 但是平台文件夹在 .gitignore 中:我想使用 config.xml 来完成。

我尝试在 config.xml 中添加:

 <platform name="android">
    <config-file target="AndroidManifest.xml" parent="/*/application/activity">
      <intent-filter><!-- ... --></intent-filter>
    </config-file>
    <!-- ... -->
 </platform>

我还尝试添加:

 <platform name="android">
    <config-file target="AndroidManifest.xml" parent="/manifest/application">
      <activity android:name="CordovaApp"> 
        <intent-filter><!-- ... --></intent-filter>
      </activity>
    </config-file>
    <!-- ... -->
 </platform>

然后我尝试更新 AndroidManifest 启动

ionic prepare

也可以:

ionic remove platform android && ionic add platform android

但AndroidManifest.xml 始终不变。 我做错了什么?

我正在使用 Ionic 1.3.2 和 Cordova 4.2.0。

编辑 这里是整个 config.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<widget id="com.ionicframework.myapp551932" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
  <name>MyApp</name>
  <description>
        myApp
    </description>
  <author email="xxx@yyy.it" href="http://www.example.com/">
      A Team
    </author>
  <content src="index.html"/>
  <access origin="*"/>
  <preference name="webviewbounce" value="false"/>
  <preference name="UIWebViewBounce" value="false"/>
  <preference name="DisallowOverscroll" value="true"/>
  <preference name="BackupWebStorage" value="none"/>
  <preference name="SplashScreen" value="screen"/>
  <preference name="SplashScreenDelay" value="3000"/>
  <feature name="StatusBar">
    <param name="ios-package" value="CDVStatusBar" onload="true"/>
  </feature>
  <platform name="android">
    <config-file target="AndroidManifest.xml" parent="/manifest/application/activity">
      <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="file" />
        <data android:mimeType="*/*" />
        <data android:pathPattern=".*\\.txt" />
        <data android:host="*" />
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="content" />
        <data android:pathPattern=".*\\.txt" />
        <data android:mimeType="*/*" />
      </intent-filter>
    </config-file>
    <icon src="resources/android/icon/drawable-ldpi-icon.png" density="ldpi"/>
    <icon src="resources/android/icon/drawable-mdpi-icon.png" density="mdpi"/>
    <icon src="resources/android/icon/drawable-hdpi-icon.png" density="hdpi"/>
    <icon src="resources/android/icon/drawable-xhdpi-icon.png" density="xhdpi"/>
    <icon src="resources/android/icon/drawable-xxhdpi-icon.png" density="xxhdpi"/>
    <icon src="resources/android/icon/drawable-xxxhdpi-icon.png" density="xxxhdpi"/>
    <splash src="resources/android/splash/drawable-land-ldpi-screen.png" density="land-ldpi"/>
    <splash src="resources/android/splash/drawable-land-mdpi-screen.png" density="land-mdpi"/>
    <splash src="resources/android/splash/drawable-land-hdpi-screen.png" density="land-hdpi"/>
    <splash src="resources/android/splash/drawable-land-xhdpi-screen.png" density="land-xhdpi"/>
    <splash src="resources/android/splash/drawable-land-xxhdpi-screen.png" density="land-xxhdpi"/>
    <splash src="resources/android/splash/drawable-land-xxxhdpi-screen.png" density="land-xxxhdpi"/>
    <splash src="resources/android/splash/drawable-port-ldpi-screen.png" density="port-ldpi"/>
    <splash src="resources/android/splash/drawable-port-mdpi-screen.png" density="port-mdpi"/>
    <splash src="resources/android/splash/drawable-port-hdpi-screen.png" density="port-hdpi"/>
    <splash src="resources/android/splash/drawable-port-xhdpi-screen.png" density="port-xhdpi"/>
    <splash src="resources/android/splash/drawable-port-xxhdpi-screen.png" density="port-xxhdpi"/>
    <splash src="resources/android/splash/drawable-port-xxxhdpi-screen.png" density="port-xxxhdpi"/>
  </platform>
  <icon src="resources/android/icon/drawable-xhdpi-icon.png"/>
</widget>

【问题讨论】:

  • 你能显示你的整个config.xml或至少xml文件的标题吗?
  • 在这里(Ionic 添加的所有内容,除了配置文件标签)。

标签: cordova ionic


【解决方案1】:

已解决!

我无法使用 Ionic 或 Cordova 来做到这一点:这是 PhoneGap 功能(请参阅此Stackoverflow answer

我可以通过其他两种方式做到这一点:

  1. 使用自定义 Cordova 插件
  2. 使用钩子

我更喜欢第二种方式。我为我的目的找到了interesting hook。 注意:请记住安装一些包:

npm install lodash elementtree plist --save-dev

不幸的是,这个钩子合并了标签。 所以我写了这个钩子的一个小改动版本:see here。你可以把这个钩子放在 /hooks/after_platform_add 中。

现在我在 config.xml 中有我的意图过滤器配置:

  <platform name="android">
    <config-file target="AndroidManifest.xml" parent="application/activity">
      <intent-filter><!-- ... --></intent-filter>
    </config-file>
    <!-- ... -->
  </platform>

我可以更新AndroidManifest.xml 重新生成android平台:

ionic platform remove android && ionic platform add android

【讨论】:

  • 好的。移至 GitHub 的要点 :)
  • 对于那些不是 XML 爱好者的人,如果您收到 xml unbound prefix 的 cordova 构建错误,那么您需要将 xmlns:android="http://schemas.android.com/apk/res/android" 添加到配置顶部的 元素中跨度>
  • 这个解决方案很好,但意味着我们每次都需要销毁android平台,否则它会继续添加多个
  • 我用一点解释编辑了答案:你可以把钩子放在 /hooks/after_platform_add 文件夹中。所以它只编辑 AndroidManifest 一次。
  • 很好,你应该向科尔多瓦人提出这个建议,不敢相信它不支持开箱即用
【解决方案2】:

Cordova 9 现在直接支持使用 &lt;config-file&gt;&lt;edit-config&gt; 部分,就像在 plugin.xml 文件中一样。

不使用任何插件或钩子,您可以直接执行以下操作,例如在AndroidManifest.xml中添加意图过滤器:

<?xml version='1.0' encoding='utf-8'?>
<widget id="yourdomain.app" version="1.7.8" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <!-- ... -->
    <platform name="android">
        <!-- ... -->
        <config-file parent="application" target="AndroidManifest.xml">
            <activity android:label="webIntentFilter" android:name="yourdomain.app">
                <intent-filter android:autoVerify="true">
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:host="yourdomain.com" android:scheme="https" />
                </intent-filter>
            </activity>
        </config-file>
    </platform>
    <!-- ... -->
</widget>

不要忘记将属性xmlns:android="http://schemas.android.com/apk/res/android" 添加到您的&lt;widget&gt; 标记中,以避免在构建时出现unbound prefix 错误。

【讨论】:

  • 使用这个启动应用后如何获取url中的数据?
【解决方案3】:

我遇到了同样的问题,但是安装(然后记住或记录依赖)一堆 npm 依赖项然后使用大型通用挂钩的想法对于我的需要来说太重了。

Hooks 可以是简单的 shell 脚本,这通常是一种更直接的修改文本文件的方法。在我的情况下,我只需要向MainActivity 活动添加一个意图过滤器,这对于sed 来说是一项微不足道的工作;我刚刚创建了文件hooks/after_prepare/020_add_moozvine_intents.sh,内容如下:

#!/usr/bin/env zsh

MANIFEST=${0:h}/../../platforms/android/AndroidManifest.xml
[[ -e $MANIFEST ]] || { print "Manifest not found at $MANIFEST." ; exit 1; }

grep -q HANDLE_MOOZVINE_NOTIFICATION $MANIFEST && { print "Manifest already modified. Nothing to do."; exit 0; }

AFTER_LINE='android:name="MainActivity"'
ADDITION='\
        <intent-filter>\
            <action android:name="HANDLE_MOOZVINE_NOTIFICATION" />\
            <category android:name="android.intent.category.DEFAULT" />\
        </intent-filter>
';

sed -i -e "/${AFTER_LINE}/a${ADDITION}" $MANIFEST

工作完成。您可以使用类似的方法对生成的文件进行任何简单的文本修改。

【讨论】:

  • 我花了几个小时寻找这个答案。谢谢你在这里分享。由于缺乏shell脚本知识,我无法考虑它,但是......它工作正常,非常感谢!
  • 太好了,非常感谢。我刚刚对其进行了修改以满足我的需要,并且效果很好:D
【解决方案4】:

这是 Rich 用 JS 为未来的 Google 员工编写的上述解决方案,因为我遇到了 shell 脚本问题。

module.exports = function (context) {
    const fs = require('fs');
    const _ = require('lodash');

    const scheme = 'flowkey';
    const insertIntent = `
    <intent-filter>
                <action android:name="android.intent.action.VIEW"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
                <category android:name="android.intent.category.BROWSABLE"></category>
                <data android:scheme="${scheme}"></data>
    </intent-filter>
    `;
    const manifestPath = context.opts.projectRoot + '/platforms/android/AndroidManifest.xml';
    const androidManifest = fs.readFileSync(manifestPath).toString();
    if (!androidManifest.includes(`android:scheme="${scheme}"`)) {
        const manifestLines = androidManifest.split(/\r?\n/);
        const lineNo = _.findIndex(manifestLines, (line) => line.includes('@string/activity_name'));
        manifestLines.splice(lineNo + 1, 0, insertIntent);
        fs.writeFileSync(manifestPath, manifestLines.join('\n'));
    }
};

使用它作为你的 after prepare 钩子。

注意:这是在 ES6 中,你可以在这里找到 ES5 版本:https://gist.github.com/smowden/f863331034bf300b960beef1ae25bf82

【讨论】:

  • 当我将脚本放入 scripts/cordova/hooks/android 并在 config.xml 中添加适当的 after_prepare 挂钩时,此解决方案对我来说效果很好
猜你喜欢
  • 1970-01-01
  • 2015-09-29
  • 1970-01-01
  • 2014-05-11
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
相关资源
最近更新 更多