从Android上通过POST上传JPEG格式的图像

时间:2014-01-26 16:07:54

标签: android file-upload http-post

我正在尝试使用Google Image搜索上传图像programmaticaly(android)并解析结果。我不断收到错误 - “图片必须采用以下格式之一:.jpg,.gif,.png,.bmp,.tif或.webp。”

从浏览器执行相同操作时,它可以正常工作。我通过fiddler比较了这两个请求,就Content-Type而言,它们看起来都相似:

Content-Type: multipart/form-data; boundary=A3EwwOwLJr168nlq1CZSlVUuQ1m5X9W

--A3EwwOwLJr168nlq1CZSlVUuQ1m5X9W
Content-Disposition: form-data; name="file"; filename="File_1390748740620.jpeg"
Content-Type: image/jpeg

我无法弄清楚问题可能是什么。请指导。代码如下(我尝试了两种方法,两种方法都在代码中):

// Approach 1:
//  ByteArrayOutputStream bos = new ByteArrayOutputStream();
//  Bitmap bitmap = BitmapFactory.decodeFile(fileName);
//  bitmap.compress(CompressFormat.JPEG, 100, bos);
//  byte[] data = bos.toByteArray();
//  ByteArrayBody bab = new ByteArrayBody(data, "image/jpeg", fileName);

// Approach 2:      
File file = new File(fileName);
ContentBody cbFile = new FileBody(file, "image/jpeg");

MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", cbFile);

HttpPost post = new HttpPost(uploadUrl);
post.setEntity(reqEntity);

1 个答案:

答案 0 :(得分:0)

这正是你想要的。

<强> HttpRequestWithEntity.java

import java.net.URI;
import java.net.URISyntaxException;

import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;

public class HttpRequestWithEntity extends HttpEntityEnclosingRequestBase {

    private String method;

    public HttpRequestWithEntity(String url, String method) {
        if (method == null || (method != null && method.isEmpty())) {
            this.method = HttpMethod.GET;
        } else {
            this.method = method;
        }
        try {
            setURI(new URI(url));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String getMethod() {
        return this.method;
    }

}

如果您想要上传照片或视频,可以在此处显示进度条。

public static class UploadPhoto extends AsyncTask<String, Void, InputStream> {
    private static final String TAG = "UploadImage";
    byte[] buffer;
    byte[] data;
    //private long dataLength = 0;
    private INotifyProgressBar iNotifyProgressBar;
    private int user_id;
    private IAddNewItemOnGridView mAddNewItemOnGridView;
    public UploadPhoto(INotifyProgressBar iNotifyProgressBar, 
            IAddNewItemOnGridView mAddNewItemOnGridView, int user_id) {
        this.iNotifyProgressBar = iNotifyProgressBar;
        this.user_id = user_id;
        this.mAddNewItemOnGridView = mAddNewItemOnGridView;
    }

    @Override
    protected InputStream doInBackground(String... names) {
        File mFile = null;
        FileBody mBody = null;
        File dcimDir = null;
        try {
            String fileName = names[0];
            dcimDir = Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
            mFile = new File(dcimDir, Def.PHOTO_TEMP_DIR + fileName);
            if (!mFile.isFile()) {
                iNotifyProgressBar.notify(0, UploadStatus.FAILED);
                return null;
            }
            HttpClient httpClient = new DefaultHttpClient();
            HttpPost postRequest = new HttpPost(Def.BASE_URL 
                    + String.format("/%d/list", this.user_id));
            final int maxBufferSize = 10 * 1024;
            mBody = new FileBody(mFile, fileName, "image/jpeg", "UTF-8"){
                int bytesRead, bytesAvailable, bufferSize;
                InputStream mInputStream = super.getInputStream();
                int dataLength = mInputStream.available();
                @Override
                public void writeTo(OutputStream out) throws IOException {
                    bytesAvailable = mInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    buffer = new byte[bufferSize];
                    bytesRead = mInputStream.read(buffer, 0, bufferSize);
                    while (bytesRead > 0) {
                        out.write(buffer, 0, bufferSize);
                        bytesAvailable = mInputStream.available();
                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        bytesRead = mInputStream.read(buffer, 0, bufferSize);
                        int progress = (int) (100 - ((bytesAvailable * 1.0) / dataLength) * 100);
                        Log.d(TAG, "Result: " + progress + "%");
                        if (progress == 100) {
                            iNotifyProgressBar.notify(progress, UploadStatus.SUCCESS);
                        } else {
                            iNotifyProgressBar.notify(progress, UploadStatus.UPLOADING);
                        }
                    }
                }
                @Override
                protected void finalize() throws Throwable {
                    super.finalize();
                    if (mInputStream != null) {
                        mInputStream.close();
                    }
                }   
            };

            MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);              
            reqEntity.addPart("photo", mBody);
            postRequest.setEntity(reqEntity);
            HttpResponse response = httpClient.execute(postRequest);
            InputStream mInputStream = response.getEntity().getContent();
            return mInputStream == null ? null : mInputStream;
        } catch (IOException e) {
            Log.e(TAG, "Error causes during upload image: " + e.getMessage());
            e.printStackTrace();
            iNotifyProgressBar.notify(0, UploadStatus.FAILED);
        } finally {
            Log.v(TAG, "Close file");
            if (mFile != null) {
                mFile = null;
            }
            if (mBody != null) {
                mBody = null;
            }
            if (dcimDir != null) {
                dcimDir = null;
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(InputStream result) {
        if (result == null) {
            iNotifyProgressBar.notify(0, UploadStatus.FAILED);
        } else {
            PhotoInfo mPhotoInfo = ApiUtils.convertStreamToPhotoInfo(result);
            if (mAddNewItemOnGridView != null && mPhotoInfo != null) {
                mAddNewItemOnGridView.notifyAdded(mPhotoInfo);
                Log.d(TAG, "Upload completed!!");
            } else {
                Log.d(TAG, "Upload is failed!!");
                iNotifyProgressBar.notify(0, UploadStatus.FAILED);
            }
        }
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
}