I'm trying to setup a system where an Android mobile phone receives notification from a server: for this task we have chosen Firebase.
While the application is in background everything works fine: after I push a message from the firebase console a notification appears on the system tray and, after the message is clicked by the user, an Intent with extra data is sent to the Activity.
My problem is uniquely when the application is already in foreground. The firebase notification is pretty clear: if the application is in foreground, no matter which type of message is sent by the server, OnMessageReceived is never called... so why it fails with my simple app? Some notes to help you solve this issue:
we're working with Android Studio 2.1.2;
"it.bagozi.ada.tutorial.firebase" contains both classes (as you might deduce from the pacakge declaration);
Below you can find all the source code used:
Main Activity
package it.bagozi.ada.tutorial.firebase;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private TextView notification;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.notification = (TextView) this.findViewById(R.id.notification_setter);
Intent i = this.getIntent();
Log.e(TAG, "Intent from Activity caller: " + i);
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
Log.d(TAG, "Key: " + key + " Value: " + value);
}
}
}
}
FirebaseNotificationService
package it.bagozi.ada.tutorial.firebase;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class FirebaseNotificationService extends FirebaseMessagingService {
private static final String TAG = FirebaseNotificationService.class.getSimpleName();
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
Log.e(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.e(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
}
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.bagozi.ada.tutorial.firebase">
<service android:name=".FirebaseNotificationService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<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>
</application>
</manifest>
Make the service declaration in your manifest a child of the "application" tag!
Related
I have created one new app for push notification in https://console.firebase.google.com. I have followed all steps mentioned at last it shows -unknown app- under the head Targeting user segment.
How to test push notification in firebase?
AndroidManifest.xml
`
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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>
</application>
`
First, for using firebase push notifications add the dependencies
dependencies {
compile 'com.google.firebase:firebase-messaging:11.6.2' // this line must be included to use FCM
}
Add a service that extends FirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
}
}
In your Manifest add this
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
Add a service that extends FirebaseInstanceIdService
public class FirebaseIDService extends FirebaseInstanceIdService {
private static final String TAG = "FirebaseIDService";
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(refreshedToken);
}
/**
* Persist token to third-party servers.
*
* Modify this method to associate the user's FCM InstanceID token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
}
Add it into the AndroidManifest.xml file, this makes sure that the service is loaded
<service android:name=".FirebaseIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
You are done implementing firebase push notifications !
Test and send your first push notification from firebase console !
hope it helped
For more info check this: https://firebase.google.com/docs/cloud-messaging/android/client?hl
happy coding !
I'm trying firebase push notification. I did everything it said in the tutorial, but it isn't working.
FirebaseMessagingService:
package com.example.firebasenf.firebasenf;
import com.google.firebase.messaging.FirebaseMessagingService;/
public class MyFirebaseMessagingService extends FirebaseMessagingService {
}
FirebaseInstanceIdService:
package com.example.firebasenf.firebasenf;
import com.google.firebase.iid.FirebaseInstanceIdService;
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
}
Manifest:
<service
android:name=".MyFirebaseMessagingService">
<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>
you need to add some methods to your code :
FirebaseMessagingService:
package com.example.firebasenf.firebasenf;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage){
Intent intent = new Intent(this,MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setContentTitle("Application Title");
notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,notificationBuilder.build());
}
}
FirebaseInstanceIdService :
package com.example.firebasenf.firebasenf;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String REG_TOKEN = "REG_TOKEN";
#Override
public void onTokenRefresh(){
String recent_token = FirebaseInstanceId.getInstance().getToken();
Log.d(REG_TOKEN,recent_token);
}
}
you need to override onMessageReceived in MyFirebaseMessagingService class to do some actions when notification is pushed.
doc
By overriding the method FirebaseMessagingService.onMessageReceived,
you can perform actions based on the received RemoteMessage object and
get the message data
#Override
public void onMessageReceived(RemoteMessage remoteMessage)
{
Log.d(TAG, "From: " + "Notification Received");
// TODO(developer): Handle FCM messages here.
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0)
{
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
//You may want show notification
}
keep in mind onMessageReceived will only triggered if the app in foreground
When your app is in the background, Android directs notification
messages to the system tray. A user tap on the notification opens the
app launcher by default.
It's my first time to use FCM, I created a new project in android studio, then I clicked on "tools" and I chose Firebase, I followed all the steps in this window
and I copied and pasted these blocks of code exactly in the same location as mentioned
here's my Java code
public class ZeftToken extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d("zeft", "Refreshed token: " + refreshedToken);
}
}
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
This is my Manifest file:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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>
<service
android:name=".ZeftToken">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application>
When I run the application I don't get the token in the logcat and it's completely missing. I don't know what's wrong.
Update
extend FirebaseMessagingService
use onNewToken instead of onTokenRefresh
getToken() method is now deprecated
#Override
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(token);
}
if you want to retrieve token in you activity
use the below code .getInstanceId() instead of .getToken() method
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( MyActivity.this, new OnSuccessListener<InstanceIdResult>() {
#Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
Log.e("newToken",newToken);
}
});
I solved my solution with this function below;
public void savePushToken(){
if (!settings.hasData(Keys.pushTokenSaved) ){
FirebaseMessaging messaging = FirebaseMessaging.getInstance();
messaging.getToken().addOnSuccessListener(s -> {
Log.d("ON TOKEN",s);
pushToken = s;
JSONObject params = new JSONObject();
JSONObject info = new JSONObject();
try {
info.put("os","android");
info.put( "framework", "flutter");
info.put( "cihaz_bilgisi", new JSONObject());
params.put("token",pushToken);
params.put("device_info",info);
} catch (JSONException e) {
e.printStackTrace();
}
NetworkHelper.request(MyMethod.put, Links.savePushToken, params, false, false,
response->{
Log.d("PUSH_REQUEST",response.toString());
if (response.has("successful")||response.optString("message").contains("Integrity constraint violation: 1062 Duplicate entry")) {
settings.setBool(Keys.pushTokenSaved, true);
}
});
});
}
}
if everyting other good. (i hope you have json file provided by fcm service ? )
just move
FirebaseInstanceId.getInstance().getToken();
to for example your application or mainactivity
if u have error ( null pointer exception ) than you firebase not initialized. Check againe tutorial. And dont forget about google-json
Maybe you've already received the token in previous instance of app. The method onTokenRefresh only gets called when it is created or updated. It will not be executed in all app instances. Clear app data or uninstall app and run it again so that new token will be created and you can see it in the log.
Make sure to store the received token in shared preferences or database for future usage.
Reference Get started with Firebase
Cross check the file path of google-service.json as specified
Check the console for FCM token when you launch the app(Main Activity)
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="in.sdev.android.stackoverflow">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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>
<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>
</application>
</manifest>
Main Activity
package in.sdev.android.stackoverflow;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
public class MainActivity extends AppCompatActivity {
public static String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "FCM token: " + refreshedToken);
}
}
Sample Firebase Package
MyFirebaseInstanceIDService.java
package in.sdev.android.stackoverflow.firebase;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import static android.content.ContentValues.TAG;
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(refreshedToken);
}
public void sendRegistrationToServer(String token){
Log.v("FirebaseService", "Token " + token);
}
}
MyFirebaseMessagingService.java
package in.sdev.android.stackoverflow.firebase;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
public static String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// ...
// TODO(developer): Handle FCM messages here.
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
}
Hope this helps
Not opening specific activity on notification click when the app is in background/not running
The notification-click starts specified activity only when the app is opened up and the notification-click is performed. If the app is in background/not running and the notification-click is performed, the application's MainActivity opens up. In short, it is like the app opens normally following the activity stack instead of opening the specified activity in the PendingIntent.
Firebase Instance Id Service:
package com.example.tamzid.pushnotification;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
public class MyAndroidFirebaseInstanceIdService extends
FirebaseInstanceIdService {
private static final String TAG = "MyAndroidFCMIIDService";
#Override
public void onTokenRefresh() {
//Get hold of the registration token
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//Log the token
Log.d(TAG, "Refreshed token: " + refreshedToken);
}
private void sendRegistrationToServer(String token) {
//Implement this method if you want to store the token on your server
}
}
Firebase Message Service:
package com.example.tamzid.pushnotification;
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;
public class MyAndroidFirebaseMsgService extends FirebaseMessagingService
{
private static final String TAG = "MyAndroidFCMService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Log data to Log Cat
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " +
remoteMessage.getNotification().getBody());
//create notification
createNotification(remoteMessage.getNotification().getBody());
}
private void createNotification( String messageBody) {
Intent intent = new Intent( this , ResultActivity. class );
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent resultIntent = PendingIntent.getActivity( this , 0,
intent,
PendingIntent.FLAG_ONE_SHOT);
Uri notificationSoundURI =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mNotificationBuilder = new
NotificationCompat.Builder( this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Android Tutorial Point FCM Tutorial")
.setContentText(messageBody)
.setAutoCancel( true )
.setSound(notificationSoundURI)
.setContentIntent(resultIntent);
NotificationManager notificationManager =
(NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, mNotificationBuilder.build());
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tamzid.pushnotification">
<application
android:name="android.support.multidex.MultiDexApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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=".ResultActivity"></activity>
<service android:name=".MyAndroidFirebaseMsgService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".MyAndroidFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"
/>
</intent-filter>
</service>
</application>
</manifest>
Try using remoteMessage.getData() instead of remoteMessage.getNotification()
Use remoteMessage.getNotification(): if message contains a
notification payload.
Use remoteMessage.getData():if message contains
a data payload.
Update onMessageReceived() as below:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0)
{
//create notification
createNotification(remoteMessage.getData().toString());
}
}
I've used the quickblox chat sample and it worked fine, But I wanted to use push notifications in it.. So I followed some tutorials and read the sample and just done like it.. But when I push notification from QuickBlox Admin Panel: Messages no thing happens in my application.. No Logs, No Notifications.. No Thing..!
I'm sure that the project number and api key are correct..
Here's the manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.quickblox.sample.chat"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
<permission
android:name="com.quickblox.sample.chat.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.quickblox.sample.chat.permission.C2D_MESSAGE" />
<!-- 5. Add the following permissions: -->
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- 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" />
<!-- Access to device info -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".ApplicationSingleton"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".ui.activities.SplashActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.activities.NewDialogActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait" />
<activity
android:name="com.quickblox.sample.chat.DialogsActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait" />
<activity
android:name=".ui.activities.ChatActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" />
<receiver
android: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="com.quickblox.sample.chat" />
</intent-filter>
</receiver>
<!-- 2. Add the following intent service: -->
<service android:name=".GCMIntentService" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
GcmBroadcastReceiver :
package com.quickblox.sample.chat;
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) {
// 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.
Log.d("Login", "Receiver - Received Message!");
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GCMIntentService :
package com.quickblox.sample.chat;
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.support.v4.app.NotificationCompat;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.quickblox.sample.chat.definitions.Consts;
public class GCMIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private static final String TAG = GCMIntentService.class.getSimpleName();
private NotificationManager notificationManager;
public GCMIntentService() {
super(Consts.GCM_INTENT_SERVICE);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "new push");
Bundle extras = intent.getExtras();
GoogleCloudMessaging googleCloudMessaging = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = googleCloudMessaging.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)) {
processNotification(Consts.GCM_SEND_ERROR, extras);
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_DELETED.equals(messageType)) {
processNotification(Consts.GCM_DELETED_MESSAGE, extras);
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// Post notification of received message.
processNotification(Consts.GCM_RECEIVED, extras);
Log.i(TAG, "Received: " + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
WakefulBroadcastReceiver.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 processNotification(String type, Bundle extras) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
final String messageValue = extras.getString("message");
Intent intent = new Intent(this, DialogsActivity.class);
intent.putExtra(Consts.EXTRA_MESSAGE, messageValue);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
intent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(Consts.GCM_NOTIFICATION)
.setStyle(
new NotificationCompat.BigTextStyle()
.bigText(messageValue))
.setContentText(messageValue);
mBuilder.setContentIntent(contentIntent);
notificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
I have the following code for registration in activity :
gcm = GoogleCloudMessaging.getInstance(this);
regId = getRegisterationId(this);
Log.d("Login", "ID: " + regId);
if (regId.isEmpty()) {
new Thread(new Runnable() {
#Override
public void run() {
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(DialogsActivity.this);
}
regId = gcm.register(Consts.PROJECT_NUMBER);
Log.d("Login", "Registered! ID: " + regId);
runOnUiThread(new Runnable() {
#Override
public void run() {
subscribeToPushNotifications(regId);
}
});
} catch (Exception e) {
Log.d("Login", "Reg e: " + e);
}
}
}).start();
} else {
Log.d("Login", "Already Exist");
subscribeToPushNotifications(regId);
} gcm = GoogleCloudMessaging.getInstance(this);
regId = getRegisterationId(this);
Log.d("Login", "ID: " + regId);
if (regId.isEmpty()) {
new Thread(new Runnable() {
#Override
public void run() {
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(DialogsActivity.this);
}
regId = gcm.register(Consts.PROJECT_NUMBER);
Log.d("Login", "Registered! ID: " + regId);
runOnUiThread(new Runnable() {
#Override
public void run() {
subscribeToPushNotifications(regId);
}
});
} catch (Exception e) {
Log.d("Login", "Reg e: " + e);
}
}
}).start();
} else {
Log.d("Login", "Already Exist");
subscribeToPushNotifications(regId);
}
public void subscribeToPushNotifications(String regId) {
String deviceId = ((TelephonyManager) getBaseContext()
.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
QBMessages.subscribeToPushNotificationsTask(regId, deviceId,
QBEnvironment.DEVELOPMENT,
new QBEntityCallbackImpl<ArrayList<QBSubscription>>() {
#Override
public void onSuccess(ArrayList<QBSubscription> result,
Bundle params) {
Log.d("Login", "Successfully Registered");
}
#Override
public void onError(List<String> errors) {
Log.d("Login", "e : " + errors);
}
});
}
private String getRegisterationId(Context context) {
SharedPreferences prefs = getGCMPreferences(context);
String registerationId = prefs.getString(PROPERTY_REG_ID, "");
if (registerationId.isEmpty()) {
Log.d("Login", "Not registered!");
return "";
}
return registerationId;
}
private SharedPreferences getGCMPreferences(Context context) {
return getSharedPreferences(DialogsActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
}
private void storeRegisterationId(Context context, String regId) {
final SharedPreferences prefs = getGCMPreferences(context);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regId);
editor.commit();
}
And I get that registration done successfully.. :S
I've been searching for the solution for 2 days now :/ Any help will be appreciated.. Thanks.
I don't have enough reputation to comment, so I am putting this as a possible answer -
I have been working through the same for the last couple of days, and here are a couple of things to check:
When you set up the GCM API key, did you set any IPs? You should leave this blank to accept all.
When you say the registration is done successfully, do you mean you get the onSuccess Log message from subscribeToPushNotificationsTask? Check your device id; I was getting null for deviceId from:
String deviceId = ((TelephonyManager)getBaseContext().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
So instead I had to use
String deviceId = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID);
What options were you selecting in the Quickblox Admin Panel > Messages? Be sure you are selecting "GCM (Android Push)" under the channel option.
Lastly, make sure you are using all production or all development for your environments (QBEnvironment.DEVELOPMENT). I somehow ended up with a mix, and switched them all to production now.
My push notifications are now working, so perhaps I can help out more if you have specific questions.