Open a different activity other than MainActivity when clicking Firebase Notification - java

In my application i want open custom activity (not MainActivity) and putExtra to this activity when click on Firebase notification.
I write below codes, but when click on notification open MainActivity, But i want open my another activity (AuctionDetailActivity).
My NotificationManager class :
public class MyNotificationManager {
private Context mCtx;
private Uri soundUri;
private static MyNotificationManager mInstance;
public MyNotificationManager(Context context) {
mCtx = context;
}
public static synchronized MyNotificationManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new MyNotificationManager(context);
}
return mInstance;
}
public void displayNotification(String title, String body) {
soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent intent = new Intent(mCtx, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("fcm_notification", "Y");
PendingIntent pendingIntent = PendingIntent.getActivity(mCtx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mCtx, Constants.NOTIF_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setSound(soundUri)
.setAutoCancel(true)
.setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400})
.setContentText(body)
.setContentIntent(pendingIntent);
NotificationManager mNotifyMgr = (NotificationManager) mCtx.getSystemService(NOTIFICATION_SERVICE);
if (mNotifyMgr != null) {
mNotifyMgr.notify(1, mBuilder.build());
}
}
}
And MyFirebaseMessagingService class :
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
showNotify(remoteMessage.getFrom(), remoteMessage.getNotification().getBody());
}
private void showNotify(String title, String body) {
MyNotificationManager myNotificationManager = new MyNotificationManager(getApplicationContext());
//myNotificationManager.displayNotification(title, body);
myNotificationManager.displayNotification(title, body);
}
}
MainActivity codes:
#Override
protected void onResume() {
super.onResume();
String fcm_notification = getIntent().getStringExtra("fcm_notification");
Log.d("FireBaseIntentLog", " FCM : " + fcm_notification);
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
Log.d("FireBaseIntentLog", "Key: " + key + " Value: " + value + " FCM : " + fcm_notification);
}
}
}
How can i fix it?

If you are sending the notification from Firebase console or inside the notification field using FCM API, the app behaves in two ways -
If your app is in foreground, the method onMessageReceived of your FCM service class will be called.
If your app is in background, nothing will happen inside your FCM service class. Rather, the notification will be handled internally by the FCM library itself and the notification with launcher activity in the intent will be shown.
And if you use FCM API to send notification and use the data field, the library does nothing itself and instead calls the method onMessageReceived regardless of whether your app is in foreground or background.
So in order to solve your issue, you can use one of the following two solutions:
Use FCM API to send notifications and use the data field instead of the notification field. Check the documentation to read more about FCM API.
In your launcher (main) activity, check for intent inside onCreate and if it is coming from notification, read the extras, finish the main activity and open your required activity.
Example for second case:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkIntent()) return;
// other code.
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
checkIntent();
}
private boolean checkIntent() {
// to receive the value, send the value as custom data from Firebase console.
String value = getIntent().getStringExtra("your_key");
if (value == null) return false;
if (value.equals("something")) {
// open one activity.
} else if (value.equals("another_thing")) {
// open another activity.
}
finish();
return true;
}

Change this below line
Intent intent = new Intent(click_action);
to this
Intent intent = new Intent(getActivity(), YourClass.class);

You just need modify in sendNotification function
public void sendNotification(String messageBody, String messageTitle, int user_id, String click_action) {
Intent intent = new Intent(mCtx, AuctionDetailActivity.class); // Need modify this line
intent.putExtra(Extras.bidID.name(), user_id);
PendingIntent pendingIntent = PendingIntent.getActivity(mCtx, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mCtx, Constants.NOTIF_CHANNEL_ID);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) mCtx.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}

Change your MyFirebaseMessagingService class as shown below replace OtherApp.class with your activity name
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Intent intent=new Intent(this,OtherApp.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);//newbg PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder= new NotificationCompat.Builder(this);
notificationBuilder.setContentTitle("FCM NOTIFICATION"); notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager =(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,notificationBuilder.build());
}
}

Related

How to open an activity on the lock screen after FCM notification

How can I open an activity on the lock screen without the user having to click on it? Like for example an alarm or a call.
In my code I can get the FCM notification and if the user clicks on the notification it is possible to open an activity, but I wanted the user not to have to click on it.
FirebaseService.java
//--- Notificacao
public void createNotificationChannel(){
mNotifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
//create a notification channel
NotificationChannel notificationChannel = new NotificationChannel(PRIMARY_CHANNEL_ID,
"Mascot Notification", NotificationManager
.IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setDescription("Notification from Mascot");
mNotifyManager.createNotificationChannel(notificationChannel);
}
}
public void sendNotification(String taskName){
NotificationCompat.Builder notifyBuilder = getNotificationBuilder(taskName);
//agora temos que entregar a notificacao
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
}
public NotificationCompat.Builder getNotificationBuilder(String taskName){
Intent intent = new Intent(this, TesteActivity.class);
PendingIntent p = getPendingIntent(NOTIFICATION_ID, intent, getApplicationContext());
return new NotificationCompat.Builder(this, PRIMARY_CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentText("titulo teste")
.setContentIntent(p)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
}
private PendingIntent getPendingIntent(int id, Intent intent, Context context){
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(intent.getComponent());
stackBuilder.addNextIntent(intent);
PendingIntent p = stackBuilder.getPendingIntent(id, PendingIntent.FLAG_UPDATE_CURRENT);
return p;
}
TesteActivity.java
public class TesteActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teste);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setTurnScreenOn(true);
setShowWhenLocked(true);
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
}
instead of mNotifyManager.notify( call, which shows your Notification, just use startActivity(..? you may need also WakeLock and showOnLockScreen attribute set for this Activity in manifest
edit: and HERE you can find article with exactly your case tutorial

Extra null for Android Notification with PendingIntent

I am trying to send a int Extra to an Activity when a notification is tapped. When I tap the notification the activity launches, but the extra is always null.
I have checked a lot of similar questions but they haven't helped me solve the problem. (I tried using onNewIntent() but it was never called). How can I successfully send the Extra?
This is the BroadcastReceiver where the intent is created:
public class EventAlarmNearReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent nextIntent = new Intent().setClass(context, EventActivity.class);
nextIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
int id = 1234;
nextIntent.putExtra("Id", (long) id);
nextIntent.setAction("nearReceiverAction");
PendingIntent nextPendingIntent = PendingIntent.getActivity(context, 1022, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
String text = "Your " + intent.getStringExtra("Name") + " is starting soon. Please read your documents.";
NotificationsDeliver.getInstance().sendNotification(context, "Meeting Mate", text, nextPendingIntent);
}
}
This is the method from NotificationsDeliver where the notification is sent:
public void sendNotification(#NonNull Context context, String title, String text, PendingIntent pendingIntent ) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_event_note_white_24dp)
.setContentTitle(title)
.setContentText(text)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVibrate(new long[] { 1000, 1000, 1000 })
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(999, builder.build());
}
This is onCreate method from EventActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
long id = intent.getLongExtra("id", 0);
}
I would guess that it's because you have capitalized the word "id" differently when putting vs getting the extra; compare:
nextIntent.putExtra("Id", (long) id);
// ^^^^
vs
long id = intent.getLongExtra("id", 0);
// ^^^^
Try using the same capitalization for both.

Android Service stops broadcasting progress after a while

I have an Activity where the user can download a video. Upon user's click, the Download Service starts to download the content.
There is a progress bar in the Activity UI which I would like to update according to download progress in the service which broadcasts the progress periodically.
Everything works fine but after a certain time the service stops sending any broadcast progress, hence, the UI does not update anymore.
Additionally, how I can resume receiving the progress broadcast when the user goes to another Activity and comes back to this Activity? I mean, even if the above issue is solved, when the user presses back button and go to other activity and comes back to this activity, the progress gets lots. How can I check for any existing broadcast and receive it whenever the user comes to this activity.
In the ACTIVITY:
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Log.d("DownloadService", "Progress Received In Activity");
Double progress = bundle.getDouble("PROGRESS");
updateDownloadProgressBar(progress);
}
}
};
private void startDownloadService() {
final String videoId = mItem.getAttributes().get(KEY_ASSET_ID);
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("VIDEOID", videoId);
startService(intent);
}
in the onResume():
registerReceiver(receiver, new IntentFilter(DownloadService.NOTIFICATION_SERVICE));
in the onPause():
unregisterReceiver(receiver);
In the SERVICE:
private void publishProgress(double progress) {
Log.d(TAG, "Broadcasting progress from Service");
Intent intent = new Intent(NOTIFICATION_SERVICE);
intent.putExtra("PROGRESS", progress);
sendBroadcast(intent);
}
The download and progress work fine to 38% then stop.
It seems that the service is being stopped/killed from the OS, to avoid that use foreground service so you can make sure it will not be killed from the OS.
See the sample code below:
Service
public class PendingService extends Service {
private final static String TAG = "PendingService";
public final static int NOTIFICATION_ID = 94;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startInForeground();
// Do your work here ...
return START_STICKY;
}
private void startInForeground() {
String NOTIFICATION_CHANNEL_ID = "default";
String NOTIFICATION_CHANNEL_NAME = "My Pending Service";
String NOTIFICATION_CHANNEL_DESC = "This notification holding a pending task";
Intent notificationIntent = new Intent(this, SplashActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.notification)
.setOngoing(true)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT >= 26) {
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
channel.setDescription(NOTIFICATION_CHANNEL_DESC);
channel.setSound(null, null);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
Notification notification = builder.build();
startForeground(NOTIFICATION_ID, notification);
}
#Override
public void onDestroy() {
super.onDestroy();
removeNotification(NOTIFICATION_ID);
// ....
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void removeNotification(int notificationId) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.cancel(notificationId);
}
}
}
Utils you may need
class ServiceUtils {
/**
* #param service: Service to run
*/
fun startService(context: Context, service: Class<out Service>) {
val serviceIntent = Intent(context, service)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(serviceIntent)
} else {
context.startService(serviceIntent)
}
}
/**
* #return True: if the service is running
*/
fun isServiceRunning(context: Context, serviceClass: Class<*>): Boolean {
val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.name == service.service.className) {
return true
}
}
return false
}
}

Get Notification Title Android

How could I get the Notification Title of the notification ?
Here's my code :
-From Notification Service :
resultIntent= new Intent(NotificationService.this, StartNAFromNS.class);
resultIntent.putExtra(Intent.EXTRA_TITLE, underestood_name.replace("__", " "));
-From StartNAFromNS :
String text = this.getIntent().getStringExtra(Intent.EXTRA_TITLE);
When doing this with only 1 notification, I get the correct title. However, if my application sends 2 notifications, I will get the title of the second notification.
How could I get the proper notification title ?
By extending NotificationListenerService and using its onNotificationPosted method in our class we will be able to get notification title, text and package name. Using notification package we get its app icon, app name and many more.
public class MyNotification extends NotificationListenerService {
Context context;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
// We can read notification while posted.
for (StatusBarNotification sbm : MyNotification.this.getActiveNotifications()) {
String title = sbm.getNotification().extras.getString("android.title");
String text = sbm.getNotification().extras.getString("android.text");
String package_name = sbm.getPackageName();
Log.v("Notification title is:", title);
Log.v("Notification text is:", text);
Log.v("Notification Package Name is:", package_name);
}
}
}
Notification id should be unique within your application.
If a notification with the same id has already been posted by your
application and has not yet been canceled, it will be replaced by the
updated information.
NotificationManager notiManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notiManager.notify(UNIQUE_ID, notification);
If you are using PendingIntent.getActivity() method, use different requestCode for different notification:
Intent resultIntent= new Intent(NotificationService.this, StartNAFromNS.class);
resultIntent.putExtra(Intent.EXTRA_TITLE, underestood_name.replace("__", " "));
PendingIntent pI = PendingIntent.getActivity(mContext, REQUEST_CODE, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Hope this will help!
This code properly working for the fcm. We can send a message and title from the fcm console or server. The notification received by the registered mobile app.
#Override
public void onMessageReceived (String from, Bundle data) {
//Getting the message from the bundle
long dateTime = data.getLong("google.sent_time");
Bundle notificationBundle = data.getBundle("notification");
String message = notificationBundle.getString("body");
String title = notificationBundle.getString("title");
//Displaying a notiffication with the message
sendNotification(title, message);
}
//The following method is generating a notification and displaying the notification
private void sendNotification(String title, String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("message", message);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestCode = 0;
PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT >= 21)
noBuilder.setSmallIcon(R.mipmap.ic_launcher);
else
noBuilder.setSmallIcon(R.mipmap.ic_launcher_small);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
}

Get multiple GCM messages

This class won't to handle multiple GCM messages and show them on notification bar,currently handle only one, how can make it to handle multiple messages?
public class GCMIntentService extends GcmListenerService {
private static final String TAG = "GCMIntentService";
int notifyid = 0;
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "from:" + from);
Log.d(TAG, "message:" + message);
sendNotification(message);
}
private void sendNotification(String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, notifyid, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.logo)
.setContentTitle("New Messsage")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSound)
.setContentIntent(pendingIntent);
int numMessages = 0;
notificationBuilder.setContentText(message).setNumber(++numMessages);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notifyid, notificationBuilder.build());
}
}
}
From the documentation:
public void notify (int id, Notification notification)
Post a notification to be shown in the status bar. If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.
notifyid never appears to change in the code you've posted, which is why you only see a single notification.

Categories