【问题标题】:Sending pictures to a web server将图片发送到 Web 服务器
【发布时间】:2011-07-21 21:14:57
【问题描述】:

我必须构建一个应用程序,该应用程序应该将图片从手机发送到网络服务器。不幸的是,我真的不知道该怎么做。有人可以帮帮我吗?

【问题讨论】:

  • 您能指定服务器堆栈和 API 吗?
  • 感谢您的回复,Ravi...这是 google apis 1.5,我不确定您所说的服务器堆栈是什么意思...您能解释一下吗?我对android有点陌生..
  • @Ravi:他没有说任何异常。
  • & @Mudassir ,服务器堆栈与您使用的后端/服务器一样:-)

标签: android


【解决方案1】:

使用网络服务来完成这项任务。

为了在android中使用网络服务,请访问此链接。

  1. kSoap2 用于从 android 调用 web 服务的库 设备。
  2. Calling simple web service in android.
  3. Calling web service & uploading file through HttpClient
  4. Web Service That Returns An Array of Objects With KSOAP - 对于 复杂的对象。
  5. Accessing a JAX-WS web service from Android
  6. How-to: Android as a RESTful Client

【讨论】:

  • 感谢您一步一步的建议,Shashank。我会试试看效果如何。
【解决方案2】:

这是我使用原始套接字将图像上传到远程服务器的代码。原始套接字优于 httpclient 的优点是您可以显示上传进度条。

免责声明:大部分代码主要来自stackoverflow。

/**
 * Asynchronous task to upload file to server
 */
class UploadImageTask extends AsyncTask<File, Integer, Boolean> {

    /** Upload file to this url */
    private static final String UPLOAD_URL = "http://thibault-laptop:8080/report";

    /** Send the file with this form name */
    private static final String FIELD_FILE = "file";
    private static final String FIELD_LATITUDE = "latitude";
    private static final String FIELD_LONGITUDE = "longitude";

    /**
     * Prepare activity before upload
     */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        setProgressBarIndeterminateVisibility(true);
        mConfirm.setEnabled(false);
        mCancel.setEnabled(false);
        showDialog(UPLOAD_PROGRESS_DIALOG);
    }

    /**
     * Clean app state after upload is completed
     */
    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        setProgressBarIndeterminateVisibility(false);
        mConfirm.setEnabled(true);
        mDialog.dismiss();

        if (result) {
            showDialog(UPLOAD_SUCCESS_DIALOG);
        } else {
            showDialog(UPLOAD_ERROR_DIALOG);
        }
    }

    @Override
    protected Boolean doInBackground(File... image) {
        return doFileUpload(image[0], UPLOAD_URL);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);

        if (values[0] == 0) {
            mDialog.setTitle(getString(R.string.progress_dialog_title_uploading));
        }

        mDialog.setProgress(values[0]);
    }

    /**
     * Upload given file to given url, using raw socket
     * @see http://stackoverflow.com/questions/4966910/androidhow-to-upload-mp3-file-to-http-server
     *
     * @param file The file to upload
     * @param uploadUrl The uri the file is to be uploaded
     *
     * @return boolean true is the upload succeeded
     */
    private boolean doFileUpload(File file, String uploadUrl) {
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        String separator = twoHyphens + boundary + lineEnd;
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;
        int sentBytes = 0;
        long fileSize = file.length();

        // The definitive url is of the kind:
        // http://host/report/latitude,longitude
        uploadUrl += "/" + mLocation.getLatitude() + "," + mLocation.getLongitude();

        // Send request
        try {
            // Configure connection
            URL url = new URL(uploadUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("PUT");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            publishProgress(0);

            dos = new DataOutputStream(conn.getOutputStream());

            // Send location params
            writeFormField(dos, separator, FIELD_LATITUDE, "" + mLocation.getLatitude());
            writeFormField(dos, separator, FIELD_LONGITUDE, "" + mLocation.getLongitude());

            // Send multipart headers
            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name=\"" + FIELD_FILE + "\";filename=\""
                    + file.getName() + "\"" + lineEnd);
            dos.writeBytes(lineEnd);

            // Read file and create buffer
            FileInputStream fileInputStream = new FileInputStream(file);
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];

            // Send file data
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            while (bytesRead > 0) {
                // Write buffer to socket
                dos.write(buffer, 0, bufferSize);

                // Update progress dialog
                sentBytes += bufferSize;
                publishProgress((int)(sentBytes * 100 / fileSize));

                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            }

            // send multipart form data necesssary after file data
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
            dos.flush();
            dos.close();
            fileInputStream.close();
        } catch (IOException ioe) {
            Log.e(TAG, "Cannot upload file: " + ioe.getMessage(), ioe);
            return false;
        }

        // Read response
        try {
            int responseCode = conn.getResponseCode();
            return responseCode == 200;
        } catch (IOException ioex) {
            Log.e(TAG, "Upload file failed: " + ioex.getMessage(), ioex);
            return false;
        } catch (Exception e) {
            Log.e(TAG, "Upload file failed: " + e.getMessage(), e);
            return false;
        }
    }

    private void writeFormField(DataOutputStream dos, String separator, String fieldName, String fieldValue) throws IOException
    {
        dos.writeBytes(separator);
        dos.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"\r\n");
        dos.writeBytes("\r\n");
        dos.writeBytes(fieldValue);
        dos.writeBytes("\r\n");
    }
}

要开始上传,请使用以下命令:

new UploadImageTask().execute(new File(imagePath));

【讨论】:

    【解决方案3】:

    我确实在 Android 中使用了 Rest webservice 和 DefaultHttpClient 类。要创建示例 REST Web 服务并在 Apache Tomcat 中部署,请按照教程Vogella

    为了让rest服务接受图片,服务器端需要multipart content-type

    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces("application/json")
    public String uploadFile(@FormDataParam("image") InputStream uploadedInputStream,
            @FormDataParam("image") FormDataContentDisposition fileDetail) {
    
        String uploadedFileLocation = "e://game/" + fileDetail.getFileName();
        boolean response=false;
        // save it
        try{
            OutputStream out = null;
            int read = 0;
            byte[] bytes = new byte[1024]; 
            out = new FileOutputStream(new File(uploadedFileLocation));
            while ((read = uploadedInputStream.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
            return response=true;
        }catch(IOException e){
            e.printStackTrace();
        }
        return response;
    
    }
    

    在android端发送图片(我是在AsyncTask的doInBackground里面做的)

                HttpClient httpClient = new DefaultHttpClient();
                HttpPost postRequest = new HttpPost("http://"+ip+":8080/MiniJarvisFaceServer/image");
                MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
                reqEntity.addPart("image", new FileBody(file));
                postRequest.setEntity(reqEntity);
                ResponseHandler<String> handler = new BasicResponseHandler();           
                String response = httpClient.execute(postRequest,handler);
                Log.d("Response", response);
                httpClient.getConnectionManager().shutdown();
    

    【讨论】:

      【解决方案4】:

      要执行 HTTP 请求,您可以使用 DefaultHttpClient 类和 HttpPost

      HttpClient client = new DefaultHttpClient();
      HttpPost post = new HttpPost("http://your.site/your/service");
      // set some headers if needed
      post.addHeader(....);
      // and an eclosed entity to send
      post.setEntity(....);
      // send a request and get response (if needed)
      InputStream responseStream = client.execute(post)..getEntity().getContent();
      

      将实体添加到请求的方法取决于您的远程服务的工作方式。

      【讨论】:

      • 感谢 Olegas,感谢示例代码。我会试试看效果如何。
      【解决方案5】:

      按照本指南进行操作。它在服务器端使用 PHP。我使用了 Android Studio 和 httpmime.4.3.6 并且工作得很好 http://www.androidhive.info/2014/12/android-uploading-camera-image-video-to-server-with-progress-bar/

      它还支持视频,并展示了如何使用服务器的一些结果进行响应。唯一棘手的一点是确保您使用的是适用于 Android 的 HttClient 和正确版本的 HttpMime。现在 HttpMime 4.4.x 不工作,浪费了我一周的时间。使用 4.3.6

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-18
        • 2015-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-29
        • 2011-10-14
        相关资源
        最近更新 更多