Android notification click restore activities - android

I have MainActivity and WorkActivity in my app. WorkActivity starting by MainActivity:
Intent intent = new Intent(view.getContext(), WorkActivity.class);
intent.putExtra("intArray", intArray);
startActivity(intent);
In WorkActivity I read intArray param and start foreground service with notification:
protected void onCreate(Bundle savedInstanceState) {
int[] intArray = getIntent().getIntArrayExtra("intArray");
Intent intent = new Intent(this, MyService.class);
intent.putExtra("intArray", intArray);
startService(intent);
}
Service notification:
Intent newIntent = new Intent(this, WorkActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, newIntent, 0);
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.icon)
.setContentTitle("title)
.setContentIntent(pIntent)
.setContentText("text");
Notification notification;
notification = builder.build();
startForeground(1, notification);
Now, when I close my app and click to notification occur error, because WorkActivity can't get
getIntent().getIntArrayExtra("intArray");
that should bу passed by MainActivity.
How to fix this?
Log:
java.lang.RuntimeException: Unable to start service com.test.MyService#9051e18 with Intent { cmp=com.test/.MyService (has extras) }: java.lang.NullPointerException: Attempt to read from null array
Error occur because WorkActivity.getIntent().getIntArrayExtra("intArray") is null.
Activity send this to service in lines:
intent.putExtra("intArray", intArray);
startService(intent);
In service I need to get some numbers from intArray like intArray[0], but intArray is null

When you go to the notification bar and select the notification, this starts a new instance of WorkActivity. This instance of WorkActivity is not started from your MainActivity, but by the notification, and the Intent you put in the notification does not have the extra intArray.
Basically you need to add the putExtra() call for intArray into this code:
Intent newIntent = new Intent(this, WorkActivity.class);
// HERE YOU NEED TO CALL newIntent.putExtra("intArray", intArray);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, newIntent, 0);
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.icon)
.setContentTitle("title)
.setContentIntent(pIntent)
.setContentText("text");

Related

Send data to activity when clicked on notification?

i am opening a activity when notification is clicked . notification is activated from a service class .i want to send data to new activity opened from notification i am using intent1.putExtra("lable",lable); but in new activity it is giving me nullpointer exeption.
intent1 = new Intent(this.getApplicationContext(), simplestop.class);
intent1.putExtra("lable",lable);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent1, 0);
Notification mNotify = new Notification.Builder(this)
.setContentTitle("title" + "!")
.setContentText("Click me!")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pIntent)
.setAutoCancel(true)
.build();
I use this code for send data to activity.
Intent intent = new Intent(this, MainActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("from", "notification");
pIntent = PendingIntent.getActivity(this, 3, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
May be you have problem in setting flag=0 or try to change request code=0 to any other integer.
Sending data.
Intent intent = new Intent(getApplicationContext(), simplestop.class);
intent.putExtra("lable", lable);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
final RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.yourLayoutOfNotification);
contentView.setOnClickPendingIntent(R.id.IdOfTheItemYouClick, contentIntent);
Try to retrieve data something like this in your simplestop.class
if (getIntent().getDataString() == null) {
String lable = Objects.requireNonNull(getIntent().getExtras()).getString("lable");
}
And I think you need to call the onNewIntent at the simplestop.class
And there to retrieve data.
And try to create a Log if the data are retrieved.
Log.d("Data", lable);
And tell what is the Log showing.

NullPointerException after Notification is clicked in notification bar(PendingIntent)

I am trying to get my PendingIntent working but whenever I click the notification in the notification drawer, my app crashes.
So basically I have this java class called CustomerCurrentlyServing.class and when it is loaded, it retrieves all the strings passed from the previous activity as shown below:
queueNo = String.valueOf(getIntent().getExtras().getInt(Constants.EX_MSG_QUEUE_NO));
queueKey = getIntent().getExtras().getString(Constants.EX_MSG_QUEUE_KEY);
shopName = getIntent().getExtras().getString(Constants.EX_MSG_SHOP_NAME);
shopKey = getIntent().getExtras().getString(Constants.EX_MSG_SHOP_KEY);
customerid = getIntent().getExtras().getString(Constants.EX_MSG_CUSTOMER_ID);
I implemented a method for the notification as shown below:
public void showNotification() {
Intent intent = new Intent(getApplicationContext(), CustomerCurrentServing.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, CustomerCurrentServing.class), 0);intent.putExtra(Constants.EX_MSG_QUEUE_NO,queueNo);
intent.putExtra(Constants.EX_MSG_QUEUE_NO,queueNo);
intent.putExtra(Constants.EX_MSG_QUEUE_KEY,queueKey);
intent.putExtra(Constants.EX_MSG_SHOP_NAME,shopName);
intent.putExtra(Constants.EX_MSG_SHOP_KEY,shopKey);
Resources r = getResources();
Notification notification = new NotificationCompat.Builder(this)
.setTicker(r.getString(R.string.notification_title))
.setSmallIcon(android.R.drawable.ic_menu_report_image)
.setContentTitle(r.getString(R.string.notification_title))
.setContentText(r.getString(R.string.notification_text))
.setContentIntent(pi)
.setAutoCancel(true)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
It is basically opening the same class when the user clicks on the notification in the notification drawer. However, it crashes whenever I click on the notification and the error is NullPointerException on the line:
queueNo = String.valueOf(getIntent().getExtras().getInt(Constants.EX_MSG_QUEUE_NO));
Any idea how to solve this error ? I have been trying to solve this error for a week and your help is greatly appreciated.
You should putExtra on the Intent you pass to PendingIntent
Intent intent = new Intent(getApplicationContext(), CustomerCurrentServing.class);
intent.putExtra(Constants.EX_MSG_QUEUE_NO,queueNo);
intent.putExtra(Constants.EX_MSG_QUEUE_NO,queueNo);
intent.putExtra(Constants.EX_MSG_QUEUE_KEY,queueKey);
intent.putExtra(Constants.EX_MSG_SHOP_NAME,shopName);
intent.putExtra(Constants.EX_MSG_SHOP_KEY,shopKey);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent , 0);
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, CustomerCurrentServing.class), 0);
here you are passing new instance of Intent
you should pass already created instance i.e.
Intent intent = new Intent(getApplicationContext(), CustomerCurrentServing.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
and write all those putExtras before creating PendingIntent object.
In this part of the code you are adding the extras to the wrong intent , you are creating an intent then creating a new one that you pass to the pending intent!
What you should be doing is this:
Intent intent = new Intent(getApplicationContext(), CustomerCurrentServing.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
intent.putExtra(Constants.EX_MSG_QUEUE_NO,queueNo);
intent.putExtra(Constants.EX_MSG_QUEUE_KEY,queueKey);
intent.putExtra(Constants.EX_MSG_SHOP_NAME,shopName);
intent.putExtra(Constants.EX_MSG_SHOP_KEY,shopKey);
And not creating a new intent like you did in your pending intent :
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, CustomerCurrentServing.class), 0);
intent.putExtra(Constants.EX_MSG_QUEUE_NO,queueNo);
If you do this you are putting the extras om the first intent then passing a whole new one without extras to your pending intent so when the user clicks on the notification and it opems up the activity the activity will try and get extras that dont exist thus giving a null pointer.

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"

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();
}
}
}
}

Android - GCM push notification that sends user to Activity does not result in onCreate call

I am able to create push notifications, and to send the user to whichever Activity I want, but I notice that whenever the user lands on that Activity, the onCreate function does not get called.
Is that supposed to be the case? How do I set it so that the onCreate of the Activity is called?
Here is my Activity:
public class QuestionActivity extends BaseListActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
and here is how the notification is generated:
Intent notificationIntent = new Intent(context, MainActivity.class);
if ( notification_type != null && notification_type.equals("question"))
{
notificationIntent = new Intent(context, QuestionActivity.class);
}
else
if ( notification_type != null && notification_type.equals("plan"))
{
notificationIntent = new Intent(context, TopicActivity.class);
}
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification notification = new NotificationCompat.Builder(context)
.setContentTitle(title)
.setContentText(message)
.setContentIntent(intent)
.setSmallIcon(icon)
.setLights(Color.YELLOW, 1, 2)
.setAutoCancel(true)
.setSound(defaultSound)
.build();
notificationManager.notify(0, notification);
Thanks!
The flags that you are using Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP mean that if the activity is already running in the current task, then instead of launching a new instance of that activity, the old existing activity will be used. In that case onCreate won't be called, since the activity already exists.

Categories

Resources