am developing an android app that uses GCM to send and receive messages. am able ro register my app with GCM and receive GCM Registration Token. but am not being notified upon receiving new messages.(seems like nothing is hapenning in my MyGcmListenerService class.)
i can only see my new messages upon reloading my chat user Interface(that is clicking the back button and then clicking again my chat button. nothing is taking place in my MyGcmListenerService.java !!!!)
below are my classes and AndroidManifest.xml
AndroidManifest.xml
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.me.myapp.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.me.myapp.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="android.support.multidex.MultiDexApplication"
>
<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.me.myapp" />
</intent-filter>
</receiver>
<service
android:name="com.me.myapp.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name="com.me.myapp.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
MyGcmListenerService.java
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
public static final String AC_GCM_MESSAGE_ACTION = "com.me.myapp.MyGcmListenerService.OrderedBroadcast";
public static final String INTERCEPTED = "intercepted";
/**
* Called when message is received.
*
* @param from SenderID of the sender.
* @param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
@Override
public void onMessageReceived(String from, Bundle data) {
d("on receive called");
final String message = data.getString("message");
final String senderName = data.getString("sender");
final String senderId = data.getString("senderId");
final String dateCreated = data.getString("dateCreated");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
d("Message received from "+ from);
Intent intent = new Intent(AC_GCM_MESSAGE_ACTION);
intent.putExtra("message", message);
intent.putExtra("senderName", senderName);
intent.putExtra("senderId", senderId);
intent.putExtra("dateCreated", dateCreated);
//dateCreated
intent.putExtra(INTERCEPTED, false);
sendOrderedBroadcast(intent, null, new MyBroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle results = getResultExtras(true);
d("entered onreceive");
boolean intercepted = results.getBoolean(INTERCEPTED);
if (!intercepted) {
sendNotification(message, senderName, senderId);
}
}
}, null, Activity.RESULT_OK, null, null);
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* @param message GCM message received.
*/
private void sendNotification(String message, String senderName, String senderId) {
Intent intent = new Intent(this, ChatActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("senderId", senderId);
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_name)
.setContentTitle(senderName)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
private void d(String s){
Log.d("MyGcmListenerService", s);
}
}
My RegistrationIntentService.java
private static final String TAG = "RegIntentService";
public RegistrationIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
d("onHandleIntent");
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
// In the (unlikely) event that multiple refresh operations occur simultaneously,
// ensure that they are processed sequentially.
synchronized (TAG) {
// [START register_for_gcm]
// Initially this call goes out to the network to retrieve the token, subsequent calls
// are local.
// [START get_token]
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
// [END get_token]
d("GCM Registration Token: " + token);
sendRegistrationToServer(token);
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
sharedPreferences.edit().putBoolean(AlphaCashPreferences.SENT_TOKEN_TO_SERVER, true).apply();
// [END register_for_gcm]
d("registration succeeded");
}
} catch (Exception e) {
d("Failed to complete token refresh", e);
// If an exception happens while fetching the new token or updating our registration data
// on a third-party server, this ensures that we'll attempt the update at a later time.
sharedPreferences.edit().putBoolean(AlphaCashPreferences.SENT_TOKEN_TO_SERVER, false).apply();
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(AlphaCashPreferences.REGISTRATION_COMPLETE);
d("regestration intent broadcasted");
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
/**
* Persist registration to third-party servers.
*
* Modify this method to associate the user's GCM registration token with any server-side account
* maintained by your application.
*
* @param token The new token.
*/
private void sendRegistrationToServer(String token) {
d("Send registration token to server");
// Add custom implementation, as needed.
Context c = getApplication();
SaveRegistrationIdRequest req = new SaveRegistrationIdRequest();
req.setCredentials(Installation.createCredentials(c));
req.setRegId(token);
Installation installation = Installation.getInstance(c);
SendGcmRegistrationIdTask task = new SendGcmRegistrationIdTask(new ApiTask.ResultListener() {
@Override
public void successHook(Object o) {
//TODO After registration of the gcm id
}
}, installation, req);
task.execute();
d("successflly sent");
}
private void d(String s){
Log.d("RegIntentService", s);
}
private void d(String s, Exception e){
Log.d("RegIntentService", s, e);
}
}
QUESTION
How can i solve my problem and be able to receive messages instantly without going back and forth ?
AFTER DEBUGGING MY APPLICATION, THIS ARE THE WARNINGS AM GETTING FROM THE LOGCAT
com.me.myapp W/dalvikvm﹕ VFY: unable to resolve virtual method 247: Landroid/app/
Notification$Builder;.setLocalOnly (Z)Landroid/app/Notification$Builder;
10-05 16:18:11.594 32178-32178/com.me.myapp W/dalvikvm﹕ VFY: unable to resolve instance field 18
10-05 16:18:11.603 32178-32178/com.me.myapp W/dalvikvm﹕ VFY: unable to resolve virtual method 1507: Landroid/os/UserManager;.getApplicationRestrictions (Ljava/lang/String;)Landroid/os/Bundle;
10-05 16:18:11.605 32178-32178/com.me.myapp E/dalvikvm﹕ Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zzb