1

I have created a web service in ASP.net which is RESTful. From an Android application I want to consume these services. Basically I am sending request and getting response in JSON, using Android's default library.

Here is my code :

public class PostImagesHandler {
    final static String TAG = "WebHandlerHttpPost";
    Context context;
    ImagesBean imageBean;

    public String postImagesRequest(String URL, Context context,
            ImagesBean imgBean) {
        this.context = context;
        String result = null;
        this.imageBean = imgBean;

        try {
            HttpPost request = new HttpPost(URL);
            System.out.println("WHAT IS URL :: " + URL);
            request.setHeader("Accept", "application/json");
            request.setHeader("Content-type", "application/json");
            request.addHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
            request.addHeader("Pragma", "no-cache"); // HTTP 1.0.
            request.addHeader("Expires", "0"); // Proxies.


                     Bitmap bm = BitmapFactory.decodeFile("sdcard/dotTest9.jpg");
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
             bm.compress(Bitmap.CompressFormat.JPEG, 90, baos);
             byte[] bytes_ = baos.toByteArray();

            String image_str = Base64.encodeToString(readFile().getBytes(),
                    Base64.NO_WRAP);
            appendLog(image_str);

            JSONStringer userJson = new JSONStringer().object()
            .key("objPostSectionImages").object().key("ID")
            .value("1").key("SUB_ID").value("1").key("MainTaskId")
            .value("1").key("ImageBase64").value(image_str)
            .key("actualAuditDate").value(getCurrentDateTime()).endObject()
             endObject();


            Log.d(TAG, "SECTION IMAGE STRING :: " + userJson.toString());

            StringEntity entity = new StringEntity(userJson.toString(), "UTF-8");
            entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                    "application/json"));
            entity.setContentType("application/json");
            request.setEntity(entity);

            HttpParams params = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(params, 30000);
            HttpConnectionParams.setSoTimeout(params, 10000);

            // Send request to WCF service
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpResponse response = httpClient.execute(request);

            if (response != null) {
                StringBuilder sb = new StringBuilder();
                BufferedReader rd = new BufferedReader(new InputStreamReader(
                        response.getEntity().getContent()));

                String line;
                while ((line = rd.readLine()) != null) {
                    sb.append(line + "\n");
                }

                result = sb.toString();
                Log.d(TAG, "AUDIT SECTION IMAGES Response: " + result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public void appendLog(String text) {
        File logFile = new File("sdcard/dotTest7.txt");
        if (!logFile.exists()) {
            try {
                logFile.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        try {
            // BufferedWriter for performance, true to set append to file flag
            BufferedWriter buf = new BufferedWriter(new FileWriter(logFile,
                    true));
            buf.append(text);
            // buf.newLine();
            buf.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @SuppressLint("SimpleDateFormat")
    public static String getCurrentDateTime() {
        return new SimpleDateFormat("MM-dd-yyyy").format(Calendar.getInstance()
                .getTime());
    }
}

I'm able to send small images this way, but while sending large images (more than 5 KB), I am facing problems. Some times I get "Request Error" and sometimes it works.

Franz Kafka
  • 10,623
  • 20
  • 93
  • 149
Mohanish
  • 469
  • 2
  • 13
  • Is there any reason the image should not be streamed to the service instead of being converted to a Base64 string ? – Deepak Bala Apr 10 '13 at 13:31
  • I am creating a json object and base64 is one parameter of that object .then this object is passed to the REST based WCF. WCF requires base64 string. – Mohanish Apr 10 '13 at 13:51
  • You could use a [multipart upload](http://stackoverflow.com/questions/1354749/wcf-service-to-accept-a-post-encoded-multipart-form-data) – Deepak Bala Apr 10 '13 at 13:53
  • I had also a thought about using Multipart. But I'm finding solution and for my personal knowledge what is the problem in sending 10 KB BASE64 string via JSON. My question is : Is it required to send 10KB BASE64 string image via Multipart ? – Mohanish Apr 10 '13 at 14:03
  • 1
    With larger images you are bound to run out of memory on Android. Large strings are frowned upon by the framework. If you use multipart upload, you might as well stream the `byte[]` instead of the base64 string. – Deepak Bala Apr 10 '13 at 14:07
  • are you sure about `"sdcard/dotTest9.jpg"` ? shouldn't it be **/** sdcard ? – njzk2 Apr 10 '13 at 14:19
  • There is no problem in converting an image into BASE64 String. As Deepak said me too thinking about same thing that large Strings is cause of the whole problem. I am not able to figure out that why no one cannot send BASE64 String Image via JSON in Android ? Only large String cause may not be there, I'm thinking so... any opinion guys... – Mohanish Apr 11 '13 at 07:03

1 Answers1

0

Maybe your ASP.NET webservice escapes forward slashes in base64 strings? This makes this data broken from the normal applications' point of view.

In small images the probability of getting / symbol after base64 transformation is significantly lower than in large one, so you getting this random error cases.

You can check your service resulting string for /\ symbols and replace them to / and check, will it work or not.

shytikov
  • 9,155
  • 8
  • 56
  • 103