I have an action to Dial a number via
uri = Uri.parse("tel:" + address);
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(uri);
PendingIntent pd = PendingIntent.getActivity(context, 0,intent,
PendingIntent.FLAG_UPDATE_CURRENT);
notif.addAction(R.drawable.ic_menu_call, "Call", pd);
but the problem is that I don't know
how/when to call the NotificationManager's manager.cancel() function
so as to dismiss the notification when the call action is clicked!
I had the same situation and I managed to solve it by creating a broadcast receiver that is called when the action button is pressed. The broadcast receiver then receives an intent with the notification id that you want to dismiss and the number you want to dial.
The is the code that creates the notification:
NotificationManager notificationManager =
(NotificationManager)MyApplication.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);
//for some versions of android you may need to create a channel with the id you want
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel chan = new NotificationChannel("your_channel_id", "ChannelName", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(chan);
}
Intent intent = new Intent(MyApplication.getAppContext(), ActionReciever.class);
intent.putExtra("phoNo", phoneNumber);
// num is the notification id
intent.putExtra("id", num);
PendingIntent myPendingIntent = PendingIntent.getBroadcast(
MyApplication.getAppContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
);
Notification n = new NotificationCompat.Builder(MyApplication.getAppContext(),
"your_channel_id")
.setSmallIcon(R.drawable.app_pic)
.addAction(R.drawable.app_pic, "Dial now", myPendingIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(num, n);
This is the broadcast receiver code, it is called when the action button is pressed. The received intent here is the intent inside the pending intent we prepared in the notification:
public class ActionReciever extends BroadcastReceiver {
#SuppressLint("MissingPermission")
#Override
public void onReceive(Context context, Intent intent) {
String phoneNumber = intent.getStringExtra("phoNo");
int id = intent.getIntExtra("id",0);
Intent i = new Intent(Intent.ACTION_DIAL);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setData(Uri.parse("tel:" + phoneNumber));
NotificationManager notificationManager =
(NotificationManager) MyApplication.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(id);
context.startActivity(i);
}
}
Register the BroadcastReceiver in the app manifest inside application tag
<receiver android:name=".ActionReciever" />
MyApplication is a class that extends the default Application so I can have a place to store the context I need.
public class MyApplication extends Application {
private static Context context;
public void onCreate() {
super.onCreate();
MyApplication.context = getApplicationContext();
}
public static Context getAppContext() {
return MyApplication.context;
}
}
Note that you need to update the manifest to run the MyApplication class like this:
android:name="com.example.yourpackage.MyApplication"
This code works even if the app is down and without a background service.
See Android READ PHONE STATE? - about phone state.
case TelephonyManager.CALL_STATE_RINGING:
notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(100); // cancel notification by ID
break;
// build your notification.
intent notificationIntent = new Intent(context,
YourPhoneActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
Bitmap bm = BitmapFactory.decodeResource(context.getResources(),
iconLarge);
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context).setSmallIcon(iconSmall).setLargeIcon(bm)
.setContentTitle(title).setContentText(message)
.setAutoCancel(false).setContentIntent(intent).setWhen(when)
.setTicker(message);
builder.getNotification();
Related
When users click the icon of my app on the Notification bar, users will be redirected to my app.
Can anyone provide sample code? How to subscribe to the click event, and the redirection.
Update
My application might be using some services that cause the display of icon on Notification bar.
My application is calling SetForeground, not getBroadcast().
Update 2
how can I redirect users to the last Activity rather than the hard-code activity? For example, the last Activity might be different when users navigate to different activity.
Notification click event in xamarin forms
It's a sample from my app, it works. I think you can do somthing similar.
public class AlarmReceiver extends BroadcastReceiver {
public final static String NOTIF_TEXT = AlarmSetActivity.class.getPackage() + ".NOTIF_TEXT";
private String notifText;
#Override
public void onReceive(Context context, Intent intent) {
notifText = intent.getExtras().getString(NOTIF_TEXT);
//().getExtras().getString(NOTE_BODY);
Toast.makeText(context, "Notification from " + R.string.app_name,
Toast.LENGTH_LONG).show();
buildNotification(context);
}
private void buildNotification(Context context) {
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = "default_channel_id";
String channelDescription = "Default Channel";
Notification.Builder builder = new Notification.Builder(context);
Intent intent = new Intent(context, **EditorActivity.class**);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
intent, 0);
builder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(context.getString(R.string.notificTitle)).setContentText(notifText)
.setContentInfo(context.getString(R.string.notificInfo)).setTicker(context.getString(R.string.notifTicker))
.setLights(0xFFFF0000, 500, 500)
//.setChannelId(id)
.setContentIntent(pendingIntent).setAutoCancel(true);
Notification notification = builder.build();
//notification.so
notificationManager.notify(2, notification);
}
}
And:
private void setAlarm(Calendar targetCal) {
mTimeTextView.setText(R.string.alarm_on);
mTimeTextView.append(String.valueOf(targetCal.getTime()));
Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
intent.putExtra(AlarmReceiver.NOTIF_TEXT,notificationText);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), RQS_TIME, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, targetCal.getTimeInMillis(),
pendingIntent);
}
I have try all the methods but it doesn't work for me. i want to open or resume app with whatever screen open while click on notification.
I used following method:
NotificationCompat.BigTextStyle notiStyle = new NotificationCompat.BigTextStyle();
notiStyle.setBigContentTitle(team);
notiStyle.bigText(message);
Intent resultIntent = new Intent(this, MainDrawerActivity.class);
resultIntent.putExtra("fromNotification", "notification");
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
int icon = R.mipmap.ic_launcher;
return new NotificationCompat.Builder(this).setSmallIcon(icon)
.setAutoCancel(true)
.setContentIntent(resultPendingIntent).setContentTitle(team)
.setContentText(message).setStyle(notiStyle).build();
To raise your application to the foreground without starting any new activity, fire its launcher intent.
This method is from an old project of mine.
/**
* Creates a new launcher intent, equivalent to the intent generated by
* clicking the icon on the home screen.
*
* #return the launcher intent
*/
public static Intent newLauncherIntent(final Context context) {
final Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
return intent;
}
The intent created by this method does not start a new task if the app is running, even though it has that flag.
This is another way to obtain a launcher intent. However, I found that this intent would always start a new task, which is not what you want if the app is running.
final Intent intent = context.getPackageManager()
.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID);
This is working fine for following three conditions:
1.if app already open and click on notification, notification should remove from status bar.
2.if app is open and in background then app should resume with whatever screen open already previously.
3.if app is close and click on notification in status bar then app should open.
private final static int NORMAL = 0x00;
private final static int BIG_TEXT_STYLE = 0x01;
private static NotificationManager mNotificationManager;
in onMessage call
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
new CreateNotification(BIG_TEXT_STYLE, team, message).execute();
then declare following class in GCMIntentService.
public class CreateNotification extends AsyncTask {
int style = NORMAL;
String team, message;
public CreateNotification(int style, String team, String message) {
this.style = style;
this.team = team;
this.message = message;
}
#Override
protected Void doInBackground(Void... params) {
Notification noti = new Notification();
switch (style) {
case BIG_TEXT_STYLE:
noti = setBigTextStyleNotification(team, message);
break;
}
noti.sound = (null);
noti.defaults = 0;
noti.sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.beep);
noti.flags |= Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(0, noti);
return null;
}
}
and finally
private Notification setBigTextStyleNotification(String team, String message) {
// Create the style object with BigTextStyle subclass.
NotificationCompat.BigTextStyle notiStyle = new NotificationCompat.BigTextStyle();
notiStyle.setBigContentTitle(team);
notiStyle.bigText(message);
Intent resultIntent = getPackageManager()
.getLaunchIntentForPackage(getPackageName());
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the Intent that starts the Activity to the top of the stack.
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
int icon = R.mipmap.ic_launcher;
return new NotificationCompat.Builder(this).setSmallIcon(icon)
.setAutoCancel(true)
.setContentIntent(resultPendingIntent).setContentTitle(team)
.setContentText(message).setStyle(notiStyle).build();
}
You should have something like this in Application class to store the current activity.
private BaseActivity mCurrentActivity = null;
public BaseActivity getCurrentActivity() {
return mCurrentActivity;
}
public void setCurrentActivity(BaseActivity currentActivity) {
this.mCurrentActivity = currentActivity;
}
Then, inside your handle notification Service class.
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
BaseActivity currentActivity = ((App) this.getApplicationContext())
.getCurrentActivity();
Intent intent;
if (currentActivity instanceof ActivityA) {
intent = new Intent(this, ActivityA.class);
} else if (currentActivity instanceof ActivityB) {
intent = new Intent(this, ActivityB.class);
} else {
intent = new Intent(this, MainActivity.class);
}
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// your code...
}
If your app is killed, default activity will be called, such as MainActivity.
Else, when you receive & click push notification message when app is on foreground or background. Current activity will stay there as default activity, such as ActivityA & ActivityB. Then you can navigate to wherever another activities or fragments.
My suggestion, better we should use Fragment, it's easier in navigate to specially screen from push notification.
//I am using write now this can possible
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent notificationIntent = new Intent(context, HomeActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
If you want to just resume the app state then instead of multiple activity I will suggest you just keep single activity and use Fragments for different screen.
On Notification click you need to define entry point of app in notification payload and the entry point decide what will be the next navigation.
If you are having only single activity then you can define that activity as a entry point and on the activity you can decide do you have to push new fragment or not.
Or second option if you are using firebase then push all notification as background notification and onMessageReceive method you can get top activity from activity stack and set that activity as entry point for the notification. But there is still problem as user may be click on notification after navigate from set entry point activity which again problem. So I prefer to go with first one approach.
make new activity
public class FinishImmediateActivity extends AppCompatActivity {
#Override protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
finish();
}
}
add to manifest.xml
<activity android:name=".FinishImmediateActivity"/>
check app is running
public static boolean isMainActivityRunning() {
ActivityManager activityManager = (ActivityManager) MyApp.getContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (int i = 0; i < tasksInfo.size(); i++) {
if (tasksInfo.get(i).baseActivity.getPackageName().equals(MyApp.getContext().getPackageName())) {
return true;
}
}
return false;
}
then call that activity in notification intent.
Intent resultIntent = new Intent(this, isMainActivityRunning() ? FinishImmediateActivity.class : HomeActivity.class);
By this way also we can achieve the above result:
try {
int icon;
icon = R.mipmap.ic_launcher;
int mNotificationId = 001;
Intent intent = new Intent(this, MainDrawerActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
//FLAG_UPDATE_CURRENT is important
PendingIntent pendingIntent = PendingIntent.getActivity(this,
(int)System.currentTimeMillis(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new
NotificationCompat.Builder(
this);
Notification notification =
mBuilder.setSmallIcon(icon).setTicker(json.getString("team")).setWhen(0)
.setAutoCancel(true)
.setContentTitle(json.getString("team"))
.setStyle(new
NotificationCompat.BigTextStyle().bigText(json.getString("message")))
.setContentIntent(pendingIntent)
.setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.beep))
NotificationManager notificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(mNotificationId, notification);
} catch (Exception e) {
e.printStackTrace();
}
I'm delivering a notification which has 2 action buttons namely "Accept" and "Reject".
I'm following this Github repo.
When user clicks "Accept", certain conditions are checked and the logic is performed accordingly.
UPDATE 2.0 - The problem is that upon clicking "Accept" button, operation is happening successfully but the notification isn't disappearing from the status bar because the id generating here: m = (new Random()).nextInt(10000); is different from here: actionIntent.putExtra("id", NotificationARBroadcastReceiver.m); every single time!
Here's the code for notification:
Intent notificationIntent = new Intent(getBaseContext(), NotificationARBroadcastReceiver.class);
notificationIntent.putExtra(NotificationARBroadcastReceiver.NOTIFICATION, getNotificationNewRequestService());
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), m, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, pendingIntent);
Here's getNotificationNewRequestService():
private Notification getNotificationNewRequestService() {
mBuilder =
new NotificationCompat.Builder(getBaseContext())
.setSmallIcon(R.mipmap.app_icon_1)
.setContentTitle("Title")
.setContentText("text...");
Intent resultIntent = new Intent(getBaseContext(), Profile.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
getBaseContext(),
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
// for action button
Intent actionIntent = new Intent(getBaseContext(), MyBroadcastSender.class);
actionIntent.putExtra("id", NotificationARBroadcastReceiver.m);
PendingIntent actionPendingIntent = PendingIntent
.getBroadcast(getBaseContext(),
0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setAutoCancel(true);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.addAction(R.drawable.ic_accepted_request_black_24dp, "Accept", actionPendingIntent);
mBuilder.addAction(R.drawable.ic_close_black_24dp, "Reject", null);
return mBuilder.build();
}
Here's NotificationARBroadcastReceiver.java file:
public class NotificationARBroadcastReceiver extends BroadcastReceiver {
public static String NOTIFICATION = "notification";
public static NotificationManager mNotifyMgr;
public static int m;
#Override
public void onReceive(Context context, Intent intent) {
m = (new Random()).nextInt(10000);
Log.d("mMain", String.valueOf(m));
mNotifyMgr =
(NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
mNotifyMgr.notify(m, notification);
}
}
Here's MyBroadcastSender.java file:
public class MyBroadcastSender extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Broadcast Received by MyBroadcastSender.", Toast.LENGTH_SHORT).show();
int id = intent.getIntExtra("id", 1);
// send back to your class
Intent newIntent = new Intent();
newIntent.setAction(context.getString(R.string.broadcast_id));
newIntent.putExtra("id1", id);
context.sendBroadcast(newIntent);
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
Toast.makeText(context, "Broadcast sent back.", Toast.LENGTH_SHORT).show();
}
}
and here's MyBroadcastReceiver.java file:
// BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
public MyBroadcastReceiver(){
super();
}
#Override public void onReceive(Context context, Intent intent) {
int id2 = intent.getIntExtra("id1", 1);
if (intent.getAction() != null && intent.getAction().equals(getString(R.string.broadcast_id))) {
NotificationARBroadcastReceiver.mNotifyMgr.cancel(id2);
Intent intent1 = new Intent(MyService.this, MainActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
Toast.makeText(context, "Broadcast received by MyBroadcastReceiver. Now, you can perform actions.",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Intent is null.", Toast.LENGTH_SHORT).show();
}
}
}
In getNotificationNewRequestService(), I'm putting notification id as an extra in "id", then in MyBroadcastSender.java, I'm getting this extra as int id = intent.getIntExtra("id", 1); and then putting again as newIntent.putExtra("id1", id); and then finally getting it in MyBroadcastReceiver.java as int id2 = intent.getIntExtra("id1", 1); and trying to remove the notification using it as NotificationARBroadcastReceiver.mNotifyMgr.cancel(id2);.
Sorry for this much code, I've to upload it all as they all are necessary.
What I want is to know how to deliver the same notification id from NotificationARBroadcastReceiver.java (which is a separate java file) to MyBroadcastReceiver(which is an inner class in MyService.java)?
Update 1.0- this is what happened when I printed out the values of m, mMain, id, id1:
D/m: 0
D/mMain: 9994
D/id: 0
D/id1: 0
Assuming getNotificationService() == getNotificationNewRequestService() Looks like the NotificationARBroadcastReceiver isn't called before the notfication is built and displayed.
You would do better to generate the notification id where you create the notification and just add it to the intent there as well you don't need to make.
So call getNotificationNewRequestService() from NotificationARBroadcastReceiver.recieve() and make sure the notification ids match up.
Edit:
move:
m = (new Random()).nextInt(10000);
before:
actionIntent.putExtra("id", NotificationARBroadcastReceiver.m); // this will be 'm'
Result:
int m = (new Random()).nextInt(10000);
Intent actionIntent = new Intent(getBaseContext(), MyBroadcastSender.class);
actionIntent.putExtra("id", m);
Log.d(getClass().getSimpleName(), "Notification Id is : " + m);
then, you can check what values are in id, id1 and id2. Don't forget to call .notify() with same Id you got from m.
You can, also, create getRandomNotificationId() and getLastGeneratedNotificationId() methods. Whenever you generate an Id, store it in public static integer variable, so that you can access it throughout the class.
Problem might be that you are accessing m from NotificationARBroadcastReceiver before initializing it. So, it will definitely be 0. And, you mentioned something about println error, are you using System.out.println()?
Before Edit:
As seen on your new edit, try closing notification before starting it:
m = (...);
// some code here
mNotifyMgr.cancel(m);
mNotifyMgr.notify(m, notification);
and see if your issue gets resolved.
I have a notification that, when I click on it, opens up my app. But my app opens up in the background and the notification drawer is still visible. My notification itself is canceled and removed, but the drawer still exists on top of everything.
The notification class looks like this:
public MyNotification(final Context context) {
this.context = context;
remoteView = new RemoteViews(context.getPackageName(), R.layout.notification);
notification = new Builder(context)
.setSmallIcon(R.drawable.notification_icon)
.build();
notification.flags = Notification.FLAG_NO_CLEAR;
notification.priority = Notification.PRIORITY_MAX;
remoteView.setOnClickPendingIntent(R.id.container, getIntent(ACTION_OPEN_APP));
notification.bigContentView = remoteView;
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(MY_NOTIFICATION_ID, notification);
}
private PendingIntent getIntent(String action) {
Intent receiveIntent = new Intent(context, NotificationReceiver.class);
receiveIntent.setAction(action);
return PendingIntent.getBroadcast(context, 0, receiveIntent, 0);
}
And my receiver looks like this:
public class NotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equalsIgnoreCase(AudioPlayerNotification.ACTION_OPEN_APP)) {
Intent openAppIntent = new Intent(context, MyActivity.class);
openAppIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
context.startActivity(openAppIntent);
}
}
I also have a base Activity that removes the notification when launching the activity. What am I missing?
Prathibhas suggested solution did not the trick, but pointed me in the right direction. The trick was to send the broadcast
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
since I'm using a broadcast receiver for the actions on the notification. The answer was provided here:
Clicking Android Notification Actions does not close Notification drawer
I'm using an android notification to alert the user once a service is finished (success or failure), and I want to delete local files once the process is done.
My problem is that in the event of failure - I want to let the user a "retry" option. and if he chooses not to retry and to dismiss the notification I want to delete local files saved for the process purposes (images...).
Is there a way to catch the notification's swipe-to-dismiss event?
DeleteIntent:
DeleteIntent is a PendingIntent object that can be associated with a notification and gets fired when the notification gets deleted, ether by :
User specific action
User Delete all the notifications.
You can set the Pending Intent to a broadcast Receiver and then perform any action you want.
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);
Builder builder = new Notification.Builder(this):
..... code for your notification
builder.setDeleteIntent(pendingIntent);
MyBroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
.... code to handle cancel
}
}
A fully flushed out answer (with thanks to Mr. Me for the answer):
1) Create a receiver to handle the swipe-to-dismiss event:
public class NotificationDismissedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int notificationId = intent.getExtras().getInt("com.my.app.notificationId");
/* Your code to handle the event here */
}
}
2) Add an entry to your manifest:
<receiver
android:name="com.my.app.receiver.NotificationDismissedReceiver"
android:exported="false" >
</receiver>
3) Create the pending intent using a unique id for the pending intent (the notification id is used here) as without this the same extras will be reused for each dismissal event:
private PendingIntent createOnDismissedIntent(Context context, int notificationId) {
Intent intent = new Intent(context, NotificationDismissedReceiver.class);
intent.putExtra("com.my.app.notificationId", notificationId);
PendingIntent pendingIntent =
PendingIntent.getBroadcast(context.getApplicationContext(),
notificationId, intent, 0);
return pendingIntent;
}
4) Build your notification:
Notification notification = new NotificationCompat.Builder(context)
.setContentTitle("My App")
.setContentText("hello world")
.setWhen(notificationTime)
.setDeleteIntent(createOnDismissedIntent(context, notificationId))
.build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationId, notification);
Another Idea:
if you create a notification normally you also need the actions one, two or 3 of them. I've created a "NotifyManager" it creates all notifications i need and also receive all Intent calls.
So i can manage all the actions AND also the catch the dismiss event at ONE place.
public class NotifyPerformService extends IntentService {
#Inject NotificationManager notificationManager;
public NotifyPerformService() {
super("NotifyService");
...//some Dagger stuff
}
#Override
public void onHandleIntent(Intent intent) {
notificationManager.performNotifyCall(intent);
}
to create the deleteIntent use this (in the NotificationManager):
private PendingIntent createOnDismissedIntent(Context context) {
Intent intent = new Intent(context, NotifyPerformMailService.class).setAction("ACTION_NOTIFY_DELETED");
PendingIntent pendingIntent = PendingIntent.getService(context, SOME_NOTIFY_DELETED_ID, intent, 0);
return pendingIntent;
}
and THAT i use to set the delete Intent like this (in the NotificationManager):
private NotificationCompat.Builder setNotificationStandardValues(Context context, long when){
String subText = "some string";
NotificationCompat.Builder builder = new NotificationCompat.Builder(context.getApplicationContext());
builder
.setLights(ContextUtils.getResourceColor(R.color.primary) , 1800, 3500) //Set the argb value that you would like the LED on the device to blink, as well as the rate
.setAutoCancel(true) //Setting this flag will make it so the notification is automatically canceled when the user clicks it in the panel.
.setWhen(when) //Set the time that the event occurred. Notifications in the panel are sorted by this time.
.setVibrate(new long[]{1000, 1000}) //Set the vibration pattern to use.
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setSmallIcon(R.drawable.ic_white_24dp)
.setGroup(NOTIFY_GROUP)
.setContentInfo(subText)
.setDeleteIntent(createOnDismissedIntent(context))
;
return builder;
}
and finally in the same NotificationManager is the perform function:
public void performNotifyCall(Intent intent) {
String action = intent.getAction();
boolean success = false;
if(action.equals(ACTION_DELETE)) {
success = delete(...);
}
if(action.equals(ACTION_SHOW)) {
success = showDetails(...);
}
if(action.equals("ACTION_NOTIFY_DELETED")) {
success = true;
}
if(success == false){
return;
}
//some cleaning stuff
}