Push Notification isn't working in Android, codename one - java

I'm failing in implementing Push Notification in Codename One, Android.
It seems registering push works perfectly now as follow, because public void registeredForPush(String deviceId) method of PushCallback interface is called successfully.
Display.getInstance().callSerially(() -> Display.getInstance().registerPush());
But, it seems server doesn't work.
new Push(PUSH_TOKEN, "Hello World", deviceId)
.gcmAuth(GCM_SERVER_API_KEY)
.send();
Above, deviceId is from the Android Phone itself, that is, app works as Push notification server as well as client.
I think this code should push notification to the phone itself.
Of course, I followed the guide here.
I also turned on Notification of this app in Phone settings and my codename one account plan is pro, but I don't know why notification arrived to my Android Phone.
Please help me with this issue.
(NetBeans IDE 8.2 (Build 201705191307)
Codename One Version: 3.7.1)

I found what the reason is.
First of all, I had to use Push.getPushKey() method to get phone's device id`.
But I had managed phones device ID as follows:
public void registeredForPush(String deviceId) {
store(deviceId); //this should be store(Push.getPushKey()); instead.
}
But it was absolutely wrong.
As Shai said in comment, the device id for pushing notification should be start 'cn1-gcm', but here deviceId was not so.
I'm just confused why registeredForPush() method has devieId as its parameter, which makes developers confusing.
Anyway, it works perfectly now while I'm using Push.getPushKey() in my code.
I'm very happy now and thanks to Shai and all of Codename One.

Related

How to use "disabledReason" in Android Management API?

So, I'm being able to disable the device using the AMAPI(Android Management API), but I want to let the user know why his device is being disabled, so I started looking for a way to show why the device was disabled and I found the "disabledReason" property, but it's not working, or I don't know where is displaying the reason that I set.
If you know where is displaying or how to display the disabledReason I will be very thankful.
device.setState("DISABLED");
UserFacingMessage reason = new UserFacingMessage();
reason.setDefaultMessage("Reason why your device was disabled...");
device.setDisabledReason(reason);
androidManagementClient
.enterprises()
.devices()
.patch(device.getName(), device).execute();
There is an issue when using the disabledReason field in AMAPI. There is no message displayed on the device indicating why the device is disabled, and this issue has not yet been resolved, but you can see it on your JSON response if you set a customized disabledReason.defaultMessage.

Cordova - Retrieve local storage from Push Plugin java files

I am programming a mobile app using Cordova. I am implementing the push notifications using Push Plugin. The app is meant to run on all platforms but right now I am testing on Android and Windows.
In a particular javascript file I am saving a value call it 'category' in the localstorage:
localStorage.setItem("category", JSON.stringify(categoryarray));
Now when sending a push notification, the category is essential to decide whether to show the notification or not. If a user is subscribed to that particular category, then, the notification is to be shown, otherwise not. For this I simply create a condition and check whether the user has subscribed to the category included in the notification (but this is not really relevant to the point of the question). When the app is running this condition can be handled in javascript. When the app is not running, this is handled in java code:
else {
extras.putBoolean("foreground", false);
// Send a notification if there is a message
if (extras.getString("message") != null && extras.getString("message").length() != 0) {
createNotification(context, extras);
}
}
Now I want to get the value from the local storage at that instance that the notification is being pushed when the app is not running (and be able to check whether the notification should be shown or not).
I came into this link: Android Service reads localStorage?
But it seems to be meant for Android native code (reference to the webview). Apart from that I haven't really understood how it works and furthermore if it is applicable for my problem.
What do you suggest? How can I do it?
Edit: I didn't initially realise that the Push plugin java code won't be compiled with the Cordova app. So editing the code that is retrievable from the Cordova directory is in reality useless. Unless, someone can still suggest something, I know that this is an unanswerable question. Will have to re-attempt to create an API for this purpose and handle who to receive which notification at server side! (The reason why I resorted to this method was because I wasn't managing to create an API for notification purposes)
I didn't initially realise that the Push plugin java code won't be compiled with the Cordova app. So editing the code that is retrievable from the Cordova directory is in reality useless. Unless, someone can still suggest something, I know that this is an unanswerable question.
This isn't true, Cordova plugin code is compiled when you compile your Cordova app. All Cordova plugin's provide native source code that gets compiled into the app when you run cordova build (or cordova run <platform>).
If you wanted to solve this completely on the client side (rather than managing the categories that a user is subscribed to on the backend and only sending a notification if the user is subscribed to a category), you could extend the PushPlugin to manage subscriptions to categories.
As a rough sketch:
In PushNotification.js, add a method to subscribe to a channel:
PushNotification.prototype.subscribeToChannel(successCallback, errorCallback, channel) {
cordova.exec(successCallback, errorCallback, "PushPlugin", "subscribeToChannel", [{channel: channel}]);
}
In PushPlugin.java catch the subscribeToChannel action in the execute function:
public boolean execute(String action, JSONArray data, CallbackContext callbackContext) {
...
if ("subscribeToChannel".equals(action)) {
//get the attached data
JSONObject jo = data.getJSONObject(0);
String channel = (String) jo.get("channel");
addChannelToSubscriptions(channel);
}
...
}
public void addChannelToSubscriptions(String channel) {
//store as a list in a sharedpreferences list
}
Then when a notification is received, you can check if the channel is a channel that has been subscribed to.
// Send a notification if subscribed to the channel
if (extras.getString("channel") != null && isSubscribedTo(extras.getString("channel"))) {
createNotification(context, extras);
}
public boolean isSubscribedTo(String channel) {
//see if the channel is in the shared preferences.
}
Personally, I think it'd be easier to manage subscriptions on the backend as to manage it in the app, you'd have to implement this logic for each platform you support. It would be easier to just add a webservice call in your Javascript. As a further alternative, if you don't want to handle the subscription logic on your backend, you could look at a service like Parse where the concept of subscribing to channels is built into the service.

Sending Push Notification to device using parse4j in java

I am using parse4j library for server side coding and on client side I have iOS device. Now I want to send the push notification from my web browser page I developed in JAVA in which I am using parse4j library to communicate with iOS device through Parse cloud. I am using gwt for coding the server side.
public void sendPushtoIOS() {
Parse.initialize("appId", "restApiId");
ParsePush parsePushObj = new ParsePush();
parsePushObj.sendInBackground("hello from server",null);
}
I am trying to send the notification with the above code, but nothing happens and iOS device doesn't receive any notification. Please could someone guide the code I written is correct or not, If not, how can I send the notification then?
try {
String rawJSON = "{\"aps\":{\"alert\":\""+"your message"+"\"},\"alerts\":{\"others\":\""+others+"\"}}";
PushNotificationPayload payload=PushNotificationPayload.fromJSON(rawJSON);
Push.payload(payload, "path of certificate.p12", password,false, appleDeviceToken);
}
catch (Exception e) {
}
As far as I understand correct, you are using the Parse4j library to send Push Notification. Did you control the current version of parse4j if it can send Push notification? Or it is pending enhancement? One suggestion; in order to send push notification write a cloud code and trigger this cloud code from parse4j. Then cloud code will send the Push notification.
Hope this helps,
Regards.
This library works fine. You can check pushes in parse dashboard, most likely you collected push requests. The only problem was that library works with channels. Maybe you do not set channels.
If you want to work with conditions, add this lines of code in library
JSONObject local = new JSONObject();
local.put("deviceType", "android");
data.put("where", local);
and remove
data.put("channel", "");
data.put("channels", new JSONArray(this.channelSet));
all of these changes must be done in method getJSONData() in class ParsePush
instead of android you can set your devices

How to use Javapns to Support Apple's Enhanced Notification Format

Greetings,
I am creating a Java based server to create push notifications for Apple's iOS APNs service. I have found Javapns on google code which seems to provide a simple basic framework to communicate with APNs, and which seems to be fairly wide used.
http://code.google.com/p/javapns/
However, reading Apple's docs, there is an "enhanced format" for notifications which supports "expiry" i.e. setting a time (well, in seconds) for a notification to expire if it hasn't yet been delivered. I do not see any way to set this using Javapns, and I am unsure how the APNs service handles expiry of notifications if you do not explicitly set it. So,
Does anyone know how to support the enhanced notification format of APNs specifically how to set the expiry?
Does anyone know how Apple handles notification expiry if it isn't explicitly set?
Does anyone have any suggestions that don't require me to start from scratch, as the server is currently functional as is?
Thanks in advance.
Andrew
I have recently made substantial contributions to the JavaPNS project, which lead to the release of JavaPNS 2.0 a few days ago. That version provides full support for the enhanced notification format, including the ability to set your own expiry.
Sylvain
Nice that you found the java library... to bad you didn't read the docs there.
I'll post some of the highlights below:
The existing code uses the 'Simple notification format' which does not return an error EVER.
See docs at:
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html
I've tried updating to the 'Enhanced notification format' which is supposed to return an error, but I'm unable to get any errors back from the APNS. (also in the link above)
With the Enhanced format, the connection isn't being dropped immediately after sending data, but I'm not getting anything back from my socket.getInputSocket.read() call.
This issue will have to be tabled until I have more time to troubleshoot.
(Someone else commented)
Thanks a lot for looking into it.
I got the same result as yours. Maybe it has something to do with Apple Gateway.
So... you could:
1) Build your own
2) Help improve the existing library
3) Try another library like: https://github.com/notnoop/java-apns
4) Do nothing
Enhanced ios push here.
To send a notification, you can do it in three steps:
Setup the connection
ApnsService service =
APNS.newService()
.withCert("/path/to/certificate.p12", "MyCertPassword")
.withSandboxDestination()
.build();
Create and send the message
String payload = APNS.newPayload().alertBody("Can't be simpler than this!").build();
String token = "fedfbcfb....";
service.push(token, payload);
To query the feedback service for inactive devices:
Map<String, Date> inactiveDevices = service.getInactiveDevices();
for (String deviceToken : inactiveDevices.keySet()) {
Date inactiveAsOf = inactiveDevices.get(deviceToken);
...
}

admob test ads appearing

I released my Android app two days ago, using admob advertising. I used my personal phone as the test phone, but took out the test mode code before releasing it. My admob status is active and I get requests and impressions on the report, but whenever I try to use the app on my personal phone i only get "test ads". I don't know why. I looked through the code of my app and can't find anything amiss. And i did delete the test version of the app and then download the released version from the market.
I'm not sure why the test ads are appearing in your app, but one way to shut them off is to go to your Admob App Settings, and choose the option "Disable test mode for all requests" as your Test Mode setting.
You customers would not have been seeing the debug ads. You probably have a line like:
AdManager.setTestDevices( new String[] {
AdManager.TEST_EMULATOR, // Android emulator
"E83D20734F72FB3108F104ABC0FFC738", // My T-Mobile G1 Test Phone
}
Assuming E83D20734F72FB3108F104ABC0FFC738 is you're personal phone, any time that phone makes a request it will get a test ad. All other phones will not be eligible for test ads, unless they are also individually added to that method.
Nick's answer works. (But is missing the final parenthesis.)
But what if I want to give my (not yet released) Android app out to 10 friends?
Is there any java code that says "treat ALL phones as test devices"?
Here is code for treat all devices as test devices:
String aid = Settings.Secure.getString(context.getContentResolver(), "android_id");
try {
Object obj;
((MessageDigest) (obj = MessageDigest.getInstance("MD5"))).update(aid.getBytes(), 0, aid.length());
aid = String.format("%032X", new Object[] { new BigInteger(1, ((MessageDigest) obj).digest()) });
} catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
aid = aid.substring(0, 32);
}
adRequest.addTestDevice(aid);

Categories