When I am getting 'notification' GCM messages, android is automatically creating a notification from the title and body, and putting it into the notification shade.
When I say "notification" here, I mean the one called notification in this document https://developers.google.com/cloud-messaging/concept-options#notifications_and_data_messages
The problem I am having is that when I click on that, nothing happens - It does not launch my activity, or dismiss the notification.
I have tried using the "click_action" options, and that has had no effect.
I have added a "data" section, and that has no effect.
when my app is in foreground, I get the onMessageReceived as expected, and the NotificationCompat I build in that re-launches the application as expected.
What am I missing to get the background notifications to launch the app?
Here is the manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="example.package"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="21" />
<!-- [START gcm_permission] -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- [END gcm_permission] -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<permission
android:name="example.package.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="example.package.permission.C2D_MESSAGE" />
<application
android:name="example.package.application.appApplication"
android:allowBackup="true"
android:icon="#drawable/app_app_icon"
android:label="#string/app_name"
android:theme="#style/AppTheme"
tools:replace="android:icon, allowBackup"
>
<activity
android:name="example.package.main.activity.MainActivity"
android:label="#string/app_name"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- [START gcm_receiver] -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="example.package" />
</intent-filter>
</receiver>
<!-- [END gcm_receiver] -->
<!-- [START gcm_listener] -->
<service
android:name="example.package.service.MyGcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!-- [END gcm_listener] -->
<!-- [START instanceId_listener] -->
<service
android:name="example.package.service.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<!-- [END instanceId_listener] -->
<service
android:name="example.package.service.RegistrationIntentService"
android:exported="false"></service>
</application>
</manifest>
Here is a sample json I send to GCM:
{
"to" : "<snipped>",
"notification" : {
"title" : "<snipped>",
"body" : "<snipped>",
"icon" : "ic_launcher"
},
"data":{"a":"b"},
"content_available": true,
"click_action":"android.intent.action.MAIN"
}
The only thing I get with verbose logging on when I click the item in the notification window is:
08-30 11:54:35.942 3684-3980/? D/InputReader: Input event(4): value=1 when=7306609326000
08-30 11:54:35.942 3684-3980/? D/InputReader: Input event(4): value=1 when=7306609326000
08-30 11:54:35.942 3684-3980/? I/InputReader: Touch event's action is 0x0 (deviceType=0) [pCnt=1, s=0.323 ] when=7306609326000
08-30 11:54:35.952 3684-3980/? D/InputReader: lastThreadEndTime = 7303509457022, currentThreadStartTime = 7303509466814, diff = 0
08-30 11:54:35.952 3684-3979/? I/InputDispatcher: Delivering touch to (4091): action: 0x0, toolType: 1
08-30 11:54:35.952 4091-4091/? D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
08-30 11:54:35.952 3684-4035/? D/lights: button : 1 +
08-30 11:54:35.992 3684-4035/? D/lights: button : 1 -
08-30 11:54:36.112 3684-3980/? D/InputReader: Input event(4): value=0 when=7306778958000
08-30 11:54:36.112 3684-3980/? D/InputReader: Input event(4): value=0 when=7306778958000
08-30 11:54:36.112 3684-3980/? I/InputReader: Touch event's action is 0x1 (deviceType=0) [pCnt=1, s=] when=7306778958000
08-30 11:54:36.112 3684-3979/? I/InputDispatcher: Delivering touch to (4091): action: 0x1, toolType: 1
This is occurring on a Marshmallow and JellyBean devices, though I have not tested anything between.
I know that I can send the 'data' element alone, to kick my service even when in background, but that has the downside of not working if the application has been force stopped. I'm really trying to figure out what I need to do to get the behavior Google describes on that link.
Here is MyGcmListenerService - It does get properly called while the app is in the foreground.
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
/**
* Called when message is received.
*
* #param from SenderID of the sender.
* #param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
#Override
public void onMessageReceived(String from, Bundle data) {
// String message = data.getString("message");
String message = data.getBundle("notification").getString("body");
String customFields = data.getBundle("notification").getString("customFields");
String title = data.getBundle("notification").getString("title");
Log.d("From: " + from);
Log.d( "Title: " + title);
Log.d( "Message: " + message);
Log.d( "CustomFields: " + customFields);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream message.
}
// [START_EXCLUDE]
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
// [END_EXCLUDE]
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* #param message GCM message received.
*/
private void sendNotification(String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
/* resumes the current activity - just like pressing link on home page */
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle("GCM Message")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
To clarify, I am looking specifically on how to get this behavior working with GCM:
According to https://developers.google.com/cloud-messaging/downstream 'When your app is in the background, Android directs messages with notification to the system tray. A user click on a notification opens the app launcher by default.'
I have been able to re-write it with FCM, and I don't see this issue, but I really want to know what I am missing.
Based from this related SO question, in JSON, "notification" is used for send simple notification without action.
According to this documentation:
Notifications provide an easy way for developers to send a user-visible display message with some predefined keys and optional custom key/value pairs. Data payloads include the developer’s custom key/value pairs only, and the client app must handle the message. You can send messages that have both notification and data payloads.
This SO question also suggested to replace MainActivity.class in the message receiver with the entry activity.
final Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
You can also check on this link with a sample code on how to open application when notification was clicked. Hope this helps!
Related
I have tried some solution from the stackoverflow . But not working properly in my case.
Below is my MyFirebaseMessagingService class which extends FirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
String url , title , body ;
Map<String,String> data = new HashMap<>();
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
title = remoteMessage.getNotification().getTitle();
body = remoteMessage.getNotification().getBody();
if(remoteMessage.getData().size()>0){
Log.d("DATA", remoteMessage.getData().toString());
try{
data = remoteMessage.getData();
url = data.get("url");
}
catch (Exception e){
Log.e("Error", e.toString());
}
showNotification(url , title , body);
}
}
private void showNotification(String url, String title, String body) {
Intent intent = new Intent(this, NotificationViewer.class);
intent.putExtra("URL",url);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) ;
notificationBuilder.setContentTitle(title);
notificationBuilder.setContentText(body);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.drawable.logo);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,notificationBuilder.build());
}
}
Below is my AndroidManifest.xml code .
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dcastalia.com.munshijobsportal">
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:name=".Controller.AppController"
android:allowBackup="true"
android:icon="#drawable/logo"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".activity.SplashActivity"
android:noHistory="true"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".firebase.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name=".firebase.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<activity android:name=".activity.NotificationViewer"
android:exported="true">
</activity>
</application>
</manifest>
I have tried out some solution but not working in my case. Everything is working fine when app is foreground but not working in background. I want to open a particular activity name NotificationViewer.Java activity when user click on the notification. But when my app is in background it keep opening my Launcher Activity.
You need to set click action in your json payload in notification request
'click_action' => 'YourTAG' and apply same tag in your manifest activity
<activity
android:name=".activity.NotificationViewer">
<intent-filter>
<action android:name="YourTAG" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
You are most likely using the Firebase Notification message instead of the Data message.
If this is the case, using Data FCM message should do the trick for you.
As can be seen in https://firebase.google.com/docs/cloud-messaging/concept-options
Use notification messages when you want FCM to handle displaying a notification on your client app's behalf. Use data messages when you want to process the messages on your client app.
Notification Messages:
When your application is in the foreground, it receives the payload, but when in the background, Notification messages are delivered to the notification tray.
Data Messages:
These are are always delivered to the application, regardless if it is in the foreground or in the background.
NOTE: The FCM data message alone will not bring your application in the foreground. You will need additional code that will do that upon reception of the data message.
I'm trying to implement push notification using GCM in my Android Application. I created a server to push messages to devices successfully and also created a api to store the device token in the server successfully. Created a client in application mentioned in the link based on the sample project. And also created a function in php to push notification to the App. When I run that function in the server I'm getting response as success. That means the message is sent from gcm to mobile. But the notification is not shown instead I'm getting the following in the log cat.
06-05 14:58:59.172 23693-28001/com.greenboards.base I/dalvikvm﹕ Could not find method android.app.Notification$Builder.setColor, referenced from method com.google.android.gms.gcm.zza.zzv
06-05 14:58:59.172 23693-28001/com.greenboards.base W/dalvikvm﹕ VFY: unable to resolve virtual method 184: Landroid/app/Notification$Builder;.setColor (I)Landroid/app/Notification$Builder;
06-05 14:58:59.173 23693-28001/com.greenboards.base D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0068
06-05 14:58:59.175 23693-28001/com.greenboards.base W/GcmNotification﹕ Failed to show notification: Missing icon
To capture the message I'm using the same listener service which denoted in the example application(I added below for the reference). So I thought the issue in the notification manager. So I commented it out and run the application. But again I'm getting the same response without any notification. I don't know what is the issue.
package com.greenboards.base;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.greenboards.base.R;
import com.google.android.gms.gcm.GcmListenerService;
import com.greenboards.base.SplashScreen;
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
/**
* Called when message is received.
*
* #param from SenderID of the sender.
* #param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* #param message GCM message received.
*/
private void sendNotification(String message) {
/*Intent intent = new Intent(this, SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 *//* Request code *//*, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle("GCM Message")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 *//* ID of notification *//*, notificationBuilder.build());*/
Log.v("notification message",message);
}
}
But whenever the message received from the server the onMessageReceived must be called in the above listener. In the onMessageReceived function there is two logging function to show message and the sender. That is also not executing. That means the function itself is not executing. Below i added the manifest content.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.greenboards.base"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />
<!-- Application Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="com.greenboards.base.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.greenboards.base.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Application Configuration and Activities -->
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity android:name=".SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- [START gcm_receiver] -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.greenboards.base" />
</intent-filter>
</receiver>
<!-- [END gcm_receiver] -->
<!-- [START gcm_listener] -->
<service
android:name="com.greenboards.base.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!-- [END gcm_listener] -->
<!-- [START instanceId_listener] -->
<service
android:name="com.greenboards.base.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<!-- [END instanceId_listener] -->
<service
android:name="com.greenboards.base.RegistrationIntentService"
android:exported="false">
</service>
</application>
</manifest>
Still now I can't able to debug what is the issue. Am I doing anything wrong or am I am missing anything?
According to this link you should have key/value pair of icon.
Check icon parameter of notification payload. It is specified as required.
So, you must include an icon in the JSON.
An example might be
{
"to":
"ci4ZzC4BW....",
"notification": {
"title": "Testing",
"body": "Success",
"icon": "#drawable/myicon"
}
}
myicon is the image named myicon.png in drawable folder in the application.
onMessageReceived is called when a message with data payload is received. When we change notification to data(like below) in the above json the onMessageReceived function will be called.
{
"to":
"ci4ZzC4BW....",
"data": {
"title": "Testing",
"body": "Success",
"icon": "#drawable/myicon"
}
}
I encounter the same problem
look at the info in logcat:
dalvikvm﹕ Could not find method android.app.Notification$Builder.setColor, referenced from method com.google.android.gms.gcm.zza.zzv
dalvikvm﹕ VFY: unable to resolve virtual method 173: Landroid/app/Notification$Builder;.setColor (I)Landroid/app/Notification$Builder;
and reference the API doc:
http://developer.android.com/reference/android/app/Notification.Builder.html
search "setColor" you will find out it added in "API level 21", means this method only works above 5.0(Lollipop)
I tried the structure below test on 2 different OS device, 5.0 & 4.4 respectively, and only work on 5.0
{"to": "/topics/global","data": {"message": "<message>"},"notification": {"icon": "ic_stat_ic_notification","body": "Use Gradle Command","title": "Self test"}}
Note :
i use the JSON test on OS 5.0, notification is shown, but onMessageReceived still not called
Though an old thread, I wanted to add on to this based on some similar issues that I'd faced.
The app has two states: active and inactive.
If the app is active, sending a notification without an icon value (I suspect the key is still required) would still work. Works for me but the key is still in there.
My JSON object looks like this:
.., icon=, sound=default, title=Bruce...
From developer docs:
For an active Android app, notification payloads are passed to
onMessageReceived() under the notification key in the data bundle.
When the app is inactive:
Notifications are delivered to the notification tray when the app is
inactive.
And here is when I hit the Missing icon issue. So a key and value pair is required if the app is inactive.
If the payload is a notification, ensure that it always has the icon key/value pair so that it will work as expected regardless of whether the app is active or inactive.
See here for details
Finally, there should be a clear distinction between what a notification is and what a data is, in the design of the application. I had been using notification for all push messages for my application which I think is not the right way of doing it.
I have implemented Parse push notifications but there is an issue on the Android side for me. Whenever I send a notification from Parse, all Android devices receive two notifications, one with the text that I have sent and the other with empty text.
Please suggest what might be wrong here
Note : I have also added native Android notifications (GCM notifications) to my project. Is it possible that they are causing this issue?
Thanks.
The AndroidManifest is setup as follows:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:name=".activityApplication"
android:label="#string/app_name"
android:icon="#drawable/icon">
<activity android:name=".activity"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
<!-- gcm -->
<receiver
android:name="com.company.activity.GCBroadcastReceiver"
android:exported="true"
android:process=":remote"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.company.activity" />
</intent-filter>
</receiver>
<service android:name=".GcmIntentService" />
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.company.activity" />
</intent-filter>
</receiver>
</application>
And this is my Broadcast Receiver :
public class GCBroadcastReceiver extends BroadcastReceiver
{
private static final String TAG = "GCBroadcastReceiver";
Context ctx;
#Override
public void onReceive(Context context, Intent intent)
{
ctx = context;
// Local notification.
Bundle bundle = intent.getExtras();
String message = bundle.getString("message");
String notificationID = bundle.getString("notificationID");
Log.v(TAG,"Notification message : " + message + "With ID : " + notificationID);
sendNotification(message, notificationID);
}
// Put the GCM message into a notification and post it.
private void sendNotification(final String message, final String notificationID)
{
Intent notificationIntent = new Intent(ctx, Activity.class);
PendingIntent intent = PendingIntent.getActivity(ctx, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx);
mBuilder.setContentIntent(intent);
mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(message));
mBuilder.setWhen(System.currentTimeMillis());
mBuilder.setSmallIcon(R.drawable.icon);
mBuilder.setContentTitle(ctx.getString(R.string.app_name));
mBuilder.setContentText(message);
mBuilder.setLights(Color.RED, 400, 400);
mBuilder.setAutoCancel(true);
//mBuilder.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + ctx.getPackageName() + "/raw/" + sound));
mBuilder.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE);
NotificationManager mNotificationManager = (NotificationManager) ctx
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
}
}
Parse uses GCM, so if you are sending a notification to an application that uses Parse, and in addition you handle the GCM message with native Android code that displays a notification, the notification may be handled twice (one time by your code and one time by Parse), which will cause it to be displayed twice.
As to why one of the notifications has empty text - the code that displays it probably expects the text to be in an extra parameter that wasn't sent by the server, and therefore there was no text to display.
UPDATE:
Now that I see you code, I can add the following :
You have two broadcast receivers that handle incoming GCM messages - com.parse.GcmBroadcastReceiver and com.company.activity.GCBroadcastReceiver. Both of them attempt to process the notifications sent to your device from Parse (from your comment below, I understand that the problem doesn't occur when you send your "local" notifications).
I'm assuming that the Parse library registers on its own to GCM. If you are using a different sender ID (API project ID) for the parse registration and for your native GCM registration, you can fix your problem by checking intent.getExtras ().get("from") in your onReceive method. If it doesn't contain the sender ID of your local notifications, don't call sendNotification(message, notificationID);, and the second notification with the empty text won't be shown.
public void onReceive(Context context, Intent intent)
{
ctx = context;
// Local notification.
Bundle bundle = intent.getExtras();
String message = bundle.getString("message");
String notificationID = bundle.getString("notificationID");
Log.v(TAG,"Notification message : " + message + "With ID : " + notificationID);
if (intent.getExtras ().get("from").equals (YOUR_SENDER_ID_FOR_LOCAL_NOTIFICATIONS))
sendNotification(message, notificationID);
}
Now, if you are using the same sender ID for both types of notifications, you can either start using different sender IDs, or you can use a different condition - check if intent.getExtras ().get("message") has a value. Your local notifications require this parameter, and I'm assuming the Parse notifications don't (which explains the notifications without text you are seeing).
Using two GCM broadcast receivers may cause other problems too, so I suggest you look at this question for further reading.
Actually I am working on the notifications for an Android app.
My two main source of information are this tutorial and the android developer web site.
Let me quickly describe my app:
In my app I use web services (WS) which work with POST HTTP request.
For the Notification I use the GCM system.
My app uses the 'POST HTTP' request system above to be register on my server.
Actually my server does exactly the same job as the one in the tutorial (that means to register an account in the database with to two parameters and the register ID of the device, and send a message to the device with GCM)
Actually all of these steps work:
My app receive successfully gets register ID (gcm.register(SENDER_ID); work)
My app get successfully registered on my server
My server receives a successful message when I try to send a message from my device
{"multicast_id" : 6276079906208554309 , "success" : 1 , "failure" : 0 , "canonical_ids" : 0 , "results" : [{"message_id" : "0:1374826298092960%978fee92f9fd7ecd"}]}
The Problem:
I receive nothing on my device
What I did:
I try to do two versions of the application:
First I made an app using a part of the code of the tutorial, but with using the package com.google.android.gms.gcm.GoogleCloudMessaging instead of the com.google.android.gcm which are deprecated (and used in the tutorial), but I was unable to receive a message, so I try a second version …
This time I took the entire tutorial and just change the register function on the server to use mine, but like the first app, I receive nothing on my device. (I did this to try to understand how work the reception but it did not help me, and now I will forget this way)
Where do I need your help:
I need some/more explanation how to receive the message sent by my server.
My main activity uses the code describe on the android developer web site.
I create a broadcast class using the code on the android developer web site.
I don’t create any IntentService or service, maybe it is my error, but according what I read I understood that I don’t need one, like before with the deprecated GCMBaseIntentService
To conclude:
I really will appreciate some help to understand what I need to receive the message on my device, because actually I don’t know where I can found the information I need to be able to use this system.
Thanks.
PS: if you need some part of my code , just ask me.
EDIT
my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidhive.pushnotifications2"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="com.androidhive.pushnotifications2.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.androidhive.pushnotifications2.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Main activity. -->
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<!-- Register Activity -->
<activity
android:name="com.androidhive.pushnotifications2.cop.RegisterActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Main Activity -->
<activity
android:name="com.androidhive.pushnotifications2.MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name" >
</activity>
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.androidhive.pushnotifications2" />
</intent-filter>
</receiver>
</application>
</manifest>
And my GcmBroadcastReceiver (who come from the tutorial)
the WakeLocker is the same as the tutorial too.
package com.androidhive.pushnotifications2;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GcmBroadcastReceiver extends BroadcastReceiver {
static final String TAG = "GCMDemo";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
Context ctx;
#Override
public void onReceive(Context context, Intent intent) {
///
WakeLocker.acquire(context);
///
System.out.println("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT");
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
ctx = context;
String messageType = gcm.getMessageType(intent);
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + intent.getExtras().toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
sendNotification("Deleted messages on server: " +
intent.getExtras().toString());
} else {
sendNotification("Received: " + intent.getExtras().toString());
}
WakeLocker.release();
setResultCode(Activity.RESULT_OK);
}
// Put the GCM message into a notification and post it.
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager)
ctx.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0,
new Intent(ctx, MainActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(ctx)
.setSmallIcon(R.drawable.common_signin_btn_icon_focus_light)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
I'm working with push notifications. Receiving and displaying notifications is currently working, however the on-click event isn't acting as it should.
int NOTIFICATION_ID = 1593;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.notification, title, System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Intent notificationIntent = new Intent(this, MyMainActivity.class);
notificationIntent.putExtra("test", "test");
notificationIntent.setAction("load_notifications");
PendingIntent intentNotification = PendingIntent.getActivity(this, 999, notificationIntent, 0);
notification.setLatestEventInfo(this, title, body, intentNotification);
notificationManager.notify(NOTIFICATION_ID, notification);
That's how I display my notification and it also includes starting/resuming my main activity.
However, the putExtra("test", "test") and the setAction seem to have no effect if I click on a notification while I'm in the app. If my app isn't working, launching it from the notification works fine.
My onResume function at my main activity:
public void onResume() {
super.onResume();
if(this.getIntent().getAction().equalsIgnoreCase("load_notifications")) {
//Do stuff
}
}
My app config is as following:
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".Activity"
android:label="#string/app_name"
android:configChanges="orientation"
android:launchMode="singleInstance"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Push notifications -->
<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.app.android" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
the answer maybe be here : Action buttons are not shown in notification
Notification Actions were introduced in API 16.
This means that you should be setting your target SDK to 16 or above.
However, only Jelly Bean and above can take advantage of the Notification Actions - make sure to test this feature on those platforms.
NotificationCompat.Builder takes care of generating a Notification compatible with whatever API it is running on, so keep using it if you are going to be supporting Ice Cream Sandwich and older. If not, simply using Notification.Builder will suffice (after changing the target SDK of course).