android图片上传

最近项目上需要图片上传功能,所以开始查询相关资料,并终于实现。

android这边使用得是android studio,后台处理这边使用得是eclipse中servlet

首先是布局:(比较简单)




    

    

android图片上传_第1张图片

然后是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 stub
		System.out.println("get");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.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);
		  }
		 }
}

 

这样就完成了,在测试时发现几个问题

  1. 使用了jar包后,有个Header[]类找不到,已经在文章种提到解决办法
  2. 测试时,使用相册中微信保存得照片、截图都可以成功上传,但是使用本机拍摄得照片时,后台接受不到图片信息。对比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,Java)