java 使用 HttpUrlConnection Android 将 base64 编码的图像发送到服务器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30119382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:30:45  来源:igfitidea点击:

Sending base64 encoded image to server using HttpUrlConnection Android

javaandroidimagebase64httpurlconnection

提问by Yusuf Isaacs

I'm trying to send base64 encoded images to a server using HttpUrlConnection. The problem I'm having is that most images gets sent successfully, however some generate a FileNotFound exception. My code for encoding the image can be found below.

我正在尝试使用 HttpUrlConnection 将 base64 编码的图像发送到服务器。我遇到的问题是大多数图像都成功发送,但有些会生成 FileNotFound 异常。我用于编码图像的代码可以在下面找到。

public static String encodeImage(Bitmap thumbnail) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            byte[] b = baos.toByteArray();
            String imageEncoded = Base64.encodeToString(b,Base64.URL_SAFE);
            return imageEncoded;
        }

When I change the line:

当我更改线路时:

String imageEncoded = Base64.encodeToString(b,Base64.URL_SAFE);

to:

到:

String imageEncoded = Base64.encodeToString(b,Base64.DEFAULT);

then most images generate a FileNotFoundException and some gets sent to the server successfully.

然后大多数图像生成 FileNotFoundException 并且一些被成功发送到服务器。

below is the code for my HttpUrlConnection:

下面是我的 HttpUrlConnection 的代码:

public class HttpManager {

    public static String getData(RequestPackage p) {

        BufferedReader reader = null;
        String uri = p.getUri();
        if (p.getMethod().equals("GET")) {
            uri += "?" + p.getEncodedParams();
        }

        try {
            URL url = new URL(uri);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod(p.getMethod());


            if (p.getMethod().equals("POST")) {
                con.setDoOutput(true);
                OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
                writer.write(p.getEncodedParams()); //Url encoded parameters
                writer.flush();
            }

            StringBuilder sb = new StringBuilder();
            reader = new BufferedReader(new InputStreamReader(con.getInputStream()));

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

            return sb.toString();

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }

    }

}

Any help will be appreciated. Thanks

任何帮助将不胜感激。谢谢

采纳答案by Vicky

I had the same problem. Just use the code below you will be fine:

我有同样的问题。只需使用下面的代码就可以了:

 public class MainActivity extends AppCompatActivity {

int SELECT_PICTURE = 101;
int CAPTURE_IMAGE = 102;
Button getImage;
ImageView selectedImage;
String encodedImage;
JSONObject jsonObject;
JSONObject Response;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getImage = (Button) findViewById(R.id.get_image);
    selectedImage = (ImageView) findViewById(R.id.selected_image);

    final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setTitle("Profile Picture");
    builder.setMessage("Chooose from?");
    builder.setPositiveButton("GALLERY", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, SELECT_PICTURE);
        }
    });
    builder.setNegativeButton("CANCEL", null );


}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request we're responding to
    if (requestCode == SELECT_PICTURE) {
        // Make sure the request was successful
        Log.d("Vicky","I'm out.");
        if (resultCode == RESULT_OK && data != null && data.getData() != null) {
            Uri selectedImageUri = data.getData();
            Bitmap selectedImageBitmap = null;
            try {
                selectedImageBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImageUri);
            } catch (IOException e) {
                e.printStackTrace();
            }
            selectedImage.setImageBitmap(selectedImageBitmap);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            selectedImageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
            byte[] byteArrayImage = byteArrayOutputStream.toByteArray();
            encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
            Log.d("Vicky","I'm in.");
            new UploadImages().execute();
        }
    }
}

private class UploadImages extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {

    }

    @Override
    protected Void doInBackground(Void... params) {

        try {
            Log.d("Vicky", "encodedImage = " + encodedImage);
            jsonObject = new JSONObject();
            jsonObject.put("imageString", encodedImage);
            jsonObject.put("imageName", "+917358513024");
            String data = jsonObject.toString();
            String yourURL = "http://54.169.88.65/events/eventmain/upload_image.php";
            URL url = new URL(yourURL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            connection.setFixedLengthStreamingMode(data.getBytes().length);
            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            OutputStream out = new BufferedOutputStream(connection.getOutputStream());
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
            writer.write(data);
            Log.d("Vicky", "Data to php = " + data);
            writer.flush();
            writer.close();
            out.close();
            connection.connect();

            InputStream in = new BufferedInputStream(connection.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    in, "UTF-8"));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            in.close();
            String result = sb.toString();
            Log.d("Vicky", "Response from php = " + result);
            //Response = new JSONObject(result);
            connection.disconnect();
        } catch (Exception e) {
            Log.d("Vicky", "Error Encountered");
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void args) {

    }
  }
}

回答by ag047

The default DEFAULT alphabet probably has a '/' in it. In other words, when you run Base64.encodeToString(b,Base64.DEFAULT), you will end up with '/'s in the result. I would double check the path in your HTTP request path on the server side.

默认的 DEFAULT 字母表中可能有一个“/”。换句话说,当您运行 Base64.encodeToString(b,Base64.DEFAULT) 时,结果中会出现“/”。我会在服务器端仔细检查您的 HTTP 请求路径中的路径。

回答by slashka

This trick saved my life. I tried all I can, except of multipart data (don't need this). My images were broken with different encodings, Base64 encode types and so on. So the trick is to use URLEncoder for your encoded image string:

这个技巧救了我的命。我尽我所能,除了多部分数据(不需要这个)。我的图像被不同的编码、Base64 编码类型等破坏了。所以诀窍是对你的编码图像字符串使用 URLEncoder:

String params = "img=" + URLEncoder.encode(base64_img_str, "UTF-8") + "&param=" + String.valueOf(someParam);

And then just send this (using HttpURLConnection):

然后发送这个(使用 HttpURLConnection):

OutputStream os = conn.getOutputStream();
                data = params.getBytes("UTF-8");
                os.write(params);
                os.flush();