I've been following the Set Up a GCM Client App tutorial and tried to understand the demo app they provided, but I couldn't understand how to send push notification with this service.
The above guide leads me to a "Generating InstanceID token" screen with never-ending ProgressBar. This program source can be obtained here: https://github.com/googlesamples/google-services/tree/master/android/gcm/app/src/main
After using the above source code I've tried next to Simple Downstream messaging, this: https://developers.google.com/cloud-messaging/downstream in order to send push to the app users.
I couldn't understand how I'm supposed to send my app users notifications with it.
I have a server and I'm great with PHP, What is left to do in order to send push notification to my application users using the GCM?
Finally managed to get the message to a TextView!
How do make it into push?
public class GcmService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
JSONObject jsonObject = new JSONObject();
Set<String> keys = data.keySet();
for (String key : keys) {
try {
jsonObject.put(key, data.get(key));
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
sendNotification("Received: " + jsonObject.toString(5));
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onDeletedMessages() {
sendNotification("Deleted messages on server");
}
#Override
public void onMessageSent(String msgId) {
sendNotification("Upstream message sent. Id=" + msgId);
}
#Override
public void onSendError(String msgId, String error) {
sendNotification("Upstream message send error. Id=" + msgId + ", error" + error);
}
private void sendNotification(final String msg) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
if (MainActivity.mTextView != null) {
MainActivity.mTextView.setText(msg);
}
}
});
}
}
Let's assume you have created a new project at Google Developers Console and taken note of 2 values: Project Number, which will be used as SENDER_ID in a client project; and API server key (created at Credentials), which will be used as API_KEY in a server project.
You can find more about basic server project with my answers at the following questions. In the second link, you will find sample code for a server project in Java, then you can refer to its logic to implement in your PHP project:
Adding Google Cloud Messagin (GCM) for Android - Registration process
How to implement a GCM Hello World for Android using Android Studio
Hope this helps!
Related
I'm trying to create a SyncAdapter for Microsoft calendars and the first step is Authentication. i'm using com.microsoft.aad:adal:2.0.4-alphaand using this code for first authentication:
getAuthenticationContext().acquireToken(
mContextActivity,
Constants.SCOPES.split(" "),
null,
Constants.CLIENT_ID,
Constants.REDIRECT_URI,
PromptBehavior.Auto,
new AuthenticationCallback<AuthenticationResult>() {
#Override
public void onSuccess(final AuthenticationResult authenticationResult) {
if (authenticationResult != null && authenticationResult.getStatus() ==
AuthenticationResult.AuthenticationStatus.Succeeded) {
dependencyResolver = new ADALDependencyResolver(
getAuthenticationContext(),
resourceId,
Constants.CLIENT_ID);
token = authenticationResult.getToken();
UserInfo userInfo = authenticationResult.getUserInfo();
if (userInfo != null) {
userIdentifier = new UserIdentifier(userInfo.getUniqueId(),
UserIdentifier.UserIdentifierType.UniqueId);
}
}
}
#Override
public void onError(Exception t) {
Log.e("initialize", "onError : " + t.getMessage());
result.setException(t);
}
}
);
this works perfectly and after entering username and password i can get token.
BUT this is for sync adapter and at some point i need to get token silently. so i used this code:
public void getTokenSilent() {
getAuthenticationContext()
.acquireTokenSilent(Constants.SCOPES.split(" "),
Constants.CLIENT_ID,
userIdentifier,
new AuthenticationCallback<AuthenticationResult>() {
#Override
public void onSuccess(
AuthenticationResult authenticationResult) {
UserInfo userInfo = authenticationResult.getUserInfo();
}
#Override
public void onError(Exception e) {
Log.e("getTokenSilent", "onError : " + e.getMessage());
}
});
}
After executing this code i got the error:
AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED Prompt is not allowed and failed to get token: ver:2.0.4-alpha
onError : Refresh token is failed and prompt is not allowed
how can i resolve this error and get or refresh token silently?
tnx in advance.
If you want to get the token silently, there are two ways for using Azure AD V2.0 endpoint.
First, acquire the access token and refresh token interactively, then get the access token in the cache or renew the access token using refresh token via acquireTokenSilent method.
Second is that the Azure AD V2.0 endpoint also support the Client Credentials flow(refer here) which normally used for the service daemon application. However the MSAL for android doesn't support this flow at present. You need to implement it yourself. You can follow this article about detail of this flow. And this flow only works for the Azure AD account.
I am developing an Android application and using Parse for push notification. Currently I have a problem when registering new device. I've used the code below to subscribe my Android phone on a specific channel on Parse server.
final String channel = "myapp_" + userId;
ParsePush.subscribeInBackground(channel, new SaveCallback() {
#Override
public void done(ParseException e) {
if (e != null) {
e.printStackTrace();
ParsePush.subscribeInBackground(channel, new SaveCallback() {
#Override
public void done(ParseException e) {
Log.e("Subscribe", e == null ? "Success" : "Failure");
}
});
} else {
Log.e("Subscribe", "Success");
}
}
});
I have a strange problem on this:
The device can be registered to Parse for the 1st time after installing apps to phone (my device has already subscribed a channel successfully) but the GCM does not return the device token. Even after I wait for a long time, but nothing good happen. Unless I quit and re-open the apps, then GCM returns device token. I don't know where is the difference between them: the 1st time using apps vs reopen apps.
Have anyone got this problem? And can you give me any suggestion to solve this?
I found the reason: the Parse registration must be proceed at onCreate action of base Application class. Then the deviceToken will be retrieved normally on Parse server.
We have created a chat application using pubnub api on phonegap. We are using a common unique channel for two users (say A & B) to send and receive messages. Also, in addition to this, we have enabled pubnub gcm notification so that users can receive notifications when their app is either in the background or closed. Now when a user A sends a pubnub message to B and instantly changes the application or hides it, then the user A himself also receives a gcm notification oh his own message. This is the only issue that is troubling us. Rest all is working fine.
In your subscribe callback, can you detect if the application is not in the foreground, and if not in the foreground, return immediately?
This way, the logic which would deliver received messages to your application logic simply doesnt fire unless you are in foreground... ?
I ran into the same similar problem you did and so I rigged something together that works for me.
private boolean isFromSelf(final Object msgSent){
boolean isEcho = false;
String msgText = msgSent.toString();
JSONObject j;
String receiver = currentUserId; //a unique string ID for each user
try
{
j = new JSONObject(msgText);
String senderID = j.get("senderID").toString();
if (senderID.equals(receiver)){
isEcho = true;
}
}
catch(Exception e)
{
e.printStackTrace();
}
return isEcho;
}
It makes the assumption that every user that publishes a message to a channel will send their unique Id as "senderID" included in the payload. Then when a message is received, extract it from the payload and check it against the user's Id. So I add isFromSelf method as the first thing that is called when I receive a message, like this:
pN = new Pubnub(pub_key, sub_key);
try {
pN.subscribe(CHANNEL_NAME, new Callback() {
public void successCallback(String channel, Object msg) {
if (!isFromSelf(msg)) {
//Now add here what you want to do with the message
}
}
public void errorCallback(String channel, PubnubError error) {
Toast.makeText(MainActivity.this, "there was an error connecting", Toast.LENGTH_SHORT).show();
}
});
} catch (PubnubException e) {
e.printStackTrace();
}
So in your case, perhaps rig together a senderID check so that if you do receive a GCM from yourself, do not display notification at all, even if app is in background.
I'm trying to add the feature of push notifications in my app and i did everything correctly according to many guides but the push is never being sent (i don't see it in the push list in parse). On the contrary, when i send a push from parse to a specific channel( which is exactly what i want to do from the device), i do get a message on devices which subscribed to that channel.
doneBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ParsePush push = new ParsePush();
push.setQuery(query);
push.setChannel(listId);
push.setMessage("Hey pal"+", it looks like "+cur_user.getUsername()+" added you to a new list."+" Log in to check it.");
push.sendInBackground(new SendCallback() {
#Override
public void done(ParseException e) {
if(e == null){
Log.d("DONE BUTTON","im here");
onBackPressed();
}else{
Log.d("PUSH ERROR",e.toString());
}
}
});
}
});
//update the list on the screen
updateData();
}
I literally have no idea why it doesn't work.
listId which sent to setChannel is a valid channel (I checked that) and it is included in the channels column in several installations in parse among other channels (i mean, i have installations with more than one channel and i want to send this message onlt to listId channel).
I'm looking for some help with push notifications on Android.
Situation:
I'm trying to do a push send from an Android device, at this time for itself ( will understand later) but when I hit the send button nothing happens
Config:
Firstly, yes, the client side push is enabled.
Secondly my onCreate method in the "extends Application" class
public void onCreate() {
super.onCreate();
//Parse
//Parse.enableLocalDatastore(this);
Parse.initialize(this, "", "");
ParseObject.registerSubclass(Groups.class);
ParseObject.registerSubclass(Users.class);
//Subscribe to push
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
// Save the current Installation to Parse.
ParseInstallation.getCurrentInstallation().saveInBackground();
}
My button to send the push notification ( its the basic code from the docs )
sendReqBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Debug push onclick");
ParsePush push = new ParsePush();
push.setChannel("");
push.setMessage("The Giants just scored! It's now 2-2 against the Mets.");
push.sendInBackground(new SendCallback() {
#Override
public void done(ParseException e) {
System.out.println("Push send done");
}
});
}
});
All other settings set by the basic android tutorial (Like manifest and basic sdk adding, I already use other parse functions)
So after this code snippets added to my app I hoped that I will get a notification on the device itself as described earlier, but nothing happens. From the parse push dashboard I tried it, and it works fine (thats why I think the manifest and other things are configured well) and in the core panel on the dashboard i can see the installation in the list and the "" mark in the channels array.
Can anyone help me out?
Thanks in advance!!
Steve