ionic-在本地通知插件中更改图标的正确方法是什么?

时间:2018-12-25 22:02:45

标签: android cordova ionic-framework

我正在尝试使用本机local notifications plugin,并且无法更改通知的默认图标。

到目前为止,我已经用两部手机测试了这两种Android设备:第一部是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”文件夹中)

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

1 个答案:

答案 0 :(得分:2)

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

我的通知是这样声明的:

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

您还直接在文件夹icon.png中需要文件res,因为它在本地通知声明中被称为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

好的,但是如何将它们放入仅在编译后生成的文件夹中?

答案是:通过创建钩子

将这些文件夹放在您可以访问的文件夹中,该文件夹一直存在于您的应用中。我个人使用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中。

只要此挂钩正常运行,一切都应该正常!