«

Android 从照相机和相册选择图片使用原生代码裁剪(支持4.4 KIKAT及以上机型)

时间:2024-3-2 19:23     作者:韩俊     分类: Android


开发过程中总会遇到选择图片上传,或拍照上传的功能,写了一个支持Android4.4及以上版本也可以使用的统一代码,调用起来很简单,只需要一段代码就可以,下面就把代码贴出来,代码比较粗糙,希望大家指正。

需要使用到的类属性。

 private int SELECT_PICTURE = 0;
 private int SELECT_CAMERA = 1;
 public final static int CONSULT_DOC_PICTURE = 1000;
 public final static int CONSULT_DOC_CAMERA = 1001;
 public final static int CORP_CAMERA_IMAGE = 1002;
 private Bitmap bmp;
 private Uri outputFileUri;
 //从相册或照相机得到的文件
 File selectImg;

创建选择弹出对话框

protected void createSelectImageDialog() {
  CharSequence[] items = { "相册", "照相机" };
  new AlertDialog.Builder(this).setTitle("选择图片来源").setItems(items, new DialogInterface.OnClickListener() {
   public void onClick(DialogInterface dialog, int which) {
    if (which == SELECT_PICTURE) {
     Intent intent = new Intent();
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
      intent.setAction(Intent.ACTION_GET_CONTENT);
      intent.addCategory(Intent.CATEGORY_OPENABLE);

     }
     else {
      intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
      intent.addCategory(Intent.CATEGORY_OPENABLE);
     }
     intent.setType("image/*");
     intent.putExtra("crop", "true");
     intent.putExtra("aspectX", 1);
     intent.putExtra("aspectY", 1);
     intent.putExtra("outputX", 300);
     intent.putExtra("outputY", 300);
     intent.putExtra("return-data", true);
     startActivityForResult(Intent.createChooser(intent, "选择图片"), CONSULT_DOC_PICTURE);
    } else {
     File file = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis()+"avator.jpg");
     outputFileUri = Uri.fromFile(file);
     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
     intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT,(1024*1024)/2);
     intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
     startActivityForResult(intent, CONSULT_DOC_CAMERA);
    }
   }
  }).create().show();
 }

选择完毕后的数据处理

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == CONSULT_DOC_PICTURE) {

   if(data == null){
    return;
   }
   if (bmp != null)// 如果不释放的话,不断取图片,将会内存不够
    bmp.recycle();
   if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT){
    if(data.hasExtra("data")){
     bmp = data.getParcelableExtra("data");
     selectImg = FileUtils.saveBitmap(bmp);
     //此处是避免bmp对象调用recycle时,可能无法回收报出异常,存放到了SD卡里,所以直接使用SD卡中的文件
     avator.setImageUri(Uri.fromFile(selectImg));
    }else{
     Toast.makeText(this, "请重新选择图片", Toast.LENGTH_SHORT).show();
    }
   }else{
    if(data.hasExtra("data")){
     bmp = data.getParcelableExtra("data");
     selectImg = FileUtils.saveBitmap(bmp);
     //此处是避免bmp对象调用recycle时,可能无法回收报出异常,存放到了SD卡里,所以直接使用SD卡中的文件
     avator.setImageUri(Uri.fromFile(selectImg));
    }else{
     Toast.makeText(this, "请重新选择图片", Toast.LENGTH_SHORT).show();
    }
   }
  } else if (requestCode == CONSULT_DOC_CAMERA) {
   File cameraImg = new File(outputFileUri.getPath());
   if(cameraImg.exists()){
    final Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setDataAndType(outputFileUri, "image/*");
    intent.putExtra("crop", "true");
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("outputX", 300);
    intent.putExtra("outputY", 300);
    intent.putExtra("return-data", true);
    this.startActivityForResult(intent, CORP_CAMERA_IMAGE);
   }else{
    Toast.makeText(this, "请重新选择图片", Toast.LENGTH_SHORT).show();
   }
  } else if (requestCode == CORP_CAMERA_IMAGE){
   if(data != null && data.hasExtra("data")){
    bmp = data.getParcelableExtra("data");
    selectImg = FileUtils.saveBitmap(bmp);
     //此处是避免bmp对象调用recycle时,可能无法回收报出异常,存放到了SD卡里,所以直接使用SD卡中的文件
     avator.setImageUri(Uri.fromFile(selectImg));
   }else{
    Toast.makeText(this, "请重新选择图片", Toast.LENGTH_SHORT).show();
   }
  }else{
   Toast.makeText(this, "请重新选择图片", Toast.LENGTH_SHORT).show();
  }
 }  

在SD卡中创建文件夹

public static void mkdir(String dirName){
    File file = new File(getSDPath()+"/"+dirName);
    if(!file.exists()){
        file.mkdir();
    }
}

将Bitmap 存放到SD卡中

public static File saveBitmap(String saveDir
        ,Bitmap thumbnail) {
    File f = new File(getSDPath()+"/"+dirName+"/", System.currentTimeMillis()+".jpg");
    if (f.exists()) {
        f.delete();
    }
    try {
        FileOutputStream out = new FileOutputStream(f);
        thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return f;
}

public static String getSDPath(){  
    File sdDir = null;  
    boolean sdCardExist = Environment.getExternalStorageState()    
            .equals(android.os.Environment.MEDIA_MOUNTED);  //判断sd卡是否存在  
    if  (sdCardExist)    
    {                                   
        sdDir = Environment.getExternalStorageDirectory();//获取跟目录  
    }    
    return sdDir.toString();  
}  

调用的时候只需要在触发事件中 直接调用createSelectImageDialog方法
只经过了,note2,moto x pro 测试
有部分国产手机,小内存时会报错,具体报错就是
File cameraImg = new File(outputFileUri.getPath());
这行代码空指针,空指针的是outputFileUri对象,本人技术有限,请大牛帮忙指正

        <p>版权声明:本文为博主原创文章,未经博主允许不得转载。</p>

标签: android

热门推荐