Commit 0c0b1079 authored by Sebastián Katzer's avatar Sebastián Katzer
Browse files

Huge Android rework.

parent 7c94104d
Loading
Loading
Loading
Loading
+6 −5
Changes for plugin.xml: 6 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -50,14 +50,14 @@
             * Android notification bar. The notification uses the default notification
             * sound and it vibrates the phone.
            -->
            <receiver android:name="de.appplant.cordova.plugin.localnotification.LocalNotificationReceiver" />
            <receiver android:name="de.appplant.cordova.plugin.localnotification.Receiver" />

            <!--
             * This class is triggered upon reboot of the device. It needs to re-register
             * the alarms with the AlarmManager since these alarms are lost in case of
             * reboot.
             -->
            <receiver android:name="de.appplant.cordova.plugin.localnotification.LocalNotificationRestore" >
            <receiver android:name="de.appplant.cordova.plugin.localnotification.Restore" >
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                </intent-filter>
@@ -66,12 +66,13 @@

        <config-file target="AndroidManifest.xml" parent="/manifest">
            <uses-permission android:name="android.permission.GET_TASKS" />
            <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
        </config-file>

        <source-file src="src/android/LocalNotificationReceiver.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
        <source-file src="src/android/LocalNotificationOptions.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
        <source-file src="src/android/LocalNotificationRestore.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
        <source-file src="src/android/LocalNotification.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
        <source-file src="src/android/Receiver.java"          target-dir="src/de/appplant/cordova/plugin/localnotification" />
        <source-file src="src/android/Options.java"           target-dir="src/de/appplant/cordova/plugin/localnotification" />
        <source-file src="src/android/Restore.java"           target-dir="src/de/appplant/cordova/plugin/localnotification" />
    </platform>

    <!-- wp8 -->
+143 −0
Changes for src/android/Helper.java: 143 added lines, 0 removed lines.
Original line number Diff line number Diff line
/**
 *  Cordova LocalNotification Plugin
 *
 *  Created by Sebastian Katzer (github.com/katzer).
 *  Copyright 2013 Sebastian Katzer. All rights reserved.
 *  LGPL v2.1 licensed
 */

package de.appplant.cordova.plugin.localnotification;

import java.util.Map;
import java.util.Set;

import org.json.JSONArray;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class Helper {

	private Context context;

    public Helper(Context context) {
    	this.context = context;
    }

    /**
     * Set an alarm.
     *
     * @param options
     *            The options that can be specified per alarm.
     */
    public void add (Options options) {
        long triggerTime = options.getDate();
        Intent intent    = new Intent(context, Receiver.class);

        intent.setAction("" + options.getId());
        intent.putExtra(Receiver.OPTIONS, options.getJSONObject().toString());

        AlarmManager am  = getAlarmManager();
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        if (options.getInterval() > 0) {
            am.setRepeating(AlarmManager.RTC_WAKEUP, triggerTime, options.getInterval(), pi);
        } else {
            am.set(AlarmManager.RTC_WAKEUP, triggerTime, pi);
        }
    }

    /**
     * Cancel a specific notification that was previously registered.
     *
     * @param notificationId
     *            The original ID of the notification that was used when it was
     *            registered using add()
     */
    public void cancel (String notificationId) {
        /*
         * Create an intent that looks similar, to the one that was registered
         * using add. Making sure the notification id in the action is the same.
         * Now we can search for such an intent using the 'getService' method
         * and cancel it.
         */

        Intent intent = new Intent(context, Receiver.class);
        intent.setAction("" + notificationId);

        PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager am  = getAlarmManager();

        try {
            am.cancel(pi);
        } catch (Exception e) {}
    }

    /**
     * Cancel all notifications that were created by this plugin.
     *
     * Android can only unregister a specific alarm. There is no such thing
     * as cancelAll. Therefore we rely on the Shared Preferences which holds
     * all our alarms to loop through these alarms and unregister them one
     * by one.
     */
    public void cancelAll() {
        SharedPreferences settings = context.getSharedPreferences(LocalNotification.PLUGIN_NAME, Context.MODE_PRIVATE);
        Map<String, ?> alarms      = settings.getAll();
        Set<String> alarmIds       = alarms.keySet();

        for (String alarmId : alarmIds) {
            cancel(alarmId);
        }
    }

    /**
     * Persist the information of this alarm to the Android Shared Preferences.
     * This will allow the application to restore the alarm upon device reboot.
     * Also this is used by the cancelAll method.
     *
     * @param args
     *            The assumption is that parse has been called already.
     */
    public void persist (String alarmId, JSONArray args) {
        Editor editor = context.getSharedPreferences(LocalNotification.PLUGIN_NAME, Context.MODE_PRIVATE).edit();

        if (alarmId != null) {
            editor.putString(alarmId, args.toString());
            editor.commit();
        }
    }

    /**
     * Remove a specific alarm from the Android shared Preferences.
     *
     * @param alarmId
     *            The Id of the notification that must be removed.
     */
    public void unpersist (String alarmId) {
        Editor editor = context.getSharedPreferences(LocalNotification.PLUGIN_NAME, Context.MODE_PRIVATE).edit();

        if (alarmId != null) {
            editor.remove(alarmId);
            editor.commit();
        }
    }

    /**
     * Clear all alarms from the Android shared Preferences.
     */
    public void unpersistAll () {
        Editor editor = context.getSharedPreferences(LocalNotification.PLUGIN_NAME, Context.MODE_PRIVATE).edit();

        editor.clear();
        editor.commit();
    }

    private AlarmManager getAlarmManager () {
        return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    }
}
 No newline at end of file
+28 −82
Changes for src/android/LocalNotification.java: 28 added lines, 82 removed lines.
Original line number Diff line number Diff line
/**
 *  LocalNotification.java
 *  Cordova LocalNotification Plugin
 *
 *  Created by Sebastian Katzer (github.com/katzer) on 31/08/2013.
 *  Created by Sebastian Katzer (github.com/katzer).
 *  Copyright 2013 Sebastian Katzer. All rights reserved.
 *  GPL v2 licensed
 *  LGPL v2.1 licensed
 */

package de.appplant.cordova.plugin.localnotification;

import java.util.Map;
import java.util.Set;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Intent;
import android.content.Context;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaWebView;
@@ -39,15 +28,24 @@ public class LocalNotification extends CordovaPlugin {

    public static final String PLUGIN_NAME = "LocalNotification";

    public static CordovaInterface cordova = null;
    public static CordovaWebView webView   = null;
    public static Context context          = null;

    @Override
    public boolean execute (String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        rememberCordovaVarsForStaticUse();

        if (action.equalsIgnoreCase("add")) {
            addWithoutBlocking(args);
            JSONObject arguments  = args.optJSONObject(0);
            final Options options = new Options(context).parse(arguments);

            persist(options.getId(), args);

            cordova.getThreadPool().execute( new Runnable() {
                public void run() {
                    add(options);
                }
            });

            return true;
        }
@@ -72,40 +70,16 @@ public class LocalNotification extends CordovaPlugin {
        return false;
    }

    private static void addWithoutBlocking (final JSONArray args) {
        cordova.getThreadPool().execute(new Runnable() {
            public void run() {
                JSONObject arguments             = args.optJSONObject(0);
                Activity activity                = cordova.getActivity();
                LocalNotificationOptions options = new LocalNotificationOptions(activity).parse(arguments);

                persist(options.getId(), args);
                add(options);
            }
        });
    }

    /**
     * Set an alarm
     * Set an alarm.
     *
     * @param options
     *            The options that can be specified per alarm.
     */
    public static void add (LocalNotificationOptions options) {
        long triggerTime = options.getDate();
        Intent intent    = new Intent(cordova.getActivity(), LocalNotificationReceiver.class);
    public static void add (Options options) {
        Helper helper = new Helper(context);

        intent.setAction("" + options.getId());
        intent.putExtra(LocalNotificationReceiver.OPTIONS, options.getJSONObject().toString());

        AlarmManager am  = getAlarmManager();
        PendingIntent pi = PendingIntent.getBroadcast(cordova.getActivity(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        if (options.getInterval() > 0) {
            am.setRepeating(AlarmManager.RTC_WAKEUP, triggerTime, options.getInterval(), pi);
        } else {
            am.set(AlarmManager.RTC_WAKEUP, triggerTime, pi);
        }
        helper.add(options);
    }

    /**
@@ -116,22 +90,9 @@ public class LocalNotification extends CordovaPlugin {
     *            registered using add()
     */
    public static void cancel (String notificationId) {
        /*
         * Create an intent that looks similar, to the one that was registered
         * using add. Making sure the notification id in the action is the same.
         * Now we can search for such an intent using the 'getService' method
         * and cancel it.
         */
        Intent intent = new Intent(cordova.getActivity(), LocalNotificationReceiver.class);
        Helper helper = new Helper(context);

        intent.setAction("" + notificationId);

        PendingIntent pi = PendingIntent.getBroadcast(cordova.getActivity(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager am  = getAlarmManager();

        try {
            am.cancel(pi);
        } catch (Exception e) {}
        helper.cancel(notificationId);
    }

    /**
@@ -143,13 +104,9 @@ public class LocalNotification extends CordovaPlugin {
     * by one.
     */
    public static void cancelAll() {
        SharedPreferences settings = cordova.getActivity().getSharedPreferences(PLUGIN_NAME, Context.MODE_PRIVATE);
        Map<String, ?> alarms      = settings.getAll();
        Set<String> alarmIds       = alarms.keySet();
        Helper helper = new Helper(context);

        for (String alarmId : alarmIds) {
            cancel(alarmId);
        }
        helper.cancelAll();
    }

    /**
@@ -161,12 +118,9 @@ public class LocalNotification extends CordovaPlugin {
     *            The assumption is that parse has been called already.
     */
    public static void persist (String alarmId, JSONArray args) {
        Editor editor = cordova.getActivity().getSharedPreferences(PLUGIN_NAME, Context.MODE_PRIVATE).edit();
        Helper helper = new Helper(context);

        if (alarmId != null) {
            editor.putString(alarmId, args.toString());
            editor.commit();
        }
        helper.persist(alarmId, args);
    }

    /**
@@ -176,33 +130,25 @@ public class LocalNotification extends CordovaPlugin {
     *            The Id of the notification that must be removed.
     */
    public static void unpersist (String alarmId) {
        Editor editor = cordova.getActivity().getSharedPreferences(PLUGIN_NAME, Context.MODE_PRIVATE).edit();
        Helper helper = new Helper(context);

        if (alarmId != null) {
            editor.remove(alarmId);
            editor.commit();
        }
        helper.unpersist(alarmId);
    }

    /**
     * Clear all alarms from the Android shared Preferences.
     */
    public static void unpersistAll () {
        Editor editor = cordova.getActivity().getSharedPreferences(PLUGIN_NAME, Context.MODE_PRIVATE).edit();

        editor.clear();
        editor.commit();
    }
        Helper helper = new Helper(context);

    private static AlarmManager getAlarmManager () {
        return (AlarmManager) cordova.getActivity().getSystemService(Context.ALARM_SERVICE);
        helper.unpersistAll();
    }

    /**
     * Save required Cordova specific variables for later use.
     */
    private void rememberCordovaVarsForStaticUse () {
        LocalNotification.cordova = super.cordova;
        LocalNotification.webView = super.webView;
        LocalNotification.context = super.cordova.getActivity();
    }
}
 No newline at end of file
+6 −10
Changes for src/android/Options.java: 6 added lines, 10 removed lines.
Original line number Diff line number Diff line
/**
 *  LocalNotificationOptions.java
 *  Cordova LocalNotification Plugin
 *
 *  Created by Sebastian Katzer (github.com/katzer) on 31/08/2013.
 *  Created by Sebastian Katzer (github.com/katzer).
 *  Copyright 2013 Sebastian Katzer. All rights reserved.
 *  GPL v2 licensed
 *  LGPL v2.1 licensed
 */

package de.appplant.cordova.plugin.localnotification;
@@ -23,29 +22,26 @@ import android.net.Uri;
/**
 * Class that helps to store the options that can be specified per alarm.
 */
public class LocalNotificationOptions {
public class Options {

    /*
     * Options that can be set when this plugin is invoked
     */
    private JSONObject options = new JSONObject();
    private String id          = null;
    private String packageName = null;
    private long interval      = 0;
    private long date          = 0;

    LocalNotificationOptions (Activity activity) {
    Options (Activity activity) {
        packageName = activity.getPackageName();
    }

    LocalNotificationOptions (Context context) {
    Options (Context context) {
        packageName = context.getPackageName();
    }

    /**
     * Parst die übergebenen Eigenschaften.
     */
    public LocalNotificationOptions parse (JSONObject options) {
    public Options parse (JSONObject options) {
        String repeat = options.optString("repeat");

        this.options = options;
+15 −13
Changes for src/android/Receiver.java: 15 added lines, 13 removed lines.
Original line number Diff line number Diff line
/**
 *  LocalNotificationReceiver.java
 *  Cordova LocalNotification Plugin
 *
 *  Created by Sebastian Katzer (github.com/katzer) on 31/08/2013.
 *  Created by Sebastian Katzer (github.com/katzer).
 *  Copyright 2013 Sebastian Katzer. All rights reserved.
 *  GPL v2 licensed
 *  LGPL v2.1 licensed
 */

package de.appplant.cordova.plugin.localnotification;
@@ -32,22 +31,22 @@ import android.os.Bundle;
 * Android notification bar. The notification uses the default notification
 * sound and it vibrates the phone.
 */
public class LocalNotificationReceiver extends BroadcastReceiver {
public class Receiver extends BroadcastReceiver {

    public static final String OPTIONS = "LOCAL_NOTIFICATION_OPTIONS";

    private Context context;
    private LocalNotificationOptions options;
    private Options options;

    @Override
    public void onReceive (Context context, Intent intent) {
        LocalNotificationOptions options = null;
        Options options = null;
        Bundle bundle   = intent.getExtras();
        JSONObject args;

        try {
            args    = new JSONObject(bundle.getString(OPTIONS));
            options = new LocalNotificationOptions(context).parse(args);
            options = new Options(context).parse(args);
        } catch (JSONException e) {}

        this.context = context;
@@ -62,8 +61,7 @@ public class LocalNotificationReceiver extends BroadcastReceiver {
        Builder notification = buildNotification();

        if (!isInBackground(context)) {
            // exec foreground callback
            invokeForegroundCallback(options);
            invokeForegroundCallback();
        }

        showNotification(notification);
@@ -154,10 +152,12 @@ public class LocalNotificationReceiver extends BroadcastReceiver {
    /**
     * Ruft die `foreground` Callback Funktion auf.
     */
    private void invokeForegroundCallback (LocalNotificationOptions options) {
    private void invokeForegroundCallback () {
            String function = options.getForeground();

        if (function != null) {
            // after reboot, LocalNotification.webView is always null
            // may be call foreground callback later
            if (function != null && LocalNotification.webView != null) {
                    LocalNotification.webView.sendJavascript(function + "(" + options.getId() + ")");
            }
    }
@@ -165,10 +165,12 @@ public class LocalNotificationReceiver extends BroadcastReceiver {
    /**
     * Ruft die `background` Callback Funktion auf.
     */
    private void invokeBackgroundCallback (LocalNotificationOptions options) {
    private void invokeBackgroundCallback () {
            String function = options.getBackground();

        if (function != null) {
            // after reboot, LocalNotification.webView is always null
            // may be call background callback later
            if (function != null && LocalNotification.webView != null) {
                    LocalNotification.webView.sendJavascript(function + "(" + options.getId() + ")");
            }
    }
Loading