I am sending images from a server script using image/jpeg type response. Here is the server code (php using CodeIgniter):
$file = file_get_contents("http://www.menucool.com/slider/prod/image-slider-5.jpg");
$this->output->set_header("Content-Type: image/jpeg; charset=UTF-8");
$this->output->set_header("HTTP/1.1 200 OK");
$this->output->set_header("Accept-Charset", "utf-8");
$this->output->set_header("Accept-Encoding", "");
$this->output->set_output($file);
And this script sends the image to android, where I try to decode using the following script:
Log.e("response",response);
try {
String decompressedResponse = decompress(response.getBytes("UTF-8"));
InputStream instream = new ByteArrayInputStream(decompressedResponse.getBytes("UTF-8"));
Log.e("inputstream",instream.toString());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
try {
while ((len = instream.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
baos.close();
} catch (IOException e) {
}
byte[] b = baos.toByteArray();
Log.e("bytearray",b.toString());
imageBitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
image.setImageBitmap(imageBitmap);
} catch (UnsupportedEncodingException e) {
Log.e("UnsupportedEcondingEception","UNSUPPORTEDENCODINGEXCEPTIOn");
} catch (IOException e1) {
return;
}
Logcatting the response shows characters like this:
���8�#
The really weird thing here is that if I call this script from a web browser, it displays the image but apparently android and eclipse cannot decode this encoding.
I think it is an android problem rather than the server's. Any suggestions, hints are really appreciated as I have been stuck for a while.
Related
I am trying to build a packet, with DatagramPacket, and then send it using DatagramSocket and retrieve an answer from the remote server.
after running this code on my MainActivity through my device, I just get a blank page, looks like it is "stuck" while trying to receive an answer from the server but nothing happens:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ByteArrayOutputStream message = null;
ByteArrayOutputStream headerStream = new ByteArrayOutputStream();
try {
message = new ByteArrayOutputStream();
outputStream.write(intToByteArray(0)); // flags
outputStream.write("08".getBytes()); // client type
outputStream.write(intToByteArray(0)); // min version
outputStream.write(intToByteArray(2)); // max version
byte[] payload = outputStream.toByteArray();
byte[] packettypeIdByte = "DD00".getBytes(); // packet type
headerStream.write(packettypeIdByte);
headerStream.write(intToByteArray(payload.length));
headerStream.write(intToByteArray(0)); // version
byte[] header = headerStream.toByteArray();
message.write(header);
message.write(payload);
} catch (IOException e) {
e.printStackTrace();
}
try {
// for discover
InetAddress ip = InetAddress.getByName("XX.XX.XX.XX");
DatagramPacket packet = new DatagramPacket(message.toByteArray(), message.toByteArray().length);
int port = XXXX
DatagramSocket ds = new DatagramSocket(port);
ds.receive(packet);
String str = new String(packet.getData(), 0, packet.getLength());
Log.d("pac", str);
} catch (IOException e) {
e.printStackTrace();
}
any ideas what am I doing wrong? or what is the proper way for using datagramPacket and datagramSocket?
I am facing problem while trying to upload a zip file containing images converted into byte array to a restful wcf service from a json client using HTTPPost. The byte array is encoded into BASE64 enclosed into JSON object and sent using StringEntity with 2 more parameters. Around 6KB of file gets uploaded without any flaws but file more than 6KB are not send and I get a Bad Request - 400 status code. Following code is used to upload the file:
File file = new File(dir, "file.zip");
byte[] buf = new byte[10240000];
fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
Log.v("read : buf ", buf + " : " + readNum + " bytes");
}
byte[] bytes = bos.toByteArray();
imgData = Base64.encodeToString(bytes, Base64.DEFAULT);
JSONObject sendData=null;
Log.d("Image Data length", imgData.length()+"");
Log.d("Image data ", imgData);
try {
sendData= new JSONObject();
sendData.put("_binaryData", imgData);
sendData.put("_fileName", "fileName");
sendData.put("userid", userID);
int len = imgData.length();
int l=sendData.toString().length();
entity = new StringEntity(sendData.toString());
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Send request
int len = imgData.length();
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
request.setHeader("Connection", "Keep-Alive");
request.setParams(httpParameters);
DefaultHttpClient httpClient = new DefaultHttpClient();
request.setEntity(entity);
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
String str=response.getStatusLine().getReasonPhrase();
int i=response.getStatusLine().getStatusCode();
Log.v("ReasonPhrase :: StatusCode",str+" "+i);
int contentLength = (int) responseEntity.getContentLength();
char[] buffer = new char[(int) responseEntity
.getContentLength()];
InputStream stream = responseEntity.getContent();
Please help me in solving this.
If a message with <6k bytes does through, but messages with >6k don't, I'd take a look at the client and host limits for things like:
MaxBufferSize
MaxBufferPoolSize
MaxReceivedMessageSize
You don't say whether or not you have control over the host server settings, but you can increase and decrease the limits on items like those mentioned earlier. You can set them to Integer.Max if necessary, a size that would allow file uploads > 1 GB.
#Override
public void run() {
URL imgurl;
int Read;
try {
imgurl = new URL(ServerUrl);
HttpURLConnection conn = (HttpURLConnection) imgurl.openConnection();
int len = conn.getContentLength();
Log.d("check", "ContentLength:" + len);
Log.d("check", "ServerUrl:" + ServerUrl);
Log.d("check", "LocalPath:" + LocalPath);
byte[] tmpByte = new byte[len];
InputStream is = conn.getInputStream();
File file = new File(LocalPath);
FileOutputStream fos = new FileOutputStream(file);
for (;;) {
Read = is.read(tmpByte);
if (Read <= 0) {
break;
}
fos.write(tmpByte, 0, Read);
}
is.close();
fos.flush();
fos.close();
conn.disconnect();
} catch (MalformedURLException e) {
ut.CalltoAlertDialog_ok(getString(R.string.alert), getString(R.string.setting_skin_downloadfail));
} catch (IOException e) {
ut.CalltoAlertDialog_ok(getString(R.string.alert), getString(R.string.setting_skin_downloadfail));
}
mAfterDown.sendEmptyMessage(0);
}
This is file download source.
This code prints error "NegativeArraySizeException" from here
byte[] tmpByte = new byte[len];
So, I checked len's value.
len's value was -1.
But..
When i created yesterday, This code was not print error.
I have 2 apk file.
The apk created yesterday is not a problem. Even now this apk is no problem.
But, The apk created today is problem.
I did not modify anything.
What is the cause of this?
I think your problem is here:
HttpURLConnection conn = (HttpURLConnection) imgurl.openConnection();
int len = conn.getContentLength();
Read documentation about the getContentLength method
Returns the content length in bytes specified by the response header
field content-length or -1 if this field is not set.
Returns the value of the response header field content-length.
So this case that getContentLength returned -1 seems to have happened to you. Then you use this -1 to set your Array size. => Exception thrown
Check the solution of this question about getContentLength returning -1, maybe you will have to do something similar.
But at least you will have to check that len > 0 before setting your array size
Here's the code:
private void sendFile(InputStream file, OutputStream out) throws IOException {
Log.d(TAG, "trying to send file...");
final int buffer_size = 4096;
try {
byte[] bytes = new byte[buffer_size];
while(true) {
int count = file.read(bytes, 0, buffer_size);
if (count == -1) {
break;
}
out.write(bytes, 0, count);
Log.d("copystream", bytes + "");
}
} catch (Exception e) {
Log.e("copystream", "exception caught while sending file... " + e.getMessage());
}
}
I'm trying to send a large File (InputStream file) over an output stream (OutputStream out). This code works for smaller files, but for something like 5mb and above (I haven't benchmarked the limit), it just freezes after sometime without error or anything.
Log.d("copystream", bytes + ""); would output for some time, but will eventually stop logging.
Log.e("copystream", "exception caught while sending file... " + e.getMessage()); never shows.
This is part of a larger codebase which is actually a file server that runs on the Android device.
Any ideas?
Here's what made it work:
while (true) {
synchronized (buffer) {
int amountRead = file.read(buffer);
if (amountRead == -1) {
break;
}
out.write(buffer, 0, amountRead);
}
}
Use Multipart POST. Something like
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null,null);
entity.addPart("File", new FileBody (new File(FILE_PATH), MIME_TYPE));
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
return response;
Use AsyncTask Class for this, here is link for example
http://developer.android.com/reference/android/os/AsyncTask.html
I make an application , this can download file form server.
use this code >>>
public int startDownload(String url, String filename) {
// create url connector
URL u;
byte[] buffer = new byte[1024];
try {
u = new URL(url + filename);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
InputStream in = c.getInputStream();
m_lMaxDownloadSz = c.getContentLength();
FileOutputStream f = new FileOutputStream(new File(FILE_PATH, filename));
m_bCancelDownload = false;
m_lCurrentDownloadSz = 0;
int len = 0;
while ((len = in.read(buffer, 0, 1024)) > 0) {
// if download is canceled.
if (m_bCancelDownload) {
f.close();
c.disconnect();
return FILE_DOWNLOAD_CANCELED;
}
if (knot++ >= PROGRESS_STEP) {
knot = 0;
myProgressDialog.setProgress(GetDownloadStatus());
}
f.write(buffer, 0, len);
m_lCurrentDownloadSz += len;
}
f.close();
c.disconnect();
} catch (Exception e) {
return FILE_DOWNLOAD_FAILED;
}
if (GetDownloadStatus() == 100) {
return FILE_DOWNLOAD_FINISHED;
} else {
return FILE_DOWNLOAD_FAILED;
}
}
and I want to use with PHP force download , but it not work , ordinary it use with file path like 'app/aaa.apk' it work! ,and I change to PHP file like 'php/forcedl.php' it not work.
I needs to use with php force download, How do I use?
ps. i have little english language skill , cause english language is not my main language
thank you
I discover for my answer
android-Java Code
__example:
byte[] buffer = new byte[1024];
String url = "http://www.bla-bla.com/forcedownload.php"
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
filesize = execute.getEntity().getContentLength();
fileOutput = new FileOutputStream(new File(FILE_PATH, "file_copyformserver.apk"));
while ((len = content.read(buffer, 0, 1024)) > 0) {
fileOutput.write(buffer, 0, len);
Thread.sleep(100);
}
fileOutput.close();
} catch (Exception e) {
e.printStackTrace();
}
php file
__example:
$file = '/home/bla-bla/domains/bla-bla.com/file/file.apk'; //not public folder
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/vnd.android.package-archive');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
this is short code , sorry if cannot run. :)
This is perhaps not the best way to do it, but have you considered renaming the file upon successfully downloading it? I haven't tried it, but I believe you can do it using the File.renameTo() method in Android.
Here's some pseudo code that I think will work, can't try it out right now though:
File.renameTo(new File(FILE_PATH, filename.replace(".apk", ".php")));