i have application that picks the file from a dedicated path on my device and sends it to server.
I m using ksoap2 lib to call .NET webservice to send my file to server. i am using Base 64 encoding.
I can send file with max size of 1MB without encryption and 850Kb with encryption. Encyrption algorithm i am using is 3DES.
If i try to send files larger than above size i get following error: Caused by: java.lang.OutOfMemoryError at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:121)
My Test environment: Android emulator with API Level 8, Android 2.2 and SDCard memory 512 MB
Is it that i am missing out something? Can using BLOB help me in this scenario
Is there any way to send larger file? i have heard of sending data chunks but have no idea on that . any link or sample code will really help.
to get file data using following code:
here url = where file is stored
public byte[] getFileData( String vURL){
instream = new FileInputStream(vURL);
size = (int) vURL.length();
fileContent = new byte[size];
instream.read(fileContent);
}
Encode the data using following code:
byte[] res = Utilities.getFileData(file);
String mdata = android.util.Base64.encodeToString(res, android.util.Base64.DEFAULT);
calling server side web service and sending data to server
SoapObject request = new SoapObject(nameSpace, methodName);
if (fileData != null && !fileData.equals("")) {
request.addProperty("vBLOBData", fileData);
}
SoapSerializationEnvelope envelope = getEnvelope(request);
HttpTransportSE ht = new HttpTransportSE(url); // ,3000
ht.debug = true;
ht.call(soapAction, envelope);
response = (envelope.getResponse()).toString();
Not able to send filedata more than 1 MB.
Thanks in advance
I don't know what you are trying to achieve, but why you don't divide your file into parts and send each part individually into a loop or into an android background service using a timer that sends a part every x seconds.
Try to set your buffer to 1024 before sending it , its about the limit of your buffer size and your ram
Use GZip Zipping algorithm to zip large file from mobile side; use same unzipping from server.
Also use MultipartEntity can help to upload large file content.
If compression doesn't help - as mentioned in previous post - you will probably have to segment the message yourself.
Segmentation
Related
I want to stream a radio with Java, my approach is to download the playlist file (.pls), then extract one of the urls given in that same file and finally, stream it with java. However, it seems I cannot find a way to do it.. I tried with JMF, but I get java.io.IOException: Invalid Http response everytime I run the code.
Here is what I tried:
Player player = Manager.createPlayer(new URL("http://50.7.98.106:8398"));
player.start();
The .pls file:
[playlist]
NumberOfEntries=1
File1=http://50.7.98.106:8398/
In the piece of code above I'm setting the URL by hand, just for testing, but I've sucessfuly done the .pls downloading code and it's working, and from this I make another question, is it a better approach to just simply play the .pls file locally? Can it be done?
You are connecting to an Icecast server, not a web server. That address/port is not sending back HTTP responses, it's sending back Icecast responses.
The HTTP specification states that the response line must start with the HTTP version of the response. Icecast responses don't do that, so they are not valid HTTP responses.
I don't know anything about implementing an Icecast client, but I suspect such clients interpret an http: URL in a .pls file as being just a host and port specification, rather than a true HTTP URL.
You can't use the URL class to download your stream, because it (rightly) rejects invalid HTTP responses, so you'll need to read the data yourself. Fortunately, that part is fairly easy:
Socket connection = new Socket("50.7.98.106", 8398);
String request = "GET / HTTP/1.1\n\n";
OutputStream out = connection.getOutputStream();
out.write(request.getBytes(StandardCharsets.US_ASCII));
out.flush();
InputStream response = connection.getInputStream();
// Skip headers until we read a blank line.
int lineLength;
do {
lineLength = 0;
for (int b = response.read();
b >= 0 && b != '\n';
b = response.read()) {
lineLength++;
}
} while (lineLength > 0);
// rest of stream is audio data.
// ...
You still will need to find something to play the audio. Java Sound can't play MP3s (without a plugin). JMF and JavaFX require a URL, not just an InputStream.
I see a lot of recommendations on Stack Overflow for JLayer, whose Player class accepts an InputStream. Using that, the rest of the code is:
Player player = new Player(response);
player.play();
In a REST client, i upload several files to a server.
In order to report to the user about the upload process, i use a progress bar.
The total size is set to the sum of the files dimension.
This is an estimated value, because there are more bytes in the upload than the number of bytes in the file.
The question is: can I obtain the actual number of bytes of the upload before that the upload begins?
This would allow for the total size to be determined rather than estimated before the upload begins.
FormDataMultiPart multiPart = new FormDataMultiPart();
FileDataBodyPart fdbp = new FileDataBodyPart("data.zip", new File("data.zip"));
BodyPart bp = multiPart.bodyPart(fdbp);
builder.post(String.class, multiPart);
Simple answer - no.
More comprehensive one: you could. But it is not worth it. Basically you would need to somehow invoke MessageBodyWriter for FormDataMultiPart instance (see org.glassfish.jersey.media.multipart.internal.MultiPartWriter.writeTo(...)) and get written bytes from that call. There are some issues related to this approach;
you'll do the writeTo operation twice - that means one request will consume twice resources as it should or
you'll have to cache the output and send it as an byte[] - you will need lots of memory (depends on data.zip file size).
I'm struggling for few days with this problem and you are my last chance solving it.
The Goal:
To upload a bitmap from android client to google app engine and save it in datastore.
I'm using Serialization to transfer object from client to server and vise versa.
Things I have tried:
sending a Bitmap
but i got java.io.NotSerializableException: android.graphics.Bitmap
then I tried create from the Bitmap Blob at the client like this:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
Byte[] bArray = bos.toByteArray();
Blob blob = new Blob(bArray);
But at the client side I dont have the google app engine classes (for Blob), So I tried to brute force it by extract specific classess but it created new problems.
So I am asking in which dierction I can go from to solve this problem.
Thanks.
Few notes:
Do not use Java serialization to transfer data between JVMs. Java serialization is not standardized and is not guaranteed to be compatible between JVMs (or even between versions).
To send binary data it's best to use HTTP POST and set Content-Type appropriately (e.g. application/octet-stream).
So, to make this work do this:
Create a servlet which handles POST and gets the binary data. Use servletRequest.getInputStream() to get hold of binary data.
Use Blobstore FileService API to save data to blobstore.
On Android side use a http client to make a POST request and add your bitmap's binary data to it. If you need to add some metadata use Http headers.
This might be useful
How to upload and store an image with google app engine (java)
Alternatively, you can try blobstore api
http://code.google.com/appengine/docs/java/blobstore/overview.html
Here is a production tested way:
Use GAE appengine to upload your bitmap to, and serve for future clients.
On the Android code, follow these steps:
Get an Upload URL from GAE
Upload your bitmap to GAE, and get a blobkey back
Later on, use the blobkey to serve the image to your clients.
GAE Servlet code:
getUploadURL:
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
String url = blobstoreService.createUploadUrl(path_to_your_upload_servlet);
uploadServlet - stores in blobstore, returns the blobkey to the uploader
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
Map<String, List<BlobKey>> uploads = blobstoreService.getUploads(request);
String fileName = uploads.keySet().iterator().next();
final BlobKey blobKey = uploads.get(fileName).get(0);
response.getWriter().println(blobKey.getKeyString());
Android client code:
String uploadUrl = getUrlAsString(..your getUrl servlet path...)
// Upload to GAE (include apache-mime4j.jar and httpmime.jar in your project for this code)
File file = new File(imageFilePath);
HttpPost postRequest = new HttpPost(uploadUrl);
MultipartEntity entity = new MultipartEntity();
entity.addPart("file", new FileBody(file));
postRequest.setEntity(entity);
HttpResponse httpResponse;
HttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setBooleanParameter("http.protocol.handle-redirects",false);
httpResponse = httpClient.execute(postRequest);
int status = httpResponse.getStatusLine().getStatusCode();
String blobKey = getInputStreamAsString(httpResponse.getEntity().getContent())
I am using the official Dropbox API for Java.
So far, everything works smoothly. Authentication via oauth works and so do other functions (like directory listings).
Now, I tried to upload a file like this:
InputStream is = getInputStream();
byte[] bytes = is2Bytes(is); // Gets all bytes "behind" the stream
int len = bytes.length;
api.putFileOverwrite(path, is, len, null);
Now, when I do this call, my application hangs for about 15 seconds and then I get an exception thrown that Dropbox server did not respond.
So, first I asked Dropbox support if there was something wrong with their server. There isn't.
Then, I played around with the parameters of the putFileOverwrite method and I found out that if I set len=0 manually, the server responds and creates a 0 byte file with the correct file name.
As another test, I manually entered the value len=100 (the original file has 250KB so that should be ok). Again, the server does NOT respond.
So, what's wrong?
That is not weird at all. Since you use your self-made method is2Bytes, the steam is empty, because you read all the bytes to count them. The proper way of doing this would be either knowing how many bytes you are going to send or using the build-in method for sending a file.
public HttpResponse putFile(String root, String dbPath, File localFile)
Very weird. I was able to work around this by re-creating a new InputStream from the byte array and send that to Dropbox:
InputStream is = getInputStream();
byte[] bytes = is2Bytes(is); // Gets all bytes "behind" the stream
int len = bytes.length;
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
api.putFileOverwrite(path, bis, len, null);
How do you make a HTTP GET request in Mule, and then stream the response to a file? My application stores the entire response in memory, but the response can be large, so this needs to be fixed. I want to save the response to a temporary file, and then stream the file contents back to the client.
Right now, I'm doing:
String restUrl = "http://www.url.com";
UMOEventContext context = RequestContext.getEventContext();
GetMethod method = new GetMethod(restUrl);
UMOMessage muleMessage = new MuleMessage(method);
muleMessage.setProperty(RestServiceWrapper.REST_SERVICE_URL, restUrl);
UMOMessage result = context.sendEvent(muleMessage, new MuleEndpointURI("vm://identifier")); //OutOfMemoryException
String body = result.getPayloadAsString();
I'm using Mule 1.3.3 and cannot upgrade. Thank you.