我正在制作一个应用程序,用户可以在其中添加来自画廊的图像,从相机捕获图像或附加PDF文件,因此我想使用截击来发送文件。我编写了MultipartRequest类,可以在其中使用ByArrayOutputStream传递位图。但是现在我要发送文件。片段中有一个sendLeave(),该片段与其他参数一起发送文件。只有MultipartRequest类和SendLeave()才是与此问题相关的代码,而其他有关如何创建文件的代码。
MultipartRequest类
public class MultipartRequest extends Request<NetworkResponse> {
private final String twoHyphens = "--";
private final String lineEnd = "\r\n";
private final String boundary = "apiclient-" + System.currentTimeMillis();
private Response.Listener<NetworkResponse> mListener;
private Response.ErrorListener mErrorListener;
private Map<String, String> mHeaders;
public MultipartRequest(int method, String url,
Response.Listener<NetworkResponse> listener,
Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return (mHeaders != null) ? mHeaders : super.getHeaders();
}
@Override
public String getBodyContentType() {
return "multipart/form-data;boundary=" + boundary;
}
@Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
try {
// populate text payload
Map<String, String> params = getParams();
if (params != null && params.size() > 0) {
textParse(dos, params, getParamsEncoding());
}
// populate data byte payload
Map<String, DataPart> data = getByteData();
if (data != null && data.size() > 0) {
dataParse(dos, data);
}
// close multipart form data after text and file data
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* Custom method handle data payload.
*
* @return Map data part label with data byte
* @throws AuthFailureError
*/
protected Map<String, DataPart> getByteData() throws AuthFailureError {
return null;
}
@Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
try {
return Response.success(
response,
HttpHeaderParser.parseCacheHeaders(response));
} catch (Exception e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(NetworkResponse response) {
mListener.onResponse(response);
}
@Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
/**
* Parse string map into data output stream by key and value.
*
* @param dataOutputStream data output stream handle string parsing
* @param params string inputs collection
* @param encoding encode the inputs, default UTF-8
* @throws IOException
*/
private void textParse(DataOutputStream dataOutputStream, Map<String, String> params, String encoding) throws IOException {
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
buildTextPart(dataOutputStream, entry.getKey(), entry.getValue());
}
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + encoding, uee);
}
}
/**
* Parse data into data output stream.
*
* @param dataOutputStream data output stream handle file attachment
* @param data loop through data
* @throws IOException
*/
private void dataParse(DataOutputStream dataOutputStream, Map<String, DataPart> data) throws IOException {
for (Map.Entry<String, DataPart> entry : data.entrySet()) {
buildDataPart(dataOutputStream, entry.getValue(), entry.getKey());
}
}
/**
* Write string data into header and data output stream.
*
* @param dataOutputStream data output stream handle string parsing
* @param parameterName name of input
* @param parameterValue value of input
* @throws IOException
*/
private void buildTextPart(DataOutputStream dataOutputStream, String parameterName, String parameterValue) throws IOException {
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + parameterName + "\"" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(parameterValue + lineEnd);
}
/**
* Write data file into header and data output stream.
*
* @param dataOutputStream data output stream handle data parsing
* @param dataFile data byte as DataPart from collection
* @param inputName name of data input
* @throws IOException
*/
private void buildDataPart(DataOutputStream dataOutputStream, DataPart dataFile, String inputName) throws IOException {
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" +
inputName + "\"; filename=\"" + dataFile.getFileName() + "\"" + lineEnd);
if (dataFile.getType() != null && !dataFile.getType().trim().isEmpty()) {
dataOutputStream.writeBytes("Content-Type: " + dataFile.getType() + lineEnd);
}
dataOutputStream.writeBytes(lineEnd);
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dataFile.getContent());
int bytesAvailable = fileInputStream.available();
int maxBufferSize = 1024 * 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dataOutputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
dataOutputStream.writeBytes(lineEnd);
}
class DataPart {
private String fileName;
private byte[] content;
private String type;
public DataPart() {
}
DataPart(String name, byte[] data) {
fileName = name;
content = data;
}
String getFileName() {
return fileName;
}
byte[] getContent() {
return content;
}
String getType() {
return type;
}
}
}
附加文档片段
public class LeaveCreate extends Fragment {
File files;
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
btnAttach.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final Dialog dialog = new Dialog(getActivity());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_layout);
dialog.show();
Button btnGallery = (Button) dialog.findViewById(R.id.btnGallery);
Button btnFile = (Button) dialog.findViewById(R.id.btnFile);
Button btnCamera = (Button) dialog.findViewById(R.id.btnCamera);
btnGallery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setType("image/*");
startActivityForResult(pickIntent,1);
}
});
btnFile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(Intent.createChooser(intent,"Select a File to Upload"),2);
}catch (android.content.ActivityNotFoundException ex){
Toast.makeText(getActivity(), "Please Install a File Manager",Toast.LENGTH_SHORT).show();
}
}
});
btnCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
String filename = "digimTemp.jpg";
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Images.Media.TITLE,filename);
mCapturedImageURI = getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,mCapturedImageURI);
startActivityForResult(cameraIntent,3);
}
});
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SendLeave();
}
});
return view;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 1) {
if (resultCode == Activity.RESULT_OK) {
Uri selectedImageUri = data.getData();
String path = getRealPathFromURI(getActivity(),selectedImageUri);
// Toast.makeText(getBaseContext(),path,
// Toast.LENGTH_LONG).show();
files = new File(path.substring(0,path.lastIndexOf("/")),path.substring(path.lastIndexOf("/"),path.length()));
btnAttach.setText("Gallery");
Bitmap b = null;
try {
b = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), selectedImageUri);
} catch (IOException e) {
e.printStackTrace();
}
Drawable d = new BitmapDrawable(getResources(), b);
d.setBounds(0, 0, 60, 60);
btnAttach.setCompoundDrawables(d, null, null, null);
btnAttach.setCompoundDrawablePadding(20);
}
}
else if (requestCode == 2) {
if (resultCode == Activity.RESULT_OK) {
Uri selectedImageUri = data.getData();
String path = null;
path = getPath(getActivity(),selectedImageUri);
Toast.makeText(getActivity().getBaseContext(),path,
Toast.LENGTH_LONG).show();
files = new File(path.substring(0,path.lastIndexOf("/")),path.substring(path.lastIndexOf("/"),path.length()));
btnAttach.setText(path.substring(path.lastIndexOf("/")+1,path.length()));
}
}
else if(requestCode == 3)
{
if (resultCode == Activity.RESULT_OK) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection, null, null, null);
int column_index_data = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToLast();
String path = cursor.getString(column_index_data);
Bitmap photo = BitmapFactory.decodeFile(path);
// CALL THIS METHOD TO GET THE URI FROM THE BITMAP
// Uri tempUri = getImageUri(getApplicationContext(), bitmap);
files = new File(path.substring(0,path.lastIndexOf("/")),path.substring(path.lastIndexOf("/"),path.length()));
if (Integer.parseInt(String.valueOf(files.length() / 1024)) > 100) {
// filesize=String.valueOf(files.length()/1048576)+" MB";
}
btnAttach.setText("Camera");
// attachment.setDrawableLe
Drawable d = new BitmapDrawable(getResources(), photo);
d.setBounds(0, 0, 60, 60);
btnAttach.setCompoundDrawables(d, null, null, null);
btnAttach.setCompoundDrawablePadding(20);
}
}
}
}
public void SendLeave(){
progressDialog.show();
MultipartRequest multipartRequest = new MultipartRequest(Request.Method.POST, SEND_LEAVE_URL, new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("parent_id", SharedPreferenceManager.getmInstance(getActivity()).getID());
params.put("student_id",studentid);
params.put("reason",txtReason.getText().toString());
params.put("start_date",txtFromDate.getText().toString());
params.put("end_date",txtToDate.getText().toString());
int i=0;
for (String temp: teacherid){
params.put("teacher_id["+(i++)+"]", temp);
}
return params;
}
@Override
protected Map<String, MultipartRequest.DataPart> getByteData() {
Map<String, MultipartRequest.DataPart> params = new HashMap<>();
params.put("file", new MultipartRequest.DataPart());
return params;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> headers = super.getHeaders();
if (headers == null || headers.equals(Collections.<String, String>emptyMap())){
headers = new HashMap<String, String>();
}
MyApp.get().addSessionCookie(headers);
return headers;
}
};
RequestQueue queue = Volley.newRequestQueue(getContext());
queue.add(multipartRequest);
}
答案 0 :(得分:0)
Volley不支持多段文件
但是有一个名为Volley Plus的定制凌空库,它支持多部分文件 或使用http url连接发送文件。 遵循this。 使用http url连接,您还可以轻松显示上传进度
答案 1 :(得分:0)
这是我用来上传PDF的内容,但是您可以将其用于任何文件。我使用了相同的VolleyMultipartRequest,您只需要从文件中获取数据就可以上传它。希望对您有帮助!
private void uploadPDF() {
VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(
Request.Method.POST,
url,
new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
//Handle response
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//Handle error
}
}
) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
//Params
return params;
}
@Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
String pdfName = String.valueOf(System.currentTimeMillis() + ".pdf");
params.put("pdf", new DataPart(pdfName, getFileData()));
return params;
}
};
//I used this because it was sending the file twice to the server
volleyMultipartRequest.setRetryPolicy(
new DefaultRetryPolicy(
0,
-1,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
)
);
requestQueue.add(volleyMultipartRequest);
}
private byte[] getFileData() {
int size = (int) pdf.length();
byte[] bytes = new byte[size];
byte[] tmpBuff = new byte[size];
try (FileInputStream inputStream = new FileInputStream(pdf)) {
int read = inputStream.read(bytes, 0, size);
if (read < size) {
int remain = size - read;
while (remain > 0) {
read = inputStream.read(tmpBuff, 0, remain);
System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
remain -= read;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return bytes;
}