Problems with Android intents after activating app from background - android

I've just started with Android development. I've created an App Engine connected Android Project in Eclipse by following this guide: Creating an App Engine Connected Android Project.
The app works, but when the task goes to background and then is activated again by receiving a GCM message, intents invoked by the GCMIntentService class do not reach the corresponding activity. What might be the problem?
public class GCMIntentService extends GCMBaseIntentService {
[...]
#Override
public void onMessage(Context context, Intent intent) {
sendNotificationIntent(context, "Message received via Google Cloud Messaging:\n\n" + intent.getStringExtra("message"), true, false);
}
[...]
private void sendNotificationIntent(Context context, String message, boolean isError, boolean isRegistrationMessage) {
Intent notificationIntent = new Intent(context, RegisterActivity.class);
notificationIntent.putExtra("gcmIntentServiceMessage", true);
notificationIntent.putExtra("registrationMessage", isRegistrationMessage);
notificationIntent.putExtra("error", isError);
notificationIntent.putExtra("message", message);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(notificationIntent);
}
[...]
}
Thanks in advance!

// add permission <uses-permission android:name="android.permission.WAKE_LOCK" />
#Override
public void onMessage(Context context, Intent intent) {
sendNotificationIntent(context, "Message received via Google Cloud Messaging:\n\n" + intent.getStringExtra("message"), true, false);
context.sendBroadcast(intent) ;
}
private void sendNotificationIntent(Context context, String message, boolean isError, boolean isRegistrationMessage) {
Intent notificationIntent = new Intent(context, RegisterActivity.class);
notificationIntent.putExtra("gcmIntentServiceMessage", true);
notificationIntent.putExtra("registrationMessage", isRegistrationMessage);
notificationIntent.putExtra("error", isError);
notificationIntent.putExtra("message", message);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationManager notificationManager =
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = neNotification(R.drawable.ic_launcher,"Title",System.currentTimeMillis());
PendingIntent intents = PendingIntent.getActivity(context, 0, notificationIntent, Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
notification.setLatestEventInfo(context , context.getString(R.string.app_name), tickerText , intents );
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(100, notification);
}
public class AppBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction() == "AppReceiver") {
// this intent is gcminit intent and you can get data from this Intent
}
}
}
// in menifest file
<receiver android:name="AppBroadcastReceiver" >
<intent-filter>
<action android:name="AppReceiver" >
</action>
</intent-filter>
</receiver>

If the activity is in background then the intent is receive in onNewIntent which will be called before onResume, thus you have to override onNewIntent
#Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
boolean b = intent.getBooleanExtra("gcmIntentServiceMessage", false);
........
}

Issue almost solved... had to add:
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
There is only one problem left: onNewIntent() is still not fired when activity is brought to front by a GCM message. I put the code in onCreate() instead.

Related

How to properly handle intents in xamarin

At the moment I am using firebase messaging for my push notification. I am attaching data to my intent so I can capture it and my application can use that data when the push is clicked.
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
const string TAG = "MyFirebaseMsgService";
public override void HandleIntent(Intent intent)
{
CreateNotification(intent);
}
private void CreateNotification(Object e)
{
var i = e as Intent;
var bundle = i.Extras;
var intent = new Intent(this, typeof(MainActivity));
var notificationName = bundle.GetString("notificationName");
if (!string.IsNullOrEmpty(notificationName))
{
intent.PutExtra("notificationName", notificationName);
}
intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.CancelCurrent | PendingIntentFlags.UpdateCurrent);
Notification.Builder builder = new Notification.Builder(this);
builder.SetSmallIcon(Resource.Drawable.icon_notification);
builder.SetContentIntent(pendingIntent);
builder.SetLargeIcon(BitmapFactory.DecodeResource(Resources, Resource.Drawable.icon));
builder.SetContentText(body);
builder.SetDefaults(NotificationDefaults.Sound);
builder.SetAutoCancel(true);
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
builder.SetChannelId("YourChannelID");
}
NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(1, builder.Build());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Then on my MainActivity Side of the program, OnCreate is triggered when the application is launched back into the foreground.
protected override void OnCreate(Bundle bundle)
{
....
App.NotificationName = Intent.GetStringExtra("notificationName");
....
}
The issue I am having now is that one one of my device (Android 7 OS) it works as intended, OnCreate is triggered when the application is brought to the foreground. The issue I am having now is that OnCreate isn't triggered on my other device (Android 8 OS). Whats the best way to handle this intents and where should I put this code App.NotificationName = Intent.GetStringExtra("notificationName"); so that it'll trigger on any device
From what I understood I guess you should use OnMessageReceived then you'll be able to get your notification using by GetNotification():
public override async void OnMessageReceived(RemoteMessage message)
{
var fromNotification = message.GetNotification();
//...use message.Data and prepare the notification to notify
}
Of cource the approach depends on your remote notification payload (Notification or Data messages)
Also you can use ActivityFlags.NewTask while creating the notification:
intent = new Intent(Application.Context, typeof(MainPage));
flags = PendingIntentFlags.CancelCurrent;
intent.SetFlags(ActivityFlags.NewTask);
But you will have to create your MainActivity as LaunchMode.SingleTop and will able to handle notification toast taps at OnNewIntent(Intent intent) and OnCreate(Bundle bundle) using by Intent instance from those overriden methods. (For OnCreate you should use Intent property of your Activity)

Alarm Notification Data disappear after rebooting phone

I am building a notification app, that uses alarm manager to set multiple notifications to reminde user of daily tasks, when phone is On everything is good, but when a reboot the phone, the notification is showing up but the notification data are lost (for example notification content) those data are saved into intent from my first activity
this is code bellow. (i have added permission and receive action to my manifest)please I need some help
public class add_rreminde extends AppCompatActivity implements View.OnClickListener{
private int notificationId=1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_rreminde);
//buton ok
findViewById(R.id.but).setOnClickListener(this);
findViewById(R.id.cancel).setOnClickListener(this);
}
#Override
public void onClick(View view){
EditText remide=findViewById(R.id.edit);
DatePicker date=findViewById(R.id.date);
Intent intent=new Intent(add_rreminde.this,AlarmReciver.class);
intent.putExtra("notificationId",notificationId);
intent.putExtra("todo",remide.getText().toString());
final int _id=(int)System.currentTimeMillis();
PendingIntent alarmIntent=PendingIntent.getBroadcast(add_rreminde.this,_id,intent,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarm=(AlarmManager)getSystemService(ALARM_SERVICE);
switch (view.getId()){
case(R.id.but):
int day=date.getDayOfMonth();
int month=date.getMonth();
int year=date.getYear();
//create date
Calendar startDate=Calendar.getInstance();
startDate.set(Calendar.DAY_OF_MONTH,day);
startDate.set(Calendar.MONTH,month);
startDate.set(Calendar.YEAR,year);
Long alarmStartDate=startDate.getTimeInMillis();
//setAlarme
alarm.set(AlarmManager.RTC_WAKEUP,alarmStartDate,alarmIntent);
Toast.makeText(getApplicationContext(),"done",Toast.LENGTH_LONG).show();
break;
case (R.id.cancel):
alarm.cancel(alarmIntent);
Toast.makeText(getApplicationContext(),"canceled",Toast.LENGTH_LONG).show();
break;
}
}
}
my reciver that push notification
public class AlarmReciver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//get id from notification id intent
int notification =intent.getIntExtra("notificationId",0);
String getMessage=intent.getStringExtra("todo");
//when notification is opened open mainActivity
Intent mainIntent=new Intent(context,add_rreminde.class);
PendingIntent contentIntent=PendingIntent.getActivity(context,0,mainIntent,0);
NotificationManager mynotificationManager=(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
//prepare notification
Notification.Builder builder=new Notification.Builder(context);
builder.setSmallIcon(R.drawable.assistant)
.setContentTitle("changer oil")
.setContentText(getMessage)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentIntent(contentIntent)
.setPriority(Notification.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_ALL);
//notify
mynotificationManager.notify(notification,builder.build());
}
}
By default, all alarms are canceled when a device shuts down. To
prevent this from happening, you can design your application to
automatically restart a repeating alarm if the user reboots the
device.
so you could add a BroadcastReceiver to receive ACTION_BOOT_COMPLETED
firstly:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
and:
<receiver android:name=".SampleBootReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
now you set alarm again when device reboot:
public class SampleBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
// Set the alarm here.
}
}
}

Stop Service from PendingIntent after Notifcation is opened

I want the service to perform a stopForeground and a stopSelf after the notification is clicked followed by the running of pendingIntent.
I have tried using a BroadcastReceiver which is never called as I checked during debugging. I have added it to manifest as well.
Intent intentHide = new Intent(this, StopServiceReceiver.class);
PendingIntent hide = PendingIntent.getBroadcast(this, (int) System.currentTimeMillis(), intentHide, PendingIntent.FLAG_CANCEL_CURRENT);
Added it to the builder
builder.setContentIntent(hide);
And the Broadcast Rec is done separately -
public class StopServiceReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 333;
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, TimerService.class);
context.stopService(service);
}
}
Manifest -
<receiver
android:name=".StopServiceReceiver"
android:enabled="true"
android:process=":remote" />
This is not working. The notification and the service both are alive.
Questions - Should I use addContent instead of setContentIntent ? If yes, then what should the parameters be ?
Is there anything I went wrong with? What could possibly be wrong with such kind of implementation? Thank you.
I had the same problem in the notification.
This code is working perfectly.
void creatnotifiaction()
{
public static final String STOP = "com.example.android";
public static final int REQUEST_CODE = 333;
filter = new IntentFilter();
filter.addAction(STOP);
Intent intentHide = new Intent(STOP);
PendingIntent hide = PendingIntent.getBroadcast(this,REQUEST_CODE,intentHide,PendingIntent.FLAG_CANCEL_CURRENT);
registerReceiver(broadcastReceiver, filter);
}
There no need to separate broadcast receiver use in same class.
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#SuppressLint("ResourceAsColor")
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.d("notification", "Received intent with action " + action);
switch (action) {
case STOP:
//your code to stop notifications or service.
break;
}
});
Let me know if that work for you.
Thanks...Happy coding.

stop Activity from displaying - Push notification (Parse)

I have just implemented Parse push notifications into my app. I want to be able to show the push notification, but i don't want the app to open when the user presses the Push notification. Instead, i just want the notification to be dismissed.
i would imagine it would be handled by the ParsePushBroadcastReciever, but i can't find anything online which fits my purpose.
Here is my subclassed ParsepushBroadcastReciever:
public class Receiver extends ParsePushBroadcastReceiver {
#Override
public void onPushOpen(Context context, Intent intent) {
Log.e("Push", "Clicked");
Intent i = new Intent(context, HomeScreen.class);
i.putExtras(intent.getExtras());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
In order for you to programatically dismiss a notification you will need to call cancel() using a NotificationManager instance passing in the ID that was passed into notify() on the NotificationManager (since this is what actually pushes the notification into the notification pane). You can't do this using the Parse SDK alone since you will need to take control of the population of notifications yourself.
First you will need to setup a NotificationManager instance then when a notification is ready to be pushed you assign it a value that you can reference later when cancelling like this:
public class MyParsePushBroadcastReceiver extends ParsePushBroadcastReceiver {
NotificationManager mNotificationManager;
int notification_id = 0;
#Override
public void onPushOpen(Context context, Intent intent) {
Log.e("Push", "Clicked");
mNotificationManager.cancel(notification_id)
}
#Override
public void onReceive(Context context, Intent intent) {
mNotificationManager = (NotificationManager)context.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
super.onReceive(context, intent);
...
}
#Override
protected Notification getNotification(Context context, Intent intent) {
Notification n = super.getNotification(context, intent);
notification_id = intent.getExtras().getInt("NOTIFICATION_TYPE");
mNotificationManager.notify(notification_id, n);
return null;
}
}
So you see by taking control of the NotificationManager (instead of passing it off to the Parse SDK to assign some unknown value) we can know exactly which values to use when calling cancel. I am letting the system build my Notification object (and I get it using super.getNotification()) but you are free to also use a Notification builder to create the notification yourself as well.

Android onNewIntent always receives same Intent

I have 2 Notifications: one for incoming messages, one for outgoing messages. On Notification click, it sends the PendingIntent to self. I put in an extra value to determine which of the Notifications was clicked:
private static final int INID = 2;
private static final int OUTID = 1;
private void update(boolean incoming, String title, String message, int number) {
notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, Entry.class);
intent.putExtra((incoming ? "IN" : "OUT"), incoming);
PendingIntent pi = PendingIntent.getActivity(Entry.this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
Notification noti = new Notification(incoming ? R.drawable.next : R.drawable.prev, incoming ? "Incoming message" : "Outgoing message", System.currentTimeMillis());
noti.flags |= Notification.FLAG_NO_CLEAR;
noti.setLatestEventInfo(this, title, message, pi);
noti.number = number;
notificationManager.notify(incoming ? INID : OUTID, noti);
}
And capture the Intent in the onNewIntent method:
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
if (intent.getExtras() != null)
for (String id : new ArrayList<String>(intent.getExtras().keySet())) {
Object v = intent.getExtras().get(id);
System.out.println(id + ": " + v);
}
else
log("onNewIntent has no EXTRAS");
}
plus the manifest line that makes sure that there's only one task (in activity tag):
android:launchMode="singleTop"
I logged that it runs through the onNewIntent method, but always use the same intent (IE if I click either the IN or OUT notification, the intent extra always contains the same bundle(logs: OUT: false)). It's always the Intent that was created last, which I found out because the initialization of both intents happens in another sequence than when they are changed:
private void buttonClick(View v) {
update(true, "IN", "in", 1);
update(false, "OUT", "out", 3);
}
private void setNotificationSettings() {
update(false, "IN", "===out message===", 0);
update(true, "OUT", "===in message===", 0);
}
Why do I always receive the same (last created) Intent?
You are passing same requestcode for all intent that why you reciev last intent everytime, so you have to pass different requestcode in pending intent..
like as below code
Your code:
PendingIntent pi = PendingIntent.getActivity(Entry.this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
Need to change:
PendingIntent pi = PendingIntent.getActivity(Entry.this, your_request_code, intent, Intent.FLAG_ACTIVITY_NEW_TASK);

Categories

Resources