I'm coding an app that uses firebase for implementing notifications. In my MainActivity I have a WebView with some url, but the thing is that when the user clicks on a notification, I want to open MainActiviy with a diferent url in the WebView. I've read a lot and I've added a bundle to the intent (that opens MainActivity when a notification is clicked) which cointains the desired url. But when I click on the notification, MainActivity restarts, I mean, it doesn't go to onNewIntent, but instead, it runs onCreate. This is how I implemented it:
private void sendNotification(String messageTitle, String messageBody, String url){
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//This adds the url to the intent
if(!url.equals("")){
Bundle bundle = new Bundle();
bundle.putString("url", url);
intent.putExtras(bundle);
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,intent, PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.default_notification_channel_id);
NotificationCompat.Builder notificationBuilder = new NotificationCompat
.Builder(this, channelId)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
NotificationChannel channel = new NotificationChannel(channelId,
"Notification channel",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0, notificationBuilder.build());
}
onNewIntent I have this:
Bundle bundle = intent.getExtras();
if (bundle != null) {
String url = bundle.getString("url");
mWebView.loadUrl(url);
}
But when the notification is clicked, the activity just restarts, so it does not run onNewIntent, and log gives me this error:
02-08 12:51:12.140 19056-19056/com.example.android.app E/ActivityThread: Activity com.example.android.app.MainActivity has leaked IntentReceiver com.example.android.app.MainActivity$1@d7818db that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Activity com.example.android.app.MainActivity has leaked IntentReceiver com.example.android.app.MainActivity$1@d7818db that was originally registered here. Are you missing a call to unregisterReceiver()?
at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:999)
at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:795)
at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1329)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1309)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1303)
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:554)
at com.example.android.app.MainActivity.onCreate(MainActivity.java:264)
at android.app.Activity.performCreate(Activity.java:6367)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2404)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2511)
at android.app.ActivityThread.access$900(ActivityThread.java:165)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1375)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5621)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
I read on a similar question on stackoverflow was to unregister a BroadCastReceiver to fix this error, but I'm a little bit lost on how to do it.
I've tried changing the intent on sendNotification to
Intent intent = new Intent("android.intent.action.MAIN");
but in that case when the user clicks the notification it doesn't do anything.
Does anyone knows how to fix it so the url loads when a user clicks? Thanks you in advance
From the Android docs it states this:
If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP
in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP
is set then this Intent will be delivered to the current instance's onNewIntent().
So looks like setting the FLAG_ACTIVITY_SINGLE_TOP
flag when you create the new intent should solve and run the onNewIntent() method, instead of re-creating the application.
create a method like this
private PendingIntent retrievePlaybackAction(final String action) {
Intent intent = new Intent(action);
return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Now add your intent like this
builder.setContentIntent(retrievePlaybackAction("OPEN_MAIN")); //change action text as you want
Create a simple class NotificationReceiver
which I guess you have created, Now create object of this class from where you are sending notifications
private NotificationReceiver notificationReceiver;
In onCreate()
register your receivers
notificationReceiver = new NotificationReceiver();
IntentFilter intentFilterNextClick = new IntentFilter("OPEN_MAIN");
registerReceiver(notificationReceiver, intentFilterNextClick);
//can create exception, better to surround with try catch
In onDestroy()
unregister your Receiver
unregisterReceiver(notificationReceiver);
//can create exception, better to surround with try catch
To open or do some action add this in your Receiver
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "onReceive: received " + intent.getAction());
String action = intent.getAction();
//no need to create switch you can also use if
switch (action) {
case "OPEN_MAIN":
openMain();
break;
}
}
//here is openMain();
private void openMain(Context context) {
Intent openMainIntent = new Intent(context, MainActivity.class);
openMainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //this flag is important
context.startActivity(openMainIntent);
}
This will also work if the app is minimized or closed
Hope this will help!
Please ask if you need more help!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.