【问题标题】:HTTP POST request Issues (Android Volley)HTTP POST 请求问题 (Android Volley)
【发布时间】:2016-09-05 13:03:53
【问题描述】:

我按照tutorial 将图像从我的手机发送到服务器,但图像从未发送。事实上,应用程序甚至不会尝试发送图像(在 logcat 中)。我在 logcat 中看到的是这样的:

编辑 2:

我在“requestQueue(request)”之后添加了这段代码,图像成功发送到服务器,但是 image_name 有一段时间没有发送到服务器原因。服务器上的文件只是“.jpg”,没有文件名。

int x=1;// retry count
    request.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 48,
            x, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}

编辑 2 后的 LOGCAT:

09-06 20:59:04.530 4188-4194/com.example.android.projectlanguage W/art: Suspending all threads took: 19.394ms
09-06 20:59:10.752 4188-4198/com.example.android.projectlanguage I/art: Background partial concurrent mark sweep GC freed 344902(7MB) AllocSpace objects, 3(39MB) LOS objects, 20% free, 63MB/79MB, paused 1.815ms total 112.441ms
09-06 20:59:16.046 4188-4194/com.example.android.projectlanguage W/art: Suspending all threads took: 7.118ms
09-06 20:59:21.501 4188-9226/com.example.android.projectlanguage D/Volley: [1453] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] http://128.199.77.211/server/connection.php 0x9c36b58 NORMAL 1> [lifetime=14541], [size=314], [rc=200], [retryCount=0]

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.hardware.camera"
    android:required="true" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

MainActivity.java

public class MainActivity extends AppCompatActivity {

private ImageButton ImageButton;
private String encoded_string, image_name;
private Bitmap bitmap;
private File file;
private Uri file_uri;


// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};

/**
 * Checks if the app has permission to write to device storage
 *
 * If the app does not has permission then the user will be prompted to grant permissions
 *
 * @param activity
 */
public static void verifyStoragePermissions(Activity activity) {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(
                activity,
                PERMISSIONS_STORAGE,
                REQUEST_EXTERNAL_STORAGE
        );
    }
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ImageButton = (ImageButton) findViewById(R.id.camera);
    ImageButton.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View view){
            Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            getFileUri();
            i.putExtra(MediaStore.EXTRA_OUTPUT,file_uri);
            startActivityForResult(i,10);
        }
    });
}

private void getFileUri() {
    image_name = "testing123.jpeg";
    file = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), image_name);

    file_uri = Uri.fromFile(file);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if(requestCode == 10 && resultCode == RESULT_OK){
        new Encode_image().execute();
    }
}

private class Encode_image extends AsyncTask<Void,Void,Void> {
   @Override
   protected Void doInBackground(Void... voids){

       bitmap = BitmapFactory.decodeFile(file_uri.getPath());
       ByteArrayOutputStream stream = new ByteArrayOutputStream();
       bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);

       byte[] array = stream.toByteArray();
       encoded_string = Base64.encodeToString(array,0);
       return null;
   }

   @Override
   protected void onPostExecute(Void aVoid){
       makeRequest();
   }
}

private void makeRequest() {
    final TextView mTextView = (TextView) findViewById(R.id.text);
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    String URL = "http://128.199.77.211/server/connection.php";
    StringRequest request = new StringRequest(Request.Method.POST, URL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    mTextView.setText(response);
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            mTextView.setText("That didn't work!");
        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            HashMap<String, String> map = new HashMap<>();
            map.put("encoded_string", encoded_string);
            map.put("image_name", image_name);

            return map;
        }
    };
    requestQueue.add(request);
  }
}

我已确保将 volley 库也包含在 build.gradle 中。

不过,Volley 确实将文本设置为“那行不通!”

编辑:

添加后"Log.e("TAG", "err", error);"对于 onErrorResponse,这是 Logcat 产生的:

09-05 23:21:44.593 18677-18677/com.example.android.projectlanguage E/TAG: err
                                                                      com.android.volley.TimeoutError
                                                                          at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:147)
                                                                          at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:114)

【问题讨论】:

  • volley 执行良好,并在 onErrorResponce 中返回结果并设置文本。可以调试 onErrorResponce 中的 VolleyError 对象吗?这将有助于诊断原因。
  • 那么,你得到了什么错误?将Log.e("TAG", "err", error); 粘贴到onErrorResponse 并告诉我们你得到了什么
  • @Mr Quattro 我已将错误编辑到最后的原始问题中
  • 代码在哪里执行?在实际设备或虚拟机上?地址对我来说似乎很可疑。我会通过 IP 进行连接。由于 localhost 只能通过同一主机访问。甚至 VM 也无法访问绑定到 localhost 或 127.0.0.1 的服务器。绑定到 0.0.0.0 以便从本地网络访问。
  • 当您构建请求时,您需要在 POST.body 中包含“实体”,即您想要的文件。添加该代码。实际上,您的帖子没有正文

标签: java android android-studio android-volley


【解决方案1】:

嘿,这是可以帮助你尝试的课程。

使用

connection = url.openConnection(); 如果您不通过 SSL 发送请求

public class MultipartRequest extends AsyncTask<Void, Integer, String> {

    /**
     * Url for uploading form data to server
     */
    private String serverUrl;

    /**
     * Url for maintaining body paramters
     */
    private HashMap<String, String> bodyParams;

    /**
     * File for uploading
     */
    private File file;

    //Connection Object
    private HttpURLConnection connection = null;

    //Data output stream

    private DataOutputStream outputStream = null;

    private DataInputStream inputStream;

    //Content managers
    private String lineEnd = "\r\n";
    private String twoHyphens = "--";
    private String boundary = "*****";

    //Response callback for request
    private ResponseCallback responseCallback;

    //Response string
    private String responseString = null;

    /**
     * Constructor for multipart request
     *
     * @param url
     * @param bodyParams
     * @param file
     */
    public MultipartRequest(String url, HashMap<String, String> bodyParams,
                            File file, ResponseCallback responseCallback){
        this.serverUrl = url;
        this.bodyParams = bodyParams;
        this.file = file;
        this.responseCallback = responseCallback;
    }

    @Override
    protected String doInBackground(Void... params) {
        try {
            URL url = new URL(serverUrl);
            connection = (HttpsURLConnection) url.openConnection();

            // Allow Inputs & Outputs
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);

            // Enable POST method
            connection.setRequestMethod("POST");

            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            connection.addRequestProperty("Authorization", StorageUtility.getBasicAuth());
            outputStream = new DataOutputStream(connection.getOutputStream());

            // attach body params
            attachBodyParams(outputStream);

            if(file != null) {
                attachFileParams(outputStream);
            }

            System.out.println("+++++++++++++++++++++++"+twoHyphens + boundary + twoHyphens + lineEnd);

            // write bytes
            outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);


            inputStream = new DataInputStream(connection.getInputStream());
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = inputStream.readLine()) != null) {
                response.append(line).append('\n');
            }

            responseString = response.toString();
        }catch (ProtocolException pe){
            pe.printStackTrace();
        }catch (IOException io){
            io.printStackTrace();
        }

        return null;
    }

    /**
     * Attach body params
     * @param outputStream
     * @throws IOException
     */
    public void attachBodyParams(DataOutputStream outputStream) throws IOException{
        for(String key : bodyParams.keySet()) {
            outputStream.writeBytes(twoHyphens + boundary + lineEnd);
            outputStream.writeBytes("Content-Disposition: form-data; name=\" " + key + "\"");
            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes(bodyParams.get(key));
            outputStream.writeBytes(lineEnd);
        }
    }

    /**
     * if there is file attach file at the end of
     * body
     *
     * @param outputStream
     * @throws IOException
     */
    public void attachFileParams(DataOutputStream outputStream) throws IOException{

        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;

        FileInputStream fileInputStream = new FileInputStream(file);

        outputStream.writeBytes(twoHyphens + boundary + lineEnd);
        outputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"");
        outputStream.writeBytes(lineEnd);
        outputStream.writeBytes("Content-Type: application/*");
        outputStream.writeBytes(lineEnd);
        outputStream.writeBytes(lineEnd);

        //hier File schreiben
        bytesAvailable = fileInputStream.available();
        bufferSize = Math.min(bytesAvailable, maxBufferSize);
        buffer = new byte[bufferSize];
        bytesRead = fileInputStream.read(buffer, 0, bufferSize);

        while (bytesRead > 0) {
            outputStream.write(buffer, 0, bufferSize);
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        }

        outputStream.writeBytes(lineEnd);

        fileInputStream.close();
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        try {
            responseCallback.onResponse(new JSONObject(responseString.toString()));
        }catch (JSONException je){
            je.printStackTrace();
            logger.error(StackTraceUtility.getStackTrace(je));
        } catch (NullPointerException ne){
            ne.printStackTrace();
            logger.error((StackTraceUtility.getStackTrace(ne)));
        }
    }
}

只需用

创建实例
new MultipartRequest(url, bodyParams,
                       file, responseCallback)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多