Activity restarts on notification click - android - java

I have an activity which plays music and shows notification
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK );
mBuilder.setContentIntent(pendingIntent);
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
final int mId = 1;
mNotificationManager.notify(mId,mBuilder.build());
the problem is that as I go back from this activity lets say activity B, and I tap on the notification the activity restarts and now I have two streams of music playing, it seems as if the activity is duplicated
I had a look into the manifest to see if I can change something, and I added this line to my activity
android:launchMode="singleTop"
this didn't help either, any ideas?
Thanks!

Please create global variable of Activity and check if it is not null then variable.finish() and launch the activity.
Activity globalVariable;
if(globalVariable!=null) {
globalVariable.finish();
}
Intent in = new Intent(this,b.class);
startActivity(in);

Related

Redirect to activity with preserving/creating activity stack

I want to start activity from notification. I want to open an activity, which is successor of some other activities.
Example activities: IntroActivity -> Photos -> SpecificPhoto. What I want to achieve: In case user clicks on notification, I want to open SpecificPhoto activity. Keep in mind, that app can be running (for example PhotosActivity is displayed), or it can be shut down.
I want to preserve back button functionality (move to PhotosActivity on back pressed).
On notification click, I need to launch IntroActivity, because user needs to login here in case he is not.
I tried following (using constants in activities, code):
On PhotosActivity onCreate:
redirectToActivity();
RedirectToActivity method:
private void redirectToActivity() {
Intent intent = getIntent();
int activityCode = intent.getIntExtra("code", 0);
switch (activityCode) {
case SpecificPhotoActivity.CODE:
startActivity(new Intent(this, SpecificPhotoActivity.class));
break;
default:
return;
}
}
By applying this approach, I can traverse the whole activity stack and go to the activity I want. However, this approach is not working in every case. Sometimes, the activity_code is not set (don't know why) and therefore we end in the first activity.
Is there any more professional approach to solve this issue? I believe this must be solved somehow in many apps.
What you want is called TaskStackBuilder.
Here's how you should construct the intent, that would navigate to SpecificPhotoActivity:
Intent action = new Intent(context, SpecificPhotoActivity.class);
PendingIntent pendingIntent = TaskStackBuilder.create(context)
.addNextIntentWithParentStack(action)
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
In order to correctly specify stack of activities, you should provide android:parentActivityName inside manifest file:
<application ...>
<activity android:name=".SpecificPhotoActivity"
android:parentActivityName=".PhotosActivity"/>
</application>
With this parameter you have specified, that the parent of SpecificPhotoActivity is PhotoActivity, thus TaskStackBuilder would understand where to navigate as soon as back button is clicked inside SpecificPhotoActivity.
Construction of the notification should be as follows:
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle(...)
.setContentText(...)
.setSmallIcon(...)
.setContentIntent(pendingIntent)
.build();
manager.notify(NOTIFICATION_ID, notification);
Now notification click would open SpecificPhotoActivity. A click on back button would navigate to PhotosActivity.
What's left is authorization handling. I suppose you are able to apprehend whether user is authorized or no during the construction of the notification. Hence, following approach should work:
PendingIntent pendingIntent = null;
if (authorized) {
Intent action = new Intent(context, SpecificPhotoActivity.class);
pendingIntent = TaskStackBuilder.create(context)
.addNextIntentWithParentStack(action)
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
} else {
Intent action = new Intent(context, IntroActivity.class);
action.putExtra("photos_flow", true);
pendingIntent = PendingIntent.getActivity(context, 0, action, 0);
}
Now, inside IntroActivity after successful authorization:
void onAuthorized() {
if(getIntent().getBooleanExtra("photos_flow", false)) {
// most possibly you should pass some id into SpecificPhotoActivity's intent
Intent[] intents = new Intent[]{new Intent(this, PhotosActivity.class), new Intent(this, SpecificPhotoActivity.class)};
startActivities(intents);
finish();
}
}

Notification passes old Intent Extras when the Activity that read the extras values is on top

Notification is giving old values.
I read the stackoverflow link but still not working for me:
Notification passes old Intent Extras
I have a Activity A.
When I am on the activity B and touch the Notification, the Extra parameter is given correctly and shows the Activity A with the correctc values read with getExtras(..);
Then the Activity A is still on the top - showing on the screen:
I click on the second notification with new values of putExtras(newValue) to create a new activity A but with new values.
The problem:
The intent.getExtras()` is reading old values of the first notification clicked instead new values given by the second notification.
I made a lot of combinations of Flags of Pending Intent and the combinations of the link on top, but the aplication is still taking the old values(the values of the first touched notification) for the second Notification. I tried the flag: PendingIntent.FLAG_UPDATE_CURRENT to update the values instead create a new one Activity and some others Flags.
How can I make the second notification give the correct values for the activity A when the Activity A is still shown on the screen?
The snippet of the code creating the notification.
public void notificationCreateGu(String newMessageUserUidOfSender) {
Intent it = new Intent(this,ActivityA.class);
it.putExtra(USER_UID_READER,newMessageUserUidOfSender);
StoreValuesClass.count=StoreValuesClass.count+2;
PendingIntent pi = PendingIntent.getActivity(this, StoreValuesClass.count,it, 0);
Notification notification = new NotificationCompat.Builder(this)
.setTicker(newMessageUserUidOfSender )
.setSmallIcon(android.R.mipmap.sym_def_app_icon)
.setContentTitle("Title Message ")
.setContentText(String.valueOf(newMessageUserUidOfSender))
.setContentIntent(pi)
.setAutoCancel(true)
.build();
int m;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
m= StoreValuesClass.count=StoreValuesClass.count+2;
notificationManager.notify((m), notification);
}
//StoreValueClass.count is a static values that can be read by the activity to give an unique id for the notification.
the snippet of code reading the values.
userUidReader = getIntent().getExtras().getString(USER_UID_READER)
I tried to reload the values into onResume() but into onResume() the still taking the old values of the first time the getExtras() is read.
i understood that the operational system Android are not creating a new Activity but only giving it to the top.
using the answser of CommonsWare that helped with the override onNewIntetn and the link:
http://www.helloandroid.com/tutorials/communicating-between-running-activities
1 into xmlFile: put th android:launchMode="singleTask"
for the activity will receive the extra parameters with getExtras.
<activity android:name=".ActivityWillReceiveWithGetExtras"
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>
2.into the activity you that will receive the values with get_extras(...) override a method called onNewIntent:
2.1 Observation: put the line:
setIntent(intent);
to set the identifier of the intent.
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);//must store the new intent unless getIntent() will return the old one
getExtraParameterActual();
}
2.2 get the Extra parameters into a function that will have inside the command getExtras(...
getExtraParameterActual();
Write the function of the top getExtraParameterActual();
private void getExtraParameterActual() {
Intent intent = getIntent();//take back the value set with //setintenT of pass 2.1
user = getIntent().getExtras().getString(USER);//
}
5.
into OnCreate() call the e getExtraParameterActual();
and if necessary reload your views with a method for example reloadMyViews()
into onResume() reload your views again with the same function of the pass 5 reloadMyViews()
7 the notificatio code I used take care with the FLAGS
public void notificationCreateGu(String User) {
Log.d(TAG,nameOfTheService+"BUG createnotification for received CHAT messages useruidOfTheFriendNear="+newMessageUserUidOfSender);
Intent it = new Intent(this,ActivityWillReceiveWithGetExtras.class);
it.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
it.putExtra(USER,user);
StoreValuesClass.count=StoreValuesClass.count+2;
PendingIntent pi = PendingIntent.getActivity(this, StoreValuesClass.count,it, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this)
.setTicker(newMessageUserUidOfSender )
.setSmallIcon(android.R.mipmap.sym_def_app_icon)
.setContentTitle("Title Message ")
.setContentText(String.valueOf(newMessageUserUidOfSender))
.setContentIntent(pi)
.setAutoCancel(true)
.build();
int m;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
m= StoreValuesClass.count=StoreValuesClass.count+2;
notificationManager.notify((m), notification);
}
Override onNewIntent() in your activity.
getIntent() returns the Intent that was used to initially create the activity. If an existing activity instance is brought back to the foreground via a startActivity() call, onNewIntent() is called to deliver to you the Intent used for that most recent startActivity() call.

Show default notification bar in Android

I have searched a lot over the internet and could'n find an answer.
I am working on a launcher project and on a click of a button, I want to launch default notification bar . Is there any API.
you can implement the android default notification using the below code. you can customize.
// Invoking the default notification service
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this);
mBuilder.setContentTitle("ur titlw");
mBuilder.setContentText("ur content");
mBuilder.setTicker("ur sticker");
mBuilder.setSmallIcon(R.drawable.uricon);
// Increase notification number every time a new notification arrives
mBuilder.setNumber(++numMessagesOne);
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ur activity where this notification shout appear);
resultIntent.putExtra("notificationId", "test");
// This ensures that navigating backward from the Activity leads out of
// the app to Home page
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent
stackBuilder.addParentStack(ur activity where it returns when click on the notification);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_ONE_SHOT // can only be used once
);
// start the activity when the user clicks the notification text
mBuilder.setContentIntent(resultPendingIntent);
myNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// pass the Notification object to the system
myNotificationManager.notify(notificationIdOne, mBuilder.build());
I hope this will be useful.

How to have a notification open a view within an activity?

Right now I have an alarm on my main activity which launches a class which launches a notification on the status bar. When I click on the notification, it opens up my main activity, now I want it to open a n specific view within that activity.
This is my notification code.
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
int icon = android.R.drawable.stat_notify_chat; // icon from resources
CharSequence tickerText = "TickerText"; // ticker-text
long when = System.currentTimeMillis(); // notification time
CharSequence contentTitle = "My notification"; // message title
CharSequence contentText = "Hello World!"; // message text
//This is the intent to open my main activity when the notification is clicked
final Intent notificationIntent = new Intent(context, mainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
// the next two lines initialize the Notification, using the configurations above
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(notifID, notification);
This is the button in the layout used by my main activity which opens the view I want the notification to open (graph view).
<Button
android:id="#+id/graphsButton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_below="#id/reviewButton"
android:layout_toRightOf="#id/medicineButton"
android:onClick="openGraphs"
android:text="Graphs" />
When you click on the button. It executes the following method in the main class.
public void openGraphs(View v) {
canExit = false;
setContentView(R.layout.graphs);
}
So basically, I got the notification to open the app and launch the main activity, but I want it to launch the graph view directly.
Can anybody help me?
You could add a flag to the pending intent set in the notification using the intent's extras. Evaluate the intent when the activity is started. If you find the flag in the starting intent execute the the code in openGraphs(). Make sure to get the most recent intent (not the one which may have started the activity earlier, here is some advice on that: https://stackoverflow.com/a/6838082/1127492).
Is there anything stopping you from showing the graph directly in the Activity?
In the above Activity instead of having a button, to show the Graph when clicked, directly set the view to R.layout.graphs in onCreate() method.
In case you have the prescribed activity for some other purpose then create a separate activity just to show the graph and point to it from the notificationIntent.

notification opening a new window no matter what in Java Android

I want to launch a notification. When I click on it, it opens a NEW window of the app.
Here's my code:
public class Noficitation extends Activity {
NotificationManager nm;
static final int uniqueID = 1394885;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent= new Intent (Intent.ACTION_MAIN);
intent.setClass(getApplicationContext(), SchoolBlichActivity.class);
PendingIntent pi=PendingIntent.getActivity(this, 0, intent, 0);
String body = " body";
String title = "title!";
Notification n =new Notification(R.drawable.table, body, System.currentTimeMillis());
n.setLatestEventInfo(this, title, body, pi);
n.defaults = Notification.DEFAULT_ALL;
n.flags = Notification.FLAG_AUTO_CANCEL;
nm.notify(uniqueID,n);
finish();
}
by the way, if i add nm.cancel(uniqueID) before the finish(), it creates the notification and immediately deletes it...
Thanks for the help :D
You might want to just add a notification in the notification bar, and when the user clicks it, it will launch the actual Activity. This way the user won't be interrupted in whatever he's doing.
Create the status bar notification like this:
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.notification_icon, "Hello", System.currentTimeMillis());
Intent notificationIntent = new Intent(this, myclass.class);
notification.setLatestEventInfo(getApplicationContext(), "My notification", "Hello world!", notificationIntent, PendingIntent.getActivity(this, 0, notificationIntent, 0));
mNotificationManager.notify(1, notification);
http://developer.android.com/guide/topics/ui/notifiers/notifications.html
Are you just trying to open a notification window in a current activity? Because if you are I dont think you need to launch it with an intent. You normally only use intents to launch new services or activities in your app unless youve built a custom view and activity/service which is to take place within the notification box. I see you have it set up in its own class which is fine but I think the way your doing it by default would open an entire new view.
If you need to launch a notification during a process or something like a button click you dont need to have the intent there.....or at least I never did :) What exactly are you trying to achieve with the notification.

Categories