interrupting activity and multiple instances of activity issues - android

My problems are hopefully related to each other. I run a countdown timer service that fires an intent in the onfinish method. When on finish completes it automatically opens/ bring the app up which I don't want it to do. why is this so? id like it to just show the notification. Also when I click on the notification instead of just resuming the activity it creates another one. I figured the problems were related to each other due to the intents. here is the code
from onFinish() not from the notification
Intent intent = new Intent(BroadcastService.this, MainActivity.class);
intent.putExtra("id1",id1);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
and here is the code for the notification
NotificationCompat.Builder notificBuilder = new NotificationCompat.Builder(this);
notificBuilder.setContentTitle("Loot");
notificBuilder.setContentText("Claim your Gold now!");
notificBuilder.setSmallIcon(R.drawable.gold2);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notificBuilder.setSound(soundUri);
notificBuilder.setAutoCancel(true);
Intent backhome = new Intent(this, MainActivity.class);
backhome.putExtra("id2",id2);
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);
taskStackBuilder.addParentStack(MainActivity.class);
taskStackBuilder.addNextIntent(backhome);
PendingIntent pd = taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
notificBuilder.setContentIntent(pd);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notifID, notificBuilder.build());
isNoteActive = true;
}

If you don't want to open your MainActivity, then you shouldn't write this code:
Intent intent = new Intent(BroadcastService.this, MainActivity.class);
...
startActivity(intent);
Opening MainActivity is exactly what this does.

Related

Going back to main activity after launching activity from notification

I launch an activity from a notification I receive. If that notification is pressed it launches an activity. If there are no previous activities on the back-stack, or only a certain one, I want to remove that certain activity and insert my main activity in there and than the new activity.
I found this Thread but I don't understand how he handles it with two intents and flags.
i.e. intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK)
Is it wise to do it the way he did it or should I edit the activity stack for that?
I am fairly new to android dev, so some advice could help me here out.
Thanks a lot ;)
Update: so I went with the stackbuilder but somehow it doesn't get set right ... I don't find my error, my boolean noActivity gets set for sure, but I think somehow I misunderstood how the stack actually puts a previous activity in there.
private void sendNotification(messageType type, Map<String, String> data, boolean noActivities) {
Intent i;
String message = "";
switch (type) {
case newFOLLOWER:
User cur = new User(data.get("other.name"));
User.lookAT = User.getOtherUserByName(cur);
i = new Intent(this, other_profile.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
message = data.get("other.name") + " is following you now. Click to see his profile";
i.putExtra("Notification", data.get("other.name") + " is following you now. Click to see his profile");
break;
default:
i = null;
break;
}
if (i != null) {
TaskStackBuilder stack = TaskStackBuilder.create(this);
if(noActivities){
stack.addParentStack(Photostream.class);
}
stack.addNextIntent(i);
PendingIntent pendingIntent = stack.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);//PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("PIC LOC")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSound)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
Update 2: So after searching quite a lot I found out that I missunderstood how the stack builder works. I found another thread where they described how the adding works. Editing the Manifest in order to have a previous stack.
I was to fast and skipped part of the tutorial you provided me so kindly ...
Thanks for your guys help ;)
You should make stack builder while creating notification like this.
Intent resultIntent = new Intent(this, NotificationTapActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
So whenever user will tap on notification, MainActivity will be inserted in stack.
One more solution in which you can handle the back press of NotoificationTapActivity. In which you can check if noting is there in stack then you can finish the current activity and starts MainActivity from there.
You should use TaskStackBuilder. This is the most efficient way and the TaskStackBuilder structure developed for that reason.
I allways use TaskStackBuilder when Push Notifications are included to my project.
Overriding onBackPress() is not good approach because it requires complex structures in your app and you need to handle many things.
Check this tutorial.
/**Just use below code inside onMessageReceived()**/
PendingIntent pendingIntent;
Uri defaultSoundUri;
Intent notification_intent;
String message = "Your Message";
notification_intent = new Intent(this, YourActivity.class);
notification_intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(this, 0 , notification_intent, PendingIntent.FLAG_ONE_SHOT);
defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(getNotificationIcon(notificationBuilder))
.setContentTitle(this.getResources().getString(R.string.app_name))
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND)
.setContentIntent(pendingIntent);
String[] multilineDescription = new String[]{message};
message = multilineDescription[0];
for (int i=1; i<multilineDescription.length; i++)
{
message += System.getProperty("line.separator");
message += multilineDescription[i];
}
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(message));
/***Above commented is for strecting the big message in Push Notification******/
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify((int)MESSAGE_NOTIFICATION_ID /* ID of notification */, notificationBuilder.build());
You can simply handle that in onBackPressed of notification activity.
With help of flag you may know that your notification activity is opened through notification click and then in onBackPressed go to your mainactivity as following:
Intent intent =new Intent(context,MainActivity.class)
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
PendingIntent can implement multi intent. Just create an array intent
Intent[] intents = new Intent[2];
Intent intent1 = new Intent(this, MainActivity.class);
Intent intent2 = new Intent(this, YourActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivities(this, 0, intents,PendingIntent.FLAG_ONE_SHOT);
And when you finish YouActivity, it will back to MainActivity.
Intent intent = getIntent();
String data= intent.getStringExtra("from");
if(data.equalsIgnoreCase("notificaton")
{
// call Mainactivity
}
else if(){}

Skip app for foreground when clicking on notification, without opening new

What I wanted to do was open the app by notification in two cases:
Case open app : Just pull background
Case closed app: Opens new app
The code that I have is the next:
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String title = context.getString(R.string.notification_title);
String message = context.getString(getNotificationText());
Bitmap largeIcon = getLargeBitmap();
NotificationCompat.Builder notification =
(NotificationCompat.Builder) new NotificationCompat.Builder(context).setContentTitle(title).setContentText(message)
.setSmallIcon(getIcon()).setLargeIcon(largeIcon).setOngoing(true);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
Intent intent = new Intent(context, MainActivity.class);
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(intent);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setContentIntent(contentIntent);
}
manager.notify(NETWORK_STATUS_NOTIFICATION_ID, notification.build());
}
The problem I have is that the code is working on Android 5 and up, but does not work on Android : JELLY_BEAN and KITKAT .
Someone help me?
Add flag FLAG_ACTIVITY_NEW_TASK to your intent :
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
From the docs :
When using this flag, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in.

Activity gets minimized when launching it from foreground service

I have two Activities in my app:
A - login Activity
B - main Activity
When the user clicks the login button in activity A I am starting a service. In the service's onCreate() method I launch activity B like this:
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat
.Builder(getApplicationContext());
builder.setContentIntent(pendingIntent);
builder.setContentTitle("Activity B in foreground service");
builder.setSmallIcon(R.drawable.ic_launcher);
startForeground(1, builder.build());
The problem is that Activity B launches minimized. I have to press the service button in the notification bar in order to get my activity maximized (fill the screen). How could I launch Activity B from service in normal way - without minimizing it (putting to background)?
Your code doesn't actually launch Activity B at all. All it does is create a Notification, that, if selected by the user, will launch Activity B.
If you want to actually launch Activity B, do this:
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Now launch the activity immediately
startActivity(notificationIntent);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat
.Builder(getApplicationContext());
... (rest of your code here)
Question already answered in android start activity from service
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
http://developer.android.com/training/basics/firstapp/starting-activity.html
Finally I found out the solution:
onCreate() method in service class:
#Override
public void onCreate() {
Intent notificationIntent = new Intent(getBaseContext(), MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
getApplication().startActivity(notificationIntent);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat
.Builder(getApplicationContext());
builder.setContentIntent(pendingIntent);
builder.setContentTitle("Activity B runs in a foreground service");
builder.setSmallIcon(R.drawable.ic_launcher);
startForeground(1, builder.build());
}
In AndroidManifest.xml add this line in Activity element:
android:launchMode="singleTop"

Android: Launch an external app from notification

I am trying to create a notification that when clicked will open an external app. I've seen the documentation for creating notifications and for sending the user to another app. But I can't seem to figure out how to combine the two. The problem is that the advised way to launch an app from a notification, is to creating the pending intent like this:
Intent intent = new Intent(this, MyActivity.class);
TaskStackBuilder stackBuidler = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MyActivity.class);
stackBuilder.addNextIntent(intent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
But to launch an external app, you have to create an implicit intent like this:
String uri = ...
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
As far as I can tell, there is no way to create the TaskStackBuilder with this kind of intent, because addParentStack() will only take an Activity, a Class, or a ComponentName.
I guess the question boils down to... is it possible to create a intent that is both pending and implicit?
The only workaround I can think of right now is to create an Activity in my app that does nothing but launch the external app.
I did try creating the intent from the URI then doing the following, but nothing happens when you click the notification:
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Well, a lot later, I think I have the solution for you.
For all the other guys who are searching for an answer to launching an external app from your own custom notification.
Here it is:
public void createMyNotification(String titl, String titlcont, String conti){
Context context = getApplicationContext();
PackageManager pm = context.getPackageManager();
Intent LaunchIntent = null;
String apppack = "com.mycompany.appack.apname.app";
String name = "";
try {
if (pm != null) {
ApplicationInfo app = context.getPackageManager().getApplicationInfo(apppack, 0);
name = (String) pm.getApplicationLabel(app);
LaunchIntent = pm.getLaunchIntentForPackage(apppack);
}
Toast.makeText(context,"Found it:" + name,Toast.LENGTH_SHORT).show();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
Intent intent = LaunchIntent; // new Intent();
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification noti = new Notification.Builder(this)
.setTicker(titl)
.setContentTitle(titlcont)
.setContentText(conti)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent).getNotification();
noti.flags = Notification.FLAG_AUTO_CANCEL;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, noti);
}
This does not use an additional Activity to launch the external app.
If you know packageName what you want start it, You can get Intent for startActivity.
Read this link start application knowing package name
I don't know if this is the best approach, but this is the solution that ended up working:
Create the notification
//Create the pending intent
Intent intent = new Intent(context, MyActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MyActivity.class);
stackBuilder.addNextIntent(intent);
PendingIndent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
//Create the notification builder
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentTitle("Notification Title")
.setContentText("Hello world!")
.setContentIntent(pendingIntent); //Attach the pending intent to launch when notification is clicked
//Send the notification
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(mId, builder.build());
MyActivity.java
public class MyActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Create implicit intent - see http://developer.android.com/training/basics/intents/sending.html
String uri = "...";
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}
I'd still be interested to know if there's a way to bypass having an additional Activity that does nothing but launch an implicit intent.

How should i do from notification back to activity without new intent

from Android Development, i implement a simple notification by the sample code, but in my app, i don't want to new intent and create the activity again, i just want to back to my last activity(it's a mediaplayer UI). if i use the sample code, it will create a new activity by
Intent resultIntent = new Intent(this, ResultActivity.class);
i comment relative code about new intent and got a notification, but didn't have idea how to back to my last activity...
back to my app from long press home key and touch my app is OK.
what i want is just like this behavior.
bleow is the sample code from Android Development, i comment the new intent portion.
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
/*Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(ResultActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);*/
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(mId, mBuilder.build());
[UPDATE]
i thought i need to set flag for intent and properity for activity.
therefore, for the activity i want to back to i set
android:launchMode="singleInstance"
and because, i don't want a new activity from intent, i just want my last activity, so i add
Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
from documentation i got that using Pendingintent.contentIntent it must include the FLAG_ACTIVITY_NEW_TASK flag and When using this flag, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in. so i also add
Intent.FLAG_ACTIVITY_NEW_TASK
but from logCat, i still saw that when i touch the notification for back to activity, the pendingintent still called onCreate() function rather than just show the last activity which still "alive".
If you want to call the Activity from background try this:
Intent intent = new Intent(this, YourLauncherActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
intent, 0);
mBuilder.setContentIntent(pendingIntent);
If you click the Notification while on Homescreen the last shown Activity of your App will be get to the foreground without starting it new. If the Activity was killed by the system you will get a new Activity.
I have used PendingIntent.getActivities instead of getActivity. This is working well in my project.
Intent backIntent = new Intent(this, HomeActivity.class);
backIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent notificationIntent = new Intent(this, NextActivity.class);
final PendingIntent pendingIntent = PendingIntent.getActivities(this, 1,
new Intent[] {backIntent, notificationIntent}, PendingIntent.FLAG_ONE_SHOT);
For me, this worked :
.setContentIntent(
PendingIntent.getActivity(
context,
0,
new Intent(context, YOUR_MAIN.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP ),PendingIntent.FLAG_ONE_SHOT))
FLAG_ONE_SHOT : DO NOT CREATE TWICE (associated with
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)
In SingleTop mode, I use this method without define explicitly the root activity class:
Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
.setComponent(getPackageManager().getLaunchIntentForPackage(getPackageName()).getComponent());
and this to resume last activity from notification:
builder.setContentIntent(PendingIntent.getActivity(context, 0, intent, 0));
or this to resume last activity from a service:
try {
PendingIntent.getActivity(this, 0, intent, 0).send();
} catch (CanceledException e) {
e.printStackTrace();
}
Code hear
Intent resultIntent = new
Intent(getApplicationContext(),MainActivity.class);
resultIntent.putExtra("splash",2);
resultIntent.putExtra("message","test");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifyPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationCompatBuilder.setContentIntent(notifyPendingIntent);
Intent intent = this.getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
String extraValue = extras.getString("notificationType");
if(extraValue !=null){
int value = Integer.parseInt(extraValue);
if (value == 1) {
intent = new Intent(SplashActivity.this,MainActivity.class);
intent.putExtra("splash",value);
intent.putExtra("message", "fromsplash");
startActivity(intent);
finish();
} else
if (value == 2){
intent = new Intent(SplashActivity.this,MainActivity.class);
intent.putExtra("swip","2");
intent.putExtra("message", "test");
startActivity(intent);
finish();
}
}
}
}

Categories

Resources