Volley PUT图像请求

时间:2016-12-15 10:20:50

标签: java android android-volley multipart

我正在尝试上传图像的凌空PUT请求,因为httpEntity现在已被弃用,我不得不做一些其他的研究,我遇到了这些解决方案,并尝试将它们实现到我的代码中: 1. https://gist.github.com/anggadarkprince/a7c536da091f4b26bb4abf2f92926594 2. How to send multipart request using Volley without HttpEntity? 3. Working POST Multipart Request with Volley and without HttpEntity 但我仍然无法上传我的图像。我要上传的图像要么从相机中捕获,要么在图库中选择,并在onClick上执行。

ProfileSetting.java

public class ProfileSetting extends AppCompatActivity implements AdapterView.OnItemSelectedListener {

private ImageView CustomerIcon;
private Button confirm_button;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_profile_setting);
    CustomerIcon = (ImageView) findViewById(R.id.CustomerIcon);
    confirm_button = (Button) findViewById(R.id.confirm_button);
    CustomerIcon.setOnClickListener(new ImageView.OnClickListener(){
        public void onClick(View v){

            showPickImageDialog();

        }


    });

    confirm_button.setOnClickListener(new Button.OnClickListener(){
        @Override
        public void onClick(View view) {

            //PUT VOLLEY
            saveProfileAccount();

        }
    });
}
private void showPickImageDialog() {
    AlertDialog.Builder builderSingle = new AlertDialog.Builder(ProfileSetting.this);
    builderSingle.setTitle("Choose Profile Icon");

    final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
            ProfileSetting.this,
            android.R.layout.select_dialog_singlechoice);
    arrayAdapter.add("Gallery");
    arrayAdapter.add("Camera");

    builderSingle.setNegativeButton(
            "cancel",
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });

    builderSingle.setAdapter(
            arrayAdapter,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    switch (which) {
                        case 0:
                            Intent pickPhoto = new Intent(Intent.ACTION_PICK,
                                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                            startActivityForResult(pickPhoto, 1);
                            break;

                        case 1:
                            Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                            startActivityForResult(takePicture, 0);
                            break;
                    }

                }
            });
    builderSingle.show();
}
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    switch(requestCode) {
        case 0:
            if(resultCode == RESULT_OK){


                Uri selectedImage = imageReturnedIntent.getData();
                CustomerIcon.setImageURI(selectedImage);

            }

            break;
        case 1:
            if(resultCode == RESULT_OK){

                Uri selectedImage = imageReturnedIntent.getData();
                CustomerIcon.setImageURI(selectedImage);

            }
            break;
    }
}
private void saveProfileAccount() {
    // loading or check internet connection or something...
    // ... then


    String url = "https://url to put image to";
    SharedPreferences sp1=this.getSharedPreferences("FINALTOKEN", Context.MODE_PRIVATE);
    final String finalToken = sp1.getString("FINALTOKEN","");


    VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.PUT, url, new Response.Listener<NetworkResponse>() {
        @Override
        public void onResponse(NetworkResponse response) {
            String resultResponse = new String(response.data);
            try {
                JSONObject result = new JSONObject(resultResponse);
                String status = result.getString("status");
                String message = result.getString("message");

                if (status.equals(Constant.REQUEST_SUCCESS)) {
                    // tell everybody you have succeed upload image and post strings
                    Log.i("Messsage", message);
                } else {
                    Log.i("Unexpected", message);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            NetworkResponse networkResponse = error.networkResponse;
            String errorMessage = "Unknown error";
            if (networkResponse == null) {
                if (error.getClass().equals(TimeoutError.class)) {
                    errorMessage = "Request timeout";
                } else if (error.getClass().equals(NoConnectionError.class)) {
                    errorMessage = "Failed to connect server";
                }
            } else {
                String result = new String(networkResponse.data);
                try {
                    JSONObject response = new JSONObject(result);
                    String status = response.getString("status");
                    String message = response.getString("message");

                    Log.e("Error Status", status);
                    Log.e("Error Message", message);

                    if (networkResponse.statusCode == 404) {
                        errorMessage = "Resource not found";
                    } else if (networkResponse.statusCode == 401) {
                        errorMessage = message+" Please login again";
                    } else if (networkResponse.statusCode == 400) {
                        errorMessage = message+ " Check your inputs";
                    } else if (networkResponse.statusCode == 500) {
                        errorMessage = message+" Something is getting wrong";
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            Log.i("Error", errorMessage);
            error.printStackTrace();
        }
    }) {
        @Override
        public Map<String,String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers= new HashMap<>();
            headers.put("Authorization",finalToken);
            return headers;
        }

        @Override
        protected Map<String, DataPart> getByteData() {
            Map<String, DataPart> params = new HashMap<>();
            // file name could found file base or direct access from real path
            // for now just get bitmap data from ImageView
            params.put("avatar", new DataPart("file_avatar.jpg", ImageConverter.getFileDataFromDrawable(getBaseContext(), CustomerIcon.getDrawable()), "image/jpeg"));

            return params;
        }
    };

    VolleySingleton.getInstance(getBaseContext()).addToRequestQueue(multipartRequest);
}
}

VolleyMultipartRequest.java和VolleySingleton.java我使用的是与第一个链接相同的类。

我的错误首先是我无法在if语句中解析符号'Constant':

if (status.equals(Constant.REQUEST_SUCCESS))

所以我尝试评论该语句,运行代码后出现以下错误:

BasicNetwork.performRequest: Unexpected response code 500 for https://my url

W/System.err: org.json.JSONException: No value for status

我不确定是什么原因导致我的问题,请帮助,谢谢!

2 个答案:

答案 0 :(得分:0)

这是使用Volley Android上传文件的简单解决方案和完整示例

1)Gradle Import

compile 'dev.dworks.libs:volleyplus:+'

2)现在创建一个类RequestManager

public class RequestManager {
    private static RequestManager mRequestManager;
    /**
     * Queue which Manages the Network Requests :-)
     */
    private static RequestQueue mRequestQueue;
    // ImageLoader Instance

    private RequestManager() {

    }

    public static RequestManager get(Context context) {

        if (mRequestManager == null)
            mRequestManager = new RequestManager();

        return mRequestManager;
    }

    /**
     * @param context application context
     */
    public static RequestQueue getnstance(Context context) {

        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(context);
        }

        return mRequestQueue;

    }


}

3)现在创建一个类来处理上传File WebService的请求

public class WebService {
    private RequestQueue mRequestQueue;
    private static WebService apiRequests = null;

    public static WebService getInstance() {
        if (apiRequests == null) {
            apiRequests = new WebService();
            return apiRequests;
        }
        return apiRequests;
    }
    public void updateProfile(Context context, String doc_name, String doc_type, String appliance_id, File file, Response.Listener<String> listener, Response.ErrorListener errorListener) {
        SimpleMultiPartRequest request = new SimpleMultiPartRequest(Request.Method.POST, "YOUR URL HERE", listener, errorListener);
//        request.setParams(data);
        mRequestQueue = RequestManager.getnstance(context);
        request.addMultipartParam("token", "text", "tdfysghfhsdfh");
        request.addMultipartParam("parameter_1", "text", doc_name);
        request.addMultipartParam("dparameter_2", "text", doc_type);
        request.addMultipartParam("parameter_3", "text", appliance_id);
            request.addFile("document_file", file.getPath());

        request.setFixedStreamingMode(true);
        mRequestQueue.add(request);
    }
}

4)现在调用方法Like This to Hit the service

public class Main2Activity extends AppCompatActivity implements Response.ErrorListener, Response.Listener<String>{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Button button=(Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                uploadData();
            }
        });
    }

    private void uploadData() {
        WebService.getInstance().updateProfile(getActivity(), "appl_doc", "appliance", "1", mChoosenFile, this, this);
    }

    @Override
    public void onErrorResponse(VolleyError error) {

    }

    @Override
    public void onResponse(String response) {
     //Your response here 
    }
}

mChoosenFile是您的图片文件

答案 1 :(得分:0)

首先使用以下代码将图像位图转换为base64字符串:

public String getStringImage(Bitmap bmp){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] imageBytes = baos.toByteArray();
        String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
        return encodedImage;
    }

然后创建类似下面的PUT请求并将base64字符串作为请求的参数传递

url = "http://example.com";
StringRequest putRequest = new StringRequest(Request.Method.PUT, url, 
    new Response.Listener<String>() 
    {
        @Override
        public void onResponse(String response) {
            // response
            Log.d("Response", response);
        }
    }, 
    new Response.ErrorListener() 
    {
         @Override
         public void onErrorResponse(VolleyError error) {
                         // error
             Log.d("Error.Response", response);
       }
    }
) {

    @Override
    protected Map<String, String> getParams() 
    {  
            Map<String, String>  params = new HashMap<String, String> ();  
            params.put("imageString", base64String);  
            return params;  
    }

};

queue.add(putRequest);

如果您在实施截击请求时遇到任何困难,请参阅Android Volley Tutorial