I have a subclassed BroadCastReceiver inside my main activity in an android application to deal with changing the GUI when a GCM comes in. All of this works fine.
The one thing that doesn't work is that if this gets called then the user has my app open on his device, and as such I want to clear the notification I entered into the notification center for this incoming GCM. If I put the cancelAll() and cancel(int) lines into my GCMIntentService, then it dismisses the notifications, but I cannot keep it there since I only want to dismiss this notification if the user has my app open. I used both the cancel() and cancelAll() to make sure that I wasn't somehow passing the wrong notification id from the IntentService (I have verified it is correct).
The problem is that there is no error and the notification in the notification center simply won't go away. I have verified that this method is getting called since I get the log entries in logcat.
I referenced this prior answer, but it doesn't work in my implementation for some reason: Starting and stopping a notification from broadcast receiver
My code inside my main activity:
private class NotificationBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("Push", "Received Push Notification!");
//Now that the user has opened the app, cancel the notification in the notification center if it is still there
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final int NOTIFICATION_ID = intent.getIntExtra("notificationId",0);
Log.v("NOTIFICATION_ID",Integer.toString(NOTIFICATION_ID));
mNotificationManager.cancel(NOTIFICATION_ID);
mNotificationManager.cancelAll();
Log.v("Canceled Notifs","Canceled");
}
}
Any ideas why?
A potentially better option is, instead of posting the notification while the app is open, to first detect if the app is visible and, if it is, don't display the notification. You can do this using Intent broadcasts or an event bus like EventBus or Otto.
Example:
public class GCMReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// this is your receiver after gcm has been received
Intent appOpenCheck = new Intent("com.example.IS_APP_OPEN");
// put extras about your notification here...
context.sendOrderedBroadcast(appOpenCheck);
}
}
public class AppNotOpenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// this is your receiver that will be hit if the app isn't open
// post your notification to the NotificationManager
}
}
Then, in AndroidManifext.xml:
<receiver
android:name=".AppNotOpenReceiver">
<intent-filter>
<action android:name="com.example.IS_APP_OPEN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Finally, in your Activity:
BroadcastReceiver appOpenAlert = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
abortBroadcast(); // prevents notification from going further
// this is your receiver that will be hit if the app is open
// update your ui
}
}
#Override
public void onStart() {
super.onStart();
IntentFilter notificationReceived = new IntentFilter();
notificationReceived.addAction("com.example.IS_APP_OPEN");
notificationReceived.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(appOpenAlert, notificationReceived);
}
#Override
public void onStop() {
unregisterReceiver(appOpenAlert);
super.onStop();
}
Related
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.
}
}
}
I have receiving GCM push notification message in my mobile successfully. But, I want to make some text update in my app working page.
While receiving push notification, app page automatically need to change text like push notification received and show to any text view, in working page.
Already referred: Updating the UI upon receiving an android push notification
For push notification am using this class to receive notification:
public class GCMBroadcastReceiver extends WakefulBroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
}
}
For MainPage Push notif text showing Activity Page Code:
public void onResume(){
super.onResume() ;
Log.v("tag","onResume working...") ;
broadcast = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "Receiver...", 1).show();
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(broadcast,new IntentFilter("com.google.android.c2dm.intent.REGISTRATION"));
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcast);
}
My above code: exactly don't know the mistake in code..
You have to call a local BroadcastReceiver which will be on your current app page.
To do this- Inside your GcmListenerService class after receiving a message on the override method onMessageReceived(String from, Bundle data) you have to call your local BroadcastReceiver on the base of relevant result from inside the method.
When the BroadcastReceiver will call, now show a message or set a text in TextView from inside the local BroadcastReceiver after getting the intent result.
Hope it will help you.
I have an IntentService defined as below:
<service android:name=".service.AppService" android:process=":app_process" android:icon="#mipmap/ic_launcher" />
I have a WakefulBroadcastReceiver that receives some data and I would like to call my already running service above. The service above is always running, even if it is killed, it restarts. How can I pass messages to that?
I read the following:
http://www.mysamplecode.com/2011/10/android-intentservice-example-using.html
http://www.truiton.com/2014/09/android-service-broadcastreceiver-example/
http://developer.android.com/guide/components/services.html
I tried to do a startService, PendingIntent among other things and nothing seems to work.
First of all, remember that an IntentService works in a different worker thread, there for it's not possible to have intercommunication with the Activity that invoked it. That's why mostly we use them for synchronization on background where feedback to the user is not needed. However, if you want to pass some information to the Activity, you have to use a BroadcastReceiver as you said, and from there create the Intent that will send "data" to the Activity.
Going back to your question, you have to add the service and the receiver in your AndroidManifest.xml inside the <application> tag
<service android:name=".AppService"
android:enabled="true"/>
<receiver android:name=".WakefulBroadcastReceiver" >
</receiver>
Then in your Activity launch the service like this (whenever you need it, in the onCreate, or in a button listener)
IntentFilter filter = new IntentFilter(WakefulBroadcastReceiver.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
WakefulBroadcastReceiver broadcastReceiver = new WakefulBroadcastReceiver();
registerReceiver(broadcastReceiver, filter);
In your BroadcastReceiver you override the onReceive() method like this:
#Override
public void onReceive(Context context, Intent intent) {
// HERE IS WHERE YOU RECEIVE THE INFORMATION FROM THE INTENTSERVICE, FROM HERE YOU CAN START AN ACTIVITY OR WHATEVER YOU AIM
Toast.makeText(context, "IntentService Broadcasting", Toast.LENGTH_SHORT).show();
}
Also in the same BroadcastReceiver add this variable that identifies the intentfilter:
public static final String ACTION_RESP = "MY_FILTER_NAME"
In your IntentService class you have to override the onHandleIntent() method like this:
#Override
protected void onHandleIntent(Intent intent) {
String msg = intent.getStringExtra("MSG");
Intent broadcast = new Intent();
broadcast.setAction(WakefulBroadcastReceiver.ACTION_RESP);
broadcast.addCategory(Intent.CATEGORY_DEFAULT);
broadcast.putExtra("MSG", resultTxt);
// HERE IS WHERE YOU SEND THE INFORMATION YOU LOADED TO THE APP
sendBroadcast(broadcast);
}
I have a demo project in my GitHub account here, where I use bound and unbound services and IntentServices:
https://github.com/isaacurbina/PermissionsAndServices
I hope it helps.
Kind regards!
You can write this in your class that extends WakefulBroadcastReceiver :
#Override
public void onReceive(Context context, Intent intent) {
Intent gcmIntent = new Intent(context, MessageService.class);
gcmIntent.putExtras(intent.getExtras());
startWakefulService(context, gcmIntent);
setResultCode(Activity.RESULT_OK);
}
And write this in your class that extend IntentService :
#Override
protected void onHandleIntent(Intent intent) {
Bundle bundle = intent.getExtras();
//do sth with that data
MessageReceiver.completeWakefulIntent(intent);
}
I am using Parse to do push notifications and the issue I am running into is that while my application is running (either in the foreground or background) the phone's operating system does not show the push notification in the notification bar. What changes to my implementation do I need to make to see the push display on the notification bar?
My extended Application class has the following in onCreate()
// initialize Parse SDK
Parse.initialize(this, Constants.APPLICATION_ID_DEBUG, Constants.CLIENT_KEY_DEBUG);
ParsePush.subscribeInBackground(Constants.CHANNEL, new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Logger.i(TAG, "successfully subscribed to broadcast channel");
} else {
Logger.e(TAG, "failed to subscribe for push: " + e);
}
}
});
ParseInstallation.getCurrentInstallation().saveInBackground();
I have a sign in system for my app, so I am using the ID of the logged in user as the Channel to subscribe users to. So in the first Activity of my app I call the following code snippet in onCreate().
private void registerNotifications() {
List<String> arryChannel = new ArrayList<String>();
arryChannel.add(session.id);
ParseInstallation parseInstallation = ParseInstallation.getCurrentInstallation();
parseInstallation.put("channels", arryChannel);
parseInstallation.saveEventually();
}
I also have a custom receiver that is working. Each time a push is sent out, it is being received by the onPushReceive method, however, I want the push to display in the notification bar.
public class ParsePushReceiver extends ParsePushBroadcastReceiver {
private static final String TAG = ParsePushReceiver.class.getSimpleName();
#Override
public void onPushOpen(Context context, Intent intent) {
Log.i(TAG, "onPushOpen");
}
#Override
protected void onPushReceive(Context context, Intent intent) {
Log.i(TAG, "onPushReceive");
}
}
Thanks in advance!
Just remove the onPushReceive method and the default behaviour will remain (show the notification in the status bar.
You are getting this behaviour because if the application is running the Parse Push notification will call the method onPushReceive that does nothing.
I have figured this out. Although the answer provided by Sandra will make a push notification appear on the notification bar, it is not connected to Parse.
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
This causes issues, because if you click on that notification the receiver you create extending ParsePushBroadcastReceiver will not register onPushOpen. My implementation for everything was correct, I only needed to add
super.onPushReceive(context, intent);
That will make the notification appear on the notification bar and also register clicks.
So make sure to make your receiver looks like this (at minimum)
public class ParsePushReceiver extends ParsePushBroadcastReceiver {
private static final String TAG = ParsePushReceiver.class.getSimpleName();
#Override
public void onPushOpen(Context context, Intent intent) {
Log.i(TAG, "onPushOpen");
}
#Override
protected void onPushReceive(Context context, Intent intent) {
Log.i(TAG, "onPushReceive");
**super.onPushReceive(context, intent);**
}
}
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.