diff --git a/README.md b/README.md index 03e8f89..c2b699e 100755 --- a/README.md +++ b/README.md @@ -55,7 +55,8 @@ You can create an AlarmNotification using the below properties: * vibrate (Optional) (bool) Vibrate the device on notification. Please note this requires the vibrate permission. * showLights (Optional) (bool) Activate notification lights on device when alarm triggered. * icon - (Optional)The icon of the notification, this can be a system icon or resource included path, e.g. use `Ti.App.Android.R.drawable.appicon` to use your app icon at `platform/android/res/drawable-*/appicon.png`. -* repeat - (Optional) (int) Used to schedule a repeating alarm. You can provide a millisecond value or use the words hourly, daily, monthly, yearly. +* repeat - (Optional) (int) Used to schedule a repeating alarm. You can provide a millisecond value or use the words hourly, daily, weekly, monthly, yearly. +* channelName - (Optional) (string) Name of notification channel name. Please note if you omit the day, month, and year parameters the module will assume you mean to make the alarm effective from the current time If second is provided, alarm will be set to now plus the number of seconds provided; if minute is provided, alarm will be set for now plus the number of minutes provided. @@ -63,6 +64,7 @@ Please note if you omit the day, month, and year parameters the module will assu The valid repeat options are: * hourly * daily +* weekly * monthly * yearly diff --git a/build.properties b/build.properties index 0b55e02..67a70f2 100755 --- a/build.properties +++ b/build.properties @@ -1,4 +1,4 @@ -titanium.platform=/Users/michielve/Library/Application Support/Titanium/mobilesdk/osx/6.1.2.GA/android -android.platform=/Users/michielve/android-sdk/platforms/android-23 -google.apis=/Users/michielve/android-sdk/add-ons/addon-google_apis-google-23 +titanium.platform=/Users/michielve/Library/Application Support/Titanium/mobilesdk/osx/7.2.0.GA/android +android.platform=/Users/michielve/Library/Android/sdk/platforms/android-26 +google.apis=/Users/michielve/Library/Android/sdk/add-ons/addon-google_apis-google-23 diff --git a/dist/alarmmanager.jar b/dist/alarmmanager.jar index 7c24d68..2898dfc 100644 Binary files a/dist/alarmmanager.jar and b/dist/alarmmanager.jar differ diff --git a/dist/bencoding.alarmmanager-android-2.0.0.zip b/dist/bencoding.alarmmanager-android-2.0.0.zip new file mode 100644 index 0000000..a518382 Binary files /dev/null and b/dist/bencoding.alarmmanager-android-2.0.0.zip differ diff --git a/documentation/index.html b/documentation/index.html index 464821c..f8f9455 100755 --- a/documentation/index.html +++ b/documentation/index.html @@ -78,16 +78,19 @@
Please note if you omit the day, month, and year parameters the module will assume you mean to make the alarm effective from the current time If second is provided, alarm will be set to now plus the number of seconds provided; if minute is provided, alarm will be set for now plus the number of minutes provided.
The valid repeat options are: * hourly * daily +* weekly * monthly * yearly
diff --git a/manifest b/manifest index b264102..57e83f7 100644 --- a/manifest +++ b/manifest @@ -2,7 +2,7 @@ # this is your module manifest and used by Titanium # during compilation, packaging, distribution, etc. # -version: 1.0.1 +version: 2.0.0 apiversion: 4 architectures: arm64-v8a armeabi-v7a x86 description: This module provides Titanium access to Androids Alarm Manager functionality diff --git a/src/bencoding/alarmmanager/AlarmManagerProxy.java b/src/bencoding/alarmmanager/AlarmManagerProxy.java index c00effa..40ede08 100755 --- a/src/bencoding/alarmmanager/AlarmManagerProxy.java +++ b/src/bencoding/alarmmanager/AlarmManagerProxy.java @@ -70,6 +70,7 @@ private Intent createAlarmNotifyIntent(KrollDict args,int requestCode){ String contentTitle = ""; String contentText = ""; String notificationSound = ""; + String channelName = "notification"; boolean playSound = optionIsEnabled(args,"playSound"); boolean doVibrate = optionIsEnabled(args,"vibrate"); boolean showLights = optionIsEnabled(args,"showLights"); @@ -84,6 +85,10 @@ private Intent createAlarmNotifyIntent(KrollDict args,int requestCode){ }; } + if (args.containsKey("channelName")) { + channelName = TiConvert.toString(args, "channelName"); + } + if (args.containsKey(TiC.PROPERTY_ICON)) { Object icon = args.get(TiC.PROPERTY_ICON); if (icon instanceof Number) { @@ -116,6 +121,7 @@ private Intent createAlarmNotifyIntent(KrollDict args,int requestCode){ intent.putExtra("notification_requestcode", requestCode); intent.putExtra("notification_root_classname", AlarmmanagerModule.rootActivityClassName); intent.putExtra("notification_request_code", requestCode); + intent.putExtra("notification_channel_name", channelName); // As of API 19 setRepeating == setInexactRepeating, see also: // http://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int, long, long, android.app.PendingIntent) @@ -188,11 +194,11 @@ private long repeatingFrequency(KrollDict args){ long freqResults = utils.DAILY_MILLISECONDS; Object repeat = args.get("repeat"); if (repeat instanceof Number) { - utils.debugLog("Repeat value provided in milliseconds found"); + utils.infoLog("Repeat value provided in milliseconds found"); freqResults = ((Number)repeat).longValue(); } else { String repeatValue = TiConvert.toString(repeat); - utils.debugLog("Repeat value of " + repeatValue + " found"); + utils.infoLog("Repeat value of " + repeatValue + " found"); if(repeatValue.toUpperCase()=="HOURLY"){ freqResults=utils.HOURLY_MILLISECONDS; } @@ -206,7 +212,7 @@ private long repeatingFrequency(KrollDict args){ freqResults=utils.YEARLY_MILLISECONDS; } } - utils.debugLog("Repeat Frequency in milliseconds is " + freqResults); + utils.infoLog("Repeat Frequency in milliseconds is " + freqResults); return freqResults; } @Kroll.method diff --git a/src/bencoding/alarmmanager/AlarmNotificationListener.java b/src/bencoding/alarmmanager/AlarmNotificationListener.java index 28ee909..9151417 100755 --- a/src/bencoding/alarmmanager/AlarmNotificationListener.java +++ b/src/bencoding/alarmmanager/AlarmNotificationListener.java @@ -17,6 +17,8 @@ import android.R; import android.app.Notification; import android.app.NotificationManager; +import android.app.NotificationChannel; +import android.media.AudioAttributes; import android.app.PendingIntent; import android.net.Uri; import android.content.BroadcastReceiver; @@ -64,6 +66,10 @@ public void onReceive(Context context, Intent intent) { utils.debugLog("On notification vibrate? " + new Boolean(doVibrate).toString()); boolean showLights = bundle.getBoolean("notification_show_lights",false); utils.debugLog("On notification show lights? " + new Boolean(showLights).toString()); + String channelName = bundle.getString("notification_channel_name"); + if (utils.isEmptyString(channelName)) { + channelName = "notification"; + } notificationManager = (NotificationManager) TiApplication.getInstance().getSystemService(TiApplication.NOTIFICATION_SERVICE); utils.debugLog("NotificationManager created"); @@ -77,13 +83,38 @@ public void onReceive(Context context, Intent intent) { notifyIntent.putExtra("customData", customData); } - //Notification notification = new Notification(icon, contentTitle, System.currentTimeMillis()); PendingIntent sender = PendingIntent.getActivity( TiApplication.getInstance().getApplicationContext(), requestCode, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT | Notification.FLAG_AUTO_CANCEL); + + String channelId = "default"; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); + if (playSound) { + // IMPORTANCE_DEFAULT has by default sound so we only have to set custom sound + if (hasCustomSound) { + AudioAttributes.Builder attrs = new AudioAttributes.Builder(); + attrs.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION); + attrs.setUsage(AudioAttributes.USAGE_NOTIFICATION); + channel.setSound(Uri.parse(soundPath), attrs.build()); + } + } else { + channel.setSound(null, null); + } + channel.enableLights(showLights); + if (doVibrate) { + channel.enableVibration(doVibrate); + } else { + // Bug - see: https://stackoverflow.com/a/47646166/1294832 + channel.setVibrationPattern(new long[]{ 0 }); + channel.enableVibration(true); + } + notificationManager.createNotificationChannel(channel); + } + NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder( - TiApplication.getInstance().getApplicationContext()) + TiApplication.getInstance().getApplicationContext(), channelId) .setWhen(System.currentTimeMillis()) .setContentText(contentText) .setContentTitle(contentTitle) @@ -107,7 +138,7 @@ private void createRepeatNotification(Bundle bundle) { Intent intent = new Intent(TiApplication.getInstance().getApplicationContext(), AlarmNotificationListener.class); // Use the same extras as the original notification - intent.putExtras(bundle); + // Update date and time by repeat interval (in milliseconds) int day = bundle.getInt("notification_day"); @@ -123,12 +154,29 @@ private void createRepeatNotification(Bundle bundle) { Calendar now = Calendar.getInstance(); long repeat_ms = bundle.getLong("notification_repeat_ms", 0); + if (repeat_ms == 0) { + utils.infoLog("repeat_ms is 0, no good!"); + // Else we can end into an infinite loop below. + return; + } int repeat_s = (int)repeat_ms / 1000; // Add frequence until cal > now while (now.getTimeInMillis() > cal.getTimeInMillis()) { cal.add(Calendar.SECOND, repeat_s); + utils.infoLog("Add second"); } + + utils.infoLog("Update bundle with new calendar: " + cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + "-" + cal.get(Calendar.DAY_OF_MONTH) + " " + cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND)); + bundle.putInt("notification_year", cal.get(Calendar.YEAR)); + bundle.putInt("notification_month", cal.get(Calendar.MONTH)); + bundle.putInt("notification_day", cal.get(Calendar.DAY_OF_MONTH)); + bundle.putInt("notification_hour", cal.get(Calendar.HOUR_OF_DAY)); + bundle.putInt("notification_minute", cal.get(Calendar.MINUTE)); + bundle.putInt("notification_second", cal.get(Calendar.SECOND)); + + // Update intent with this updated bundle. + intent.putExtras(bundle); int requestCode = bundle.getInt("notification_request_code", AlarmmanagerModule.DEFAULT_REQUEST_CODE); intent.setData(Uri.parse("alarmId://" + requestCode)); @@ -160,7 +208,10 @@ private NotificationCompat.Builder createNotifyFlags(NotificationCompat.Builder // DEFAULT_SOUND overrides custom sound, so never set both if (playSound) { if(hasCustomSound){ - notification.setSound(Uri.parse(soundPath)); + // if >= 26, we set it on the channel. + //if (android.os.Build.VERSION.SDK_INT < 26) { + notification.setSound(Uri.parse(soundPath)); + //} } else { defaults = defaults | Notification.DEFAULT_SOUND; }