【问题标题】:Android file upload to server (written in PHP) not workingAndroid文件上传到服务器(用PHP编写)不起作用
【发布时间】:2014-06-02 13:52:20
【问题描述】:

我是 PHP 新手。我正在构建一个需要将图像上传到我的服务器的 android 项目。我遇到的问题是,当我只向服务器发送一个键和一个值(无文件)时,它工作得很好。但是,一旦我尝试发送文件,php 中的超全局变量 $_POST 和 $_FILES 就是空的!发送的文件很小,所以它与file_max_upload_size无关。文件未损坏。我认为这与android模拟器上应用程序发送的InputStream的编码有关。我的代码如下:

应用程序中用于发送图像和键值对的 Java 代码:

    public Future<JSONObject> asyncSendPOSTRequest(String URL, Map<String, String> params, Map<String, Pair<String,InputStream>> files) throws InterruptedException, ExecutionException, JSONException, UnsupportedEncodingException {  
            HttpPost request = new HttpPost(URL);
            MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
            if(params!=null) {
                for(String key : params.keySet()) {
                    multipartEntity.addTextBody(key, params.get(key), ContentType.TEXT_PLAIN);
                }
            }
            if(files!=null) {
                for(String key : files.keySet()) {
                    multipartEntity.addPart(key, new InputStreamBody(files.get(key).second,ContentType.MULTIPART_FORM_DATA, files.get(key).first));
                }
            }
            request.setEntity(multipartEntity.build());


Future<JSONObject> future = threadPool.submit(new executeRequest(request));
        return future;
    }
//Thread to communicate with server.
    private class executeRequest implements Callable<JSONObject> {

        HttpRequestBase request;

        public executeRequest(HttpRequestBase request) {
            this.request = request;
        }
        @Override
        public JSONObject call() throws Exception {
            HttpResponse httpResponse = httpClient.execute(request);
            BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
            StringBuilder stringReply = new StringBuilder();
            String replyLine;
            while ((replyLine = reader.readLine()) != null) {
                stringReply.append(replyLine);
            }
            return new JSONObject(stringReply.toString());
        }   
    }

服务器上的代码:

#!/usr/bin/php
<?php
$uploads_dir = __DIR__ . '/uploads';
$status = -1;
    if ($_FILES["picture"]["error"] == UPLOAD_ERR_OK) {
        $tmp_name = $_FILES["picture"]["tmp_name"];
        $name = $_FILES["picture"]["name"];
        $status = move_uploaded_file($tmp_name, "$uploads_dir/$name");
    }
$response["status"] = $status;
$response["user_id"] = $_POST["user_id"];
$response["name"] =  $name;
$response["extension"] = end (explode(".", $name));
echo json_encode($response);
?>

【问题讨论】:

    标签: java php android apache


    【解决方案1】:

    你设置错误数据类型的可能问题

    enctype="multipart/form-data"
    

    【讨论】:

    • 我将其更改为 ContentType.APPLICATION_OCTET_STREAM。还是不行!
    【解决方案2】:
    public class Helpher extends AsyncTask<String, Void, String> {
        Context context;
        JSONObject json;
        ProgressDialog dialog;
        int serverResponseCode = 0;
        DataOutputStream dos = null;
        FileInputStream fis = null;
        BufferedReader br = null;
    
    
        public Helpher(Context context) {
            this.context = context;
        }
    
        protected void onPreExecute() {
    
            dialog = ProgressDialog.show(Main2Activity.this, "ProgressDialog", "Wait!");
        }
    
        @Override
        protected String doInBackground(String... arg0) {
    
            try {
                File f = new File(arg0[0]);
                URL url = new URL("http://localhost:8888/imageupload.php");
                int bytesRead;
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.setUseCaches(false);
                conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
    
                String contentDisposition = "Content-Disposition: form-data; name=\"keyValueForFile\"; filename=\""
                        + f.getName() + "\"";
                String contentType = "Content-Type: application/octet-stream";
    
    
                dos = new DataOutputStream(conn.getOutputStream());
                fis = new FileInputStream(f);
    
                dos.writeBytes(SPACER + BOUNDARY + NEW_LINE);
                dos.writeBytes("Content-Disposition: form-data; name=\"parameterKey\""
                        + NEW_LINE);
                dos.writeBytes(NEW_LINE);
                dos.writeBytes("parameterValue" + NEW_LINE);
    
                dos.writeBytes(SPACER + BOUNDARY + NEW_LINE);
                dos.writeBytes(contentDisposition + NEW_LINE);
                dos.writeBytes(contentType + NEW_LINE);
                dos.writeBytes(NEW_LINE);
                byte[] buffer = new byte[MAX_BUFFER_SIZE];
                while ((bytesRead = fis.read(buffer)) != -1) {
                    dos.write(buffer, 0, bytesRead);
                }
                dos.writeBytes(NEW_LINE);
                dos.writeBytes(SPACER + BOUNDARY + SPACER);
                dos.flush();
    
                int responseCode = conn.getResponseCode();
                if (responseCode != 200) {
                    Log.w(TAG,
                            responseCode + " Error: " + conn.getResponseMessage());
                    return null;
                }
    
                br = new BufferedReader(
                        new InputStreamReader(conn.getInputStream()));
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
                Log.d(TAG, "Sucessfully uploaded " + f.getName());
    
            } catch (MalformedURLException e) {
            } catch (IOException e) {
            } finally {
                try {
                    dos.close();
                    if (fis != null)
                        fis.close();
                    if (br != null)
                        br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return String.valueOf(serverResponseCode);
        }
    
    
        @Override
        protected void onPostExecute(String result) {
            dialog.dismiss();
    
        }
    
    }
    

    这是用于从 Android 上传图像的 AsyncTask“Helpher”类。要调用此类,请使用以下语法。

    new Main2Activity.Helpher(this).execute(fileUri.getPath(),parameterValue);
    

    这里fileUri.getPath()本地图片位置。如果你想在“StringBuilder sb”中查看服务器响应值可以打印sb值

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-17
      • 2014-10-29
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多