I am creating an application with push notification from my server. I am successful in registering the device with GCM and got the regID. Later, when I used to send the notification using the ID it’s not receiving any notification. I have listed all the code below and I am not sure where I am making mistake. Please Help me. Thank you.
Manifest
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="22" />
<permission
android:name="com.example.mycab.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.example.mycab.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".AppController"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- Splash screen -->
<activity
android:name=".SplashScreen"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Black.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".LoginActivity"
android:label="#string/app_name"
android:launchMode="singleTop"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="adjustPan" />
<!-- Main activity -->
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".RegisterActivity"
android:label="#string/app_name"
android:launchMode="singleTop"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="adjustPan" />
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<receiver
android:name=".GcmBroadcastReceiver"
android:exported="true"
android:permission="com.google.android.c2m.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.mycab" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
</manifest>
GcmBroadcastReceiver.java
package com.example.mycab;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("PUSH RECEIVED!!!");
ComponentName comp = new ComponentName(context.getPackageName(),GCMNotificationIntentService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GCMIntentService.java
package com.example.mycab;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
public class GCMIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GCMIntentService() {
super("GcmIntentService");
}
public static final String TAG = "GCM Demo";
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
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());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
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());
sendNotification("Received: " + extras.toString());
Log.i(TAG, "Received: " + extras.toString());
}
}
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_home)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
Related
I have generated the token but still unable to get the notification.
When I am sending the message to the User Segment it is showing status as completed but I did not receive any notification.
I am uploading my manifest file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sumit.v_care">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECIEVE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.c2dm.permission.message"/>
<application
android:allowBackup="true"
android:icon="#mipmap/vcare"
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>
<activity android:name=".memberlog"
android:parentActivityName=".MainActivity">
</activity>
<activity android:name=".memberp"
android:parentActivityName=".memberlog">
</activity>
<activity android:name=".donate"
android:parentActivityName=".memberp">
</activity>
<activity android:name=".ResultActivity">
</activity>
<service
android:name=".Mymessagingservice"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>
Mymessagingservice.java
package com.example.sumit.v_care;
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.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
/**
* Created by Sumit on 22-02-2017.
*/
public class Mymessagingservice extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Displaying data in log
//It is optional
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getBody());
}
//This method is only generating push notification
//It is same as we did in earlier posts
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Firebase Push Notification")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
I am using push notification in my app. it is working fine when the app is running or in the foreground state.but when the user clean the app from the task manager/tab then the notification is not coming. I tried many method like package restart and all. but i could not get the solution. if anyone know what i am doing wrong. please tell me.
This is my GcmBroadcastReceiver class :-
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{ ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
This is GcmIntentService class by which i send the notification :-
public class GcmIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
private final static String TAG = "GcmIntentService";
private Context mContext;
public GcmIntentService() {
super("GcmIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
Log.d(TAG, "Notification Data Json :" + extras.getString("message"));
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
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());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
// This loop represents the service doing some work.
for (int i = 0; i < 5; i++) {
Log.d(TAG, " Working... " + (i + 1) + "/5 # "
+ SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i(TAG, "Completed work # " + SystemClock.elapsedRealtime());
sendNotification(extras.getString("message"));
}
} // Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
} // Put the message into a notification and post it.
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("KEY","aman");
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setSmallIcon(android.R.drawable.sym_def_app_icon)
.setContentTitle("Telepoh")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
mBuilder.setContentIntent(contentIntent);
mBuilder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
mBuilder.setAutoCancel(true);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
private int getNotificationIcon() {
boolean useWhiteIcon = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
return useWhiteIcon ? R.drawable.gcm : R.drawable.push_icon;
}
}
And This is my 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="package_name"
android:versionCode="2"
android:versionName="1.2">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<permission android:name="android.permission.GET_ACCOUNTS" />
<permission android:name="android.permission.CAMERA" />
<permission
android:name="com.google.android.gcm.demo.app.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.google.android.gcm.demo.app.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:screenOrientation="portrait"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:replace="android:icon">
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="API_KEY" />
<activity
android:name=".WelcomeActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop"
android:theme="#style/AppTheme.NoActionBar"></activity>
<activity
android:name=".LoginActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".RegisterActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity android:name=".ForgetPasswordActivity" />
<activity android:name="pacahe_name.controller.GalleryUtil" />
<activity android:name="nl.changer.polypicker.ImagePickerActivity" />
<receiver
android:name="package_name.GCM.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name=package_name" />
</intent-filter>
</receiver>
<service android:name="package_name.GCM.GcmIntentService" />
<activity
android:name="com.facebook.FacebookActivity"
android:screenOrientation="portrait" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/fb_id" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
The push notification working fine when the app in the run state and in the foreground state. But My problem is when app clean from the task manager then the notification is not coming.I tried package restarted but it does not working.If anyone know what i am doing wrong then please tell me.
Hello i am trying to use the GCM service with the push notification in android, but i keeps give an error with this code
package com.subhi.gcmdemo;
/**
* Created by subhi on 2/4/2016.
*/
import com.google.GoogleCloudMessaging;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
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, MainActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
// .setSmallIcon(R.drawable.ic_stat_gcm)
.setContentTitle("GCMDemo")
.setSmallIcon(R.drawable.ic_launcher)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
and this is the manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.subhi.gcmdemo" >
<application
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>
</application>
<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" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.subhi.gcmdemo.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.programmingtechniques.gcmdemo.permission.C2D_MESSAGE" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="22" />
</manifest>
and i had used the dependencies
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
so if anyone can help me with this problem please?
I have checked your AndroidManifest.xml you have not defined your broadcast receiver and GcmIntentService class as service.
<receiver android:name="com.package .application.service.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.app.twoway" />
</intent-filter>
</receiver>
<service android:name="com.package.application.service.GcmIntentService" />
I have successfully implemented GCM and messages successfully arrive to my devices when the App is in running and background states.
But when the App is in a closed state, some devices receive the message and some do not. To get the message, I have to start the application again.
Manifest:
<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" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.example.hp.abcd.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.hp.abcd.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".Splash"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".RegisterActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.hp.abcd.REGISTER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".Subject"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.hp.abcd.Subject" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name" >
</activity>
<activity
android:name=".Message"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.hp.abcd.MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver
android:name="com.example.hp.abcd.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.example.hp.abcd" />
</intent-filter>
</receiver>
<service android:name=".GCMNotificationIntentService" />
</application>
BroadcastReceiver:
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Waking up mobile if it is sleeping
ComponentName comp = new ComponentName(context.getPackageName(),
GCMNotificationIntentService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
GCMNotificationIntent service
import android.app.IntentService;
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.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class GCMNotificationIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GCMNotificationIntentService() {
super("GcmIntentService");
}
public static final String TAG = "GCMNotificationIntentService";
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
String msg = intent.getStringExtra("message");
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
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());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
for (int i = 0; i < 3; i++) {
Log.i(TAG,
"Working... " + (i + 1) + "/5 # "+ SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work # " + SystemClock.elapsedRealtime());
sendNotification(""
+ extras.get(Config.MESSAGE_KEY));
Log.i(TAG, "Received: " + extras.toString());
}
}
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
DatabaseHandler db = new DatabaseHandler(this);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Log.d(TAG, "Preparing to send notification...: " + msg);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Calendar c = Calendar.getInstance();
SimpleDateFormat d = new SimpleDateFormat("dd MMMM,yyyy");
SimpleDateFormat t = new SimpleDateFormat("HH:mm");
String strDate = d.format(c.getTime());
String strTime = t.format(c.getTime());
db.addContact(new Contact(msg, strDate, strTime));
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, Message.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.gcm_logo)
.setContentTitle("India")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg)
.setSound(soundUri);
mBuilder.setAutoCancel(true);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
Log.d(TAG, "Notification sent successfully.");
}
}
If you "force close" an app, then it will become unresponsive to all broadcasts until the user starts it again.
If you "remove from recents" (like on some devices, long hold the "home" key) then this is not a force close, and even if the app is in the background, it will continue to receive messages.
See this post here: Will I receive GCM messages if Android kill my app and if I do a Force Close from the settings?
My GCM client is able to register on all versions but messages are received on android above 4.x versions, not on android 2.3.6. I have made many changes but I cannot figure this problem out please help me, thanks in advance.
manifest file code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.democlientapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<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="android.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.democlientapp.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.democlientapp.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
<activity
android:name="com.democlientapp.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>
<activity
android:name="com.democlientapp.MainActivity"
android:label="#string/app_name" >
</activity>
<receiver
android:name="com.democlientapp.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.democlientapp" />
</intent-filter>
</receiver>
<service android:name="com.democlientapp.GcmIntentService" />
</application>
</manifest>
GCMBrodcastReceiver.java
package com.democlientapp;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("tag", "****************GcmBroadcastReceiver.java ok*************");
// 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.java
package com.democlientapp;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GcmIntentService extends IntentService {
public static int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
String TAG="tag";
SharedPreferences sp;
StringBuffer sb;
public GcmIntentService() {
super("GcmIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.i("tg", "intent sservice******************");
String extras1 = intent.getExtras().getString("data");
//Log.i("tag", "string extras :"+extras1.toString());
Bundle extras=intent.getExtras();
//Log.i("tag", "bundle extras :"+extras);
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
Log.i("tag", "entered");
/*
* 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(1000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work # " + SystemClock.elapsedRealtime());
Log.i(TAG, "Received: " + extras.toString());
// Post notification of received message.
sendNotification("Received: " + extras);
}
}
//Log.i(TAG, "Received11111111111111111111");
//sendNotification("Received: registeration "+extras);
// Release the wake lock provided by the WakefulBroadcastReceiver.
//Log.i(TAG, "Received22222222222222222222222");
GcmBroadcastReceiver.completeWakefulIntent(intent);
//Log.i(TAG, "Received3333333333333333");
}
// 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) {
Log.i("tag","GcmBroadcastReceiver.java send notification");
//storing message in shared preference
StoreMsg(msg);
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Spy notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
//mNotificationManager.no
//NOTIFICATION_ID++;
}
public void StoreMsg(String Msg)
{
String name="MyPrefs";
sp = this.getSharedPreferences(name, Context.MODE_PRIVATE);
sb=new StringBuffer();
String mg = sp.getString("MESSAGES", "false");
if (mg.equals("false")) {
//sb.append(mg);
sb.append(Msg);
}
else{
sb.append(mg+"\n****************");
sb.append("\n"+Msg);
}
Log.i("tag", "storemsg is: "+sb);
Editor editor = sp.edit();
editor.putString("MESSAGES",sb.toString());
//Log.i("tag","Gcmintentservice.java,MESSAGES storing SharedPreferences");
editor.commit();
//Log.i("tag", "registeractivity.java, onclick method client username exists in DB");
}
public String getMsg(){
String name="MyPrefs";
sp = this.getSharedPreferences(name, Context.MODE_PRIVATE);
String prefName = sp.getString("MESSAGES", "false");
Log.i("tag", "storemsg is: "+sb);
return prefName;
}
}
If you are using product flavors maybe you have the same problem than I found.
I found that when using flavors with diferent applicationId, then your package in the AndroidManifest file for the permission and the category is not correct.
And this does not matter for Android 5.x, but for Android 2.3 causes that the broadcast receiver will never be called.
The solution I found is use the gradle's placeholder support. Using ${applicationId} the issue is resolved for all the Android versions.
build.gradle:
productFlavors {
prod {
applicationId 'com.democlientapp'
}
dev {
applicationId 'com.democlientapp.dev'
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.democlientapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<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="android.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
<activity
android:name="com.democlientapp.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>
<activity
android:name="com.democlientapp.MainActivity"
android:label="#string/app_name" >
</activity>
<receiver
android:name="com.democlientapp.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="${applicationId}" />
</intent-filter>
</receiver>
<service android:name="com.democlientapp.GcmIntentService" />
</application>
</manifest>
Use Latest dependency/library for GCM for sdk version 4 or heigher
compile "com.google.android.gms:play-services-gcm:10.2.0"
in build.gradle file in dependency.
and add build.gragle level file
classpath 'com.google.gms:google-services:3.0.0'
its works for hiegher versions.