【问题标题】:ionic - What is the correct way to change icon in local notifications plugin?ionic - 在本地通知插件中更改图标的正确方法是什么?
【发布时间】:2019-05-24 08:27:47
【问题描述】:

我正在尝试使用原生 local notifications plugin,但在更改通知的默认图标时遇到了麻烦。

到目前为止,我已经使用两部手机进行了测试,都是安卓设备:第一部是 Oreo (8.1.0),另一部是 Nougat (7.0)。我正在使用 Ionic CLI 4.5.0,我知道它的包装器与插件不兼容,如插件存储库中所述。

根据this answer 的建议,我尝试了许多图标 URI 的路径,但似乎没有任何效果。

在提供程序中,这是代码的相关部分:

declare var cordova: any;
...
// inside a function that takes "id", "nome" and "tempo" as parameters:
cordova.plugins.notification.local.schedule({
    id: id,
    title: nome,
    text: "Sua atividade agendada, \"" + nome + "\", está prestes a começar!",
    at: new Date(tempo),
    foreground: true,
    icon: 'res://icone-notif.png',
    smallIcon: 'res://icone-notif-24.png'
});

在我的 config.xml 中,我添加了以下几行:

<platform name="android">
    ...
    <resource-file src="resources/android/icon/icone-notif-24.png" target="res/icone-notif-24.png" />
    <resource-file src="resources/android/icon/icone-notif.png" target="res/icone-notif.png" />
</platform>

(我检查了每个文件,它们被正确放置在我项目的“res”文件夹中)

通知图标应该显示为我保存在这些文件夹中的图像,但我得到的只是默认的白色方块。

【问题讨论】:

    标签: android cordova ionic-framework


    【解决方案1】:

    我挣扎了很长时间,这是我为解决这个问题所做的:

    我的通知是这样声明的:

    const notification = {
        id: idNotif,
        text: this.getNotifText(notifs[0].type),
        trigger: {at: dateNotif},
        led: 'FF0000',
        smallIcon: 'res://ic_stat_notify.png',
        icon: 'res://icon.png',
        vibrate: true
    };
    this.localNotifications.schedule(notification);
    

    在该代码示例中,请注意这些图标的链接以res:// 为前缀。这些图标实际上位于platforms/android/app/src/main/res 文件夹中,该文件夹会在您编译应用程序时自动生成(例如ionic cordova run android)。

    如果您希望通知正常工作,您应该在 res 文件夹中有以下文件夹:

    • drawable-mdpi
    • drawable-hdpi
    • drawable-xhdpi
    • drawable-xxhdpi
    • drawable-xxxhdpi

    您还需要直接在文件夹res 中的文件icon.png,因为它在本地通知声明中被引用为icon 参数。

    这些文件夹对应于Android 中可能的不同图标大小,具体取决于像素密度。您可以在icon handbook 中找到更多相关信息。触发通知时,会自动在这 5 种可能的尺寸中选择合适的图标尺寸。

    这些文件夹中的每一个都必须包含文件ic_stat_notify.png,该文件需要是正确格式的图标:

    • drawable-mdpi:24x24
    • drawable-hdpi:36x36
    • drawable-xhdpi: 48x48
    • drawable-xxhdpi: 72x72
    • drawable-xxxhdpi: 96x96
    • icon.png: 96x96

    好的,但是如何将这些放在编译后生成的文件夹中?

    答案是:通过创建一个hook

    将这些文件夹放在您可以访问且始终存在于您的应用中的文件夹中。就个人而言,我使用了resources/android/icon

    然后,创建一个挂钩,在每次编译应用程序时将这些文件复制到正确的文件夹中。

    这是我的钩子icon_notif.js(注意:它深受this tutorial的启发):

    #!/usr/bin/env node
    
    var filestocopy = [];
    var filestocopyAndroid = [
        {
            "resources/android/icon/drawable-mdpi/ic_stat_notify.png":
            "platforms/android/app/src/main/res/drawable-mdpi/ic_stat_notify.png"
        },
        {
            "resources/android/icon/drawable-hdpi/ic_stat_notify.png":
            "platforms/android/app/src/main/res/drawable-hdpi/ic_stat_notify.png"
        },
        {
            "resources/android/icon/drawable-xhdpi/ic_stat_notify.png":
            "platforms/android/app/src/main/res/drawable-xhdpi/ic_stat_notify.png"
        },
        {
            "resources/android/icon/drawable-xxhdpi/ic_stat_notify.png":
            "platforms/android/app/src/main/res/drawable-xxhdpi/ic_stat_notify.png"
        },
        {
            "resources/android/icon/drawable-xxxhdpi/ic_stat_notify.png":
            "platforms/android/app/src/main/res/drawable-xxxhdpi/ic_stat_notify.png"
        },
        {
            "resources/android/icon/icon.png":
            "platforms/android/app/src/main/res/icon.png"
        }
    ];
    
    var fs = require('fs');
    var path = require('path');
    var rootdir = './';
    var androiddir = path.join(rootdir, "platforms/android");
    var iosdir = path.join(rootdir, "platforms/ios");
    
    if(fs.existsSync(androiddir)) {
        filestocopy = filestocopyAndroid;
        console.log("Android platform file recognized");
    } else if(fs.existsSync(iosdir)) {
        console.log("iOS platform file recognized");
        filestocopy = filestocopyiOS;
    } else {
        console.log("Error: no Android or iOS platform file was recognized.");
        filestocopy = [];
    }
    
    console.log("~~~~ Start Copying Notification Status Icons");
    filestocopy.forEach(function (obj) {
        Object.keys(obj).forEach(function (key) {
            var val = obj[key];
            var srcfile = path.join(rootdir, key);
            var destfile = path.join(rootdir, val);
            console.log("copying: " + srcfile);
            console.log("     to: " + destfile);
            var destdir = path.dirname(destfile);
            if(!fs.existsSync(destdir)) {
                fs.mkdirSync(destdir);
            }
            if (fs.existsSync(srcfile) && fs.existsSync(destdir)) {
                fs.createReadStream(srcfile).pipe(
                    fs.createWriteStream(destfile));
            }
        });
    });
    console.log("~~~~ End Copying Notification Status Icons");
    

    基本上,此脚本会将正确的文件夹复制到新生成的platforms/android/app/src/main/res folder

    只要这个钩子运行正常,一切都应该正常!

    【讨论】:

    • 我没有使用您提供的挂钩文件,因为我找不到将它们放置在我的项目中的文件夹,所以我像以前一样使用了 config.xml,但使用了正确的您发布的路径。而且我还调整了每个 dpi 的图标大小以确保它可以工作,现在它完成了!非常感谢!
    • 很高兴我能帮上忙。 :)
    • 谢谢!救了我两次。这个工具可以帮助生成图片和文件夹:romannurik.github.io/AndroidAssetStudio/icons-notification.html
    • 对于使用cordova >= 7.0.0的任何人:我需要用&lt;resource-file src="resources/android/icon/drawable-xxx-icon.png" target="app/src/main/res/drawable-xxx/icon.png" /&gt;替换&lt;icon density="xxx" src="resources/android/icon/drawable-xxx-icon.png" /&gt;(我真的不知道为什么根据文档仍然应该支持icon,但是对我来说,运行cordova build android时没有复制资源)
    猜你喜欢
    • 2017-02-12
    • 2023-03-08
    • 2013-04-04
    • 2017-06-26
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 2014-01-07
    • 2022-09-28
    相关资源
    最近更新 更多