public class GcmIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private static final String TAG = "GcmIntentService";
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GcmIntentService() {
super("GcmIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
/*
* Filter messages based on message type. Since it is likely that GCM
* will be extended in the future with new message types, just ignore
* any message types you're not interested in, or that you don't
* recognize.
*/
if (GoogleCloudMessaging.
MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_DELETED.equals(messageType)) {
sendNotification("Deleted messages on server: " +
extras.toString());
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// This loop represents the service doing some work.
for (int i=0; i<5; i++) {
Log.i(TAG, "Working... " + (i+1)
+ "/5 # " + SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work # " + SystemClock.elapsedRealtime());
// Post notification of received message.
sendNotification(extras.getString("Notice"));
Log.i(TAG, "Received: " + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, Notification.class),PendingIntent.FLAG_UPDATE_CURRENT );
//PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),
//0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
// .setSmallIcon(R.drawable.ic_stat_gcm)
.setContentTitle("MobileHealth")
.setSmallIcon(R.drawable.ic_launcher)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
Here is my code for notification. i am able to get the message using the ip address when i have first send the message but now when i am using a new ip address i am not able to get the message and in the log cat it displays Invalid app and invalid package name : perhaps you didnot include a pendingIntent in the extras
Related
I have been trying showing heads up notification as part of Full Screen Intent. It works well in some devices and if device is not locked, it shows up as heads up notification.
But in samsung devices, i have set system notification setting to brief (that shows notification for brief amount of time and then disappear back to system tray). This setting causing heads up notification to appear for small amount of time.
For the same setting, whatsapp and system caller app able to show heads up notification for incoming call.
i have used the following code
Channel creation
private void createFullIntentChannel(){
NotificationManager manager = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + ctx.getPackageName() + "/raw/new_ride.mp3" ) ;
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.build();
String NOTIFICATION_CHANNEL_ID = "com.myapp.app.fullintent";
String channelName = "FullRide";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH);
chan.setLightColor(Color.BLUE);
chan.enableVibration(true);
chan.setImportance(NotificationManager.IMPORTANCE_HIGH);
chan.setSound(sound, attributes);
chan.setShowBadge(true);
chan.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
manager.createNotificationChannel(chan);
}
}
Setting content and action buttons on notification
public void showFullScreenIntent(final int notifId, String pickLoc, String dropLoc, String tripType, String accountID, String accountType,
String qrMode, Integer stopCount, Integer vhclType, String estInfo) {
setMediaPlayerFile();
if (mediaPlayer != null) {
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
PlayFile();
}
});
PlayFile();
}
// set content pending intent
Intent fullScreenIntent = new Intent(ctx, NewRideRequest.class);
fullScreenIntent.putExtra("Action", "UserChoice");
fullScreenIntent.putExtra("ID", notifId);
fullScreenIntent.putExtra("BookingID", String.valueOf(notifId));
PendingIntent contentIntent = PendingIntent.getActivity(ctx, ACTION_USER_REQUEST_ID,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
// set action button accept pending intent
Intent acceptIntent = new Intent(ctx, NewRideRequest.class);
acceptIntent.putExtra("Action", "Accept");
acceptIntent.putExtra("ID", notifId);
acceptIntent.putExtra("BookingID", String.valueOf(notifId));
PendingIntent pendingAcceptIntent = PendingIntent
.getActivity(ctx, ACTION_INTENT_REQUEST_ID, acceptIntent,PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
// set action button reject pending intent
Intent rejectIntent = new Intent(ctx, NotificationAction.class);
rejectIntent.putExtra("Action", "Reject");
rejectIntent.putExtra("ID", notifId);
rejectIntent.putExtra("BookingID", String.valueOf(notifId));
PendingIntent pendingRejectIntent = PendingIntent
.getBroadcast(ctx, ACTION_INTENT_REQUEST_ID, rejectIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + ctx.getPackageName() + "/raw/new_ride.mp3") ;
createFullIntentChannel();
String val = dbHelper.GetVehicleMaster(dbHelper.getReadableDatabase(), vhclType);
// set notification builder
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(ctx, "com.myapp.app.fullintent")
.setSmallIcon(R.drawable.ic_yego_logo)
.setContentTitle("New " + (val.contains(",") ? val.split(",")[0] : "") + " Ride Request")
.setContentText(getContent(stopCount, pickLoc, dropLoc))
//.setSound(sound)
.setOngoing(true)
.setTimeoutAfter(10000)
.setDefaults(Notification.DEFAULT_VIBRATE| Notification.DEFAULT_SOUND)
.addAction(R.drawable.payment_success_1, getActionText(R.string.txt_accept, R.color.colorGreen), pendingAcceptIntent)
.addAction(R.drawable.payment_failed_1, getActionText(R.string.txt_reject, R.color.colorRed), pendingRejectIntent)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setFullScreenIntent(contentIntent, true);
Notification incomingCallNotification = notificationBuilder.build();
incomingCallNotification.sound = sound;
//incomingCallNotification.flags = Notification.FLAG_INSISTENT;
final NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notifId, incomingCallNotification);
Handler handler = new Handler(Looper.getMainLooper());
long delayInMilliseconds = 10000;
handler.postDelayed(new Runnable() {
public void run() {
try {
Log.e("MyApp", "Handler runs");
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
notificationManager.cancel(notifId);
}catch (Exception e){
}
}
}, delayInMilliseconds);
}
Please suggest how can i set ongoing heads up notification to be on screen regardless of system setting of notification.
I've created a simple notification and styled it with different colors and general style using a completely new layer created and designed..
Once I trigger the notification though Firebase Messages, when the app is at the foreground, it works perfectly showing the exact styling I need.
But when the app is in the background, it uses it's fugly default style.
Anyway to fix that? Thanks.
The notification java class file code -
public class MyFirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
private static final String TAG = "FirebaseMessagingServic";
public MyFirebaseMessagingService() {
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String title = remoteMessage.getNotification().getTitle();
String message = remoteMessage.getNotification().getBody();
Log.d(TAG, "onMessageReceived: Message Received! \n " +
"Title : " + title + "\n" +
"Message : " + message);
sendNotification(title, message);
}
#Override
public void onDeletedMessages() {
}
private void sendNotification(String title, String messageBody) {
final RemoteViews remoteViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.notification_layout);
remoteViews.setTextViewText(R.id.remoteview_notification_short_message, messageBody);
remoteViews.setTextViewText(R.id.notificationDate, title);
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = "0";
Uri defaultSoundUri= Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName() + "/raw/notice");
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.minilogored)
.setContentIntent(pendingIntent)
.setContent(remoteViews)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setLights(0xf14d39, 1500, 2000)
.setPriority(NotificationCompat.PRIORITY_HIGH);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
Please refer the link to know more about Data message and Display message how to handle in onMessageReceived() callback function.
How to handle notification when app in background in Firebase
https://firebase.google.com/docs/cloud-messaging/android/receive
I need help. As I wrote in title , I don't know how to keep data from notification when it arrives and the application is in background or killed. What i need to pass ( code below) is a Plate that i need for an elaboration . Here is the code:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String text= remoteMessage.getNotification().getBody();
SharedPreferences s = getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE);
Functions.putStringInPrefs(s, Constants.PREFS_ALERT_PLATE, text);
if (Functions.isUserSignedUp(this)) {
if (remoteMessage.getNotification() != null) {
// Log.d(TAG, "Message Title:" + remoteMessage.getNotification().getTitle());
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
try {
sendNotification(remoteMessage.getNotification());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void sendNotification(RemoteMessage.Notification notification) {
Intent intent = new Intent(this, FragmentChangeActivity.class);
String prova = notification.getBody();
intent.putExtra("alert_plate" , prova);
GlobalData.alertPlate=prova; // object used as cache
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if(notification.getTitle()!= null){
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.details_icon).setContentTitle(notification.getTitle());
} else{
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.details_icon).setContentTitle(getString(R.string.app_name));
}
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.details_icon).setContentText(notification.getBody())
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(new Random().nextInt((100000000 - 1) + 1) + 1, new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.details_icon).build());
}
}
What do I need to change ? Thank you !
Ps. In manifest the class is declared in the correct way .
There are two types of FCM messages
1) Notification message
2) Data message
So if you want to receive data when the app is close you have to send your data using data message. Your data format will be something look like below
{
"to": "device_id",
"data": {
"param_1": "vale 1",
"param_2": "value 2",
"param_3": "Value 3"
}
}
After receiving the message now you can store your data in shared preference or database whatever you want.
My MyFirebaseMessagingService.
public class MyFirebaseMessagingService
extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "FRCM:"+ remoteMessage.getFrom());
/*Check if the message contains data*/
if(remoteMessage.getData().size() > 0){
Log.d(TAG,"Message data: "+ remoteMessage.getData());
}
/*Check if the message contains notification*/
if(remoteMessage.getNotification() != null){
Log.d(TAG,"Message body: "+ remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getBody());
}
}
/*Display Notification Body*/
private void sendNotification(String body) {
Intent intent = new Intent(this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0/*Request code*/, intent, PendingIntent.FLAG_ONE_SHOT);
/*Set sound of Notification*/
Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notifiBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_event_note_black_24dp)
.setContentTitle("Firebase Cloud Messaging")
.setContentText(body)
.setAutoCancel(true)
.setSound(notificationSound)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0/*ID of notification*/, notifiBuilder.build());
intent = new Intent("myAction");
intent.putExtra("title", title);
intent.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
and My Activity Messaging is.
public class Mess{
}
You send messages from your phone using FCM. You need to make a POST to https://fcm.googleapis.com/fcm/send api with payload that you want to send, and you server key found in Firebase Console project or You can Use POSTMAN google chrome extension
As an exameple of payload sending to a single user with to param:
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
Also, to param can be used for topics "to": "topics/yourTopic"
In data you can send whatever you want, message is received in onMessageReceived() service from Firebase.
More details you can found in Firebase documentation.
For sending data to another activity
private void sendNotification(String body) {
Intent intent = new Intent(this, Home.class);
here you can set intent
intent.putExtra("word", body);
and to read from activity use
b = getIntent().getExtras();
String passed_from = b.getString("word");
I'm getting this error on GCM and sometime I receive the message but no notification was generated. Could anyone help me to identify what's the problem?
Here's my code (some business logic code was removed for simplicity):
GcmBroadcastReceiver:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GcmIntentService:
public class GcmIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
public GcmIntentService() {
super(ConstantManager.SENDER_ID);
}
/**
* Method called on device registered
**/
#Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
}
/**
* Method called on device un registred
* */
#Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
}
/**
* Method called on Receiving a new message
* */
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("message");
String type = intent.getExtras().getString("type");
int eventId = 0;
generateNotification(context, message,2,eventId);
}
/**
* Method called on receiving a deleted message
* */
#Override
protected void onDeletedMessages(Context context, int total) {
Log.i(TAG, "Received deleted messages notification");
// notifies user
generateNotification(context, "Deleted Message",0,0);
}
/**
* Method called on Error
* */
#Override
public void onError(Context context, String errorId) {
Log.i(TAG, "Received error: " + errorId);
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
// log message
Log.i(TAG, "Received recoverable error: " + errorId);
return super.onRecoverableError(context, errorId);
}
/**
* Issues a notification to inform the user that server has sent a message.
*/
#SuppressWarnings("deprecation")
private static void generateNotification(Context context, String message,int type,int referId) {
int icon = R.drawable.logo_v2;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Log.i(TAG, "Generating Notification");
String title = context.getString(R.string.app_name);
if(GeneralManager.sessionManager.isLoggedIn())
{
if(type==2)
{
Log.i(TAG, "Type 2");
Intent notificationIntent = new Intent(context, PendingEventDetailsActivity.class);
SharedPreferences pref = context.getSharedPreferences(SessionManager.PREF_NAME, SessionManager.PRIVATE_MODE);
String userId = pref.getString(SessionManager.KEY_USER_ID,null);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
notificationIntent.putExtra("eventId", String.valueOf(referId));
notificationIntent.putExtra("userId", userId);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
else
{
Log.i(TAG, "Other type");
Intent notificationIntent = new Intent(context, WelcomeActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
notificationIntent.putExtra("notification", "true");
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
}
}
}
I know this answer is ver late,but hope it can help someone else.
This problem can be solved by two Methods :
Method 1 :
This problem is encountered when WakeLock is released incorrectly i.e. When library tries to release WakeLock that holds nothing (internal lock counter becomes negative).To avoid this you can add following line of code(catching the exception if the WakeLock is not active) on WakeLocker.release(); :
synchronized (LOCK) {
// sanity check for null as this is a public method
if (WakeLock != null) {
Log.v(TAG, "Releasing wakelocker");
try {
WakeLocker.release();
} catch (Throwable th) {
// ignoring this exception, probably wakeLock was already released
}
} else {
// should never happen during normal workflow
Log.e(TAG, "Reference of WakeLock is null");
}
}
Method 2 :
This is more convenient way of solving the problem, u can use WakeLocker.isHeld(); on WakeLocker.release(); i.e.
if (WakeLocker.isHeld())
WakeLocker.release();
Hope it helps anyone.