Notification addAction creates button with no behavior - android

I am trying to add a button to my notification in android.
I use the addAction method in order to add an intent which supposes to open up the main activity (same as clicking the entire notification) but with an extra bundle with data.
this is what I have done so far:
notificationManager = (NotificationManager)this.getSystemService(NOTIFICATION_SERVICE);
//regular intent to view main activity
PendingIntent contentIntent = PendingIntent.getActivity(this,Constants.MAIN_ACTIVITY,
new Intent(this, MainActivity.class), 0);
//intent for viewing transaction dialog, within main activity using PURCHASE_DIALOG request code
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(Constants.LIST, (java.util.ArrayList<? extends android.os.Parcelable>) list);
PendingIntent purchaseIntent = PendingIntent.getActivity(
this, Constants.PURCHASE_DIALOG,
new Intent(this, MainActivity.class), 0, bundle);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(Constants.NOTIFICATION_TOPIC)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(watchResponse.toString()))
.setAutoCancel(true)
.addAction(R.drawable.ic_launcher, "Buy", purchaseIntent)
.setContentText(message);
mBuilder.setContentIntent(contentIntent);
notificationManager.notify(NOTIFICATION_ID, mBuilder.build());
I simply expect that my onResume in MainActivity class will be called once clicking the extra action, and there i'll be able to get the bundle trough getIntent(), yet nothing happens when I click on it. the button is clicked, but the activity remains open and my application activity wont start.

I had a very similar issue but a very different solution. Pending intent is also not fired if you have declared <service android:enabled="false"></service> in your manifest.xml file.
Replace from android:enabled="false" to android:enabled="true"
This might not be a direct issue of the problem. But if you create the service in android studio using default template it automatically adds these properties to the service.
If this does not work there is a similar question you can find here:
Android Notification Action is not fired (PendingIntent)

Related

Notification in single Activity architecture

I'm using single activity architecture in my app. Now I'm stuck with handing notifications. I'm receiving notification from firebase and when app is on background, the google play services handle such notifications great. When it's tapped it brings the app from background to foreground (it does't recreate activity / app).
I need to have the same behaviour for notification received while the app is on foreground. Therefore I override onMessageReceived() in my firebase service and create new notification here. I tried many variation of Intent's Flags passed to the notification and launchMode in manifest but it always results into activity recreation (activity has different hashcode and it's onCreate() it's called) after tapping on notification created by onMessageReceived().
Here is the code:
#Override
public void onMessageReceived(#NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Logger.d("Msg received " + remoteMessage.getNotification().getTitle());
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this, FCM_CHANNEL_ID)
.setContentTitle(remoteMessage.getNotification().getTitle())
.setContentText(remoteMessage.getNotification().getBody())
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true)
.setStyle(new NotificationCompat.BigTextStyle().bigText(remoteMessage.getNotification().getBody()))
.build();
NotificationManagerCompat manager = NotificationManagerCompat.from(getApplicationContext());
manager.notify(FCM_NOTIFICATION_ID, notification);
}
manifest: android:launchMode="singleTask"
Any idea what to change to prevent activity recreation? (I'm testing on android 10, MainActivity extends AppCompatActivity)
Thanks.
Finally I get it work. All magic was done by adding those two lines to my code.
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
Original answer
Did you try this?
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Use the
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK flags.
This will start activity as the root of the stack.

android java notification tap reset activity

i use this code for notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext(), "notify_001");
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
intent,PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pendingIntent);
when i tap on notification app open and restart MainActivity i dont want to restart MainActivity.
If you want to just bring your app to the foreground (if it is running) or start it (if it is not running), you should use the following approach:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext(),
"notify_001");
Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
intent,PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pendingIntent);
This simulates clicking on the app icon on the HOME screen.
If possible try to add the launch modes to the main activity.
in manifest under the activity tag just use this tag. Or you can add this mode while starting the pending intent for main activity from the notification manager class.
android:launchMode="singleTask"
sample code
<activity
android:name=".MainActivity"
android:label="singleTask"
android:launchMode="singleTask"
android:taskAffinity="">
this should make the new launch to pass the data to existing activity if any opened and is present on back stack.
Also make sure you override the below method to receive the new data in main activity
protected void onNewIntent (Intent intent){
//your update code goes here
}

How to dismiss notification without intent?

I want to display a notification inside the app that disappears when the notification is tapped without starting an activity.
I use an empty intent and it works:
Intent intent = new Intent();
PendingIntent contentIntent = PendingIntent.getActivity(context, (int)System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, "")
.setSmallIcon(R.drawable.icon)
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setTicker(text);
.setContentIntent(contentIntent);
However, there are some crashes:
java.lang.RuntimeException: bad array lengths
at android.os.Parcel.readIntArray(Parcel.java:789)
at android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:339)
at android.app.NotificationManager.notify(NotificationManager.java:139)
at android.app.NotificationManager.notify(NotificationManager.java:112)
...
According to this SO answer the crashes seem to happen because intent is not starting an activity.
A notification can be dismissed by its ID, but I cannot dismiss it when there is no activity to start and call the dismiss method.
How can I dismiss the notification on tap inside the app without using an empty intent?
Update:
According to this SO questions it seems to be an Android issue. The crashes I got reported also happened on Android 4.3.
Update 2:
According to this SO answer it seems to be due to a too large bitmap set with setLargeIcon. So I am reducing the bitmap size now with Glide.
You can create an intent which calls a BroadcastReceiver which then cancels the notification.
Your PendingIntentcan be created like this:
private PendingIntent getCancelNotificationIntent() {
Intent cancelIntent = new Intent(context, CancelNotification.class);
return PendingIntent.getBroadcast(context, 0, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
The CancelNotification.java class would look similar to this:
public class CancelNotification extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
notificationManager.cancel(NOTIFICATION_ID);
}
}
EDIT:
NOTIFICATION_ID is a constant you define and pass to the NotificationManager like this:
notificationManager.notify(NOTIFICATION_ID, yourNotificationObject);
NOTE: don't forget to register the receiver in your manifest file like this:
<receiver android:name="com.example.package.CancelNotification" />
If you don't want to start an activity when users tap the notification you can build an pending intent which sends a broadcast or start a service.
Here is an example:
PendingIntent.getBroadcast(context, 12, new Intent("any intent action"), PendingIntent.FLAG_UPDATE_CURRENT)
But what prevents your activity to have implementation like this:
#Override
public void onCreate(Bundle savedInstanceState) {}
with additional nodisplay theme in manifest:
android:theme="#android:style/Theme.NoDisplay"
It'd be simply a no-op one.

Several issues with opening android notification

Hi all I have several isssues with my android notification. my code is the following:
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("at_now", true);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP |
Intent.FLAG_ACTIVITY_NEW_TASK|
Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
intent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(name)
.setVibrate(new long[]{500, 500, 1000})
.setLights(Color.RED, 500, 1000)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setStyle(new NotificationCompat.InboxStyle()
.setBigContentTitle(name)
.addLine(content_txt)
.addLine(mesagge)
).setContentText(content_txt);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
Session.getInstance(getApplicationContext()).getSharedPreferences().edit().putBoolean("REFRESHNOW",true).commit();
But it has several bugs.
1.) It opens every time new instance of the application if i do something and i get notification. Later when I close the app which was opened after clicking the notification, the previous screen appears, even if it is the same activity.
2.) if i recieve notification when my application is not opened it works fine. after i close the application I get back to my system menu. it is ok!
3.)When i opened application by clicking to notification, and if i get after another notification, it is no way it opens MainActivity it just bring forward the application, even if i am not in the main activity.
4.) the notification message does not disappear after clicking on it.
I have added these lines to my manifest as well:
android:noHistory="true"
android:launchMode = "singleTop"
5.)at main activity after opening it from intent i have extras like these : . So even the extras which i put to the intent does not work.
In NotificationGcmIntentService class use below code to clear notification . NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setAutoCancel(true);

Catch two notifications in android

I am creating notifications with following code:
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setContentTitle(messageBody)
.setAutoCancel(true)
.setSmallIcon(R.drawable.top_icon)
.setContentText(senderName)
.setTicker(senderName+" ")
.setSound(soundUri);
Intent resultIntent = new Intent(this, LoginActivity.class);
resultIntent.putExtra("gcm_username",senderName);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_ONE_SHOT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NotificationID.getID(senderName), mBuilder.build());
When user clicks the notification I am catching it with following code in loginActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
gcmUserId= getIntent().getStringExtra("gcm_username");
startAction(gcmUserId);
....
My problem starts here.
Scenario:
1)When app is closed user receives notifications from 2 different users
2)User clicks first notification and app starts then startAction method calls.
3)Then user clicks the second notification
But when user clicks the second notification app has already started so startAction won't be able to call again because it is in the onCreate method.How can catch second notification ?
You can handle it inside onNewIntent(). You would need to override that method inside your activity. The docs say:
This is called for activities that set launchMode to "singleTop" in their package, or if a client used the FLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent). In either case, when the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.

Categories

Resources