Commit 331227c6 authored by Sebastián Katzer's avatar Sebastián Katzer
Browse files

Halbwegs funktionsfähiger Android Support

parent 8eda6a2d
Loading
Loading
Loading
Loading

src/android/AlarmReceiver.java

deleted100644 → 0
+0 −87
Changes for src/android/AlarmReceiver.java: 0 added lines, 87 removed lines.
Original line number Diff line number Diff line
package de.appplant.cordova.plugin;

import java.util.Calendar;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

/**
 * The alarm receiver is triggered when a scheduled alarm is fired. This class
 * reads the information in the intent and displays this information in the
 * Android notification bar. The notification uses the default notification
 * sound and it vibrates the phone.
 *
 * @author dvtoever
 */
public class AlarmReceiver extends BroadcastReceiver {

	public static final String TITLE = "ALARM_TITLE";
	public static final String SUBTITLE = "ALARM_SUBTITLE";
	public static final String TICKER_TEXT = "ALARM_TICKER";
	public static final String NOTIFICATION_ID = "NOTIFICATION_ID";

	/* Contains time in 24hour format 'HH:mm' e.g. '04:30' or '18:23' */
	public static final String HOUR_OF_DAY = "HOUR_OF_DAY";
	public static final String MINUTE = "MINUTES";

	@Override
	public void onReceive(Context context, Intent intent) {
		Log.d("AlarmReceiver", "AlarmReceiver invoked!");

		final Bundle bundle = intent.getExtras();
		final Object systemService = context.getSystemService(Context.NOTIFICATION_SERVICE);

		// Retrieve notification details from the intent
		final String tickerText = bundle.getString(TICKER_TEXT);
		final String notificationTitle = bundle.getString(TITLE);
		final String notificationSubText = bundle.getString(SUBTITLE);
		int notificationId = 0;

		try {
			notificationId = Integer.parseInt(bundle.getString(NOTIFICATION_ID));
		} catch (Exception e) {
			Log.d("AlarmReceiver", "Unable to process alarm with id: " + bundle.getString(NOTIFICATION_ID));
		}

		Calendar currentCal = Calendar.getInstance();
		int alarmHour = bundle.getInt(HOUR_OF_DAY);
		int alarmMin = bundle.getInt(MINUTE);
		int currentHour = currentCal.get(Calendar.HOUR_OF_DAY);
		int currentMin = currentCal.get(Calendar.MINUTE);

		if (currentHour != alarmHour && currentMin != alarmMin) {
			/*
			 * If you set a repeating alarm at 11:00 in the morning and it
			 * should trigger every morning at 08:00 o'clock, it will
			 * immediately fire. E.g. Android tries to make up for the
			 * 'forgotten' reminder for that day. Therefore we ignore the event
			 * if Android tries to 'catch up'.
			 */
			Log.d(LocalNotification.PLUGIN_NAME, "AlarmReceiver, ignoring alarm since it is due");
			return;
		}

		// Construct the notification and notificationManager objects
		final NotificationManager notificationMgr = (NotificationManager) systemService;
		final Notification notification = new Notification(R.drawable.ic_launcher, tickerText,
				System.currentTimeMillis());
		final PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
		notification.defaults |= Notification.DEFAULT_SOUND;
		notification.vibrate = new long[] { 0, 100, 200, 300 };
		notification.setLatestEventInfo(context, notificationTitle, notificationSubText, contentIntent);

		/*
		 * If you want all reminders to stay in the notification bar, you should
		 * generate a random ID. If you want do replace an existing
		 * notification, make sure the ID below matches the ID that you store in
		 * the alarm intent.
		 */
		notificationMgr.notify(notificationId, notification);
	}
}
 No newline at end of file
+0 −63
Changes for src/android/AlarmRestoreOnBoot.java: 0 added lines, 63 removed lines.
Original line number Diff line number Diff line
package de.appplant.cordova.plugin;

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

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

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;

/**
 * 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.
 *
 * @author dvtoever
 */
public class AlarmRestoreOnBoot extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
	final String pluginName = LocalNotification.PLUGIN_NAME;

	// Obtain alarm details form Shared Preferences
	final SharedPreferences alarmSettings = context.getSharedPreferences(pluginName, Context.MODE_PRIVATE);
	final Map<String, ?> allAlarms = alarmSettings.getAll();
	final Set<String> alarmIds = allAlarms.keySet();

	/*
	 * For each alarm, parse its alarm options and register is again with
	 * the Alarm Manager
	 */
	for (String alarmId : alarmIds) {
	    try {
		final AlarmHelper alarm = new AlarmHelper(context);
		final JSONArray alarmDetails = new JSONArray(alarmSettings.getString(alarmId, ""));
		final AlarmOptions options = new AlarmOptions();

		options.parseOptions(alarmDetails);

		final boolean daily = options.isRepeatDaily();
		final String title = options.getAlarmTitle();
		final String subTitle = options.getAlarmSubTitle();
		final String ticker = options.getAlarmTicker();
		final String id = options.getNotificationId();
		final Calendar cal = options.getCal();

		alarm.addAlarm(daily, title, subTitle, ticker, id, cal);

	    } catch (JSONException e) {
		Log.d(pluginName,
			"AlarmRestoreOnBoot: Error while restoring alarm details after reboot: " + e.toString());
	    }

	    Log.d(pluginName, "AlarmRestoreOnBoot: Successfully restored alarms upon reboot");
	}
    }
}
 No newline at end of file
+16 −27
Changes for src/android/LocalNotification.java: 16 added lines, 27 removed lines.
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@

package de.appplant.cordova.plugin;

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

@@ -40,14 +39,14 @@ public class LocalNotification extends CordovaPlugin {
    @Override
    public boolean execute (String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        JSONObject arguments             = args.getJSONObject(0);
        LocalNotificationOptions options = new LocalNotificationOptions();
        LocalNotificationOptions options = new LocalNotificationOptions(arguments);

        options.parse(arguments);

        String alarmId = options.getNotificationId();
        String alarmId = options.getId();

        if (action.equalsIgnoreCase("add")) {
            if (alarmId != null)
                persist(alarmId, args);

            add(options);

            return true;
@@ -58,10 +57,9 @@ public class LocalNotification extends CordovaPlugin {
            cancel(alarmId);

            return true;

        }

        if (action.equalsIgnoreCase("cancelall")) {
        if (action.equalsIgnoreCase("cancelAll")) {
            unpersistAll();
            cancelAll();

@@ -78,27 +76,18 @@ public class LocalNotification extends CordovaPlugin {
     * @param options
     *            The options that can be specified per alarm.
     */
    public void add(LocalNotificationOptions options) {
        Calendar calendar = options.getCalendar();
        long triggerTime  = calendar.getTimeInMillis();
        int hour          = calendar.get(Calendar.HOUR_OF_DAY);
        int min           = calendar.get(Calendar.MINUTE);

        Intent intent     = new Intent(cordova.getActivity(), AlarmReceiver.class);

        intent.setAction("" + options.getNotificationId());
        intent.putExtra(AlarmReceiver.TITLE, options.getTitle());
        intent.putExtra(AlarmReceiver.SUBTITLE, options.getSubTitle());
        intent.putExtra(AlarmReceiver.TICKER_TEXT, options.getTicker());
        intent.putExtra(AlarmReceiver.NOTIFICATION_ID, options.getNotificationId());
        intent.putExtra(AlarmReceiver.HOUR_OF_DAY, hour);
        intent.putExtra(AlarmReceiver.MINUTE, min);
    private void add (LocalNotificationOptions options) {
        long triggerTime = options.getDate();
        Intent intent    = new Intent(cordova.getActivity(), LocalNotificationReceiver.class);

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

        PendingIntent sender = PendingIntent.getBroadcast(cordova.getActivity(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        /* Get the AlarmManager service */
        AlarmManager am      = getAlarmManager();
        PendingIntent sender = PendingIntent.getBroadcast(cordova.getActivity(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        if (options.isRepeatDaily()) {
        if (options.getInterval() > 0) {
            am.setRepeating(AlarmManager.RTC_WAKEUP, triggerTime, AlarmManager.INTERVAL_DAY, sender);
        } else {
            am.set(AlarmManager.RTC_WAKEUP, triggerTime, sender);
@@ -112,14 +101,14 @@ public class LocalNotification extends CordovaPlugin {
     *            The original ID of the notification that was used when it was
     *            registered using add()
     */
    public void cancel (String notificationId) {
    private 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(), AlarmReceiver.class);
        Intent intent = new Intent(cordova.getActivity(), LocalNotificationReceiver.class);

        intent.setAction("" + notificationId);

@@ -139,7 +128,7 @@ public class LocalNotification extends CordovaPlugin {
     * all our alarms to loop through these alarms and unregister them one
     * by one.
     */
    public void cancelAll() {
    private void cancelAll() {
        SharedPreferences settings = cordova.getActivity().getSharedPreferences(PLUGIN_NAME, Context.MODE_PRIVATE);
        Map<String, ?> alarms      = settings.getAll();
        Set<String> alarmIds       = alarms.keySet();
+32 −41
Changes for src/android/LocalNotificationOptions.java: 32 added lines, 41 removed lines.
Original line number Diff line number Diff line
@@ -9,10 +9,10 @@

package de.appplant.cordova.plugin;

import java.util.Calendar;

import org.json.JSONObject;

import android.R;

/**
 * Class that helps to store the options that can be specified per alarm.
 */
@@ -21,93 +21,84 @@ public class LocalNotificationOptions {
    /*
     * Options that can be set when this plugin is invoked
     */
    private Calendar calendar = Calendar.getInstance();
    private String title      = null;
    private String subTitle   = null;
    private String sound      = null;
    private long interval     = 0;
    private String foreground = null;
    private String background = null;
    private int icon          = -1;
    private int badge         = 0;
    private JSONObject options = new JSONObject();
    private String id          = null;
    private long interval      = 0;
    private long date          = 0;

    /**
     * Parse options passed from javascript part of this plugin.
     */
    public void parse (JSONObject options) {
        String date    = options.optString("date");
        String message = options.optString("message");

        if (!"".equals(date)) {
            calendar.setTimeInMillis(1000*Long.parseLong(date));
    LocalNotificationOptions (JSONObject options) {
        this.options = options;
        date         = options.optLong("date") * 1000;
        //interval   = options.optString("repeat");
        id           = options.optString("id");
    }

        if (!"".equals(message)) {
            String lines[] = message.split("\\r?\\n");

            title = lines[0];

            if (lines.length > 1)
                subTitle = lines[1];
    /**
     * Gibt die Eigenschaften als JSONObjekt an.
     */
    public JSONObject getJSONObject() {
        return options;
    }

        sound      = options.optString("sound");
        icon       = options.optInt("icon");
        //interval   = options.optString("repeat");
        foreground = options.optString("foreground");
        background = options.optString("background");
        badge      = options.optInt("badge");
        id         = options.optString("id");
    /**
     * Gibt die Zeit in Sekunden an, wann die Notification aufpoppen soll.
     */
    public long getDate() {
        return date;
    }

    /**
     * Gibt den Kalender mit dem Datum der nächsten Notification an.
     * Gibt die Nachricht der Notification an.
     */
    public Calendar getCalendar() {
       return calendar;
    public String getMessage () {
        return options.optString("message");
    }

    /**
     * Gibt den Titel der Notification an.
     */
    public String getTitle () {
       return title;
        return getMessage().split("\\r?\\n")[0];
    }

    /**
     * Gibt den Untertitel der Notification an.
     */
    public String getSubTitle () {
       return subTitle;
        String[] lines = getMessage().split("\\r?\\n");

        return (lines.length > 1) ? lines[1] : "";
    }

    /**
     * Gibt den Pfad zum Sound der Notification an.
     */
    public String getSound () {
       return sound;
        return options.optString("sound", null);
    }

    /**
     * Gibt den Pfad zum Icon der Notification an.
     */
    public int getIcon () {
       return icon;
        return options.optInt("icon", R.drawable.ic_menu_info_details);
    }

    /**
     * Gibt den Pfad zur Callback-Funktion der Notification an.
     */
    public String getForeground () {
       return foreground;
        return options.optString("foreground", null);
    }

    /**
     * Gibt den Pfad zur Callback-Funktion der Notification an.
     */
    public String getBackground () {
       return background;
        return options.optString("background", null);
    }

    /**
@@ -121,7 +112,7 @@ public class LocalNotificationOptions {
     * Gibt die Badge-Nummer der Notification an.
     */
    public int getBadge () {
       return badge;
        return options.optInt("badge", 0);
    }

    /**
+93 −0
Changes for src/android/LocalNotificationReceiver.java: 93 added lines, 0 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.
 *  Copyright 2013 Sebastian Katzer. All rights reserved.
 *  GPL v2 licensed
 */

package de.appplant.cordova.plugin;

import java.util.Calendar;

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

import android.R;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.Notification.Builder;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;

/**
 * The alarm receiver is triggered when a scheduled alarm is fired. This class
 * reads the information in the intent and displays this information in the
 * Android notification bar. The notification uses the default notification
 * sound and it vibrates the phone.
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class LocalNotificationReceiver extends BroadcastReceiver {

	public static final String OPTIONS = "LOCAL_NOTIFICATION_OPTIONS";

	@Override
	public void onReceive (Context context, Intent intent) {
		NotificationManager notificationMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
		LocalNotificationOptions options    = null;
		Bundle bundle                       = intent.getExtras();
		int id                              = 0;
		JSONObject args;

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

		try {
			id = Integer.parseInt(options.getId());
		} catch (Exception e) {}

		/*
		 * If you set a repeating alarm at 11:00 in the morning and it
		 * should trigger every morning at 08:00 o'clock, it will
		 * immediately fire. E.g. Android tries to make up for the
		 * 'forgotten' reminder for that day. Therefore we ignore the event
		 * if Android tries to 'catch up'.
		 */
		if (options.getInterval() > 0) {
			Calendar now    = Calendar.getInstance();
			int alarmHour   = 0;//bundle.getInt(HOUR_OF_DAY);
			int alarmMin    = 0;//bundle.getInt(MINUTE);
			int currentHour = now.get(Calendar.HOUR_OF_DAY);
			int currentMin  = now.get(Calendar.MINUTE);

			if (currentHour != alarmHour && currentMin != alarmMin) {

				return;
			}
		}

		Builder notification = new Notification.Builder(context)
		.setContentTitle(options.getTitle())
		.setContentText(options.getSubTitle())
		//.setVibrate(new long[] { 0, 100, 200, 300 })
		.setDefaults(Notification.DEFAULT_SOUND)
		.setNumber(0)
		.setSmallIcon(options.getIcon());

		/*
		 * If you want all reminders to stay in the notification bar, you should
		 * generate a random ID. If you want do replace an existing
		 * notification, make sure the ID below matches the ID that you store in
		 * the alarm intent.
		 */
		notificationMgr.notify(id, notification.build());
	}
}
 No newline at end of file