/* * Apache 2.0 License * * Copyright (c) Sebastian Katzer 2017 * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apache License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://opensource.org/licenses/Apache-2.0/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. */ // codebeat:disable[TOO_MANY_FUNCTIONS] package de.appplant.cordova.plugin.notification; import android.annotation.SuppressLint; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.SharedPreferences; import android.service.notification.StatusBarNotification; import android.support.v4.app.NotificationManagerCompat; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; import java.util.Set; import de.appplant.cordova.plugin.badge.BadgeImpl; import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION_CODES.M; import static android.os.Build.VERSION_CODES.O; import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_DEFAULT; import static de.appplant.cordova.plugin.notification.Notification.PREF_KEY_ID; import static de.appplant.cordova.plugin.notification.Notification.Type.TRIGGERED; /** * Central way to access all or single local notifications set by specific * state like triggered or scheduled. Offers shortcut ways to schedule, * cancel or clear local notifications. */ public final class Manager { // TODO: temporary static final String CHANNEL_ID = "default-channel-id"; // TODO: temporary private static final CharSequence CHANNEL_NAME = "Default channel"; // The application context private Context context; /** * Constructor * * @param context Application context */ private Manager(Context context) { this.context = context; createDefaultChannel(); } /** * Static method to retrieve class instance. * * @param context Application context */ public static Manager getInstance(Context context) { return new Manager(context); } /** * Check if app has local notification permission. */ public boolean hasPermission () { return getNotCompMgr().areNotificationsEnabled(); } /** * 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(); Notification toast = new Notification(context, options); toast.schedule(request, receiver); return toast; } /** * TODO: temporary */ @SuppressLint("WrongConstant") private void createDefaultChannel() { NotificationManager mgr = getNotMgr(); if (SDK_INT < O) return; NotificationChannel channel = mgr.getNotificationChannel(CHANNEL_ID); if (channel != null) return; channel = new NotificationChannel( CHANNEL_ID, CHANNEL_NAME, IMPORTANCE_DEFAULT); mgr.createNotificationChannel(channel); } /** * Update local notification specified by ID. * * @param id The notification ID. * @param updates JSON object with notification options. * @param receiver Receiver to handle the trigger event. */ public Notification update (int id, JSONObject updates, Class receiver) { Notification notification = get(id); if (notification == null) return null; notification.update(updates, receiver); return notification; } /** * Clear local notification specified by ID. * * @param id The notification ID. */ public Notification clear (int id) { Notification toast = get(id); if (toast != null) { toast.clear(); } return toast; } /** * Clear all local notifications. */ public void clearAll () { List toasts = getByType(TRIGGERED); for (Notification toast : toasts) { toast.clear(); } getNotCompMgr().cancelAll(); setBadge(0); } /** * Clear local notification specified by ID. * * @param id The notification ID */ public Notification cancel (int id) { Notification toast = get(id); if (toast != null) { toast.cancel(); } return toast; } /** * Cancel all local notifications. */ public void cancelAll () { List notifications = getAll(); for (Notification notification : notifications) { notification.cancel(); } getNotCompMgr().cancelAll(); setBadge(0); } /** * All local notifications IDs. */ public List getIds() { Set keys = getPrefs().getAll().keySet(); List ids = new ArrayList(); for (String key : keys) { try { ids.add(Integer.parseInt(key)); } catch (NumberFormatException e) { e.printStackTrace(); } } return ids; } /** * All local notification IDs for given type. * * @param type The notification life cycle type */ public List getIdsByType(Notification.Type type) { if (type == Notification.Type.ALL) return getIds(); StatusBarNotification[] activeToasts = getActiveNotifications(); List activeIds = new ArrayList(); for (StatusBarNotification toast : activeToasts) { activeIds.add(toast.getId()); } if (type == TRIGGERED) return activeIds; List ids = getIds(); ids.removeAll(activeIds); return ids; } /** * List of local notifications with matching ID. * * @param ids Set of notification IDs. */ private List getByIds(List ids) { List toasts = new ArrayList(); for (int id : ids) { Notification toast = get(id); if (toast != null) { toasts.add(toast); } } return toasts; } /** * List of all local notification. */ public List getAll() { return getByIds(getIds()); } /** * List of local notifications from given type. * * @param type The notification life cycle type */ private List getByType(Notification.Type type) { if (type == Notification.Type.ALL) return getAll(); List ids = getIdsByType(type); return getByIds(ids); } /** * List of properties from all local notifications. */ public List getOptions() { return getOptionsById(getIds()); } /** * List of properties from local notifications with matching ID. * * @param ids Set of notification IDs */ public List getOptionsById(List ids) { List toasts = new ArrayList(); for (int id : ids) { Options options = getOptions(id); if (options != null) { toasts.add(options.getDict()); } } return toasts; } /** * List of properties from all local notifications from given type. * * @param type * The notification life cycle type */ public List getOptionsByType(Notification.Type type) { ArrayList options = new ArrayList(); List notifications = getByType(type); for (Notification notification : notifications) { options.add(notification.getOptions().getDict()); } return options; } /** * Get local notification options. * * @param id Notification ID. * * @return null if could not found. */ public Options getOptions(int id) { SharedPreferences prefs = getPrefs(); String toastId = Integer.toString(id); if (!prefs.contains(toastId)) return null; try { String json = prefs.getString(toastId, null); JSONObject dict = new JSONObject(json); return new Options(context, dict); } catch (JSONException e) { e.printStackTrace(); return null; } } /** * Get existent local notification. * * @param id Notification ID. * * @return null if could not found. */ public Notification get(int id) { Options options = getOptions(id); if (options == null) return null; return new Notification(context, options); } /** * Set the badge number of the app icon. * * @param badge The badge number. */ public void setBadge (int badge) { if (badge == 0) { new BadgeImpl(context).clearBadge(); } else { new BadgeImpl(context).setBadge(badge); } } /** * Get all active status bar notifications. */ StatusBarNotification[] getActiveNotifications() { if (SDK_INT >= M) { return getNotMgr().getActiveNotifications(); } else { return new StatusBarNotification[0]; } } /** * Shared private preferences for the application. */ private SharedPreferences getPrefs () { return context.getSharedPreferences(PREF_KEY_ID, Context.MODE_PRIVATE); } /** * Notification manager for the application. */ private NotificationManager getNotMgr() { return (NotificationManager) context.getSystemService( Context.NOTIFICATION_SERVICE); } /** * Notification compat manager for the application. */ private NotificationManagerCompat getNotCompMgr() { return NotificationManagerCompat.from(context); } } // codebeat:enable[TOO_MANY_FUNCTIONS]