0

I'm trying to implement a function, which passes base64 encoded image from a webview to my web application via HTTP Post. And then, lets say, this image must be shown right away in my view. I've used this example but it didn't work properly, so after googling a little bit, I've started using AsyncTask:

public void tryUpload(String url, Context context) {
    new UploadTask(context).execute(url);
}

private class UploadTask extends AsyncTask<String, Void, HttpResponse> {
    private Context context;
    public UploadTask(Context ctx) {
        context = ctx;
    }

    @Override
    protected HttpResponse doInBackground(String... urls) {
        List<NameValuePair> formData = new ArrayList<NameValuePair>(3);
        formData.add(new BasicNameValuePair("image", "base64EncodedString"));

        HttpPost httpPost = new HttpPost(urls[0]);
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(formData, HTTP.UTF_8));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        HttpClient httpClient = new DefaultHttpClient();
        HttpResponse response = null;
        try {
            response = httpClient.execute(httpPost);

            WebView browser = (WebView) findViewById(R.id.my_web_engine);
            browser.setWebChromeClient(new MyWebChromeClient());
            browser.setWebViewClient(new MyWebViewClient());

            try{
                String data = new BasicResponseHandler().handleResponse(response);
                browser.loadDataWithBaseURL(urls[0], data, "text/html", HTTP.UTF_8, null);
            } catch (IOException e) {
                e.printStackTrace();
        }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return response;
    }

    @Override
    protected void onPostExecute(HttpResponse response) {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            String responseBody = null;
            try {
                responseBody = EntityUtils.toString(response.getEntity());
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (responseBody.equalsIgnoreCase("OK"))
                Log.w("myApp", "Everything is OK");
            else
                Log.w("myApp", "Something is wrong");
        }
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (Intent.ACTION_SEND.equals(action) && type != null) {
        if (type.startsWith("image/")) {
                    // for simplicity skipped image encoding to base64
                    String url = getResources().getString(R.string.url) + "/MyController/ImageUpload";
                    Context context = ImageUploadActivity.this;
                    tryUpload(url, context);
            }
        }
    }
}

And here is my ASP.NET MVC action:

// temporary removed authorization
[HttpPost]
public ActionResult ImageUpload(string image)
{
    // skipped some lines
    ViewData.Add("imageFromWebView", image);
    return View();
}

And a View contains following line:

<img src="data:image/png;base64,<%: (string)ViewData["imageFromWebView"] %>"/>

When I delete [HttpPost], the view is loaded without a problem, but the image is not displayed.

But when I leave [HttpPost], I get an exception

org.apache.http.client.HttpResponseException: Not Found

in the following line:

String data = new BasicResponseHandler().handleResponse(response);

Does anyone know what I'm doing wrong?

  • You only should do something with your WebView in onPostExecute. There you should load the response. Please show the source/data you give in loadDataWithBaseURL(). – greenapps May 28 '14 at 10:35
  • @greenapps url[0] = "http://m.mysite.com/TestEnvironment/MyController/ImageUpload" and I don't know what data supposed to be in "data" variable, because it throws an error `org.apache.http.client.HttpResponseException: Not Found`. Seems like it tries to find an appropriate action, which handles HTTP Post and has one parameter - image, but it fails to find it for some reason. Maybe because it doesn't carries a parameter and is not able to find an action without parameters. It just a long shot. – user3232395 May 28 '14 at 11:22
  • @greenapps Just out of curiosity I've added one more action with the same name, but without any parameters. And it worked. The view opened without any exception. This means, that loadDataWithBaseURL() doesn't carry post parameters for some reason. :( P.S. Also removed `[HttpPost]` attribute of the action, because otherwise it didn't worked. – user3232395 May 28 '14 at 11:26
  • @greenapps After moving that code part which is AFTER `response = httpClient.execute(httpPost);` to onPostExecute method, I get `FATAL EXCEPTION: main android.os.NetworkOnMainThreadException` in `String data = new BasicResponseHandler().handleResponse(response);` line. Any suggestions? – user3232395 May 28 '14 at 11:40
  • Of course you get that exception. `String data = new Basi......` should stay in doOnBackGround. Change it to `data = new Basi...` and make `String data;` a private variable of the task. – greenapps May 28 '14 at 11:49
  • I'm wondering why you do not feed `responseBody` to the WebView instead of `data`. – greenapps May 28 '14 at 12:05
  • @greenapps I guess you're right - I have to delete `data` and feed `responseBody` to the WebView, because they should carry the same information (that's what happens when combining multiple examples into one). Anyway, response in onPostExecute method still comes with statusline `HTTP/1.1 404 Not Found` therefore I get `FATAL EXCEPTION: main android.os.NetworkOnMainThreadException` exception in `responseBody = EntityUtils.toString(response.getEntity());` line. Any other thoughts what could possibly be wrong in my code? – user3232395 May 28 '14 at 14:07
  • Then put that in `doOnBackGround()` as you did with data. – greenapps May 28 '14 at 14:26
  • `new BasicNameValuePair("image", "base64EncodedString")` can not be true! That should be `new BasicNameValuePair("image", base64EncodedString)`. And you put your image in that String base64 encoded. – greenapps May 28 '14 at 14:28
  • Can you provide a link to some api documentation for m.mysite.com ? Specially for uploading an image as you do here. Could not find it there. – greenapps May 28 '14 at 15:01
  • Is the link you provided earlier complete? It ends on ".../ImageUpload". I would think it would end with the name of a script. Whatever is posted or called always there is the same `404 Error - File not found` in responseBody. – greenapps May 28 '14 at 15:42
  • @greenapps After moving `responseBody` to doOnBackground(), the webview loads an error page (it's good, because it loads the page without exceptions). `"base64EncodedString"` is correct, it's just a random string, not a parameter, because my action accepts one parameter - string. And when I'll be able to transfer any string, I'll put there a base64 encoded picture. I'm sorry, but I can't provide a real link, because the software I'm developing is proprietary and not accessible to anybody. – user3232395 May 29 '14 at 11:04
  • @greenapps And a link end is correct, because it's .NET MVC framework and `.../MyController/ImageUpload` means, that it looks in MyController for an action named `ImageUpload`, which accepts one HTTP Post parameter. Ant this actions returns a view `ImageUpload.aspx`. What I see in a webview is posted here http://jsfiddle.net/UD6jn/2/embedded/result/ The same result is shown when I try to open this link in my desktop browser. – user3232395 May 29 '14 at 11:06
  • @greenapps I think the problem is that somehow the POST parameter (an image string) is not transfered from webview to action, so the program looks for another action named `ImageUpload` which does not require any parameters, so it fails to find and shows an error. – user3232395 May 29 '14 at 11:06
  • who can answetr this question? http://stackoverflow.com/q/40329672/6796473 –  Oct 31 '16 at 07:53

0 Answers0