The whole thing works perfectly, except image won't show, no errors, Using RoR. What am I missing? All called by async class btw. Been trying several different methods with no avail, if someone could help me out that would be great. Willing to post more if needed.
Thanks!
public static void multiPart(Bitmap image, String topicid, String topost, Context c){
String responseString = "";
{
try {
String imageName = System.currentTimeMillis() + ".jpg";
HttpClient httpClient = new MyHttpClient(c);
HttpPost postRequest = new HttpPost("https://urlofmyapi");
if (image==null){
Log.d("TAG", "NULL IMAGE");
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
image.compress(CompressFormat.JPEG, 75, bos);
byte[] data = bos.toByteArray();
ByteArrayBody bab = new ByteArrayBody(data, imageName);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("feed", new StringBody(topost));
reqEntity.addPart("post_to", new StringBody(topicid));
reqEntity.addPart("upload_file", bab);
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader reader = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
responseString = s.toString();
System.out.println("Response: " + responseString);
} catch (Exception e) {
Log.e(e.getClass().getName(), e.getMessage());
}
}
}
Perhaps you can do following step to import library into your Android.
requirement library:
apache-mime4j-0.6.jar
httpmime-4.0.1.jar
Right click your project and click properties
select java build path
select tab called "Order and Export"
Apply it
Fully uninstall you apk file with the adb uninstall due to existing apk not cater for new library
install again your apk
run it
Thanks,
Jenz
HTTP POSTing images from Java to RoR always seems to have undue issues for me. Have you tried attaching the binary as a org.apache.http.entity.mime.content.FileBody object, like this Android Multipart Upload question?
Related
I have created a java program that can upload a file to a ckan installation, (currently my local testing installation, haven't tested it on a live one).
The text files that i tested my application are uploaded to ckan properly. I do have a problem with some zip files.
After some test and failure attempts, i realized that the problem is in the size of the file. For zip files less than 4Kb it works, but for larger files it fails with the error "server Error".
The files failing to upload via my java application, upload just fine when using the ckan front end, so i am guessing the problem is with my java application and not the ckan installation. This is the code I am using:
StringBuilder sb = new StringBuilder();
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
File file = new File(uploadFileName);
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyyMMdd_HHmmss");
String date=dateFormatGmt.format(new Date());
HttpPost postRequest;
try {
ContentType zipType=ContentType.create("zip");
ContentBody cbFile = new FileBody(file,zipType);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("file", cbFile)
.addPart("url",new StringBody(HOST+"/files/"+date+"/"+uploadFileName,ContentType.TEXT_PLAIN))
.addPart("upload",cbFile)
.addPart("title",new StringBody(TITLE,ContentType.TEXT_PLAIN))
.addPart("description",new StringBody(DESCRIPTION+date,ContentType.TEXT_PLAIN))
.addPart("comment",new StringBody(COMMENT,ContentType.TEXT_PLAIN))
.addPart("key", new StringBody(uploadFileName+date,ContentType.TEXT_PLAIN))
.addPart("package_id",new StringBody("test2",ContentType.TEXT_PLAIN))
.addPart("notes", new StringBody("notes",ContentType.TEXT_PLAIN))
.build();
postRequest = new HttpPost(HOST+"/api/action/resource_create");
postRequest.setEntity(reqEntity);
postRequest.setHeader("X-CKAN-API-Key", myApiKey);
HttpResponse response = httpclient.execute(postRequest);
int statusCode = response.getStatusLine().getStatusCode();
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
}
catch (IOException ioe) {
System.out.println(ioe);
}
finally {
httpclient.getConnectionManager().shutdown();
}
im having a strange problem when receiving json results from the server. I have no idea what the problem is. The thing is that my String json result is corrupted, with strange symbols.
The result is like this (taken from eclipse debug)
Image :
Another strange thing that happens is that when I change the URL of the service to an alternative one, it works and the data is not corrupted. The URLs are the same but once redirects everything to the other.
The URL is use always is (example) http://www.hello.com
The URL that works is http://www.hello.com.uy
(cant post the exact link for security reasons)
The second one redirects everything to the first one, its the only thing it does.
I have tried changing the encoding to UTF-8 and it is still not working, here is the code (with one of the URLs commented)
I have also tried using Dev HTTP Client extension from chrome to check the service and it works fine, no corrupted data. Also, it works perfectly on iOS so i think its just and android/java issue.
DevClient:
try {
JSONObject json = new JSONObject();
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
HttpClient client = new DefaultHttpClient(httpParams);
//String url = TAG_BASEURL_REST +"Sucursal";
String url = "http://www.-------.com/rest/Sucursal";
//String url = "http://www.--------.com.uy/rest/Sucursal";
HttpGet request = new HttpGet(url);
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
String jsonRes = sb.toString();
JSONArray jObj = new JSONArray(jsonRes);
return jObj;
}
} catch (Throwable t) {
Log.i("Error", "Request failed: " + t.toString(), t);
}
return null;
InputStream is = entity.getContent();
// check if the response is gzipped
Header encoding = response.getFirstHeader("Content-Encoding");
if (encoding != null && encoding.getValue().equals("gzip")) {
is = new GZIPInputStream(is);
}
I am trying to test an android app using Robotium in Eclipse android JUnit testing.
I want to capture screenshots at different stages using Robotium and process them using OpenCV library on my PC instead of the android device.
I have been reading forums on separating these two tasks. However, haven't been able to do so.
It would be great if anyone can shed some pointers on this.
Thanks
To separate this two tasks, you need to realize (for example) REST client on android and server on the desktop.
Client should connect to server
Server pings client and client sends him screenshots. Perhaps, you will need to create separate thread in test.
Client should do the following:
When you need to take screenshot:
Object res = null;
res = new File(takeScreenShot(solo));
Then
public static String takeScreenShot(Solo _solo) {
solo = _solo;
String dir = "/sdcard/Robotium-Screenshots/";
String fileName = "screenshot";
java.io.File file = new java.io.File(dir, fileName);
if (file.exists()) {
file.delete();
}
solo.takeScreenshot(fileName);
solo.sleep(2000);
return "/sdcard/Robotium-Screenshots/" + fileName + ".jpg";
}
You need to send it
service.sendScreen(file);
and in your service will do smthng like this:
public static JSONObject sendScreen(final File file) {
JSONObject res;
String response;
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(host + "/" + methodName);
MultipartEntity entity = new MultipartEntity();
entity.addPart("file", new FileBody(file));
httppost.setEntity(entity);
try{
response = httpclient.execute(httppost, responseHandler);
res = (JSONObject) JSONValue.parse(response);
}
catch(IOException e)
{
res = null;
e.printStackTrace();
}
return res;
}
Here's example of code on C# to parse screenshot
public void StepError(Stream stream)
{
var result = new DCStepErrorResponce();
const string imageName = "file";
string fullFileName = String.Empty;
var parser = new MultipartFormDataParser(stream);
if (parser.Files.Any(file => file.Name == imageName))
{
Stream data = parser.Files.First(file => file.Name == imageName).Data;
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "HFAutomationTesting", "Temp", "ScreenShots");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
do
{
string fileName = String.Format("{0:yy_MM_dd_HH_mm_ss_ffff}.jpg", DateTime.Now);
fullFileName = Path.Combine(path, fileName);
} while (File.Exists(fullFileName));
var fileToUpload = new FileStream(fullFileName, FileMode.Create);
byte[] bytearray = ToByteArray(data);
fileToUpload.Write(bytearray, 0, bytearray.Length);
fileToUpload.Close();
fileToUpload.Dispose();
}
}
You need just to realize rest server on C# and debug it.
I have an Android device. I want to fill a form in my app, with edittexts etc (one of these fields would take the path of an image on the SDCard). I want these form contents to be the data for an HTML form in an external website where this file (from the SD Card) needs to be uploaded. The HTML form has an upload button. I do not want to show this HTML webpage to my android app users. Is there any way to do this? Please let me know! Thanks!
EDIT: I've looked through many websites and I understand that I should use a HttpPost. I have a few doubts though:
1. What is the url that you use in HttpPost- Is it the url which contains the form, or the url which the form redirects to.
2. In a multipartentity, what is the first parameter in addPart? Is it the ID given to the field or the name?
3. How does the HttpPost know which form it should go to?
Well, you need to make a MultiPart Http Post. You could use this sample:
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("target_link");
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("data1", new StringBody("Data1"));
reqEntity.addPart("data2", new StringBody("Data2"));
reqEntity.addPart("data3",new StringBody("Data3"));
try{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 80, bos);
byte[] data = bos.toByteArray();
ByteArrayBody bab = new ByteArrayBody(data, "forest.jpg");
reqEntity.addPart("picture", bab);
}
catch(Exception e){
//Log.v("Exception in Image", ""+e);
reqEntity.addPart("picture", new StringBody(""));
}
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
Personally, I prefer to use Spring for Android as that is easier to configure. Here's a link with a multi-part Http Post.
Good luck!
Good day fellow developers.
I'm busy for android to upload images from a app.
I also got it working (code will follow below).
But when i send large images (10 megapixels) my app crashes with an out-of-memory exception.
A solution for this is to use compression but what if i want to send the full size image?
I think perhaps something with a stream but i'm not familair with streams. Perhaps urlconnection might help to but i really have no idea.
I give the filename the name File[0 to 9999].jpg
The post value with the image date is called Filedata
I give a UID for the post value dropboxid
The code below works but i would love to solve my problem that prevents me from sending high res images.
kind regards
try
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, bos);
byte[] data = bos.toByteArray();
HttpPost postRequest = new HttpPost(URL_SEND);
ByteArrayBody bab = new ByteArrayBody(data, "File" + pad(random.nextInt(9999) + 1) + ".jpg");
MultipartEntity reqEntity = new multipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("Filedata", bab);
reqEntity.addPart("dropboxId", new StringBody(URLEncoder.encode(uid)));
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
while((sResponse = reader.readLine()) != null)
{
s = s.append(sResponse);
}
if(d) Log.i(E, "Send response:\n" + s);
}
catch (Exception e)
{
if(d) Log.e(E, "Error while sending: " + e.getMessage());
return ERROR;
}
When using ByteArrayOutputStream and then calling #toByteArray() you've effectively doubled the amount of memory the JPEG is using. ByteArrayOutputStream keeps an internal array with the encoded JPEG and when you call #toByteArray() it allocates a new array & copies the data from the internal buffer.
Consider encoding large bitmaps to a temporary file & using FileOutputStream and FileInputStream to encode and send the image.
Without "uploading" - your app survives "nicely" with the just the huge bitmap in memory I assume?
Edit: FileBody
File img = new File(this is where you put the path of your image)
ContentBody cb = new FileBody(img, "File" + pad(random.nextInt(9999) + 1) + ".jpg", "image/jpg", null);
MultipartEntity reqEntity = new multipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("Filedata", cb);
reqEntity.addPart("dropboxId", new StringBody(URLEncoder.encode(uid)));