Compress the image with base64 and send post from android to php - php

ByteArrayOutputStream bytearray = new ByteArrayOutputStream();
mBitmapProfile.compress(Bitmap.CompressFormat.JPEG, 100, bytearray);
String base64 = Base64.encodeToString(bytearray.toByteArray(), Base64.DEFAULT);
String data = URLEncoder.encode("SOURCE", "UTF-8") + "=" base64;
String result = getHttpData("http://example/p.php", data);
private String getHttpData(String httpUrl, String param) {
String urlString = httpUrl;
String data = param;
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
// urlConnection.setReadTimeout(DATARETRIEVAL_TIMEOUT);
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
wr.write(data);
wr.flush();
int responseCode = urlConnection.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
BufferedReader br=new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String response = "";
String line = "";
while ((line = br.readLine()) != null) {
response+=line;
}
return response;
}
} catch(MalformedURLException e){
e.printStackTrace();
return null;
} catch(IOException e) {
e.printStackTrace();
return null;
}
return "";
}
After base64 encoding the image
Using POST, making requests from Android to PHP will cause problems.
ex)
android send data : /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBA+BAQEBAQE==
php receive data : /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBABAQEBAQE
Some special characters are lost.
Why is that so?

The problem is that base64 encoded data can contain '+' characters. In x-www-form-urlencoded data the receiver knows that '+' is an encoding of a space character. Thus since you aren't URL encoding your base64 value, any instances of '+' will cause the data to be corrupted when received.

Related

BufferedReader UTF-8 BOM

I have a method in Java where I try to get one integer (user id) through a POST json request, this is the method:
public static Integer getUserIdOwnerOfMsg(Message msg) {
Integer idUser = null;
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("textMsg", msg.getTextMsg());
jsonObject.put("hourMsg", msg.getHourMsg());
List list = new LinkedList();
list.addAll(Arrays.asList(jsonObject));
String jsonString = list.toString();
String urlStr = SERVER_PATH + "getUserIdOwnerOfMsgJSON.php";
URL url = new URL(urlStr);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "your user agent");
con.setRequestProperty("Accept-Language", "sp,SP;q=0.5");
//con.setRequestProperty("Content-Type", "text/html; charset=UTF-8");
String urlParameters = "json=" + jsonString;
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
InputStream instream;
int status = con.getResponseCode();
if (status != HttpURLConnection.HTTP_OK)
instream = con.getErrorStream();
else
instream = con.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(instream, "UTF-8")); // ISO-8859-1
in.mark(1);
if(in.read() != 0xFEFF)
in.reset();
String inputLine;
StringBuilder response = new StringBuilder();
while((inputLine = in.readLine()) != null)
response.append(inputLine);
in.close();
JSONObject object = new JSONObject(response.toString());
Boolean correct = object.getBoolean("correct");
if (correct) {
idUser = object.getInt("id");
}
} catch (Exception e) {
e.printStackTrace();
}
return idUser;
}
The problem is that the response contains a UTF-8 BOM character, on postman the result it's ok and I can see the id: ({"id":"7","correct":true})
But debugging on android studio I got the value "" or null for idUser, I don't know why, I've tried so many ways to resolve this problem without succeed.
Also on the php server side I've executed echo mb_detect_encoding($idUsuario); and I got ASCII encoding in case that could help to find the solution.
Any help will be apreciated, thank you!
So finally I got the solution, I post it here in case someone have the same issue as me, the problem was with the parameters of the JSON, because they included UTF-8 characters like €, so instead of reading the parameters like this:
wr.writeBytes (urlParameters);
I have to do this:
byte[] buf = urlParameters.getBytes("UTF-8");
wr.write(buf, 0, buf.length);
I post also the complete function in case someone needs it:
public static Integer getUserIdOwnerOfMsg(Message msg) {
Integer idUser = null;
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("textMsg", msg.getTextMsg());
jsonObject.put("hourMsg", msg.getHourMsg());
List list = new LinkedList();
list.addAll(Arrays.asList(jsonObject));
String jsonString = list.toString();
String urlStr = SERVER_PATH + "getUserIdOwnerOfMsgJSON.php";
URL url = new URL(urlStr);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "your user agent");
con.setRequestProperty("Accept-Language", "sp,SP;q=0.5");
String urlParameters = "json=" + jsonString;
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream (con.getOutputStream());
byte[] buf = urlParameters.getBytes("UTF-8");
wr.write(buf, 0, buf.length);
wr.flush();
wr.close();
InputStream instream;
int status = con.getResponseCode();
if (status != HttpURLConnection.HTTP_OK)
instream = con.getErrorStream();
else
instream = con.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(instream, Charset.forName("UTF-8")),8192);
String inputLine;
StringBuilder response = new StringBuilder();
while((inputLine = in.readLine()) != null)
response.append(inputLine);
JSONObject object = new JSONObject(response.toString());
Boolean correct = object.getBoolean("correct");
if (correct) {
try {
String idUserText = object.getString("id");
idUser = Integer.valueOf(idUserText);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
return idUser;
}
That's all, happy coding!

Base64 encoding product different result

I am working on android project which can upload image from user's phone galery. The method i use to upload the image is to encode the image to base64 in android and send it to PHP files on server, then the PHP file decodes it then put it on server.
But the problem is the result of PHP decoding is different with the original image. Although the image is still working, but i am afraid sometimes it's gonna be a bug :D..
How to solve it?
Class UploadImageCatalog
#Override
protected String doInBackground(String... params) {
String urlAPI = params[0];
String id = params[1];
String imageByte = params[2];
try {
URL url = new URL(urlAPI);
HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
urlCon.setReadTimeout(15000);
urlCon.setConnectTimeout(15000);
urlCon.setDoOutput(true);
urlCon.setRequestMethod("POST");
OutputStream os = urlCon.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
String postData = URLEncoder.encode("id", "UTF-8")+"="+URLEncoder.encode(id, "UTF-8")+"&"+
URLEncoder.encode("imageByte", "UTF-8")+"="+URLEncoder.encode(imageByte, "UTF-8");
bw.write(postData);
bw.flush();
bw.close();
osw.close();
os.close();
urlCon.connect();
int responseCode = urlCon.getResponseCode();
if (responseCode == HTTP_OK) {
InputStream is = urlCon.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String responseString = br.readLine();
br.close();
isr.close();
is.close();
return responseString;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Method getStringImage()
private String getStringImage(Bitmap bmp){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
return Base64.encodeToString(imageBytes, Base64.DEFAULT);
}
Mehthod to upload image
btSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (updateImage) {
new UploadImageCatalog(ViewProductActivity.this)
.execute(SERVER_URL+"/project/katalogmukenalukis/uploadimage.php",
String.valueOf(idToView), getStringImage(imageLoadedBitmap));
} else {
updateData();
}
}
});
uploadimage.php
<?php
$id = $_POST['id'];
$imageByte = $_POST['imageByte'];
$target = __DIR__."/asset/".$id;
if (file_exists($target)) {unlink($target);}
if (file_put_contents($target, base64_decode($imageByte))) {
echo json_encode(array("success" => true));
} else {
echo json_encode(array("success" => false, "message" => ""));
}
?>

My android decode doesn't work with php encode

I'm wondering what the format of a json is suppose to be since it seems php and android has two different types.
When encode the php, it looks like this:
{"id":8435,"name":"Sears"}
{"id":8436,"name":"Sears Appliance Services"}
But when I try to decode in android. It comes out as one big string in android (because it's just viewing the source code of the php page).
This is the code:
Php:
echo json_encode($results[$i]);
Android:
url = new URL("site");
String param = "arg1=" + URLEncoder.encode("value1", "UTF-8");
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setFixedLengthStreamingMode(param.getBytes().length);
conn.setRequestProperty("Content-Type","application/x-www-form- urlencoded");
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.close();
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String s;
while ((s = reader.readLine()) != null) {
result += s;
}
JSONObject jObject = new JSONObject(result);

gzip compression in android app as client and php server

In my android app i want to send compressed data to php server using gzip compression and receive response from the server and decompress the response if it is compressed. But when i am sending compressed data,server is getting null and not the data which i am sending and it is returning error message.
This is code i am using for compression--
public static String compress(String strData) throws Exception
{
ByteArrayOutputStream obj = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(obj);
gzip.write(strData.getBytes("UTF-8"));
gzip.close();
String outStr = obj.toString("UTF-8");
return outStr;
}
This is the code used for decomprssion---
public static String decompress(String str) throws Exception
{
byte[] bytes1 = str.getBytes("UTF-8");
GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes1));
BufferedReader bf = new BufferedReader(new InputStreamReader(gis, "UTF-8"));
String outStr = "";
String line;
while ((line=bf.readLine())!=null) {
outStr += line;
}
return outStr;
}
And I also add a header to httppost request
httpPost.addHeader("Accept-Encoding", "gzip, deflate");
can anyone please tell me what to do if I want to compress data before sending to server and also receive response and decompress it, if it is compressed.
public static void main() {
String myString = "H4sIAAAAAAAAA5WMuwrCMBSGX0XOnCFpLoZ0ExH0FaTDyU0DTVsSB6H03Y3dHN3+67fCgm8wjAA6dz2DASmjUsjRCs8tahu5FCw6DQQmzKEt";
byte[] decode = Base64.decode(myString, Base64.NO_WRAP);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decode);
int read;
try {
GZIPInputStream gzipInputStream = new GZIPInputStream(byteArrayInputStream);
BufferedReader br = new BufferedReader(new InputStreamReader(gzipInputStream));
System.out.println("read222 :" + br.readLine());
DataInputStream dataInputStream = new DataInputStream(gzipInputStream);
//System.out.println("read222 :" + dataInputStream.retoString());
for (int i = 0; i < decode.length; i++) {
read = dataInputStream.readInt();
int rRead = Integer.reverseBytes(read);
System.out.println("read :" + dataInputStream.read());
}
} catch (IOException e) {
e.printStackTrace();
}
}
run your code in a thread or asynctask or service whereever you want
Thread thread=new Thread(new Runnable()
{
#Override
public void run()
{
try
{
String body = "Naval is working on zip and unzip processed return json";
URL url = new URL("http://yourServerUrl/yourgzip.php");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-encoding", "gzip");
conn.setRequestProperty("Content-type", "application/octet-stream");
GZIPOutputStream dos = new GZIPOutputStream(conn.getOutputStream());
dos.write(body.getBytes());
dos.flush();
dos.close();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder builder=new StringBuilder();
String decodedString = "";
while ((decodedString = in.readLine()) != null)
{
builder.append(decodedString);
}
in.close();
Log.e("Data", builder.toString());
}
catch (Exception e)
{
Log.e("Datae", builder.toString());
}
}
});
thread.start();
on server side ask them to use this code
$postdata=gzinflate( substr($HTTP_RAW_POST_DATA,10,-8) );
as $HTTP_RAW_POST_DATA deprecated so use file_get_contents() like to return array
$post = array_map('urldecode',explode('&',file_get_contents("php://input")));
or like this method to decompress a gzip stream that was pushed to my webserver
$x = file_get_contents("compress.zlib://php://input");
and using
$data_as_associate_Array=json_decode($x,true);

return JSON and parse in java, android

I am returning a JSON string from PHP:
<?php
$results = array(
"result" => "success",
"username" => "some username",
"projects" => "some other value"
);
echo json_encode($results);
?>
I found a java example online that works. It uses StringBuilder and outputs the response using Toast. I want to actually parse it as a JSON object so I can reference each key=>value, but not sure how to do it. This is the example I am using:
private void tryLogin(String usernameInput, String passwordInput)
{
HttpURLConnection connection;
OutputStreamWriter request = null;
URL url = null;
String response = null;
String parameters = "username=" + usernameInput + "&password=" + passwordInput;
try
{
url = new URL(getString(R.string.loginLocation));
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestMethod("POST");
request = new OutputStreamWriter(connection.getOutputStream());
request.write(parameters);
request.flush();
request.close();
String line = "";
InputStreamReader isr = new InputStreamReader(connection.getInputStream());
BufferedReader reader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
response = sb.toString();
Toast.makeText(this, "Message from server: \n" + response, 0).show();
isr.close();
reader.close();
}
catch(IOException e)
{
Log.i("NetworkTest","Network Error: " + e);
}
}
This is what the code currently returns:
05-04 19:19:54.724: INFO/NetworkTest(1061): {"result":"success","username":"rondog","projects":"1,2"}
Just to be clear, I am pretty sure I know how to parse the string. What I am confused on is getting the response back from the server and pushing that to the JSONObject (or is 'response' the object that I pass?). Any help is appreciated, thanks!
(or is 'response' the object that I pass?)
Yes, it is. It expects a string object in it's constructor to parse it.

Categories