Cosc 4730 Android Notifications Plus Alarms and BroadcastReceivers Notifications • There are a couple of ways to notify users without interrupting what they are doing • The first is Toast, use the factory method – Toast.makeText(getBaseContext(), "Text to display to user", Toast.LENGTH_SHORT).show(); – getBaseContext() or getContext() • Toast.LENGTH_SHORT or Toast.LENGTH_LONG is the duration it will be displayed. Notifications and Android APIs • The notifications have underground a lot of change. – There is a completely deprecated method from 2.3.3 and below – The newer method in 3.0 to 4.1 – 4.1+ (and popups in 5.0) – And so much of this is used from the v4 support library. • Things will not look the same, but at least you can use the same code. Status Bar Notifications • A status bar notification adds an icon to the system's status bar (with an optional ticker-text message) and an expanded message in the "Notifications" window. – You can also configure the notification to alert the user with a sound, a vibration, and flashing lights on the device. • When the user selects the expanded message, Android fires an Intent that is defined by the notification (usually to launch an Activity). Basics of notifications (all APIs) • First get the NotificationManager – retrieve a reference to the NotificationManager with getSystemService() • Create a Notification object – Min requirements are an icon, text, and time of the event. • Note, time of event is the time currently or in past. – For “future” events we have to use alarms, which is covered later. • Pass it your Notification object with notify() via the notification manager. – Also send an ID number. This ID is used by your app, doesn’t have to unique, but should be if you want more then one. – The system will show your notification on the status bar and the user will interact with it. API 10 (2.3.3) and below NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int icon = R.drawable.icon; CharSequence tickerText = "Hello"; long when = System.currentTimeMillis(); Notification notification = new Notification(icon, tickerText, when); //send the notification mNotificationManager.notify(ID_number, notification); Canceling notifications • To cancel a specific notification mNotificationManager.cancel(ID_number); • To cancel all of the notifications mNotificationManager.cancelAll(); • In newer API/support library. – .setAutoCancel(true) • which the user clicks it, it will clear. Adding to the notification • To add sound – default sound • notification.defaults |= Notification.DEFAULT_SOUND; – To use a different sound with your notifications, pass a Uri reference to the sound field. The following example uses a known audio file saved to the device SD card: • notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3"); – the audio file is chosen from the internal MediaStore's ContentProvider: • notification.sound = Uri.withAppendedPath( Audio.Media.INTERNAL_CONTENT_URI, "6"); Adding to the notification (2) • Adding vibration – To use the default pattern • notification.defaults |= Notification.DEFAULT_VIBRATE; – To define your own vibration pattern, pass an array of long values to the vibrate field: • long[] vibrate = {0,100,200,300}; • notification.vibrate = vibrate; – You'll need to add <uses-permission android:name="android.permission.VIBRATE"></u ses-permission> in the AndroidManifest.xml Adding to the notification (3) • Adding flashing lights – To use the default light setting, add "DEFAULT_LIGHTS" to the defaults field: • notification.defaults |= Notification.DEFAULT_LIGHTS; – To define your own color and pattern, define a value for the ledARGB field (for the color), the ledOffMS field (length of time, in milliseconds, to keep the light off), the ledOnMS (length of time, in milliseconds, to keep the light on), and also add "FLAG_SHOW_LIGHTS" to the flags field: • • • • notification.ledARGB = 0xff00ff00; notification.ledOnMS = 300; notification.ledOffMS = 1000; notification.flags |= Notification.FLAG_SHOW_LIGHTS; Adding to the notification (4) • FLAG_AUTO_CANCEL – flag Add this to the flags field to automatically cancel the notification after it is selected from the Notifications window. • FLAG_INSISTENT – flag Add this to the flags field to repeat the audio until the user responds. – Should be flag "uh pick me! PICK ME!" • FLAG_ONGOING_EVENT – flag Add this to the flags field to group the notification under the "Ongoing" title in the Notifications window. – This indicates that the application is on-going — its processes is still running in the background, even when the application is not visible (such as with music or a phone call). • FLAG_NO_CLEAR – flag Add this to the flags field to indicate that the notification should not be cleared by the "Clear notifications" button Emulator note • Many of the additional flags do nothing with the emulator – There is no default sounds, it's set to silent – no lights or vibration either, of course. Notifications 3.0+ • We are going to use the support library at this point, so we code everything the same. • Note, the Action Buttons (AddAction()) will not display on 4.1 and below. NotificationCompat • So you can write the “new” notifications, this is a support library, call NotificationCompat – This allows us to create fancy notifications, but still work for the lower API. How it works. • Create a NotificationCompat.Builder object and then once you have it configured, have it build the notification. – use the NotificationCompat from the support lib v4 – import android.support.v4.app.NotificationCompat; – import android.support.v4.app.NotificationManagerCompat; – Side note, this also allows notifications to show up on android wear devices as well. Simple notification Notification noti = new NotificationCompat.Builder(getApplicationContext()) .setSmallIcon(R.drawable.ic_launcher) .setWhen(System.currentTimeMillis()) //When the event occurred, now .setTicker("Message on status bar") //message shown on the status bar .setContentTitle("Marquee Message") //Title message top row. .setContentText("Icon and Message") //second row .setContentIntent(contentIntent) //what activity to open. .setAutoCancel(true) //allow auto cancel when pressed. .build(); //finally build and return a Notification. • Show the notification nm.notify(NotID, noti); Lights, sounds, etc. • Just like before with can use the defaults – .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND); • Or use the newer methods to choose your own. – setLights(int argb, int onMs, int offMs) – setSound(Uri sound) – setVibrate(long[] pattern) Action Buttons • Add the following to your notification • addAction(int icon, CharSequence title, PendingIntent intent) – Icon and title for the button – The intent should be completely different intent from the setContentIntent(intent), so you know which button was clicked. • See the example code, where I have four intents for the example with three buttons. Expanded text • This one we need change the style of the notification. First use the builder to create the default • NotificationCompat.Builder build = new NotificationCompat.Builder(ge …; • Now change to another style and add more text Notification noti = new NotificationCompat.BigTextStyle(build) .bigText(“…”) //lots text here. .build(); Expanded text (2) • And we can get something like this Expanded with image. • Same idea, except style is Notification noti = new NotificationCompat.BigPictureStyle(build) .bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.jelly_bean)) .build(); • Note two addAction(..) methods were added in the build. Style of an inbox • Inbox style and use addline and setSummaryText Notification noti = new NotificationCompat.InboxStyle(build) .addLine("Cupcake: Hi, how are you?") .addLine("Jelly Bean: Yummy") .setSummaryText("+999 more emails") .build(); But I want to notify a user later! • There is no native way to that with the notifications. • You need to use an AlarmManager and calendar object. CALENDAR Calendar object • It a pretty simple object, • Used briefly in the GUI demo for the date/time pickers. • Get an intance, which has the current time set. Calendar calendar = Calendar.getInstance(); • Use a get(..) and set(..) to change the information as needed. – Set using the following constants Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND • Say I want to set the calendar to 4:40am calendar.set(Calendar.HOUR_OF_DAY, 4); calendar.set(Calendar.MINUTE, 40); calendar.set(Calendar.SECOND, 0); • As note, if it is already passed 4:40am, there would be a problem later • Say I want to set it for 2 minutes from now. calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) +2); ALARMMANAGER AlarmManager • These allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running. – We get an in AlarmManager service • Set an intent and pendingIntent for the activity (or say a broadcast receiver) to call. • A time in Milliseconds when to send the intent • And that we want a “wakeup call” at that time. • Get the AlarmManager – AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); Example code • Using the calendar object for 2 minutes later. • Create the intent and pendingIntent Intent notificationIntent = new Intent("edu.cs4730.notificationdemo.DisplayNotification"); PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.this, NotID, notificationIntent, 0); • Now set the alarm alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), contentIntent); Example code (2) • What is this: • Intent("edu.cs4730.notificationdemo.DisplayNotification"); – We could also just give a Activity name. • It comes from the manifest file where we describe the activity or broadcast receiver. This case an activity. <activity android:name=".DisplayNotification" … /> <intent-filter> <action android:name="edu.cs4730.notificationdemo.DisplayNotification" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> Finally! • The displayNotification activity is called when the alarm goes off. And it’s the displayNotification activity that now creates and notification. BROADCAST RECEIVER BroadcastReceiver • Part of the android.content package. – Basically a listener, but for “broadcast” information. • Such as sms and other broadcast data. • Including our own broadcast intents. • Note, you don’t have access to most screen widgets in a broadcast receiver, except toast. – Override the onReceive(Context, Intent) method • The intent holds the information from the broadcast. Note, we will come back with a full lecture on BroadcastReceiver later on as well. BroadcastReceiver (2) • A broadcastReceiver can be registered into two ways: – Context.registerReceiver() in the “main” code • The receiver can be added and removed as needed. – Via a receiver tag in the AndroidManifest file. • will start up at boot. – We use this method for simplicity. Extend the BroadcastReceiver public class myReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { } } • Intent Tells you what it is, via the get getAction() method. AndroidManifest.xml • We also need to add the class. This is a receiver class so it may look something like this <receiver android:name=".myRecv"> <intent-filter> <action android:name="edu.cs4730.notificationdemo.broad Notification"/> </intent-filter> </receiver> As a Note • We could setup multiple intents to be received by the receiver, so we normally check the action to make sure it’s “ours”. Example public class myBroadcastReciever extends BroadcastReceiver { private static final String ACTION = "edu.cs4730.notificationdemo.broadNotification"; • @Override public void onReceive(Context context, Intent intent) { String info= "no bundle"; if (intent.getAction().equals(ACTION)){ //is it our action Bundle extras = intent.getExtras(); if (extras != null) { info = extras.getString("mytype"); if (info == null) { info = "nothing"; } Likely toast or start an activity or notification. Whatever is needed now. }}} Demo code • notificiationDemo.zip – notificationDemo project • All the different notifications listed in here – Lots of buttons to try out each one. • Alarms and the broadcastReceiver – notificationDemo2 project • Need first one installed • Sends to the broadcast receiver • And uses an alarm to send to the broadcast receiver • You may also find http://developer.android.com/guide/topics/ui/no tifiers/notifications.html helpful. Lastly android 5 notifications. • In Lollipop three new pieces were added. – setVisibility() and specify one of these values: – VISIBILITY_PRIVATE: Shows basic information, such as the notification’s icon, but hides the notification’s full content. – VISIBILITY_PUBLIC: Shows the notification’s full content. – VISIBILITY_SECRET: Shows nothing, excluding even the notification’s icon. – addPerson(): Enables you to add one or more people who are relevant to a notification. – setPriority(): Marks the notification as more or less important than normal notifications. • Notifications with the priority field set to PRIORITY_MAX or PRIORITY_HIGH appear in a small floating window if the notification also has sound or vibration. Lastly android 5 notifications (2) • Adding the following (with NotificationCompat) .setPriority(Notification.PRIORITY_MAX) .setVibrate(new long[]{1000, 1000, 1000, 1000, 1000}) – We can produce this kind of notification: References • • • • • • • • • • http://stackoverflow.com/questions/1198558/how-to-send-parameters-from-a-notification-clickto-an-activity http://mobiforge.com/developing/story/displaying-status-bar-notifications-android http://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html http://mobiforge.com/developing/story/displaying-status-bar-notifications-android http://stackoverflow.com/questions/12006724/set-a-combination-of-vibration-lights-or-sound-fora-notification-in-android http://developer.android.com/reference/android/app/Notification.html http://developer.android.com/reference/android/content/BroadcastReceiver.html http://stackoverflow.com/questions/12372654/how-to-trigger-broadcast-receiver-fromnotification http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html Android 5 notifications information: – – http://developer.android.com/about/versions/android-5.0.html#Notifications http://www.intertech.com/Blog/android-development-tutorial-lollipop-notifications/ Q&A