How to cancel a countdown timer when a notification is clicked? - android

I know this has been asked a million times in other forums, but I haven't got a perfect answer yet. This is my requirement:
When the activity goes to bacground, the timer starts and after 10 sec the notification appears. If the user doesn't click on the notification after 10 sec the notification changes.
When the user clicks on the first notification, the last viewed screen appears - i.e the activity comes to the foreground. This is achieved by:
Intent notificationIntent = new Intent(TimedAlert.this, FirstActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
But i want the timer to stop immediately after the activity comes to foreground. I.e in onResume () I give timer.cancel() but this doesn't seem to work. I also tried onNewIntent() but it works only when I am on the first activity when the app goes to background from the second activity. On coming to foreground the onNewIntent() method is not called, even though I have given single top for the second activity.
How can I achieve this behavior?

when the user click on the Notification, the system will call your notificationIntent, in your case the system will start FirstActivity, then in your FirstActivity you can stop the count down.

Related

How can I create an app with the behavior of the default Android "timer" app?

I want to create an app that allows the user to set a timer. When they start the timer, they see a screen with a countdown. Simultaneously, a notification appears in the system tray (the top bar). This notification contains the current state of the countdown. If the app is minimized and the user taps that notification, they return to the countdown screen in the app.
I'm trying to do this with a foreground Service, and then implementing the notification like so:
Intent notificationIntent = new Intent(this, TimerActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
The problem is, this seems to restart the activity, not resume it (onCreate gets called again), so the timer appears zeroed out in the activity. Is there a way around this?

What is the best way to finish() an activity from a foreground service without bringing the app to the foreground?

I am trying to build an app that can be used for calling.
My CallActivity is declared singleTop in the manifest file. I have a foreground service (CallService) which is started as soon as the app goes to the background while the user is on a call, since the device must not sleep during a call.
The notification for my CallService allows the user to either resume the call or hangup. My goal is to have the user press a button on the notification and hangup the ongoing call without bringing the app to the foreground.
I have tried using PendingIntent.getActivity() to start the CallActivity once the app is in background, from the CallService. But I have not been able to hangup the call yet. Here is some code...
Intent returnToCallIntent = new Intent(this, CallActivity.class);
PendingIntent returnPendingIntent = PendingIntent.getActivity(this, 0, returnToCallIntent, 0);
Intent hangUpCallIntent = new Intent(this, CallActivity.class);
hangUpCallIntent.putExtra("ACTION_FINISH_ACTIVITY", true);
PendingIntent hangUpPendingIntent = PendingIntent.getActivity(this, 0, hangUpCallIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Right now both pending intents resolve to the same action which is hanging up the call while bring the app to the foreground. I figured out that this is happening because the 2 intents only differ in their extras and hence android does not distinguish them, i.e. intent#filterEquals() does not see any difference between them.
But the more important question is how can I finish() the CallActivity and have it pop off the backstack silently, without bringing it to the foreground. Also, after the CallActivity has been stopped, I need to stop the CallService in the background. So when the user taps the app in the recents screen, she/he should see the activity which was prior to the CallActivity on the backstack.
PS: Logic to hang up the call has been done in onNewIntent() method in CallActivity.
You can have your Activity register an anonymous BroadcastReceiver that listens for a specific broadcast Intent. When your Service wants to finish the Activity, it can just send the broadcast Intent that the Activity is listening for.
In onReceive() of the BroadcastReceiver, just call finish(). This won't bring the Activity to the foreground.

Multiple fullscreen android notifications at the same time not stacking

I am working on an android project that has an alarm clock like functionality.
I schedule an intentService for each alarm instance (fires at 9pm, for example.), this intentService builds the notification and displays it. The notification includes a fullScreenIntent, which works as expected and launches the activity. I use the following code to do this:
alarmActivityIntent = new Intent(this, AlarmActivity.class);
PendingIntent alarmActivityPendingIntent = PendingIntent.getActivity(this, alertSchedule.getIntentId(), alarmActivityIntent, PendingIntent.FLAG_CANCEL_CURRENT);
mBuilder.setFullScreenIntent(alarmActivityPendingIntent, true);
Notification mNotification = mBuilder.build();
mNotificationManager.notify(alertSchedule.getIntentId(), mNotification);
This works as expected when only one alarm is set to fire at a specific time, however if two alarms are set to fire at a specific time the behavior changes.
I want the first fullScreenIntent to start its activity, then when that activity finishes, show the next one. I believe I want to build up a task stack, and push these alarm intents onto it. However this is all new to me.
Is it possible to group these notifications?
If you are using the full screen Intent feature, you don't need to use an IntentService or a Notification at all. Just have the AlarmManager start your Activity when it fires.
You don't want to build a task stack, that is all too complicated. If you have multiple alarms that can fire at the same time, you can have the AlarmManager start the same Activity each time. Set the launch mode of this Activity to singleTop (in the manifest), so that if the Activity is already showing when the alarm fires, it will not create another instance of the Activity on top of the existing one, but instead will deliver the Intent by calling onNewIntent() on the existing instance of the Activity. In onNewIntent() you can save the data (extras) of the Intent in a queue that will be processed when the user finishes the currently shown Activity. To do that, just override onBackPressed() so that when the user presses the BACK button to finish the current Activity, you can check if there are any additional alarms waiting in the queue. If there are none, you can just call super.onBackPressed() to finish the Activity. If there is anything in the queue, you can remove the first element in the queue and display that in your Activity. Keep doing that until the queue is empty.

ongoing notification opening existing Activity

I want to show a notification while a timer is running and when the user clicks the notifiaction it opens the timer activity.
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, Activity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
The problem right now is that when I start the timer and press home and then click the notification it opens the Activity with the running timer.
But when I start the timer, then open another activity (via ActionBar.NAVIGATION_MODE_LIST), then press home and click the notification it opens a new Activity (empty).
I thought addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); would help (thats what I used to navigate between Activities)
im using android:launchMode="singleTop" and android:configChanges="orientation|screenSize"
for every Activity.
I wouldn't rely on your activity persisting and it is unnecessary
Store the timer start time into sharedpreferences and then simply load up the start time when the activity is recreated.
If something is meant to happen after a certain time, like a countdown time, then you'll need to set up an Alarm and handle it that way.
Remember that activities are just UI. Don't trust an activity to be doing anything when the user isn't looking at it.

How can I keep my ongoing audio task ongoing?

I'm having a specific problem that I'd love some insight on. Here is my code
Intent i = new Intent();
i.setDataAndType(media, mediaType);
startActivity(i);
This starts an audio activity for me and it even puts a notification item in the notification bar saying that it is an ongoing task. However, if I hit the Home button or Back button the ongoing task is immediately killed for me. I was confused by this behavior.
I found a way to keep the task going by the following: when the audio activity starts I drag down the notification bar and click the notification item ( which really just shows me the same activity again ) and when I do this it behaves accordingly. When I click the Home button it continues. When I hit the back button, it continues. For some reason when I click the notification item the "correct" Intent is fired.
What I'd like is for this behavior to start when I first launch the audio, because no one that uses my app is going to pull down the notification bar and click the notification item to get this to work properly.
Use a Service. Specifically, you will want to call startForegroundService() in the service's creation/start callback.

Categories

Resources