Turn off GCM Notifications - android

I am developing the app where I'm using GCM. I have taken sample GCM example from google samples from github and implemented every thing is fine,But i want to TURNOFF the GCM notifications. I have specified GCM notification turn ON/OFF in another Activity using toggle button.when i click on toggle button it should work accordingly
I found subscribeTopics method in RegistrationIntentService.java
private void subscribeTopics(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
similarly i have written Un Subscribe method
To TURN OFF Notifications
private void UnSubscribeTopics(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
pubSub.unSubscribe(token, "/topics/" + topic, null);
}
}
I'm unable to call UnSubscribeTopics method.Because that method is in RegistrationIntentService.java which extends Intentservice.How can i call method 'UnSubscribeTopics'
I'm still getting notifications and here they are using Intent service.I have gone through internet some are saying to delete token(secret token) or delete instance id,but I'm confused what to do?? and how i do that .I am new to Intent service.here they using broadcast receiver also how can i call that in my activity.
Any help???
Thanks in advance.

You have two options to do that:
'SharedPreferences' you should have a preference that contain the value if the user should be notified or not. You may set the preference value to 'false'. In your 'GCMIntentService', check the value of the preference, if it's false, do nothing.
You may unregister your app to avoid receiving push notifications. You can use 'GCMRegistrar.unregistrar()' to make this happen.

Related

Unable to register for push notifications on Android in Xamarin together with IntercomIO

I added the IntercomIO SDK to our Xamarin.Forms app through a couple binding libraries this week and I'm currently trying to get the Push Notifications to work but soon after I call PushHandlerService.Register(this) in the MainActivity the app crashes saying that it can't find the class com.google.android.gms.gcm.GcmReceiver which isn't even being caught by the try catch block around this call.
Here is the method inside the MainActivity which is responsible for setting up the push notifications on Android.
public void registerForPushNotifications()
{
try
{
GcmClient.CheckDevice(this);
GcmClient.CheckManifest(this);
//Register the app for push notifications.
PushHandlerService.Initialize(this);
//if (!GcmClient.IsRegistered(this))//Temporarily force the app to register for push notifications
{
System.Diagnostics.Debug.WriteLine("Registering");
// Register for GCM
PushHandlerService.Register(this);
}
LocalBroadcastManager lbc = LocalBroadcastManager.GetInstance(this);
PushActionReceiver rec = new PushActionReceiver(this);
lbc.RegisterReceiver(rec, new IntentFilter("pushaction"));
}
catch (Java.Net.MalformedURLException)
{
var e = new Exception("There was an error creating the Mobile Service. Verify the URL");
System.Diagnostics.Debug.Fail(String.Format(#"Exception at {0}: {1}", this.GetType().Name, e.Message));
Insights.Report(e);
}
catch (Exception e)
{
System.Diagnostics.Debug.Fail(String.Format(#"Exception at {0}: {1}", this.GetType().Name, e.Message));
if (e.GetType() != typeof(TaskCanceledException))
Insights.Report(e);
}
}
And in the Manifest I added the receiver definition for Intercom
<receiver android:name="io.intercom.android.sdk.gcm.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND"></receiver>
The issue doesn't happen when I don't call PushHandlerService.Register(this) but then obviously I can't receive any push notifications anymore (including the ones from our own system)
What's going on here? I have the libraries and dependancies setup properly but it doesn't seem to be able to find the GcmReceiver class..
Apparently updating to the latest SDK's in the SDK Manager solved this crash. I am still not receiving any push notifications but I'm guessing this is due to a different issue. At least the app doesn't crash anymore when trying to register for the push notifications.
Dale from Intercom here. Are you using any other third party push providers, or do you have your own GCM receiver? It's possible that they are consuming our push and not passing them on. This can be difficult in Xamarin, Phonegap, Cordova ect. as often the registration and receiver services are not available. I have included below a link to our GCM doc and the section that may be most relevant to you. If this doesn't help fix the issue get in touch with us on the cordova repo: https://github.com/intercom/intercom-cordova or reach out to us in your Intercom dashboard/ email us at team#intercom.io.
We have GCM docs here: https://docs.intercom.com/configure-intercom-for-your-product-or-site/configure-intercom-for-mobile/enable-push-notifications-with-intercom-for-android-gcm
The issue that might be causing you difficulty in your setup is:
Step 7. Using Intercom with other GCM setups (Optional)
This only applies to applications that also use GCM for their own content, or use a third party service for GCM. You’ll need to update the your GcmListenerService and the class where you generate your device token.
You should have a class that generates a push device token and sends it to your backend. In addition to sending the token to your backend you will need to forward it to Intercom, like this:
private final IntercomPushClient intercomPushClient = new IntercomPushClient();
public void onHandleIntent(Intent intent) {
InstanceID instanceId = InstanceID.getInstance(this);
String senderId = "YOUR_SENDER_ID";
String token = instanceId.getToken(senderId,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
pushClient.sendTokenToIntercom(getApplication(), token);
}
You should have a class that extends GcmListenerService. That service will consume pushes intended for Intercom. To allow us to draw the Intercom push set up your GcmListenerService, like this:
private final IntercomPushClient intercomPushClient = new IntercomPushClient();
public void onMessageReceived(String from, Bundle message) {
if (intercomPushClient.isIntercomPush(message)) {
intercomPushClient.handlePush(getApplication(), message);
} else {
//DO HOST LOGIC HERE
}
}

Quickblox group chat message listener doesn't work

I have integrated my app with Quickblox and I registered the group chat global listener after session has created as follow.
register GroupChatManagerListener after session created.
if (groupChatManager != null) {
groupChatManager.addGroupChatManagerListener(this);
}
and in the GroupChatManagerListener I have the following code.
#Override
public void chatCreated(QBGroupChat qbGroupChat) {
qbGroupChat.addMessageListener(mQBGroupChatMessageListener);
qbGroupChat.addMessageSentListener(mQBMessageSentListener);
}
I put the log, and it seems like the chatCreated never been called. Could anyone tell me what could be the possible reasons that this doesn't work or any suggestion to listen the group message globally.
Note: I implement exactly the same for private chat, and it works fine.
Thanks for help.

Parse.com push notifications not consistently working receiving "GCM -MISMATCH SENDER ID" error

Push notifications from parse.com is not consistently working. Randomly push notifications will fail, resulting in a GCM - MISMATCH SENDER ID" error. It is my understanding that programmatically we do not have to do anything with the GCM because parse.com sends the objectId to GCM. In either case, I have not been able to pinpoint any specific reason why this error occurs sometimes and other times it doesn't. Additionally, I am using Parse version, 1.10.2.
My Application class has the following
Parse.initialize(this, APPLICATION_ID_DEBUG, CLIENT_KEY_DEBUG);
Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE);
ParsePush.subscribeInBackground(Constants.CHANNEL, new SaveCallback() {
#Override
public void done(ParseException e) {
if (Utils.checkIfNull(e)) {
// subscribed to channel
} else {
// failed to subscribe to channel
}
}
});
After the user logs into my app I attach a channel to them. The channel data I save is just the user's unique id I am getting from server.
List<String> arryChannel = new ArrayList<>();
arryChannel.add(uniqueUserId);
final ParseInstallation parseInstallation = ParseInstallation.getCurrentInstallation();
parseInstallation.put(Constants.CHANNEL, arryChannel);
parseInstallation.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (Utils.checkIfNull(e)) {
// update channel with user's unique id
} else {
// failed to update channel with user unique id
}
}
});
Finally, when the user logs out I unsubscribe them from their channel. I added unsubscribe to try and prevent any one device from receiving multiple push notifications because they have logged in as multiple users into the app and subscribed to multiple channels. The following is how my code looks when you log out.
ParsePush.unsubscribeInBackground(Constants.CHANNEL, new SaveCallback() {
#Override
public void done(ParseException e) {
if (Utils.checkIfNull(e)) {
// successfully unsubscribed to channel
// save the updated (unsubscribed) parse installation
final ParseInstallation parseInstallation = ParseInstallation.getCurrentInstallation();
parseInstallation.put(Constants.CHANNEL, new ArrayList<String>());
parseInstallation.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (Utils.checkIfNull(e)) {
// add whatever logs here to check for any issues with unsubscribing
} else {
// failed to update channel
}
}
});
} else {
Logger.e("PARSE", "failed to unsubscribed to channel: " + e.getMessage());
}
}
});
The result of this implementation is that when push notifications are not working, it will continue to fail for about 50-100 times. Then it will start working for about 150-200 times. Then it goes back to not working. It is not a work, not-work type back and forth. It is more of a fail, fail, fail multiples times and then success, success, success multiple times. Any help on what I am missing in my implementation is appreciated. Thanks in advance.
I have finally figured out the answer to this question! The issue had nothing to do with my implementation. For anyone else experiencing this same conflict, please look for any other 3rd party services that also are using push notifications. For me, Mixpanel was the culprit. When I deleted mixpanel.initPushHandling() from my codebase, all started working. And this makes sense, because when you initialize push notifications for mixpanel, you pass in a value that is used for GCMSenderID. Parse push notifications work differently. With parse.com, you do not have to send a GCMSenderID, because parse will automatically send in an objectId to perform their push notifications. Between the two, this causes a GCM-MISMATCH-SENDER error.
So the solution is, remove any sort of services that may be conflicting with parse.com. And feel free to use my implementation, it is good. Cheers!
I faced the problem and after some rummage, finally found the solution. As Parse said in it's docs you should provide each Sender_ID that your app uses to push messages, if you use another push provider in addition to Parse. Take a look at below:
The Parse Android SDK chooses a reasonable default configuration so that you do not have to worry about GCM registration ids, sender ids, or API keys. In particular, the SDK will automatically register your app for push at startup time using Parse's sender ID (1076345567071) and will store the resulting registration ID in the deviceToken field of the app's current ParseInstallation.
However, as an advanced feature for developers that want to send pushes from multiple push providers, Parse allows you to optionally register your app for pushes with additional GCM sender IDs. To do this, specify the additional GCM sender ID with the following <meta-data> tag as a child of the <application> element in your app's AndroidManifest.xml:
<meta-data android:name="com.parse.push.gcm_sender_id"
android:value="id:YOUR_SENDER_ID" />;
In the sample snippet above, YOUR_SENDER_ID should be replaced by a numeric GCM sender ID. Note that the Parse SDK expects you to prefix your sender ID with an id: prefix, as shown in the sample snippet.
If you want to register your app with multiple additional sender IDs, then the android:value in the <meta-data> element above should hold a comma-delimited list of sender IDs, as in the following snippet:
<meta-data android:name="com.parse.push.gcm_sender_id"
android:value="id:YOUR_SENDER_ID_1,YOUR_SENDER_ID_2,YOUR_SENDER_ID_3" />;

Sending message to disconnected mobile from wearable

I'm trying to send an event or better a message to the mobile while the wearable is disconnected.
Here is the code I'm using:
Wearable.MessageApi.sendMessage(
mGoogleApiClient, node, event, message).setResultCallback(
new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
if(!sendMessageResult.getStatus().isSuccess()) {
Log.e(TAG, "Failed to send message with status code: "
+ sendMessageResult.getStatus().getStatusCode());
}
}
}
);
The node ID is cached when onPeerConnected(Node peer) is called so I don't need to query the Node API to get an empty list. However I send the data to the node which is offline. That results the StatusCode 4000 which is TARGET_NODE_NOT_CONNECTED. Of course I know that, but what is the best way to cache this event to send it as soon as possible?
I ended in the that idea which Maciej Ciemięga pointed out in the comments. I'm using the DataAPI to store and forward my events. After the event was recieved by the mobile I delete the path from the data layer, since it did its job.
You should keep in mind the deletion will invoke again the onDataChanged method. So you should check the type of the DataEvent:
event.getType() == DataEvent.TYPE_DELETED
If you don't keep that in mind you may get an infinity loop.

Google Hangouts breaks SMS order

I've got an app that sends a text message as a response after receiving a text message. (Auto Respond) When SMS is enabled in hangouts, my app wasn't sending its messages. I fixed that by doing this:
<intent-filter android:priority="500">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
After sending the message, my app also writes that sent message to the user's SMS log (inbox/outbox displayed by messaging apps.)
But now that my SMS receiver is higher priority than Hangouts, the sent message is written to the user's SMS log AFTER the received message when it should be the other way around.
So it shows like this:
Response Message
Received Message - this is what triggered the response
But it should be:
Received Message - triggers response
Response Message
Is there a way for me to wait for the received message to be written before writing the response message? It works fine when SMS is disabled in Hangouts. But since Hangouts is now writing that message instead of the default SMS receiver, it messes things up like crazy.
EDIT: Thanks to Keith's response, this is the code that worked for me:
context.getContentResolver().registerContentObserver(
Uri.parse("content://sms"),
true,
smsObserver);
And this class:
private class SMSObserver extends ContentObserver
{
public SMSObserver()
{
super(null);
}
#Override
public boolean deliverSelfNotifications() {
return true;
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
if(!selfChange)
//sendResponse
context.getContentResolver().unregisterContentObserver(this);
}
#Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if(!selfChange)
//sendResponse
context.getContentResolver().unregisterContentObserver(this);
}
}
I'm not sure if the self change part is necessary, but it works so I'm not changing it.
Try a ContentObserver on the SMS database to listen for when Hangouts writes to the SMS content provider. This approach should be compatible with 4.4/Hangouts as well as earlier versions; you'd just wait until something is written to write your sent message.
Tested two different versions on Android 4.3, Galaxy Nexus:
context.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, myContentObserver);
or
cursor = context.getContentResolver().query(Uri.parse("content://sms/inbox"),
new String[] { SMS_ID, SMS_ADDRESS, SMS_READ },
"read = 0",
null,
null);
cursor.registerContentObserver(myContentObserver);
But I couldn't use the non-Cursor version with sms/inbox for some reason. The downside of the Cursor-based version is that it seems to need to stay open so then you have to be sure to close it later.
Also, neither version is being called when the read status changes.

Categories

Resources