Commit 331227c6 by Sebastián Katzer

Halbwegs funktionsfähiger Android Support

parent 8eda6a2d
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
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
......@@ -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();
......
......@@ -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);
}
/**
......
/**
* 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment