android图片上传
16lz
2022-06-09
最近项目上需要图片上传功能,所以开始查询相关资料,并终于实现。
android这边使用得是android studio,后台处理这边使用得是eclipse中servlet
首先是布局:(比较简单)
<?xml version="1.0" encoding="utf-8"?>
然后是activity
相册和拍照2种方式
final CharSequence[] items = {"相册", "拍照"}; AlertDialog.Builder dlg = new AlertDialog.Builder(UploadActivity.this); dlg.setTitle("添加图片"); dlg.setTitle("添加图片"); dlg.setItems(items, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { // 这里item是根据选择的方式, if (item == 0) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, RESULT_LOAD_IMG); } else { try { Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, 0); } catch (Exception e) { e.printStackTrace(); } } } }).create(); dlg.show();
重写onActivityResult方法
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); try { if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK && null != data) { Uri selectedImage = data.getData(); String[] filePathColumn = { MediaStore.Images.Media.DATA }; // 获取游标 Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); imgPath = cursor.getString(columnIndex); cursor.close(); ImageView imgView = (ImageView) findViewById(R.id.imageView); imgView.setImageBitmap(BitmapFactory.decodeFile(imgPath)); } else if(requestCode ==0){ Bundle bundle = data.getExtras(); bitmap = (Bitmap) bundle.get("data"); ImageView imgView = (ImageView) findViewById(R.id.imageView); imgView.setImageBitmap(bitmap); encodeImagetoString(bitmap); } else{ Toast.makeText(this, "You haven't picked Image", Toast.LENGTH_LONG).show(); } } catch (Exception e) { Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG).show(); } }
将图片转64编码
private void encodeImagetoString( Bitmap b) { new AsyncTask() { protected void onPreExecute() { }; @Override protected String doInBackground(Void... params) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); // 压缩图片 bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream); byte[] byte_arr = stream.toByteArray(); // Base64图片转码为String encodedString = Base64.encodeToString(byte_arr, 0); return ""; } @Override protected void onPostExecute(String msg) { prgDialog.setMessage("Calling Upload"); // 将转换后的图片添加到上传的参数中 params.put("image", encodedString); Toast.makeText(getApplicationContext(), encodedString.length()+"", Toast.LENGTH_LONG).show(); params.put("filename", "bbb"); // 上传图片 imageUpload(); } }.execute(null, null, null); }
上传图片
public void imageUpload() { prgDialog.setMessage("Invoking JSP"); String url = AppConfig.URLS.UPLOADPIC; AsyncHttpClient client = new AsyncHttpClient(); client.post(url, params, new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] bytes) { prgDialog.hide(); Toast.makeText(getApplicationContext(), "upload success", Toast.LENGTH_LONG).show(); } @Override public void onFailure(int statusCode, Header[] headers, byte[] bytes, Throwable throwable) { prgDialog.hide(); if (statusCode == 404) { Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show(); } // 当 Http 响应码'500' else if (statusCode == 500) { Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show(); } // 当 Http 响应码 404, 500 else { Toast.makeText( getApplicationContext(), "Error Occured n Most Common Error: n1. Device " + "not connected to Internetn2. Web App is not deployed in App servern3." + " App server is not runningn HTTP Status code : " + statusCode, Toast.LENGTH_LONG).show(); } } }); }
这段代码使用到了android-async-http-1.4.8.jar,其中使用时,一个Header[]类找不到,因此,经过查询后,解决办法如下:
useLibrary 'org.apache.http.legacy' 此段代码加build.gradle到配置文件中即可
最后,这个所使用到的权限:
这样,android端就完成了,就差java后台接受上传至服务器中。
接下来是Java后台,我这里的后台在Tomcat中运行
UploadImage(servlet)
@WebServlet("/UploadImage")public class UploadImage extends HttpServlet {private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public UploadImage() { super(); // TODO Auto-generated constructor stub }/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubSystem.out.println("get");}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubrequest.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");String imgEncodedStr = request.getParameter("image");String fileName = request.getParameter("filename");System.out.println("Filename: "+ fileName);//System.out.println(imgEncodedStr);if(imgEncodedStr != null){ convertStringtoImage(imgEncodedStr, fileName); System.out.print("Image upload complete, Please check your directory"); } else{ System.out.print("图片为空"); }} public void convertStringtoImage(String encodedImageStr, String fileName) { try { // Base64解码图片 byte[] imageByteArray = Base64.decodeBase64(encodedImageStr); // FileOutputStream imageOutFile = new FileOutputStream("D:/jhglpic/uploads/" + fileName+".jpg"); imageOutFile.write(imageByteArray); imageOutFile.close(); System.out.println("成功"); } catch (FileNotFoundException fnfe) { System.out.println("Image Path not found" + fnfe); } catch (IOException ioe) { System.out.println("Exception while converting the Image " + ioe); } }}
这样就完成了,在测试时发现几个问题
- 使用了jar包后,有个Header[]类找不到,已经在文章种提到解决办法
- 测试时,使用相册中微信保存得照片、截图都可以成功上传,但是使用本机拍摄得照片时,后台接受不到图片信息。对比2两者得区别,发现本机拍摄得照片有4M大小左右,可能就是太大了,需要对图片进行处理,如下:
options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 只获取图片的大小信息,而不是将整张图片载入在内存中,避免内存溢出 BitmapFactory.decodeFile(imgPath, options); int inSampleSize = 2; int height = options.outHeight; int width= options.outWidth; int minLen = Math.min(height, width); // 原图的最小边长 if(minLen > 100) { // 如果原始图像的最小边长大于100dp(此处单位我认为是dp,而非px) float ratio = (float)minLen / 100.0f; // 计算像素压缩比例 inSampleSize = (int)ratio; } options.inJustDecodeBounds = false; options.inSampleSize = inSampleSize; // 设置为刚才计算的压缩比例 bitmap = BitmapFactory.decodeFile(imgPath, options); ByteArrayOutputStream stream = new ByteArrayOutputStream(); // 压缩图片 bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream); byte[] byte_arr = stream.toByteArray(); // Base64图片转码为String encodedString = Base64.encodeToString(byte_arr, 0); bitmap.recycle();
最后附有 UploadActivity类
更多相关文章
- Android(安卓)TabHost的标签放在底部,已写成框架,继承即可
- Android(安卓)Studio 简单介绍和使用问题小结
- Dagger2+Retrofit+RxJava
- Android(安卓)Studio 中使用SVN注意事项
- android fragment 使用name关联Fragment
- [置顶] Android中使用Movie显示gif动态图
- 箭头函数的基础使用
- NPM 和webpack 的基础使用
- Python list sort方法的具体使用