GCM 2.0 is not working in Android P - android

I'm implementing GCM in Android P.
But I cannot receive the broadcasting from GCM.
What's wrong in Android P?
By the way, working well in Android O.
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
registrationIntent.setPackage("com.google.android.gsf");
registrationIntent.putExtra("sender", sender_id);
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
public class GCMBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
String messageType = gcm.getMessageType(intent);
Log.e("GCM", "action=" + intent.getAction() + " registration_id="+intent.getStringExtra("registration_id"));
}
}

You must be using an older version of GCM.
Upgrade to GCM 11 or higher. (The latest is 15.0.1: com.google.android.gms:play-services-gcm:15.0.1), or even better, migrate to FCM. (GCM is now deprecated)

the documentation states ...
As of April 10, 2018, Google has deprecated GCM. The GCM server and client APIs are deprecated and will be removed as soon as April 11, 2019. Migrate GCM apps to Firebase Cloud Messaging (FCM), which inherits the reliable and scalable GCM infrastructure, plus many new features. See the migration guide to learn more.
therefore, you might (sooner or later) have to migrate to FCM.
since recently, there's also Firebase In-App Messaging.

I solved this problem myself by using GCM 3.0 way like below:
public void getInstanceIdToken() {
if (checkPlayServices()) {
// Start IntentService to register this application with GCM.
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
public class RegistrationIntentService extends IntentService {
private static String TAG = RegistrationIntentService.class.getSimpleName();
public RegistrationIntentService() {
super(TAG);
}
String senderId = "YourSenderId";
#Override
protected void onHandleIntent(#Nullable Intent intent) {
InstanceID instanceID = InstanceID.getInstance(this);
try {
String token = instanceID.getToken(senderId,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
} catch (IOException e) {
e.printStackTrace();
}
}
}

Related

How to get Baidu channel id?

We are trying to integrate the Baidu SDK and use it together with Azure Notification Hub in the back-end.
In Android we are using the SDK: lib-techain-release-3.5.7.4
To get the PushId of the device we use:
public class BaiduReceiver extends BroadcastReceiver {
private static final int TYPE_REGISTRATION = 1;
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (!PUSH_ACTION.equals(action)) {
return;
}
Bundle bundle = intent.getExtras();
int type = bundle.getInt("event_type", -1);
switch (type) {
case TYPE_REGISTRATION:
String uid = bundle.getString("push_uid");
break;
default:
break;
}
}
}
Which works. This ID can be used to send push notifications from the Baidu console.
However, when integrating with Azure Notification Hub, it also requires a "Channel ID" (see https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.notificationhubs.baiduregistrationdescription?view=azure-dotnet)
How do we obtain this channel Id in Android?
We have the information about how to integrate with Baidu here on the Get started with Notification Hubs using Baidu in particular needing to override the onBind method of the custom PushMessageReceiver class.

android firebase reg id recived but notification not show in phone display

I will try to show personal single notification on my phone tray, but I can't rich, so help.
I am having an issue with FireBase Cloud Messaging in which I get the Token from the device and send the notification test through the Google Firebase notification console, however, the notification is never logged nor pushed to the android virtual device. The documentation for FCM is almost exactly the code that I have below and little else in the way of what else you would have to do to get push notifications working with firebase. I have gone through all of the setup information (build.gradle additions, Installing google play services, etc...) as specified in the documentation, but still do not have messages generating. What is wrong with the code that I am not receiving my push notifications to the logcat or the device? Please let me know any further information that would be helpful. Thanks.
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) {
FirebaseMessaging.getInstance().subscribeToTopic(Config.TOPIC_GLOBAL);
displayFirebaseRegId();
} else if (intent.getAction().equals(Config.PUSH_NOTIFICATION))
{
String message = intent.getStringExtra("message");
Toast.makeText(getApplicationContext(), "Push notification: " + message, Toast.LENGTH_LONG).show();
txtMessage.setText(message);
}
}
};
displayFirebaseRegId();
}
private void displayFirebaseRegId() {
SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0);
String regId = pref.getString("regId", null);
Log.e(TAG, "Firebase reg id: " + regId);
if (!TextUtils.isEmpty(regId))
txtRegId.setText("Firebase Reg Id: " + regId);
else
txtRegId.setText("Firebase Reg Id is not received yet!");
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(Config.REGISTRATION_COMPLETE));
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(Config.PUSH_NOTIFICATION));
NotificationUtils.clearNotifications(getApplicationContext());
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
super.onPause();
}
And I will add lib of fire base messaging is:
compile 'com.google.firebase:firebase-messaging:11.0.4'
You don't need to subscribe inside the BroadcastReceiver you can just do it inside the onTokenRefresh method in the FirebaseInstanceIdService
You don't need to get the push notification in the BroadcastReceiver, you have to do it inside the onMessageReceive in the FirebaseMessagingService
FCM is extremely unreliable with emulators, simply use a real device, I have struggled with this and in some cases I even get the notification days later when opening the emulator for other projects, test this with real phones

Non deprecated GCM Cloud Endpoints example 2016

Last year when you added a Cloud Endpoints plus GCM module to an Android Studio project, the IDE created some sample code both in the backend and the app that showed how to use GCM with Cloud Endpoints.
However, with the newer versions of Android Studio you only get the backend part added for you. So I went back into my old projects and dug up some of the convenient app code which registered, and sent GCM push notifications in Android.
Here is what that code looks like:
GcmBroadcastReceiver.java
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.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GcmIntentService.java
public class GcmIntentService extends IntentService {
android.support.v4.app.NotificationCompat.Builder notification;
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 != null && !extras.isEmpty()) { // has effect of unparcelling Bundle
// Since we're not using two way messaging, this is all we really to check for
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
Logger.getLogger("GCM_RECEIVED").log(Level.INFO, extras.toString());
showToast(extras.getString("message"));
sendNotification(extras.getString("message"));
}
}
//call to the API and get new data.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
protected void showToast(final String message) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
});
}
private void sendNotification(String msg) {
notification = new android.support.v4.app.NotificationCompat.Builder(this);
//set number of notifications count
//notification.setNumber(x);
//cancels notification when app is opened.
notification.setAutoCancel(true);
//build the notification
notification.setSmallIcon(R.drawable.greenicon);
notification.setTicker("This is the ticker!");
//set time
notification.setWhen(System.currentTimeMillis());
notification.setContentTitle("New message!");
notification.setContentText(msg);
notification.setSound((Settings.System.DEFAULT_NOTIFICATION_URI));
//LED
notification.setLights(Color.RED, 3000, 3000);
// intent
Intent intent = new Intent(this, MainActivity.class);
//give phone access to perform this intent b/c they may be in another part of their phone.
//aka gives phone access to the intents in our app
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//what to do when notification is clicked:
notification.setContentIntent(pendingIntent);
//Builds notification and issues it (sends it to device). Can build and send out notifcations
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//send out notification with uniqueID
nm.notify(2158, notification.build());
}
}
GcmRegistrationAsyncTask
class GcmRegistrationAsyncTask extends AsyncTask<Void, Void, String> {
private static Registration regService = null;
private GoogleCloudMessaging gcm;
private Context context;
// TODO: change to your own sender ID to Google Developers Console project number, as per instructions above
private static final String SENDER_ID = "1026567774990";
public GcmRegistrationAsyncTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(Void... params) {
if (regService == null) {
Registration.Builder builder = new Registration.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// Need setRootUrl and setGoogleClientRequestInitializer only for local testing,
// otherwise they can be skipped
.setRootUrl("https://push-notif-45657747.appspot.com/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
#Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest)
throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
}) ;
// end of optional local run code
regService = builder.build();
}
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
String regId = gcm.register(SENDER_ID);
msg = "Device registered, registration ID=" + regId;
// You should send the registration ID to your server over HTTP,
// so it can use GCM/HTTP or CCS to send messages to your app.
// The request to your server should be authenticated if your app
// is using accounts.
regService.register(regId).execute();
} catch (IOException ex) {
ex.printStackTrace();
msg = "Error: " + ex.getMessage();
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
Logger.getLogger("REGISTRATION").log(Level.INFO, msg);
}
}
However, I am getting some deprecated errors in Android Studio now:
gcm.register(SENDER_ID); is deprecated and so is GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.
This GCM stuff is pretty confusing to begin with and while there is some information here on how to use it, I was wondering if anyone had any currently working non-deprecated examples or maybe you could suggest some edits to the above code if you know what you are doing...? Much thanks!
Wanted to give people a little guide here in case they were lost.
First check out and stay up to date with this Google Cloud Messaging Android example:
https://github.com/google/gcm
To make it work you will have to generate a google-services.json file which you can do here:
https://developers.google.com/mobile/add
Make sure you are logged into the google developers console before you go that link. It will load your projects for you and automatically set up the gcm api key for you in your projects credentials.
Copy/paste the google-services.json into the /app directory of your Android project.
Add a cloud endpoints with gcm module to the android project.
Enter your gcm api key (which you can view on your credentials page on developers console) into the webapp-WEB_INF/appengine-web.xml file in your cloud endpoints backend:
<property name="gcm.api.key" value="your-api-key-here"/>
This way, inside the Android client and MessagingEndpoint the code will automatically get the api key (in the endpoint it will be the line Sender sender = new Sender(API_KEY); for example, which will just retrieve it for you).
Run the sample gcm android project and it should work. Send a push notification with the API's explorer you deployed.
BIG NOTE: when you are ready to use the sample code in your own app make sure the RegistrationIntentService is in the root of your package or it won't work! Took a while to figure that out... Not sure if it is a bug or what.

GCM Android Push Notification: send OK but not delivered

I'm trying to send push notification to android devices. I have not problem to register the ID of the emulator or the devices, but it's impossibile to receive messages also if the send status is 200 OK.
I also try to look to firewall settings, but it's already turned off.
I tried also to use PushBots service from web: same thing. Device registered correctly, message sent, but not delivered to emulator or devices.
It was my mistake. I didn't notice the app was giving me exception when sending push from web for an error in the manifest Receiver.
Implemented the NotificationManager now I receive the push messagge into device.
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmMessageHandler will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmMessageHandler.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
mes = extras.getString("title");
sendNotification(mes);
sendAlert(mes);
Log.i("GCM", "Received : (" +messageType+") "+extras.getString("title"));
GcmBroadcastReceiver.completeWakefulIntent(intent);
}

Two ways for registration and starting service in Google Cloud Messaging (GCM)

I'm trying to develop an application with GCM. I read the official document about GCM, but feeling like there are two ways for doing these.
1. As for registering an android device for GCM
It seems like there are two ways for registering a device to GCM.
"http://developer.android.com/guide/google/gcm/gs.html#android-app"
says,
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, SENDER_ID);
} else {
Log.v(TAG, "Already registered");
}
on the other hand,
"http://developer.android.com/guide/google/gcm/gcm.html#registering"
says,
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
// sets the app name in the intent
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
registrationIntent.putExtra("sender", senderID);
startService(registrationIntent);
2. As for getting responses from GCM server and starting a service for handling them
Also, I'm feeling like there are two ways to start intent for handling the response.
"http://developer.android.com/guide/google/gcm/gs.html#android-app" instructs like,
"make a sub class of com.google.android.gcm.GCMBaseIntentService"
and implement
onRegistered(Context context, String regId)
onUnRegistered(Context context, String regId)
onMessage(Context context, Intent intent)
...etc.
While "http://developer.android.com/guide/google/gcm/gcm.html#registering" is described with,
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public final void onReceive(Context context, Intent intent) {
MyIntentService.runIntentInService(context, intent);
setResult(Activity.RESULT_OK, null, null);
}
}
public class MyIntentService extends IntentService {
private static PowerManager.WakeLock sWakeLock;
private static final Object LOCK = MyIntentService.class;
static void runIntentInService(Context context, Intent intent) {
synchronized(LOCK) {
if (sWakeLock == null) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
sWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "my_wakelock");
}
}
sWakeLock.acquire();
intent.setClassName(context, MyIntentService.class.getName());
context.startService(intent);
}
#Override
public final void onHandleIntent(Intent intent) {
try {
String action = intent.getAction();
if (action.equals("com.google.android.c2dm.intent.REGISTRATION")) {
handleRegistration(intent);
} else if (action.equals("com.google.android.c2dm.intent.RECEIVE")) {
handleMessage(intent);
}
} finally {
synchronized(LOCK) {
sWakeLock.release();
}
}
}
}
Is it right that there are two ways for doing both of the processes above, and I can use whichever way I want to?
It seems like there are two ways for registering a device to GCM.
There is only real way, which is your second approach. GCMRegistrar uses the second approach under the covers to implement the first approach.
Also, I'm feeling like there are two ways to start intent for handling the response.
There is only one real way, which is your second approach. GCMBaseIntentService uses the second approach under the covers to implement the first approach -- this is why you need to register that BroadcastReceiver supplied by GCM in your manifest.
All else being equal, I recommend the first approach, as it is simpler and handles various issues for you. However, either way works.

Categories

Resources