Reputation: 43
Parse is closing and I found some service which can send push. And I want use GCM. I got an example from github and created a new project in android studio and added this code. When I start app, in console I have
GCM Registration Token: dRmYwe49H4U:APA91bEECX4BfFbiRD7Ike9SHeunVqRim5T_F5YNmojInf-loo4GOxlVZfVlXcWCay2jbnFHEeo3QtoXIB418sxqyAtUBHH_bKO3snBmLemNE42L-6q61GqF5bnABt0Vcpy1Pm2rqTSN
I think it is a success, app subscribed in gcm. Then I use service and tried to send some push message to device. In service it says Success
but in device no push message is received. And don't know why it is not working.
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<permission android:name="com.example.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.permission.C2D_MESSAGE" />
<!-- [START gcm_permission] -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- [END gcm_permission] -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:name="android.support.multidex.MultiDexApplication"
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>
<!-- [START gcm_receiver] -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="gcm.play.android.samples.com.gcmquickstart" />
</intent-filter>
</receiver>
<!-- [END gcm_receiver] -->
<!-- [START gcm_listener] -->
<service
android: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=".MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<!-- [END instanceId_listener] -->
<service
android:name=".RegistrationIntentService"
android:exported="false">
</service>
</application>
</manifest>
MainActivity
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private static final String TAG = "RegIntentService";
private BroadcastReceiver mRegistrationBroadcastReceiver;
private ProgressBar mRegistrationProgressBar;
private TextView mInformationTextView;
GoogleCloudMessaging gcm;
String regid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRegistrationProgressBar = (ProgressBar) findViewById(R.id.registrationProgressBar);
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mRegistrationProgressBar.setVisibility(ProgressBar.GONE);
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context);
boolean sentToken = sharedPreferences
.getBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, false);
if (sentToken) {
mInformationTextView.setText(getString(R.string.gcm_send_message));
} else {
mInformationTextView.setText(getString(R.string.token_error_message));
}
}
};
mInformationTextView = (TextView) findViewById(R.id.informationTextView);
if (checkPlayServices()) {
// Start IntentService to register this application with GCM.
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(QuickstartPreferences.REGISTRATION_COMPLETE));
}
@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
super.onPause();
}
/**
* Check the device to make sure it has the Google Play Services APK. If
* it doesn't, display a dialog that allows users to download the APK from
* the Google Play Store or enable it in the device's system settings.
*/
private boolean checkPlayServices() {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
} else {
Log.i(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
MyGcmListenerService
private static final String TAG = "RegIntentService";
@Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.e(TAG, "From: " + from);
Log.e(TAG, "Message: " + message);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream 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.common_google_signin_btn_icon_dark)
.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());
}
MyInstanceIDListenerService
@Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
QuickstartPreferences
public static final String SENT_TOKEN_TO_SERVER = "37106xxxxxx";
public static final String REGISTRATION_COMPLETE = "registrationComplete";
RegistrationIntentService
private static final String TAG = "RegIntentService";
private static final String[] TOPICS = {"global"};
public RegistrationIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.google_app_id),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
// [END get_token]
Log.e(TAG, "GCM Registration Token: " + token);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(token);
// Subscribe to topic channels
subscribeTopics(token);
sharedPreferences.edit().putBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, true).apply();
Log.e(TAG, "sharedPreferences");
} catch (Exception e) {
Log.e(TAG, "Failed to complete token refresh", e);
sharedPreferences.edit().putBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, false).apply();
}
Intent registrationComplete = new Intent(QuickstartPreferences.REGISTRATION_COMPLETE);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
private void sendRegistrationToServer(String token) {
}
private void subscribeTopics(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
Upvotes: 0
Views: 4817
Reputation: 13494
Sometimes, devices don't receive push message because its Google Play Services app wasn't installed properly. It's essential for GCM because every apps on your phone, from syncing and API access to push notifications, goes through Google Play Services. Read this article and you can see and download the latest version of Google Play Services.
Based from Google documentation, even though the app server posts a message to GCM and receives a message ID back, it does not mean that the message was already delivered to the device. It only means that it was accepted for delivery. What happens to the message after it is accepted depends on many factors.
Also make sure that you set your SENDER ID you received from Google properly and that your device was registered with GCM service correctly.
Upvotes: 1
Reputation: 2109
I just wrote a recipe with step-by-step instructions for setting up the build scripts, Android Manifest and code. See the 4th (last) recipe: Push notification using Google Cloud Messaging https://www.packtpub.com/books/content/practical-how-recipes-android
I also wrote an Android based GCM Tester, though it's probably the same functionality as the one you linked.
Upvotes: 3