Android - Do job onClick Notification? - android

How can on i process specific method when i press on notification without open activity while application is opened by user?
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("frame", 1);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(contentIntent);

You ask how to read your extras from intent? You should implement onNewIntent() in your activity and handle incoming Intent there. If you got more code that handles intent content then it's good to make it separate method:
#Override
public void onCreate(Bundle savedState)
{
super.onCreate(savedState);
dealWithIntentData(getIntent());
}
#Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
dealWithIntentData(intent);
}
protected void dealWithIntentData(Intent intent) {
...
}

You can create a different PendingIntent depending on what you need to do. In your snippet you are starting an activity by calling
PendingIntent.getActivity(this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
You can start a service by calling
PendingIntent.getService(), or send a broadcast by calling PendingIntent.getBroadcast()
More specifically to your question, if you don't want to be depended on any activities, try sending a Broadcast (with getBroadcast) and execute any logic on the Broadcast's onReceive()
More info # http://developer.android.com/reference/android/app/PendingIntent.html

I don't fully understand your question, but maybe do you want to make a broadcast Receiver & handle some action in it?
You can use PendingIntent.getBroadcast method for that.
So, using broadcast you can start activity from receiver, or, if receiver is inside activity, handle something

Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("frame", 1);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
int frame = intent.getIntExtra("frame", 0);
// TODO your code...
}

Related

Getting Toast Message from Notification

Is it possible to have a Toast being shown when I click on one of the Variants of Notification? I tried to sending this Toast by intent to another class but could not find a way to do so.
Also, i have tried just creating intent to another class which just has a function of creating a Toast message upon being called, but this did not work because the Toast was being shown upon creation of Notification. Please help. Thanks.
Intent intent = new Intent();
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setTicker("Info")
.setContentTitle("Info ")
.setContentText("NotiText")
.addAction(R.drawable.ic_stat_name, "This should make Toast upon clicking", pendingIntentCall)
.setSmallIcon(R.drawable.ic_stat_name).setAutoCancel(true);
Your intent does nothing. When passing the Intent to PendingActivity.getActivity(...), you must define it as an explicit intent for an Activity. For example:
Intent intent = new Intent(this, SomeActivity.class);
But if you only want to show a toast message, it would be probably better not to start an activity, because that would be quite an expensive operation for that purpose. Instead, you can create a PendingIntent also for a service or a broadcast. For example:
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
And MyBroadcastReceiver.java could look like this (basically):
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context.getApplicationContext(), "Your message", Toast.LENGTH_SHORT).show();
}
}
Btw, it is recommended to add an action or extra to the intent when you create it, and check for that action or extra when receiving the intent to verify that it's actually the intent that you expected to receive.

PendingIntent does not send Intent extras

My MainActicity starts RefreshService with a Intent which has a boolean extra called isNextWeek.
My RefreshService makes a Notification which starts my MainActivity when the user clicks on it.
this looks like this:
Log.d("Refresh", "RefreshService got: isNextWeek: " + String.valueOf(isNextWeek));
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.putExtra(MainActivity.IS_NEXT_WEEK, isNextWeek);
Log.d("Refresh", "RefreshService put in Intent: isNextWeek: " + String.valueOf(notificationIntent.getBooleanExtra(MainActivity.IS_NEXT_WEEK,false)));
pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
builder = new NotificationCompat.Builder(this).setContentTitle("Title").setContentText("ContentText").setSmallIcon(R.drawable.ic_notification).setContentIntent(pendingIntent);
notification = builder.build();
// Hide the notification after its selected
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(NOTIFICATION_REFRESH, notification);
As you can see the notificationIntent should have the booleanextra IS_NEXT_WEEK with the value of isNextWeek which is put in the PendingIntent.
When I click now this Notification I always get false as value of isNextWeek
This is the way I get the value in the MainActivity:
isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);
Log:
08-04 00:19:32.500 13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity sent: isNextWeek: true
08-04 00:19:32.510 13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService got: isNextWeek: true
08-04 00:19:32.510 13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService put in Intent: isNextWeek: true
08-04 00:19:41.990 13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity.onCreate got: isNextWeek: false
When I directly start the MainActivity with an Intent with the ìsNextValue` like this:
Intent i = new Intent(this, MainActivity.class);
i.putExtra(IS_NEXT_WEEK, isNextWeek);
finish();
startActivity(i);
everything works fine and I get true when isNextWeek is true.
What do I make wrong that there is always a false value?
UPDATE
this solves the problem:
https://stackoverflow.com/a/18049676/2180161
Quote:
My suspicion is that, since the only thing changing in the Intent is
the extras, the PendingIntent.getActivity(...) factory method is
simply re-using the old intent as an optimization.
In RefreshService, try:
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
See:
http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_CANCEL_CURRENT
UPDATE 2
See answer below why it is better to use PendingIntent.FLAG_UPDATE_CURRENT.
Using PendingIntent.FLAG_CANCEL_CURRENT not a good solution because of inefficient use of memory. Instead use PendingIntent.FLAG_UPDATE_CURRENT.
Use also Intent.FLAG_ACTIVITY_SINGLE_TOP (the activity will not be launched if it is already running at the top of the history stack).
Intent resultIntent = new Intent(this, FragmentPagerSupportActivity.class).
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
resultIntent.putExtra(FragmentPagerSupportActivity.PAGE_NUMBER_KEY, pageNumber);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
Then:
#Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
int startPageNumber;
if ( savedInstanceState != null)
{
startPageNumber = savedInstanceState.getInt(PAGE_NUMBER_KEY);
//so on
It should work now.
If you still have not expected behaviour, try to implement void onNewIntent(Intent intent) event handler, that way you can access the new intent that was called for the activity (which is not the same as just calling getIntent(), this will always return the first Intent that launched your activity.
#Override
protected void onNewIntent(Intent intent) {
int startPageNumber;
if (intent != null) {
startPageNumber = intent.getExtras().getInt(PAGE_NUMBER_KEY);
} else {
startPageNumber = 0;
}
}
I think you need to update the Intent when you receive a new one by overriding onNewIntent(Intent) in your Activity. Add the following to your Activity:
#Override
public void onNewIntent(Intent newIntent) {
this.setIntent(newIntent);
// Now getIntent() returns the updated Intent
isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);
}
Edit:
This is needed only if your Activity has already been started when the intent is received. If your activity is started (and not just resumed) by the intent, then the problem is elsewhere and my suggestion may not fix it.
Following code should work:-
int icon = R.drawable.icon;
String message = "hello";
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.putExtra("isNexWeek", true);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, pIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
In MainActivity onCreate:
if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("isNextWeek")) {
boolean isNextWeek = getIntent().getExtras().getBoolean("isNextWeek");
}
So the actual reason is that the PendingIntent will cache the previous intent if the intents only differ in their extras. In my situation no combination of PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_CANCEL_CURRENT solves this as either the old intent will be replaced or the new one will stay the same as the initial one.
You need to ensure that Android cannot cache the Intents behind the PendingIntent. The solution for me is to make them differ in their data attribute.
so in the original posters code you would need to ensure that the data attribute is unique per each combination of extras that you are attaching.
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.putExtra(MainActivity.IS_NEXT_WEEK, isNextWeek);
notificationIntent.setData(Uri.parse("myapp://nextWeek/" + (isNextWeek ? "1" : "0"))
Alternatively you could probably also just add a uuid to the data uri (however, if you have lots and lots of notifications, it might be nice to cache them

Implement setOnClickPendingIntent from notification

I build custom notification that contain button and i want to listin when user press on it.
The button should not open any activity but only logic staff like change song.
the Code:
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification);
contentView.setTextViewText(R.id.toptext, nowPlayingTitle);
//this not work
Intent intent = new Intent(this, receiver.class);
intent.putExtra("UNIQ", "1");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this.getApplicationContext(), 234324243, intent, PendingIntent.FLAG_CANCEL_CURRENT)
contentView.setOnClickPendingIntent(R.id.imageButtonPlay,
pendingIntent);
notification.contentView = contentView;
// this is to return to my activity if click somwhere else in notification
Intent notificationIntent = new Intent(this, MYACTIVITY.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
mNotificationManager.notify(NOTIFICATION_ID, notification);
I don't get the hang of the setOnClickPendingIntent what need to be in the second param?
How can i just call a function after user press on the button?
im probably missing something cause i dont understand the receiver side and what happend after user press
You are missing the fact that the button you created actually doesn't belong to your application. It is created in another context, in another process. There is no way it can call your function.
Instead, when the user taps the button, that pending intent is fired. You can catch it by your receiver (in your activity), check some parameters and do the action.
Or you can implement a service and handle this intent in background. I'd prefer this way.
thanks for quick answer. I try using receiver but it never fired.
The code is in the main question and i created for the reciever class the following code:
public class receiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
}
}
but click on the notification never fire the receiver ( Test on debug mode )

Window already focused, ignoring focus gain of: com.android.internal.view

Unfortunately, I was unable to find a resolution to this issue in other StackOverflow posts so I apologize in advance for re-posting this question. Essentially, I have an AppWidget that creates a Notification. I want the user to click the Notification to launch an Activity. The AppWidget and Activity are in the same APK.
The following code is all in the AppWidget. Clicking on the Notification broadcasts a custom Intent which is received by the AppWidget.
The problem is that the Activity does not appear to launch, even though logcat demonstrates that the custom Intent has indeed been broadcast. The only clue is the logcat message reiterated in the post title.
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Constants.BROWSER_INTENT)) {
launchActivity(context, R.layout.appwidget, R.id.launch_button, Activity.class);
}
super.onReceive(context, intent);
}
private void displayNotification(Context context, String ticker, String title, String msg) {
Intent intent = new Intent(context, ThisWidget.class);
intent.setAction(Constants.BROWSER_INTENT);
PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon, ticker, System.currentTimeMillis());
notification.setLatestEventInfo(context, title, msg, pending);
notificationManager.notify(1, notification);
}
Some notes:
Pressing a button to execute launchActivity() works (it launches the
Activity)
launchActivity uses Intent.FLAG_ACTIVITY_NEW_TASK as
recommended by Android lifecycle documentation
Has anyone solved this issue when launching an Activity from a Notification press?
er, figures, I answered my own question just minutes after posting it. I guess I was over-complicating the implementation by using an Intent action. I changed these lines:
Intent intent = new Intent(context, ThisWidget.class);
intent.setAction(Constants.BROWSER_INTENT);
PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);
to this:
Intent intent = new Intent(context, Activity.class);
PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);
and it worked.
Sorry for the bogus post.

passing variable to an activity through an Intent is always the same

My application receives a C2DM message and sends a status bad notification with the C2DM message. So far so good.
When the user clicks on the notification, an activity is called, passing the C2DM message as a variable.
Now, the first time it works smoothly, the second time the variable passed is not refreshed. It's always the first variable passed.
Am I missing something?
Here are the snipperts:
C2DM Notification
Intent notificationIntent = new Intent(context, BMBPad.class);
notificationIntent.putExtra("seqid", message);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
This is how I read the variable in the Activity called by the Intent.
extra = this.getIntent().getExtras();
seqidi = extra.getString("seqid");
Anyone any idea why that happens?
You need to use the flag PendingIntent.FLAG_UPDATE_CURRENT
In your case:
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Please also have a look here: Android PendingIntent
You can try to append this snippet in the Activity called by the Intent.
/**
* Override super.onNewIntent() to let getIntent() fetch the latest intent
* that was used to start this Activity rather than the first intent.
*/
#Override
public void onNewIntent(Intent intent){
super.onNewIntent(intent);
setIntent(intent);
}
override onNewIntent() method, get your variable like this:
#Override
public void onNewIntent(Intent intent){
super.onNewIntent(intent);
seqid = intent.getStringExtra("seqid","");
}
because start the activity again will trigger onNewIntent() method.

Categories

Resources