In my application I notify the user with notifications, if something special happens:
public void triggerNotification(String msg) {
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent contentIntent = new Intent(this, ABC.class);
Notification notification = new Notification(R.drawable.icon, msg, System.currentTimeMillis());
notification.setLatestEventInfo(this, "ABC", msg, PendingIntent.getActivity(this.getBaseContext(), 0, contentIntent, PendingIntent.FLAG_CANCEL_CURRENT));
notification.flags = Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(notificationCounter, notification);
notificationCounter++;
}
If the user clicks on the Notification, the onCreate() method is called. But I want that a specific method in my app is called, or if the app is not in the foreground, that it is brought back to the foreground.
I know there are lots of tutorials that explain how to handle notifications, but I just don't understand them completely and wasn't ever able to implement the things like I'd like to.
To bring your app to the foreground if it is running already you need to set different flags on your intent:
contentIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
For running a specific method you could just pass extra information along with the intent and interpret it in your application to decide which method to run.
The recommendation to use FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_SINGLE_TOP only partially solves the problem. The activity in the Android manifest should also have these settings applied so that launching the activity from the home screen has the same behavior. Without these properties multiple instances of the activity can be launched.
<activity android:name="foo"
android:clearTaskOnLaunch="true"
android:launchMode="singleTop"
android:label="#string/app_name">
I've discovered that if you use Intent contentIntent = new Intent(this, ABC.class); this calls onCreate(); regardless of the flags set.
Use Intent contentIntent = getIntent(); to skip onCreate(); and that moves to onStart();
Related
I used calling functionality in my application. when the app is in the foreground then the application is working well. but when the app is in the background then how to open incoming call Activity in android. When a push notification is appeared then open incoming call Activity in android. how to perform this task?
Android 10 (API level 29) and higher place restrictions on when apps can start activities when the app is running in the background. These restrictions help minimize interruptions for the user and keep the user more in control of what's shown on their screen.
https://developer.android.com/guide/components/activities/background-starts
You have to call it in firebase messaging service.
Intent intent = new Intent(this, IncomingCallActivity.class);
intent.putExtra(Constants.KEY_FIRST_NAME, firstName);
intent.putExtra(Constants.KEY_LAST_NAME, lastName);
intent.putExtra(Constants.KEY_EMAIL, email);
intent.putExtra(Constants.KEY_ID, id);
intent.putExtra(Constants.KEY_DP, dp);
intent.putExtra(Constants.CALL_TYPE, callType);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);
in manifest
<activity
android:name="IncomingCallActivity"
android:screenOrientation="portrait"
android:showOnLockScreen="true"
android:showWhenLocked="true"
android:turnScreenOn="true" />
<service
android:name="MessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Notifications may have a pending intent attached. This pending intent may start an activity. See Notification.Builder.setContentIntent()
You can add a Pending Intent to your notification, so when user clicks on it, your intent will be launched.
To create a Pending Intent you should:
Create a normal Intent to your destination Activity.
val goActivity = Intent(context, Activity::class.java)
Create a Pending Intent passing a context, a request code to identify the Pending Intent, your normal Intent and a flag to configure the way your Intent is launched.
val goActivityPending = PendingIntent.getActivity(context, pendingIntentCode, goActivity, PendingIntent.FLAG_NEW_TASK)
Add your Pending Intent to your notification builder with method setContentIntent.
val notification = NotificationCompat.Builder(context, channelId) .setContentTitle(context.getString(R.string.notificationTitle)) .setContentText(context.getString(R.string.notificationContent)) .setContentIntent(goActivityPending)
That's it! When you click the notification, your activity will be oppened. You can also use addAction() to add buttons to your notification with different Pending Intents.
If you want to know more about Intent flags, read this: Pending Intent Flags
I have a BroadcastReceiver registered in the manifest file so that even after the app is wiped closed, it receives location updates.
<receiver android:name="com.tenforwardconsulting.cordova.bgloc.LocationReceiver">
<intent-filter>
<action android:name="myBroadcast" />
<action android:name="stopUpdating" />
</intent-filter>
</receiver>
When the app is opened, it starts a locationManager using pendingIntents.
Intent intent = new Intent(context, LocationReceiver.class);
intent.setAction("myBroadcast");
intent.putExtra("session_id", session_id);
//intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
lpendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), 58534, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//Register for broadcast intents
locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, lpendingIntent);
This works great and even after app is closed i keep getting updates. Now when I want to stop getting updates, I can set my BroadcastReceiver using getComponentEnabledSetting() and set it's state to disabled just fine. But I'm pretty sure my pendingIntent would keep going through every minute. I can't seem to figure out how to stop it. I've tried recreating it inside the broadcastReceiver like many answers on here like so...
Intent intent1 = new Intent(context, LocationReceiver.class);
PendingIntent.getBroadcast(context, 58534, intent1, PendingIntent.FLAG_UPDATE_CURRENT).cancel();
But it just keeps on going through to the BroadcastReceiver after doing this every minute. Am I doing something wrong here?
You need to re-create the PendingIntent exactly as it was when it was initially set up, and call removeUpdates() in order to stop the location update callbacks.
Note that there is no need to call cancel() on the PendingIntent.
Also note that you would need to persist the session_id somehow, using a field in an Application subclass, or using SharedPreferences. This is needed in order to re-create the PendingIntent correctly.
So, your code to stop location updates would be something like this:
Intent intent = new Intent(context, LocationReceiver.class);
intent.setAction("myBroadcast");
intent.putExtra("session_id", session_id);
PendingIntent lpendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), 58534, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//Unregister for broadcast intents
LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
locationManager.removeUpdates(lpendingIntent);
My application contains multiple activities. I have implemented push notifications and also shown the notification in bar. My issue is, when i click on notification is take me to the specific activity that i has specified.
Intent intent =new Intent(GcmService.this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(GcmService.this, 0, intent, 0);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
getApplicationContext())
.setContentTitle(getResources().getString(R.string.app_name))
.setAutoCancel(true)
.setContentIntent(pendingIntent);
notificationBuilder.setContentIntent(pendingIntent);
mNotificationManager.notify((int) when, notificationBuilder.build());
I want if my activity is in background, and user click on the notification app resume the current activity that is in background and show dialog box.
And if my application is closed. open the Launching activity and then show the dialog box.
If you want to continue again when you click the notification(in this case your application still running on background) than you can using this method :
http://developer.android.com/training/basics/activity-lifecycle/stopping.html
I've tried it and it works.
You can link your notification to a DispatcherActivity.
If you have open Activities on the backstack, finish the DispatcherActivity suddenly in onCreate(). If not, forward to your launching activity and finish the DispatcherActivity too.
To track your active activities on backstack use this How to know Activity Count of my application? suggestions.
The main part of my app is a service that displays a notification. The GUI of the app is only used to be able to change some settings. When I click on that notification, some data should be send in the background without opening the app. To do that, I created an invisible activity.
When I open the app (the configuration part) and exit it with the back button, everything works as intended; when clicking on the notification the data is send without opening the app.
When I exit the app with the home button, every time I click the notification the app opens again.
This is my notification and the Intent to call the data activity:
PendingIntent toggleLightsIntent =
PendingIntent.getActivity(
this,
0,
new Intent(this, HyperionToggleSwitchActivity.class),
PendingIntent.FLAG_NO_CREATE);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("HyperionSwitch")
.setContentText("Switch lights")
.setContentIntent(toggleLightsIntent)
.build();
And this is the part where I send the data:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sendJson(blue);
finish();
}
What do I have to change so the app won't open when clicking the notification?
It's my first app and took me quite a while to get what I have so far...
As per earlier comment:
You could change your hidden activity into a Service (which generally doesn't have any ui), or leverage the service that manages the notification, and have the PendingIntent sent directly to that service using PendingIntent.getService() .
Try this code^
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(MainActivity.FILE_NAME, "somefile");
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
I am in trouble with notification intents. I have a service(Service checks for messages and creates notification) which creates notifications. And application has an action bar and via slide menu users can navigate between activities.
http://i.stack.imgur.com/YJXe6.png
When user clicks notification it opens a new activity on the current activity.(Like an independent new instance). I want to open them in the same instance as if user navigating manually(Like clicking A when on B activity ie)
My current activity launchMode is standard(Although I tried singleTop and singleTask and flags)
Current Notification code :
Intent i = null;
i = new Intent(this, MessagesListActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,i, 0);
Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setContentTitle(title);
notificationBuilder.setContentText(msg);
notificationBuilder.setSmallIcon(R.drawable.speech_bubble_orange);
notificationBuilder.setContentIntent(contentIntent);
notificationBuilder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = notificationBuilder.build();
notificationManager.notify(Constants.UNREADMESSAGESNOTIFICATIONID,notification);
Thanks for your help.
I solved the problem. With this combination new launched activity clears stackback. I also did not change the launchmodes (still standard)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
In your manifest, you have to tag your activity as single instance, and keep the singleTask
android:launchMode= "singleTask" | "singleInstance"
in addition, you may have to remove the single top flag from your intent.
If I understood correctly, I think what you are looking for is the TaskStackBuilder. It allows you to create a backstack to provide proper navigation to the Activity being launched by the PendingIntent.
See the docs here for more information.