i'm not able to receive GCM messages on devices running android below lollipop.
Push messages works on android 5, 6 and 7.
I really don't know why ... There is my app code:
Manifest:
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="25"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<permission android:name="sbntt.android.xenoss.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="sbntt.android.xenoss.permission.C2D_MESSAGE" />
<application
android:name="android.support.multidex.MultiDexApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<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="sbntt.android.xenoss" />
</intent-filter>
</receiver>
<service
android:name="sbntt.android.xenoss.GCMPushReceiverService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".GCMRegistrationIntentService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service
android:name=".GCMTokenRefreshListenerService"
android:exported="false">
</service>
</application>
GCMPushReceiverService class
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
if (Settings.preference != null) {
if (Settings.preference.getBoolean("notifications", true)) {
sendNotification(message);
}
} else {
sendNotification(message);
}
}
private void sendNotification(String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestCode = 0;
PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_menu_youtube)
.setContentTitle("TITLE")
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setSound(sound)
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(Notification.PRIORITY_HIGH);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, noBuilder.build());
}
Registration works fine!
Thanks for your help.
GCM need to be updated Play Service on devices . you can notify users to update Play Service or use less play service version in your project .
Related
I am using online tool to send Notification to my Device
http://gcm-alert.appspot.com/
http://techzog.com/development/gcm-notification-test-tool-android/
They both returns,
Failure: HTTP Status Code: 401 -Unauthorized
I have followed following steps to implement Google Clound Messaging API
Create Configuration File added it in my Project->app Folder
Created Async Task In Main Activity and write Following Code.
SharedPreferences getPreference= getSharedPreferences("GCMToken", Context.MODE_PRIVATE);
String tokenID= getPreference.getString("tokenID","");
if(tokenID.isEmpty()) {
InstanceID gcmTokenistanceID = InstanceID.getInstance(getApplicationContext());
token = gcmTokenistanceID.getToken(getString(R.string.project_id),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
GCMServiceURL= "MyWebServerURL.com/="+token;
Log.i("TOKEN From IF Condition", token);
saveTokenID(token);
Then I created NotificationService and extend this class with GcmListenerService
public class GCMNotificationService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("Test Message from Server");
NotificationManager notificationManager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Title")
.setContentText(message);
notificationManager.notify(1, mBuilder.build());
}
Manifest File
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.app.myapp.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.app.myapp.permission.C2D_MESSAGE" />
<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="com.app.myapp" />
</intent-filter>
</receiver>
<service
android:name="com.app.myapp.GCMNotificationService" android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
Kindly guide me what i am doing wrong here
Add this permission
<uses-permission android:name="android.permission.INTERNET" />
I am trying to implement GCM. Everything works fine except that the onMessageReceived() method gets called only when the app is running.
I searched for solutions but I am unable to find the case that matches mine. My request body for GCM contains only the "to" and "data" parts, not the "notification" part.
This is the body of the request sent to GCM:
{"data":{"title":"Test","message":"Test Message"},"to":"ffl3Q260K8E:APA91bG90Ra_CyXdmB4ztcCXYKEMKFliZ_MVpkqYnzUW2Xizcem4iknSt9guKDeEbWYl2YwwEKa7kKVllE0mBRzUOGhO5jJfAM6vuzisq3qqe_hJ1Dy-mpFQat4_ErfKRKRQOJvhKi4q"}
This is my GcmListenerService:
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
sendNotification(message);
}
private void sendNotification(String message) {
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);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_app_icon)
.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());
}
}
and this is the manifest file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<permission android:name="com.example.demoapp.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.demoapp.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<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.example.demoapp" />
</intent-filter>
</receiver>
<service
android:name=".services.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".services.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service android:name=".services.RegistrationIntentService"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
In your Android Manifest, the category name <category android:name="com.example.gcm" /> in your receiver's <intent-filter> tag must be the same as your package name. So replace com.example.gcm with the package name that you have declared in your manifest.
This will allow your receiver to receive gcm messages when the app is not running.
Make sure your payload is having the 'notification' also beside the 'data'. When app is at background, the message will be send to the message tray.
Something like this example
{
"to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
"notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "myicon"
},
"data" : {
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
}
}
Kindly refer here for more info: https://developers.google.com/cloud-messaging/concept-options.
I'm developing a Android IM Chat app using PubNub and Backendless. I'm currently working on sending a Push Notification to user when they get a new chat message. I successfully integrated PubNub and GCM. So, I can send notification to the device using those two services. I followed this tutorial to get this done.
https://www.pubnub.com/blog/2015-06-24-sending-receiving-android-push-notifications-with-gcm-google-cloud-messaging/
But even though notification message is sending, it's not showing in the notification bar of the mobile phone as a push notification. Message come to the device with the tone. But no message is showing as notification bar. Can anyone please help me with the issue. Here is my code so far
This is my AndroidManifest file
<permission android:name="your.package.name.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="your.package.name.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--<receiver
android:name="your.package.name.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="your.package.name" />
</intent-filter>
</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="your.package.name" />
</intent-filter>
</receiver>
<!-- [START gcm_listener] -->
<service
android:name="your.package.name.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="your.package.name.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<!-- [END instanceId_listener] -->
<service
android:name="your.package.name.RegistrationIntentService"
android:exported="false">
</service>
</application>
This is my MainActivity Class ( Some Parts of the class)
[ Send Notification method ]
public void sendNotification() {
PnGcmMessage gcmMessage = new PnGcmMessage();
JSONObject jso = new JSONObject();
try {
jso.put("GCMSays", "hi");
} catch (JSONException e) { }
gcmMessage.setData(jso);
PnMessage message = new PnMessage(
pubnub,
"GCMPush",
callback,
gcmMessage);
try {
message.publish();
} catch (PubnubException e) {
e.printStackTrace();
}
}
This is GCMListenerService class
ublic class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
// [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);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream 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.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)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message));
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
Can anyone please tell what is the wrong with this implementation. I can give you more code if you want.
Thanks in advance
I found the error I have been made when I was defining the sendNortification method. I have commented out the .setSmallIcon property in NotificationCompact which is a required notification content.
Thanks
I am trying to get started with Parse push notification on Android, but I could not find any way to implement my own BroadcastReceiver which would perform action in response to a push notification.
In their "getting started", they give a program sample where the receiver and the intent service is contained in the jar file (and not implemented in the code, so that I could try and play with it). A similar question has been asked here, but it's two years old and the answer has 11 downvotes.
There are a few other blog posts, e.g. as in here, but none of them work properly (the one in that link was two years old).
So please kindly suggest a step by step way to implement the same.
EDIT:
I tried the code as suggested by droidx. But it does not work. I am sending my AndroidManifest.xml (rest of the code is exactly as he suggested):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rahulserver.parsenotificationdemo" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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" />
<!--
IMPORTANT: Change "com.parse.starter.permission.C2D_MESSAGE" in the lines below
to match your app's package name + ".permission.C2D_MESSAGE".
-->
<permission android:protectionLevel="signature"
android:name="com.rahulserver.parsenotificationdemo.permission.C2D_MESSAGE" />
<uses-permission android:name="com.rahulserver.parsenotificationdemo.permission.C2D_MESSAGE" />
<application
android:name=".ParseNotification"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<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=".MyCustomParsePushReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</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" />
<!--
IMPORTANT: Change "com.parse.starter" to match your app's package name.
-->
<category android:name="com.rahulserver.parsenotificationdemo" />
</intent-filter>
</receiver>
</application>
</manifest>
Here's an example!
public class ParseCustomBroadcastReceiver extends ParsePushBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
Log.d(TAG, json.getString("alert").toString());
final String notificationTitle = json.getString("title").toString();
final String notificationContent = json.getString("alert").toString();
final String uri = json.getString("uri");
Intent resultIntent = null;
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
resultIntent = new Intent(context, HomeScreen.class);
stackBuilder.addParentStack(HomeScreen.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
//Customize your notification - sample code
NotificationCompat.Builder builder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_notification_icon)
.setContentTitle(notificationTitle)
.setContentText(notificationContent);
int mNotificationId = 001;
NotificationManager mNotifyMgr =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotifyMgr.notify(mNotificationId, builder.build());
} catch (JSONException e) {
Log.d(TAG, e.getMessage());
}
}
}
Following this guide, replace android name for the receiver to the path of your custom broadcastreceiver
<receiver
android:name=".receivers.ParseCustomBroadcastReceiver"
android:exported="false" >
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
In your application class, make sure to have subscribed to Parse Push like this
Parse.initialize(this, ParseUtils.PARSE_APPLICATION_ID_DEV, ParseUtils.PARSE_CLIENT_KEY_DEV);
ParseObject.registerSubclass(Article.class);
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d(TAG, "successfully subscribed to the broadcast channel.");
} else {
Log.e(TAG, "failed to subscribe for push", e);
}
}
});
Update:
The above broadcast receiver expects to send a json object notification from parse dashboard usually consists of three name value pairs:
{ "alert": "Alert message", "title": "Title", "uri": "bla bla" }
When you use only plain string for eg: hello world! in parse push dashboard, internally it goes as only alert tag. something like this : {"alert" : "hello world!, "title" = null/"", "uri" = null/""}
The broadcast receiver code above doesn't have this null checks, so it's caught in the catch with exception No title/uri.
So you can add some null checks based on what you are expecting from the push notification.
Something like this:
JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
Log.d(TAG, json.getString("alert").toString());
if (json.has("title")) {
notificationTitle = json.getString("title").toString();
}
if (json.has("alert")) {
notificationAlert = json.getString("alert").toString();
}
if(json.has("uri")) {
notificationURI = json.getString("uri");
}
Then set appropriate contentTitle and contentText in notification
NotificationCompat.Builder builder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(notificationAlert)
.setContentText(notificationAlert);
Hope this helps!
I have created a Android app.I want that when it gets installed in the device it will show no GUI part. When we will broadcast the message from the server, on selection of the notification i want the user to show the GUI part. How can we do this is Android?
I tried this in my Notification function where i am starting the new Intent
setTheme(android.R.style.Theme);
This in my Manifest.XML file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.iween.gcmclient" android:versionCode="1" android:versionName="1.0">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17"/>
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="com.example.iween.gcmclient.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission
android:name="com.example.iween.gcmclient.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Main activity. -->
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="com.example.iween.gcmclient.DemoActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTop">
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="com.example.iween.gcmclient.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
</receiver>
<service android:name="com.example.iween.gcmclient.GcmIntentService" />
</application>
</manifest>
Notification Function
private void sendNotification(String recivedMessage) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, DemoActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_gcm)
.setContentTitle("Iween Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(recivedMessage))
.setContentText(recivedMessage);
mBuilder.build().flags = Notification.FLAG_AUTO_CANCEL;
Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder.setSound(notificationSound);
mBuilder.setAutoCancel(true);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
Try this way
Create one public static int variable which will update when notification receives
For eg In your receiver class
public static int THEME = 0;
onReceive(){
if(cond1){
THEME = R.style.them1;
}else if(cond2){
THEME = R.style.them2;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
if(THEME!=0){
setTheme(THEME);
}
super.onCreate(savedInstanceState);