android中跳转相册,相机获取图片后截取图片并保存SDCARD

本文主要讲述了在Android开发中遇到的一个问题:通过相机或相册获取图片后,仅在三星手机上能成功截取和保存图片到SDCARD,其他手机则无效。文章详细介绍了所采用的解决方法,并提供了关键代码片段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在开发过程中遇到相机或者相册获取图片后截取图片时只有三星手机可以用其他手机全部没有效果。

  原本使用的方法是:

	public void scropPic(Uri uri) {
		Intent intent = new Intent();
		intent.setAction("com.android.camera.action.CROP");
		intent.setDataAndType(uri, "image/*");
		intent.putExtra("return-data", true);
		startActivityForResult(intent, 2);
	}

据说是intent.putExtra("return-data", true); 不能用true。具体也不太了解。所以收集各位大神的方法后总结过来的。

接下来看详细代码。


先准备好这4个方法

1.

   /**
     * 进入相机拍照获取图片
     * @param context
     * @param REQUE_CODE_CAMERA
     */
    private void getImageFromCamer(Context context,int REQUE_CODE_CAMERA) {
        //判断sdcard是否存在
        String status = Environment.getExternalStorageState();
        if (status.equals(Environment.MEDIA_MOUNTED)) {
            try {
                //qwe为相片保存的文件夹名
                File dir = new File(Environment.getExternalStorageDirectory() + "/" + "qwe");
                if (!dir.exists())
                    dir.mkdirs();

                Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                //asd为保存的相片名
                File f = new File(dir, "asd");// localTempImgDir和localTempImageFileName是自己定义的名字
                Uri u = Uri.fromFile(f);
                intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, u);
                ((Activity) context).startActivityForResult(intent, REQUE_CODE_CROP);
            } catch (ActivityNotFoundException e) {
                // TODO Auto-generated catch block
                Toast.makeText(context, "没有找到储存目录", Toast.LENGTH_LONG).show();
            }
        } else {
            Toast.makeText(context, "没有储存卡", Toast.LENGTH_LONG).show();
        }
    }
2.

/**
     * 进入相机获取图片
     * @param context
     * @param REQUE_CODE_PHOTO
     */
    public static void getImageFromPhoto(Context context, int REQUE_CODE_PHOTO) {
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        ((Activity) context).startActivityForResult(intent, REQUE_CODE_PHOTO);

    }
3.
/**
     * 进入图片截取页面
     * @param context
     * @param uri
     * @param REQUE_CODE_CROP
     */
    public static void startPhotoZoom(Context context, Uri uri, int REQUE_CODE_CROP) {
        int dp = 500;

        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
        intent.putExtra("crop", "true");
        intent.putExtra("scale", true);// 去黑边
        intent.putExtra("scaleUpIfNeeded", true);// 去黑边
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);// 输出是X方向的比例
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高,切忌不要再改动下列数字,会卡死
        intent.putExtra("outputX", dp);// 输出X方向的像素
        intent.putExtra("outputY", dp);   
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        intent.putExtra("return-data", false);// 设置为不返回数据

        ((Activity) context).startActivityForResult(intent, REQUE_CODE_CROP);
    }
4.

  /**
     * 把图片的路径转换成bitmap格式的图片
     * @param uri
     * @param mContext
     * @return
     */
    public static Bitmap getBitmapFromUri(Uri uri, Context mContext) {
        try {
            // 读取uri所在的图片
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), uri);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
最关键的是在onActivityResult:
@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK) {
            return;
        }
        switch (requestCode) {
        //跳转相册返回后进入图片截取页面
        case REQUE_CODE_PHOTO:
            if (null != data) {// 为了取消选取不报空指针用的
                uri = data.getData();
                startPhotoZoom(this, uri, 2);
            }
            break;
        //跳转图片截取页面返回后保存图片并设置图片
        case REQUE_CODE_CROP:
            if (uri == null) {
                break;
            }
            cropBitmap = getBitmapFromUri(uri, this);
            if (cropBitmap != null) {
                try {
                    CunQuTuQian.saveImage(cropBitmap, etName.getText().toString().trim());
                    bitmap = CunQuTuQian.loadImage(etName.getText().toString().trim());
                    ivTu.setImageBitmap(bitmap);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

            break;
        //跳转到相机返回后进入图片截取界面
        case  REQUE_CODE_CAMERA:
            //获得相片地址
            File f = new File(Environment.getExternalStorageDirectory() + "/" + "qwe" + "/" + "asd");
            try {
                uri = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(),
                        f.getAbsolutePath(), null, null));<pre name="code" class="java">public class CunQuTuQian {

    private final static String ALBUM_PATH 
    = Environment.getExternalStorageDirectory() + "/download_test/";

    //保存bitmap类型图片到 Environment.getExternalStorageDirectory() + "/download_test/";
    @SuppressLint("NewApi")
    public static void  saveImage(Bitmap bm, String fileName) throws IOException { 

        File dirFile = new File(ALBUM_PATH); 
        if(!dirFile.exists()){ 
        dirFile.mkdir(); 
        } 
        File myCaptureFile = new File(ALBUM_PATH + fileName); 
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile)); 
        bm.compress(Bitmap.CompressFormat.JPEG, 80, bos); 
        bos.flush(); 
        bos.close(); 
        }
    //从 Environment.getExternalStorageDirectory() + "/download_test/";读取bitmap类型图片
    public static Bitmap loadImage(String fileName) throws FileNotFoundException{
        FileInputStream is = new FileInputStream(ALBUM_PATH + fileName);
        Bitmap bitmap = BitmapFactory.decodeStream(is);
        return bitmap;

    }

}

// u就是拍摄获得的原始图片的uri,剩下的你想干神马坏事请便…… startPhotoZoom(this, uri, 2); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; default: break; } }

最后加上保存图片的工具类:

public class CunQuTuQian {

    private final static String ALBUM_PATH 
    = Environment.getExternalStorageDirectory() + "/download_test/";

    //保存bitmap类型图片到 Environment.getExternalStorageDirectory() + "/download_test/";
    @SuppressLint("NewApi")
    public static void  saveImage(Bitmap bm, String fileName) throws IOException { 

        File dirFile = new File(ALBUM_PATH); 
        if(!dirFile.exists()){ 
        dirFile.mkdir(); 
        } 
        File myCaptureFile = new File(ALBUM_PATH + fileName); 
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile)); 
        bm.compress(Bitmap.CompressFormat.JPEG, 80, bos); 
        bos.flush(); 
        bos.close(); 
        }
    //从 Environment.getExternalStorageDirectory() + "/download_test/";读取bitmap类型图片
    public static Bitmap loadImage(String fileName) throws FileNotFoundException{
        FileInputStream is = new FileInputStream(ALBUM_PATH + fileName);
        Bitmap bitmap = BitmapFactory.decodeStream(is);
        return bitmap;

    }

}

注意事项:
添加这两个权限
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Samsung的系统相机,版式是横板的,如果你的activity恰巧是竖版的,那么获取这个回调uri的时候,很可能为空! 
原因在于,如果你没有设置版式改变的时候,activity不要调用onCreate方法!这就是要命的地方! 
设置方法其实很简单: 
1、在Manfest.xml中,给activity添加一个属性:android:configChanges="orientation|keyboardHidden" 
2、在activity中添加: 
@Override 
    public void onConfigurationChanged(Configuration config) { 
    super.onConfigurationChanged(config); 
    } 

另外还有一个蛋疼的错误容易犯:千万别给这个activity添加单例模式,即:android:launchMode="singleInstance"
在android4.0以后应该添加screenSize这样才能达到不重新加载的效果
android:configChanges="orientation|keyboardHidden|screenSize"




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值