Arabic text display issues - java

Volley response is not showing the Arabic character ف
Instead of this character I'm getting a diamond question mark � .
All the other characters are showing properly, I don't know the what is happening with this character alone.Is it the problem of volley web service?
Any help appreciated.
final RequestQueue requestQueue = Volley.newRequestQueue(Register.this);
String url = Config.url + "validateID";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
response = response.trim();
if (response != null) {
try {
response = new String(response.getBytes(), "UTF-8");
response = Html.fromHtml(response).toString();
response = fixEncodingUnicode(response);
System.out.println("######utf####" + response);
try {
JSONObject jsonObject = new JSONObject(response);
String respCode = jsonObject.getString("responseCode");
String status = jsonObject.getString("status");
if (respCode.equals("200") && status.equals("ACTIVE")) {
ed_full_name.setText(jsonObject.getString("name"));
ed_full_name_arabic.setText(jsonObject.getString("namearabic"));
}
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
}
public static String fixEncodingUnicode(String response) {
String str = "";
try {
str = new String(response.getBytes("windows-1254"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String decodedStr = Html.fromHtml(str).toString();
return decodedStr;
}

I am afraid the patching code from a wrong encoding to a correct encoding cannot guarantee all characters survive the process. The main principle in java is that String always holds Unicode text; so there always is a conversion to bytes representing text in some encoding.
response = new String(response.getBytes(), "UTF-8");
This is wrong. getBytes() without charset uses the default charset from the platform which runs the current application. So it has a different effect on your development Windows PC and the production Linux server. Any effect is totally misleading.
response = Html.fromHtml(response).toString();
This encodes HTML entities. In a request a sign then the <form> is missing an accept-encoding="UTF-8". Part of the request headers. Then the browser sends non-Latin as HTML entities.
Here it might be a communication failure between layers, where the request part is missing a UTF-8 accepting header.
response = fixEncodingUnicode(response); or str = new String(response.getBytes("windows-1254"), "UTF-8");
Unneeded as String in java already is in Unicode. It would introduce a diamond whenever a Unicode symbol was not translatable in Windows-1254.
So all seems wrong. The error seems to be made earlier on.
Correct the requests, as otherwise a correct request might give wrong results. Go for UTF-8 rather than Windows-1254.
You can dump, log the bytes if the input parameter response, with something like:
Arrays.toString(response.codePoints().toArray())
(A hexadecimal format would be more readable.)

As #Joop Eggen said, no need of html and Windows-1254 encoding. Just use the default enocding of Volley that is ISO-8859-1.
response = new String(response.getBytes("ISO-8859-1"), "UTF-8");
complete code is below.
final RequestQueue requestQueue = Volley.newRequestQueue(Register.this);
String url = Config.url + "validateID";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
response = response.trim();
if (response != null) {
try {
response = new String(response.getBytes("ISO-8859-1"), "UTF-8");
try {
JSONObject jsonObject = new JSONObject(response);
String respCode = jsonObject.getString("responseCode");
String status = jsonObject.getString("status");
if (respCode.equals("200") && status.equals("ACTIVE")) {
ed_full_name.setText(jsonObject.getString("name"));
ed_full_name_arabic.setText(jsonObject.getString("namearabic"));
}
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
}

Related

How to implement a post method for Imgflip API

I am trying to create an app on android studio and im new to this IDE and language. I managed to implement the GET method for Imflip api, but im stuck on the POST method. I would like to return an Meme with a caption added by the user.
Im using Android Studio 3.4.1. I've tried the code attached. For testing purposes, i've hardcoded the username, password, and two captions. Also, when i call POST() I pass the id 61579 as a parameter. I've tried finding he value for the response but it says that its "200"...
What i need is a url for the created meme.
Hope anyone can help.
Thanks in Advance.
private void POST(String memeID) {
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "https://api.imgflip.com/caption_image";
JSONObject jsonBody = new JSONObject();
jsonBody.put("template_id", memeID);
jsonBody.put("username", "Meme_Genie");
jsonBody.put("password", "Password");
jsonBody.put("text0", "Hello");
jsonBody.put("text1", "World");
final String requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
}
Switching from encode = "json" to encode = "form"
Or switching your body to BodySerializationMethod.UrlEncoded will work

Send JSON Object in POST request from Android Volley receive java restful webservices

I want small example to send JSON object in POST request from android volley and it has to receive Java Restful Webservices
You can use the following working sample code. Hope this helps!
...
try {
RequestQueue queue = Volley.newRequestQueue(this);
jsonBody = new JSONObject();
jsonBody.put("Title", "VolleyApp Android Demo");
jsonBody.put("Author", "BNK");
jsonBody.put("Date", "2015/08/26");
requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(1, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
textView.setText(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
textView.setText(error.toString());
}
}) {
#Override
public String getBodyContentType() {
return String.format("application/json; charset=utf-8");
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
requestBody, "utf-8");
return null;
}
}
};
queue.addToRequestQueue(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
Moreover, can you clarify what does it has to receive Java Restful Webservices mean? My above request receives String value.

How to send json from android to php?

To post json from android to php, i used Volley library StringRequest object.
StringRequest sr = new StringRequest(Request.Method.POST,url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// some code
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//some code
}
}){
#Override
protected Map<String,String> getParams(){
Map<String, String> params = new HashMap<String, String>();
ArrayList<Command> commands = MyApplication.readFromPreferences(getActivity(), Constants.COMMAND);
String jsonCommands = new Gson().toJson(commands);
params.put("commands", jsonCommands);
return params;
}
};
And to catch the data in php and verify if it was sent correcttly, I used this
echo $_POST["commands"];
Output:
[{\"product\":{\"category_id\":1,\"created_at\":\"2015-06-13 17:49:58\",\"description\":\"CF77 COIN FINDER\",\"url_image\":\"IMG_76ECDC-707E7E-70AC81-0A1248-4675F3-F0F783.jpg\",\"name\":\"CF77 COIN FINDER\",\"pid\":12,\"price\":500.0},\"product_quantity\":3},{\"product\":{\"category_id\":1,\"created_at\":\"2015-06-13 17:49:58\",\"description\":\"JEOSONAR 3D DUAL SYSTEM\",\"url_image\":\"IMG_2D9DF0-2EB7E9-ED26C0-2C833B-B6A5C5-5C7C02.jpg\",\"name\":\"JEOSONAR 3D DUAL SYSTEM\",\"pid\":15,\"price\":500.0},\"product_quantity\":1},{\"product\":{\"category_id\":1,\"created_at\":\"2015-06-13 17:49:58\",\"description\":\"MAKRO POINTER\",\"url_image\":\"IMG_Macro.jpg\",\"name\":\"MAKRO POINTER\",\"pid\":18,\"price\":500.0},\"product_quantity\":3}]
I have noticed that when sending the json string with POST Method using Volley library, a lot of anti-slashes have been added to escape double quotes.
So here comes my problem:
I want to decode json to an array of objects in php, so i used
$commands = json_decode( $_POST["commands"],true);
But it always returns an empty array because of the invalide above json (caused by the anti-slashes).
Is there a method in php or in java SDK providing a contract for sending and receiving json without having this kind of problems? Or should i reformat the json in php and delete all the anti-slashes?
The problem is that you try to send the json data in the URL parameters.
You need to override the getBody() method to return the json data as request body, not as url parameters.
Eg:
/**
* Returns the raw POST or PUT body to be sent.
*
* #throws AuthFailureError in the event of auth failure
*/
public byte[] getBody() throws AuthFailureError {
return new Gson().toJson(commands).getBytes();
}
And then in PHP you can:
$jsonRequest = json_decode(stream_get_contents(STDIN));
first there is problem with the json itself is not build correctly is better to JSONObject for this, for example:
JSONObject js = new JSONObject();
try {
js.put("value",10);
} catch (JSONException e) {
e.printStackTrace();
}
String jss = js.toString();
you can check if the parse is success by copy the string and copy it in online parser like this http://json.parser.online.fr/
Finally, I solved my problem using a custom json_decode method in order to clean the json string before decoding it.
function json_clean_decode($json, $assoc = false, $depth = 512, $options = 0) {
// search and remove comments like /* */ and //
$json = preg_replace("#(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|([\s\t]//.*)|(^//.*)#", '', $json);
// search and remove all backslashes
$json = str_replace("\\","", $json);
if(version_compare(phpversion(), '5.4.0', '>=')) {
$json = json_decode($json, $assoc, $depth, $options);
}
elseif(version_compare(phpversion(), '5.3.0', '>=')) {
$json = json_decode($json, $assoc, $depth);
}
else {
$json = json_decode($json, $assoc);
}
return $json;
}
You can use this method to send json to web service.
public String makeServiceCallSubmit(String url, int method,
JSONArray object) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-type", "application/json");
StringEntity se = new StringEntity(object.toString());
// se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httpPost.setEntity(se);
httpResponse = httpClient.execute(httpPost);
}
httpEntity = httpResponse.getEntity();
Response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return Response;
}

How to do a Volley PUT to a drupal table

I'm attempting to do a PUT in x-www-form-urlencoded to a drupal table with Volley from my Android app. I'm try to send a 'type' and 'value', in the params and I get a 500 error. A basic StringRequest returns 404.
Here's my latest code. I've only found one or two entries that touch on the Volley Put. Any help would be appreciated. Have a great day.
private void postTestAnswerResult(String id, String answerResult) {
StringRequest req = null;
requestQueue = Volley.newRequestQueue(this);
final String baseURL = "http://blah.blah.com/api/answer/";
String URL = baseURL + id;
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("Content-Type","application/x-www-form-urlencoded");
params.put("type", answerResult);
req = new StringRequest(Request.Method.PUT, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.v("Response:%n %s", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
try {
String responseBody = new String(
volleyError.networkResponse.data, "utf-8");
JSONObject jsonObject = new JSONObject(responseBody);
} catch (JSONException e) {
// Handle a malformed json response
} catch (UnsupportedEncodingException error) {
}
}
}
);
requestQueue.add(req);
}
In case you are still having problems with this, as #Meier points out in a comment above, you are not using the params variable, or rather you aren't using it correctly. The data doesn't get sent to the server, and the server is probably expecting the data resulting in the 500 error.
You need to override the getParams method of the StringRequest call in order to send the data. So, the following would be closer to getting the job done:
private void postTestAnswerResult(String id, String answerResult) {
StringRequest req = null;
requestQueue = Volley.newRequestQueue(this);
final String baseURL = "http://blah.blah.com/api/answer/";
String URL = baseURL + id;
req = new StringRequest(Request.Method.PUT, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.v("Response:%n %s", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
try {
String responseBody = new String(
volleyError.networkResponse.data, "utf-8");
JSONObject jsonObject = new JSONObject(responseBody);
} catch (JSONException e) {
// Handle a malformed json response
} catch (UnsupportedEncodingException error) {
}
}
}
) {
#Override
protected Map<String, String> getParams()
{
HashMap<String, String> params = new HashMap<String, String>();
// params.put("Content-Type","application/x-www-form-urlencoded"); This shouldn't be here. This is a HTTP header. If you want to specify header you should also override getHeaders.
params.put("type", answerResult);
return params;
}
};
requestQueue.add(req);
Browser don't ignore 500 errors. They very often show up as ugly messages in the browser window.

Android Https OAuth 401 Unauthorized error

private void login() {
androidID = Secure.getString(MainActivity.this.getContentResolver(), Secure.ANDROID_ID);
String uP = androidID.concat(":ClientTrustedSecret");
byte[] authByteAry = null;
try {
authByteAry = uP.getBytes("UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
String base64 = Base64.encodeToString(authByteAry, Base64.DEFAULT).trim();
client.addHeader("Authorization", "Basic ".concat(base64));
// Following format is required to post to OAuth
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("grant_type", "password");
jsonObject.put("username", "abc");
jsonObject.put("password", "abc");
} catch (JSONException e1) {
e1.printStackTrace();
}
String contentType = "application/json; charset=UTF-8";
StringEntity data = null;
try {
// Send the json to the server
data = new StringEntity(jsonObject.toString());
client.post(MainActivity.this, baseURL.concat("/tokens"), data, contentType, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
oauthAccessTokenString = jsonObject.get("access_token").toString();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t, String err) {
System.out.println("login failed");
}
});
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
The above is how I login. And when making another web serivce call I get the unauthorized. The unlock method requires the following headers.
http://i.imgur.com/EaWDO.png
private void unlock()
{
AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
asyncHttpClient.addHeader("Locale", "en_US");
asyncHttpClient.addHeader("X-Originator-Type", "app");
asyncHttpClient.addHeader("Content-Type", "application/json");
// asyncHttpClient.addHeader("Connection", "Keep-Alive");
// asyncHttpClient.addHeader("X-Device-Id", androidID);
// asyncHttpClient.addHeader("X-via", deviceId);
// asyncHttpClient.addHeader("ClientID", "abc#abc.com");
asyncHttpClient.addHeader("Authorization", "Bearer ".concat(oauthAccessTokenString));
asyncHttpClient.get("host/users?loginName=abc#abc.com", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
System.out.println(response);
}
#Override
public void onFailure(Throwable t, String err) {
System.out.println("Unlock server call failed");
Log.d("printing error: ", err);
}
});
}
Above code throws 401 unauthorized exception. No references in documentation which I have, to call back url. I am providing the oauth access token just fine, but then why is it that I still get 401? Does the secret has anything to do with the second call? I am told is that I need to set up my headers that way. I am also told that "For https, the client needs to be able to handle the validation of the certificate. Does anyone knows how to solve it?
It was a wrong web service address :( There was no need to handle the validation of the certificate. There was nothing about call back url. The secret had nothing to do. But the documentation that I have is very poorly written, at one place they mentioned only the headers and then in another place they say body is required is well. So just make sure you go through the documents properly.

Categories

Resources