「シンプル体重管理」のリマインダー機能で、バイブレーションのオン・オフがAndroid 8以降の端末で動かないことに気がつき、いろいろと調査したところ、通知チャンネルを作成して管理するとのことでした。
バイブレーションのオン・オフが動かない理由もわかりました。
通知チャネルを作成した後に、通知の動作を変更することはできません。その時点ではユーザーが完全にコントロールします。ただし、チャネルの名前と説明はデベロッパーが変更できます。
現状、cordova-plugin-local-notificationプラグインはいくつか問題があるので、改造にチャレンジしてみました。
「シンプル体重管理」の前バージョンはkatzer氏が開発したプラグインを使用していましたが、Android 8以降で実行すると「Default channel」という名称の通知チャンネルが作成されてしまいます。
それを解決するため、Steffaan氏が通知チャンネルの名称を設定できるように改造しましたが、こちらは初めて通知が発生した場合に通知チャンネルが登録される仕組みとなっており、これではユーザーが通知前にバイブレーションの設定を行うことができません。
1 2 3 4 5 6 7 8 9 10 |
cordova.plugins.notification.local.schedule({ id: id, channel: channel, channelDescription: channelDescription, title: title, text: message, trigger: { every: { hour: hh, minute: mm } }, vibrate: vibrate, foreground: false }); |
改造点は以下のとおりです。
- Android 8以降の端末に登録された通知チャンネル「Default channel」を削除する。
- schedule()を実行するとき通知チャンネルを作成する。
※Android 7までの端末には影響ありません。
local-notification.js
1 2 3 4 5 6 |
/** * Remove default channel. */ exports.removeDefaultChannel = function (callback, scope) { this._exec('removeDefaultChannel', null, callback, scope); }; |
LocalNotification.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
@Override public boolean execute (final String action, final JSONArray args, final CallbackContext command) throws JSONException { if (action.equals("launch")) { launch(command); return true; } cordova.getThreadPool().execute(new Runnable() { public void run() { // 追加 if (action.equals("removeDefaultChannel")) { removeDefaultChannel(command); } else } }); return true; } /** * Remove Default channel. */ private void removeDefaultChannel(CallbackContext command) { boolean res = getNotMgr().removeDefaultChannel(); String msg = "OK"; if (res) { fireEvent("removedefaultchannel"); } else { msg = "NG"; } command.success(msg); } |
Manager.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/** * Schedule local notification specified by request. * * @param request Set of notification options. * @param receiver Receiver to handle the trigger event. */ public Notification schedule (Request request, Class<?> receiver) { Options options = request.getOptions(); // 追加 if (SDK_INT >= O) { this.createChannel(options); } Notification toast = new Notification(context, options); toast.schedule(request, receiver); return toast; } /** * Remove default channel. */ public boolean removeDefaultChannel() { boolean res = false; if (SDK_INT >= O) { NotificationChannel channel = getNotMgr().getNotificationChannel(DEFAULT_CHANNEL_ID); if (channel != null) { getNotMgr().deleteNotificationChannel(DEFAULT_CHANNEL_ID); res = true; } } return res; } |
TriggerReceiver.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
/** * Called when a local notification was triggered. Does present the local * notification, re-schedule the alarm if necessary and fire trigger event. * * @param notification Wrapper around the local notification. * @param bundle The bundled extras. */ @Override public void onTrigger (Notification notification, Bundle bundle) { boolean isUpdate = bundle.getBoolean(Notification.EXTRA_UPDATE, false); Context context = notification.getContext(); Options options = notification.getOptions(); Manager manager = Manager.getInstance(context); int badge = options.getBadgeNumber(); if (badge > 0) { manager.setBadge(badge); } if (options.shallWakeUp()) { wakeUp(context); } // コメントアウト //manager.createChannel(options); notification.show(); if (!isUpdate && isAppRunning()) { fireEvent("trigger", notification); } if (!options.isInfiniteTrigger()) return; Calendar cal = Calendar.getInstance(); cal.add(MINUTE, 1); Request req = new Request(options, cal.getTime()); manager.schedule(req, this.getClass()); } |
シリコンパワー デスクトップPC用メモリ DDR4-2666(PC4-21300) オーバークロック 8GB×2枚 永久保証 SP016GXLZU266BDA 新品価格 |