In this part of my Android video tutorial I’ll cover the NotificationManager, TaskStackBuilder, PendingIntent, AlarmManager and more on Intents.
The focus this time is on being able to notify the user of events even if my app isn’t running. The code is set up so that you can easily copy and paste out the capabilities you need directly into your app. All of the code follows the video below with a ton of comments to help.
If you like videos like this it helps to tell Google Plus with a click here [googleplusone]
Code From the Video
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Show Notification"
android:id="@+id/showNotificationBut"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:onClick="showNotification"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop Notification"
android:id="@+id/stopNotificationBut"
android:layout_below="@+id/showNotificationBut"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:onClick="stopNotification"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Alert in 5 Seconds"
android:id="@+id/alertButton"
android:layout_below="@+id/stopNotificationBut"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:onClick="setAlarm"/>
</RelativeLayout>
MainActivity.java
package com.newthinktank.derekbanas.notificationex;
import android.app.AlarmManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import java.util.GregorianCalendar;
// NotificationManager : Allows us to notify the user that something happened in the background
// AlarmManager : Allows you to schedule for your application to do something at a later date
// even if it is in the background
public class MainActivity extends ActionBarActivity {
Button showNotificationBut, stopNotificationBut, alertButton;
// Allows us to notify the user that something happened in the background
NotificationManager notificationManager;
// Used to track notifications
int notifID = 33;
// Used to track if notification is active in the task bar
boolean isNotificActive = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize buttons
showNotificationBut = (Button) findViewById(R.id.showNotificationBut);
stopNotificationBut = (Button) findViewById(R.id.stopNotificationBut);
alertButton = (Button) findViewById(R.id.alertButton);
}
public void showNotification(View view) {
// Builds a notification
NotificationCompat.Builder notificBuilder = new NotificationCompat.Builder(this)
.setContentTitle("Message")
.setContentText("New Message")
.setTicker("Alert New Message")
.setSmallIcon(R.drawable.ntt_logo_24_24);
// Define that we have the intention of opening MoreInfoNotification
Intent moreInfoIntent = new Intent(this, MoreInfoNotification.class);
// Used to stack tasks across activites so we go to the proper place when back is clicked
TaskStackBuilder tStackBuilder = TaskStackBuilder.create(this);
// Add all parents of this activity to the stack
tStackBuilder.addParentStack(MoreInfoNotification.class);
// Add our new Intent to the stack
tStackBuilder.addNextIntent(moreInfoIntent);
// Define an Intent and an action to perform with it by another application
// FLAG_UPDATE_CURRENT : If the intent exists keep it but update it if needed
PendingIntent pendingIntent = tStackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
// Defines the Intent to fire when the notification is clicked
notificBuilder.setContentIntent(pendingIntent);
// Gets a NotificationManager which is used to notify the user of the background event
notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Post the notification
notificationManager.notify(notifID, notificBuilder.build());
// Used so that we can't stop a notification that has already been stopped
isNotificActive = true;
}
public void stopNotification(View view) {
// If the notification is still active close it
if(isNotificActive) {
notificationManager.cancel(notifID);
}
}
public void setAlarm(View view) {
// Define a time value of 5 seconds
Long alertTime = new GregorianCalendar().getTimeInMillis()+5*1000;
// Define our intention of executing AlertReceiver
Intent alertIntent = new Intent(this, AlertReceiver.class);
// Allows you to schedule for your application to do something at a later date
// even if it is in he background or isn't active
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// set() schedules an alarm to trigger
// Trigger for alertIntent to fire in 5 seconds
// FLAG_UPDATE_CURRENT : Update the Intent if active
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime,
PendingIntent.getBroadcast(this, 1, alertIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
}
}
more_info_notific.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Info on the notification"
android:id="@+id/textView"
android:textSize="16sp"/>
</LinearLayout>
MoreInfoNotification.java
package com.newthinktank.derekbanas.notificationex;
import android.app.Activity;
import android.os.Bundle;
// Called when the notification is clicked on in the task bar
public class MoreInfoNotification extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.more_info_notific);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.newthinktank.derekbanas.notificationex" >
<!-- Permission to use AlarmManager -->
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<!-- Permission to Send SMS -->
<uses-permission android:name="android.permission.SEND_SMS"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MoreInfoNotification"
android:label="More on notification"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
<receiver android:name=".AlertReceiver"/>
</application>
</manifest>
AlertReceiver.java
package com.newthinktank.derekbanas.notificationex;
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.support.v4.app.NotificationCompat;
public class AlertReceiver extends BroadcastReceiver{
// Called when a broadcast is made targeting this class
@Override
public void onReceive(Context context, Intent intent) {
createNotification(context, "Times Up", "5 Seconds Has Passed", "Alert");
}
public void createNotification(Context context, String msg, String msgText, String msgAlert){
// Define an Intent and an action to perform with it by another application
PendingIntent notificIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
// Builds a notification
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ntt_logo_24_24)
.setContentTitle(msg)
.setTicker(msgAlert)
.setContentText(msgText);
// Defines the Intent to fire when the notification is clicked
mBuilder.setContentIntent(notificIntent);
// Set the default notification option
// DEFAULT_SOUND : Make sound
// DEFAULT_VIBRATE : Vibrate
// DEFAULT_LIGHTS : Use the default light notification
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
// Auto cancels the notification when clicked on in the task bar
mBuilder.setAutoCancel(true);
// Gets a NotificationManager which is used to notify the user of the background event
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Post the notification
mNotificationManager.notify(1, mBuilder.build());
}
}