make multiple http post in android - java

hello i want to ask some question
i want to make application that connected with a web services that i made
my app has 2 uniqueID called app_id and token, app_id generate only once when the app first start and token generated by web service
every request, i must check whenever the token already expired or not, if the token already expired it will call separate web service and generate new token
the problem is the app must access 2 different web service: to request new token and to get another desired data
i use asynctask, but the response from web service for request token always same every request and i have no idea why
protected Boolean doInBackground(Void... params) {
int status = 0;
int token_expired=0;
String token_val = token.getToken(getBaseContext());
for(int i=0;i<5 && status==0;i++) {
try {
Thread.sleep(1000);
//function to check if token already expired or not and request new token using http post
token_expired = token.checkToken(getBaseContext());
System.out.println("token expired: " +token_expired);
if (token_expired==1 || token_expired==2) {
//function to call another web service and get a data from it
status = rclient.Execute("POST");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (status==0) {
return false;
}else{
return true;
}
}
thanks before!

oh yeah this is a function of check token from class token handler
public Integer checkToken(Context context) {
int status = 0; //0 = failed to request token , 1 = successfully request new token, 2 = token has not expired yet
String token_id = getToken(context);
System.out.println("token_id: " +token_id);
//if (token_id!=null) {
Long time = getTime(context);
Long curr_time = System.currentTimeMillis()/1000;
System.out.println("time before: " +time);
System.out.println("time current: " +curr_time);
Long interval = curr_time - time;
System.out.println("interval: " +interval);
if (interval>10) {
status = TokenGenerator(context);
}else {
status = 2;
}
//}
return status;
}
}
and this is a function to request new token from the same class
public synchronized Integer TokenGenerator(Context context) {
int status = 0;
SharedPreferences sharedPrefs = context.getSharedPreferences(TOKEN_STORAGE, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
try {
rclient.AddJSON("app_id", uniqueID);
rclient.CompileJSON();
} catch (JSONException e1) {
e1.printStackTrace();
}
try {
status = rclient.Execute("POST");
} catch (Exception e) {
e.printStackTrace();
}
if (status==1) {
String response = rclient.getResponse();
String token = null;
System.out.println("uuid_response: " +response);
try {
JSONObject json = new JSONObject(response);
token = json.getString("result");
} catch (JSONException e) {
e.printStackTrace();
}
Long tsLong = System.currentTimeMillis()/1000;
String ts = tsLong.toString();
System.out.println("time: " +ts);
Editor editor = sharedPrefs.edit();
editor.putString(TIMESTAMP, ts);
editor.putString(TOKEN_ID, token);
editor.commit();
}
return status;
}
so basically the rest client class called two times, first at class token handler to request a new token, and second from the activity itself

As per the code posted by you, I think rclient.Execute("POST") is used to get the data. But the below piece of code
if (token_expired==1 || token_expired==2) {
//function to call another web service and get a data from it
status = rclient.Execute("POST");
}
says that if the token is still alive you are trying to get the new token again.
I think the line status = rclient.Execute("POST"); should be replaced with the code to fetch the data from the server.

problem solved after i put constructor of rest client class in function

Related

How to verify that a string is JWT token?

In Java How can we verify that i given String is a JWT Token without using Signature?
I am using
try {
return (new JwtConsumerBuilder()).setVerificationKey(SECRET_KEY).build().processToClaims(token);
} catch (InvalidJwtException var4) {
throw new IOException("Failed to parse");
}
This works fine but I want to verify this without SECRET_KEY.
I Just want to verify whether it is a JWT token or not.
Here is an example to check the structure of the JWT. You only need to add the validations of the data that the JWT should carry
boolean isJWT(String jwt) {
String[] jwtSplitted = jwt.split("\\.");
if (jwtSplitted.length != 3) // The JWT is composed of three parts
return false;
try {
String jsonFirstPart = new String(Base64.getDecoder().decode(jwtSplitted[0]));
JSONObject firstPart = new JSONObject(jsonFirstPart); // The first part of the JWT is a JSON
if (!firstPart.has("alg")) // The first part has the attribute "alg"
return false;
String jsonSecondPart = new String(Base64.getDecoder().decode(jwtSplitted[1]));
JSONObject secondPart = new JSONObject(jsonSecondPart); // The first part of the JWT is a JSON
//Put the validations you think are necessary for the data the JWT should take to validate
}catch (JSONException err){
return false;
}
return true;
}
You can decode JWT from base64 and check necessarily field. Or simply check token, why you want verify it, It's not faster then simpy check it.
Try this one.
public static JSONObject getPayload(String jwt) {
try {
Base64.Decoder dec = Base64.getDecoder();
final String payload = jwt.split(SecurityConstants.SPLIT_SLASH)[PAYLOAD];
final byte[] sectionDecoded = dec.decode(payload);
final String jwtSection = new String(sectionDecoded, SecurityConstants.CODE_PAGE);
return new JSONObject(jwtSection);
} catch (final UnsupportedEncodingException e) {
throw new InvalidParameterException(e.getMessage());
} catch (final Exception e) {
throw new InvalidParameterException(SecurityConstants.ERROR_IN_PARSING_JSON);
}
}
Next You need to get from jwt body this part which is important for You eg.
JSONObject body = JWTUtils.getPayload(token);
String username = body.getString("username");

Is there a method to wait for a refreshed token in okhttp3 interceptor?

Recently I had to work with a big old project that uses Retrofit 1, okhttp3, jobManager and Picasso 2.71828
The application receives data from the server.
Interaction logic: the user logs in, receives the token, the refresh token. They are stored in the SharedPreferences with shHelper. With a token, he can send requests (somewhere he is in the url, and somewhere in the body), with the help of refresh token the user can get a new token if the session is reset or the token is rotten.
Authorization errors (401) are processed by the okhttp3 authenticator, which we managed to use with Picasso.
But there was a problem - Picasso if there are several pictures on the screen - sends several requests in succession, simultaneously or almost simultaneously, and since they all immediately receive the answer 401, if the token is rotten, the authenticator immediately sends the same number of requests for updating the token.
Is there some elegant way to wait for the token to be updated and then repeat the requests for the rest of the pictures? Now it happens as follows - having received an error 401, the token is reset to zero (token = "") and all other streams that fall into the authenticator checking if (token == "") execute Thread.sleep () and I am very dissatisfied with it
private Authenticator getAuthenticator() {
return (route, response) -> {
if (errorCount > 3){
return null;
}
if (response.request().url().toString().endsWith("/refreshToken")) {
Log.d(TAG, "getAuthenticator: " + "refreshToken");
PasswordRepeatActivity.start(context);
return null;
}
if (response.request().url().toString().endsWith("/auth")) {
String message = "Попробуйте позже";
try {
com.google.gson.Gson gson = Gson.builder().create();
ApiResponse apiError = gson.fromJson(response.body().string(), ApiResponse.class);
message = apiError.getMessage();
} catch (Exception e) {
e.printStackTrace();
}
throw new IOException(message);
}
String login = spHelper.getCurrentLogin();
Auth auth = spHelper.getAuth(login);
String token = auth.getToken();
HttpUrl oldUrl = response.request().url();
//if token is empty - repeat checking after some time
Log.d(TAG, "getAuthenticator: token ==" + token);
if (token != null && token.isEmpty()) {
boolean isEmpty = true;
while (isEmpty){
try {
Log.d(TAG, "Authenticator: sleeping...");
Thread.sleep(500);
String mToken = spHelper.getAuth(login).getToken();
if (mToken!= null && !mToken.isEmpty()){
isEmpty = false;
}
Log.d(TAG, "Authenticator: check if token is refreshed");
if (!mToken.isEmpty() && oldUrl.toString().contains("token") && !mToken.equals(oldUrl.queryParameter("token"))) {
Log.d(TAG, "Authenticator: token is valid, token: " + mToken);
return getRefreshedUrlRequest(mToken, oldUrl);
}
} catch (InterruptedException e) {
e.printStackTrace();
return response.request();
}
}
return response.request();
} else if (oldUrl.toString().contains("token") && !token.equals(oldUrl.queryParameter("token"))) {
Log.d(TAG, "Authenticator: token is valid, token: " + token);
return getRefreshedUrlRequest(token, oldUrl);
} else {
auth.clearToken();
spHelper.putAuth(login, auth);
String refreshToken = auth.getRefreshToken();
RefreshRequest refreshRequest = new RefreshRequest(refreshToken);
try {
AuthResponse refreshResponse = dataApi.refresh(refreshRequest);
errorCount = 0;
Auth newAuth = refreshResponse.getResponse();
spHelper.putAuth(login, newAuth);
Request request = response.request();
RequestBody requestBody = request.body();
String newToken = newAuth.getToken();
Log.d(TAG, "Authenticator: token refreshed, old token: " + token + " -> " + "new token : " + newToken);
if (oldUrl.toString().contains("token")) {
return getRefreshedUrlRequest(newToken, oldUrl);
}
if (requestBody != null
&& requestBody.contentType() != null
&& requestBody.contentType().subtype() != null
&& requestBody.contentType().subtype().contains("json")) {
requestBody = processApplicationJsonRequestBody(requestBody, newToken);
}
if (requestBody != null) {
Request.Builder requestBuilder = request.newBuilder();
request = requestBuilder
.post(requestBody)
.build();
} else {
LoginActivity.show(context);
}
return request;
} catch (RequestException e) {
AtlasPatienteLog.d(TAG, "Can't refresh token: " + e.getMessage());
return response.request();
}
}
};
}
I'm looking for ways after the first error 401 to send one request to refresh the token and wait for it with all other threads, and then send requests with a new token.
Besides waiting for the updated token in the authenticator, is there any way to simplify this code somehow? Now this method is about 100 lines long and every time it is necessary to change it - even reading and keeping logic in your head becomes a problem.
So, after some time and some tries I made the part of authenticator syncronized on some lock object. Now only one thread at the time can access authenticator. So, if token need to bs refreshed - it will be, and after refreshing all of the threads waiting for new token will repeat their calls with new token.
Thanks #Yuri Schimke for sharing very usefull information.
private Authenticator getAuthenticator() {
return (route, response) -> {
String responseUrl = response.request().url().toString();
if (responseUrl.endsWith("/refreshToken") ) {
Log.d(TAG, "getAuthenticator: " + "refreshToken");
PasswordRepeatActivity.start(context);
return null;
}
if (responseUrl.endsWith("/auth")) {
String message = "Попробуйте позже";
try {
com.google.gson.Gson gson = Gson.builder().create();
ApiResponse apiError = gson.fromJson(response.body().string(), ApiResponse.class);
message = apiError.getMessage();
} catch (Exception e) {
e.printStackTrace();
}
throw new IOException(message);
}
synchronized (LOCK) {
String login = spHelper.getCurrentLogin();
Auth auth = spHelper.getAuth(login);
String token = auth.getToken();
HttpUrl oldUrl = response.request().url();
if (oldUrl.toString().contains("token") && !token.equals(oldUrl.queryParameter("token"))) {
Log.d(TAG, "Authenticator: token is valid, token: " + token);
return getRefreshedUrlRequest(token, oldUrl);
} else {
String refreshToken = auth.getRefreshToken();
RefreshRequest refreshRequest = new RefreshRequest(refreshToken);
try {
AuthResponse refreshResponse = dataApi.refresh(refreshRequest);
Auth newAuth = refreshResponse.getResponse();
spHelper.putAuth(login, newAuth);
Request request = response.request();
RequestBody requestBody = request.body();
String newToken = newAuth.getToken();
Log.d(TAG, "Authenticator: token refreshed, old token: " + token + " -> " + "new token : " + newToken);
if (oldUrl.toString().contains("token")) {
return getRefreshedUrlRequest(newToken, oldUrl);
}
if (requestBody != null
&& requestBody.contentType() != null
&& requestBody.contentType().subtype() != null
&& requestBody.contentType().subtype().contains("json")) {
requestBody = processApplicationJsonRequestBody(requestBody, newToken);
}
if (requestBody != null) {
Request.Builder requestBuilder = request.newBuilder();
request = requestBuilder
.post(requestBody)
.build();
} else {
LoginActivity.show(context);
}
return request;
} catch (RequestException e) {
AtlasPatienteLog.d(TAG, "Can't refresh token: " + e.getMessage());
PasswordRepeatActivity.start(context);
return null;
}
}
}
};
}
With just OkHttp, you will generally need to handle this complexity in your app whether that is outside the call, in an Authenticator or inside a proactively authenticating Interceptor. Concurrency isn't handled for you in these cases either.
Discussed here
https://github.com/square/okhttp/issues/3714#issuecomment-350469364
Make sure to make a synchronous refresh call, as an async call may not have a free thread to execute on.
the answer from #swankjesse was that if you make a sync call in an
interceptor, then you are tying up a thread, but won't deadlock
because it doesn't need to grab another thread and doesn't hold a lock
during that time.
Some blogs on similar topics
https://objectpartners.com/2018/06/08/okhttp-authenticator-selectively-reauthorizing-requests/
https://medium.com/#sandeeptengale/problem-solved-2-access-token-refresh-with-okhttp-authenticator-5ccb798ede70
https://blog.coinbase.com/okhttp-oauth-token-refreshes-b598f55dd3b2

Passing text and multiple images as an array using okhttp

I am using Okhttp lib to send data to server. I want to set text and images in RequestBody. For uploading multiple image to server using Okhttp i follow this link. I have implemented that type of code in my app in another activity class and its work fine. I have checked this question that how to pass array in RequestBody.
My arrayList format is like this
blockList
{
block0
{
description0 = First block
image0 = {image1, image2}
video0 = videolink
disp_order0 = 0
block0 = 0
}
block1
{
description1 = second block
image1 = {image1,image2,image2}
video1 = videolink
disp_order1 = 1
block1 = 1
}
.....
}
My Requirement :-
Now i want to send multiple images as an array in single parameter. When i send first block then parameter names are description0,image0[],video1,disp_order and block0 and image0[] will contain first block images as array and same for other.
API is working fine because when i test in postman then i receive the data in server side. You can see in below..
Here is my java function that set the data in RequestBody and make a call to send that data on sever.
ProgressDialog pd;
private OkHttpClient client;
private void saveCastBoxOnServer(String castBoxTitle, String selectedCastBoxId, String selectedCategoryId,
String userId, String action, ArrayList<CastBoxBlock> blockList)
{
try
{
client = new OkHttpClient.Builder()
.retryOnConnectionFailure(true)
.build();
ArrayList<CastBoxBlock> blockArrayList = blockList;
int blockSize = blockArrayList.size();
MultipartBody.Builder multipartBuilderNew = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (int i = 0; i < blockSize; i++)
{
String description = blockArrayList.get(i).getBlockDescription();
String descriptionField = "description"+i;
multipartBuilderNew.addFormDataPart(descriptionField, description);
/**This is used for distribution of images and videos. After that set that
* Images and video in multipartBuilder.
**/
CastBoxBlock model = blockArrayList.get(i);
ArrayList<SelectedMediaModel> mediaModels = model.getSelectedMediaModelArrayList();
int mediaModelsSize = mediaModels.size();
String passingVideoUri = "";
String videoUri = "";
for (int j = 0; j < mediaModelsSize; j++)
{
String mediaType = mediaModels.get(j).getMediaType();
if (mediaType.equals(StringKeyConstant.mediaVideo))
{
videoUri = mediaModels.get(j).getMediaPath();
if (passingVideoUri.trim().length()==0){
passingVideoUri = videoUri;
}else{
passingVideoUri = passingVideoUri + "," + videoUri;
}
}
else if (mediaType.equals(StringKeyConstant.mediaImage))
{
String imagePath = mediaModels.get(j).getMediaPath();
File sourceFile = new File(imagePath);
/**Changes whether JPEG or PNG**/
final MediaType MEDIA_TYPE = MediaType.parse(
constant.getFileExt(imagePath).endsWith("png") ? "image/png" : "image/jpeg");
String imageName = System.currentTimeMillis() + j + "_block_img.jpg";
String imageField = "image"+i+"["+j+"]";
multipartBuilderNew.addFormDataPart(imageField,imageName,
RequestBody.create(MEDIA_TYPE, sourceFile));
}
}
/**This is used to set the {#videoUri} block of videos and send to sever**/
String videoField = "video"+i;
multipartBuilderNew.addFormDataPart(videoField, passingVideoUri);
/**This will set the {#display_order} in multipartBuilder**/
String displayOrderField = "disp_order"+i;
String displayOrder = blockArrayList.get(i).getBlockIndex();
multipartBuilderNew.addFormDataPart(displayOrderField, displayOrder);
/**This will set the {#block} value in multipartBuilder**/
String blockField = "block"+i;
String block = ""+i;
multipartBuilderNew.addFormDataPart(blockField, block);
}
pd = new ProgressDialog(activity);
pd.setCancelable(false);
pd.setMessage(getResources().getString(R.string.please_wait));
pd.show();
RequestBody formBody = multipartBuilderNew
.addFormDataPart("cast_title", castBoxTitle)
.addFormDataPart("user_id", userId)
.addFormDataPart("cast_box", selectedCastBoxId)
.addFormDataPart("category", selectedCategoryId)
.addFormDataPart("action", action)
.build();
Request request = new Request.Builder()
.url(ApiUtils.ADD_FETCH_USER_CAST)
.post(formBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "Get Api credential fail."+call.toString());
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException
{
try
{
if (pd != null){
pd.cancel();
pd.dismiss();
pd = null;
}
String castSavedResponse = response.body().string();
Log.i(TAG, "castSavedResponse = " + castSavedResponse);
}
catch (Exception e){
Log.e(TAG, "***Error : onResponse() method");
e.printStackTrace();
}
}
});
}
catch (Exception e){
Log.e(TAG, "***Error : saveCastBoxOnServer()");
e.printStackTrace();
}
}
Thanks in advance. If any one will help it would be very appreciate.
When i check your code then i note one things. I am no sure but i think you change your code on image[] place. you can just change your code as below. I hope this will help you and you got the solution.
Use this code
String imageField = "image"+i+"[]";
Instead of
String imageField = "image"+i+"["+j+"]";
when i passed simple images as an array in Okhttp then i do code as above. For uploading multiple images on server using Okhttp, i also follow this link as you follow.

Iphone emoji Unicode decode issue for push notification dispatch by APNs

My web service publish push notification to APNs and APNs send to destination IOS device.
When apns contain Unicode emoji on alert body push notification and Iphone os can't decode my Unicode emoji '\uD83D\uDE0A' app already kill.
Push notification show same '\uD83D\uDE0A', No emoji shown on banner notification bar on top.
Android application works fine by GCM dispatches push notification But IOS not support.
Iphone-Ios supports only this format '\ue415'
Here code that from ActiveMQ subscribe chat payload get into web-service
public void onPublish(UTF8Buffer topic, Buffer msg, Runnable ack) {
try {
String body = msg.utf8().toString();
if (logger.isInfoEnabled()) {
logger.info("MQTT connection.listener.onPublish(), msg Received ["
+ body + "]");
}
if (body.contains("\"cmd\":\"chat\"")
&& body.contains("\"is_sender_msg\":true")) {
QueueMgr.addToChatQueue(body); //Changed true to false
}
else if(body.contains("\"cmd\":\"msg_seen\"")){
QueueMgr.addToChatReadSeenQueue(body);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ack.run();
}
}
My code for create push notification on java
public static JSONObject constructePushJson(JSONObject jsonObject,String[] cloudkeyWithDevice) throws JSONException {
if(cloudkeyWithDevice[0] != null){
JSONObject pnAPIdata = new JSONObject();
if(cloudkeyWithDevice[1].equals("a") || cloudkeyWithDevice[1].equals("d")){
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_CMD, com.anyorg.constants.AppConstants.CMD_ANDROID_PUSH);
}
else{
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_CMD, com.anyorg.constants.AppConstants.CMD_IOS_PUSH);
}
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_APP_TOKEN, com.anyorg.constants.AppConstants.DEFAULT_APP_TOKEN);
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_DEVICE_TOKEN, cloudkeyWithDevice[0]);
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_USER_ID, jsonObject.getInt(com.anyorg.constants.AppConstants.FLD_TO_USER_ID));
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_DEVICE_ID, 0);
String alertMsg=StringEscapeUtils.unescapeJava(jsonObject.getString(com.anyorg.constants.AppConstants.FLD_BODY));
jsonObject.put(com.anyorg.constants.AppConstants.FLD_BODY,alertMsg);
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_ALERT_MSG, "AryaConnect: "+alertMsg);//(jsonObject.isNull("body")) ? jsonObject.getString("from_user_name")+": Sent a file" : jsonObject.getString("from_user_name")+": "+jsonObject.getString("body")
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_MSG, jsonObject);//jsonObject.getString(com.anyorg.constants.AppConstants.FLD_BODY)
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_CALLBACK_URL, callbackUrl);
pnAPIdata.put(com.anyorg.constants.AppConstants.MAC_ADDRESS_ID, jsonObject.getString("mobile_rec_id"));
return pnAPIdata;
}
else{
return null;
}
}
Publish to APNs code
public class ANSNotificationDispatcher implements NotificationDispatcher {
protected static final Logger logger = Logger
.getLogger(ANSNotificationDispatcher.class);
public static final String OS_NAME = AppConstants.OS_TYPE_IPHONE;
String keystore;
String password;
boolean production;
public ANSNotificationDispatcher() {
try {
keystore = AppConfig.getAPNKeystore();
password = AppConfig.getAPNKeystorePassword();
PushyAPNMgr.init(keystore, password, AppConfig.isAPNProdcution());
} catch (Throwable e) {
e.printStackTrace();
}
}
private void push(Payload payload, String token, String userId,
String deviceId) throws ConfigurationException,
DeviceUnregisteredException {
// QueueManager.addToIOsQueue(payLoad, token, userId, ivUserDeviceId);
long stime = System.currentTimeMillis();
try {
PushyAPNMgr.push(token, payload.toString());
if (logger.isInfoEnabled())
logger.info("push(): APN PN userId [" + userId
+ "], device id [" + deviceId + "] payoad [" + payload
+ "] Response time ["
+ (System.currentTimeMillis() - stime) + "]ms");
} catch (Exception e) {
e.printStackTrace();
throw new ConfigurationException();
}
}
public static Payload createComplexPayload(JSONObject jsonObject) {
PushNotificationPayload complexPayload = null;
try {
complexPayload = createPayload(jsonObject);
String msg = Common.getStringAsNull(jsonObject,
AppConstants.FLD_MSG);
if (!Common.isEmpty(msg)) {
complexPayload.addCustomDictionary(AppConstants.FLD_MSG, msg);
}
if (logger.isInfoEnabled()) {
logger.info("createComplexPayloadV2(): payload ["
+ complexPayload.getPayload().toString() + "]");
}
} catch (JSONException e) {
e.printStackTrace();
}
return complexPayload;
}
public void dispatch(JSONObject jsonObject, String jsonData)
throws NotificationException, DeviceUnregisteredException,
MultipleRegistartionIdException, ConfigurationException {
String deviceToken = Common.getStringAsNull(jsonObject,
AppConstants.FLD_DEVICE_TOKEN);
if (Common.isEmpty(deviceToken)) {
logger.error("dispatch(): device token is null, cmd [" + jsonData
+ "]");
return;
}
Payload payload = createComplexPayload(jsonObject);
String userId = Common.getStringAsNull(jsonObject,
AppConstants.FLD_USER_ID);
String deviceId = Common.getStringAsNull(jsonObject,
AppConstants.FLD_DEVICE_ID);
push(payload, deviceToken, userId, deviceId);
}
public static void handleInvalidTokeException(String token) {
}
public static void handleDeviceUnregisteredException(String token) {
}
}
Ios push notification managed by Ios OS
My Apache Catalina log
I am a web service cloud developer faceing this issue last one days for only Ios app. So please, if some body have knowledge or done before. please advise and refer me some idea.
Emoji in my push notifications link.
https://mixpanel.com/help/questions/articles/how-do-i-send-custom-parameters-like-emoji-in-my-push-notifications
Thanks
Finally, APNs issue resolve in (Ios app) on java web service code by this Unicode encode and decode process. (unescapeJava and escapeJava) from lib commons-lang-2.6.jar and class org.apache.commons.lang.StringEscapeUtils
emojiBytes = alertMsg.getBytes("UTF-8"); text = new String(emojiBytes, "UTF-8");
private static PushNotificationPayload createPayload(JSONObject jsonObject)
throws JSONException {
String alertMsg = Common.getStringUnicodeAsNull1(jsonObject,
AppConstants.FLD_ALERT_MSG);
byte[] emojiBytes=null;
String text=null;
try {
emojiBytes = alertMsg.getBytes("UTF-8");
text = new String(emojiBytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//String emojiAsString = new String(emojiBytes, Charset.forName("UTF-8"));
//System.out.println("#####alertMsg: "+text);
Integer badgeCnt;
if (jsonObject.has(AppConstants.FLD_BADGE_CNT)){
badgeCnt = Common.getIntegerAsNull(jsonObject,
AppConstants.FLD_BADGE_CNT);
}else{
badgeCnt = AppConstants.VAL_ZERO;
}
PushNotificationPayload payload = createPayload(badgeCnt, text);
return payload;
}
String alertMsg = Common.getStringUnicodeAsNull1(jsonObject,
AppConstants.FLD_ALERT_MSG);
public static String getStringUnicodeAsNull1(JSONObject jsonObject,
String key) {
try {
if(jsonObject.isNull(key))
return null;
else
return StringEscapeUtils.unescapeJava(jsonObject.getString(key));
} catch (JSONException je) {
return null;
}
}
Respected sir and ma'am, If there is any other solution of java APNs emoji Unicode on IOS Push Notification.
Then please give me some hints.Thanks
you shouldn't need to mess about with html decoding. As you say the code point for smiling face is \u263A. In PHP you can represent that in a UTF8-encoded string as "\xE2\x98\xBA"
Lightning bolt (actually 'high voltage sign') is \u26A1 or "\xE2\x9A\xA1" in UTF-8.
Both these characters are present in some non-emoji fonts as regular Unicode symbols. You can see with:
<?php
header('Content-type: text/html; charset=utf-8');
echo "\xE2\x9A\xA1";
echo "\xE2\x98\xBA";
or other things...
for the googlers. json_encode() adds double \
$message = "\ue04a";
$body['aps'] = array(
'alert' => $message,
'sound' => 'default',
'type' => $type,
'param' => $param
);
$payload = json_encode($body);
$payload = str_replace("\", "\\", $payload);
Please check with this two way... i think this is helpfull for you.

Thread contention in Asynctask

I'm having a thread contention issue when my program gets to executing an asynctask whose current purpose is to connect to an ftp server and based on a successful connection then make a get HTTP parsing request in order to access JSON data I need to write into a local SQLite database.
I'm slightly new in understanding thread contention but having read around particulalry this article I suspect it is a deadlock.
Below is my debug window which is called when I run my app. I'm doing so on a device and not an emulator:
Below is the asynctask code:
/**
* Background Async Task to Load all product by making HTTP Request
* */
class LoadAllProducts extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
//pDialog = new ProgressDialog(AllProductsActivity.this);
//pDialog.setMessage("Loading products. Please wait...");
Log.i("LoadAllProducts", "LoadAllProducts - Loading products. Please wait...");
//pDialog.setIndeterminate(false);
//pDialog.setCancelable(false);
//pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
Log.i("LoadAllProducts", "URL: " + url_all_products);
ftpConnectLoginAndUpload = new FTPConnectLoginAndUpload();
if(ftpConnectLoginAndUpload.execute()) {
// Check your log cat for JSON response
Log.d("LoadAllProducts ", "About to execute JSONObject json = jParser.makeHttpRequest(url_all_products, \"GET\", params);");
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);
// Check your log cat for JSON response
Log.d("LoadAllProducts ", json.toString());
/*try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_PRODUCTS); // products is a variable holding the value from the 2nd key-value pairing.
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
String price = c.getString("price");
String created_at = c.getString("created_at");
String updated_at = c.getString("updated_at");
Log.d("LoadAllProducts ", "JSON item var i.e. id:" + id);
Log.d("LoadAllProducts ", "JSON item var i.e. name:" + name);
Log.d("LoadAllProducts ", "JSON item var i.e. price:" + price);
Log.d("LoadAllProducts ", "JSON item var i.e. created_at:" + created_at);
Log.d("LoadAllProducts ", "JSON item var i.e. updated_at:" + updated_at);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_PID, id);
map.put(TAG_NAME, name);
// adding HashList to ArrayList
productsList.add(map);
}
} else {
// no products found
// Launch Add New product Activity
Intent i = new Intent(getApplicationContext(),
NewProductActivity.class);
// Closing all previous activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}*/
} else {
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
Log.i("LoadAllProducts", "LoadAllProducts - dismiss the dialog after getting all products");
// updating UI from Background Thread
/*runOnUiThread(new Runnable() {
public void run() {
//Updating parsed JSON data into ListView
ListAdapter adapter = new SimpleAdapter(
AllProductsActivity.this, productsList,
R.layout.list_item, new String[] { TAG_PID,
TAG_NAME},
new int[] { R.id.pid, R.id.name });
// updating listview
setListAdapter(adapter);
}
});*/
}
}
Below is the FTP log in code:
//!< FTP Connect, Login And Upload
public class FTPConnectLoginAndUpload {
//!<
private void showServerReply(FTPClient ftpClient) {
String[] replies = ftpClient.getReplyStrings();
if (replies != null && replies.length > 0) {
for (String aReply : replies) {
System.out.println("---> showServerReply(FTPClient ftpClient) - SERVER: " + aReply);
}
}
}
//!<
public boolean execute() {
// Boston's FTP login credentials
String server = "XX.XXX.XXX.XX";
int port = 21;
String user = "XXXXXXXX_XXXXXX";
String pass = "XXXXXXXX";
// Time out period after connection attempt
int timeOut = 5000;
boolean ftpResult;
// FTPClient encapsulates all the functionality necessary to store and retrieve files from an FTP server
// This class takes care of all low level details of interacting with an FTP server and provides a convenient higher level interface
FTPClient ftpClient = new FTPClient();
// Execute FTP process
try {
// Set connection timeout in milliseconds
ftpClient.setConnectTimeout(timeOut);
// Sets the timeout in milliseconds to use when reading from the data connection.
ftpClient.setDataTimeout(timeOut);
// Connect using provided server and port numb
ftpClient.connect(server, port);
System.out.println("\n---> ftpClient.connect(server, port) has been executed.\n---> Server used was "
+ server + " and port number used was: " + port);
System.out.println("\n---> ftpClient.getReplyString() returns: " + ftpClient.getReplyString());
// Returns server reply
System.out.println("\n---> Server reply is as follows:");
showServerReply(ftpClient);
System.out.println("---> End of server reply");
// Get server reply code
int replyCode = ftpClient.getReplyCode();
System.out.println("\n---> ftpClient replyCode is: " + replyCode);
// Determine if a reply code is a positive completion response. All codes beginning with a 2 are positive completion responses.
// The FTP server will send a positive completion response on the final successful completion of a command.
if (!FTPReply.isPositiveCompletion(replyCode)) {
System.out.println("\n---> Operation failed. Server reply code: " + replyCode);
ftpResult = false;
return ftpResult;
} else {
System.out.println("\n---> Operation successful. Server reply code: " + replyCode);
// Attempt login
boolean success = ftpClient.login(user, pass);
System.out.println("\n---> ftpClient.login(user, pass); has been called.");
// Determine log in success
if (!success) {
System.out.println("\n ---> Unable to login to the server");
ftpResult = false;
return ftpResult;
} else {
System.out.println("\n---> Successfully logged into server");
ftpResult = true;
}
//
ftpClient.enterLocalPassiveMode();
// Show server reply after logging in
System.out.println("\n---> Server response after logging in is as follows:");
showServerReply(ftpClient);
System.out.println("---> End of server response after logging");
return ftpResult;
}
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
ftpResult = false;
return ftpResult;
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
ftpResult = false;
return ftpResult;
}
} catch (IOException ex) {
ex.printStackTrace();
ftpResult = false;
return ftpResult;
}
}
}
}

Categories