整理android调用系统相机的方法及遇到的问题

在项目中遇到需要调用系统相机的功能点,整理方法如下

1.拍照完成之后直接存图片

   Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
   intent.putExtra("crop", "true");// crop=true 有这句才能出来最后的裁剪页面.
   intent.putExtra("aspectX", 5); // 这两项为裁剪框的比例.
   intent.putExtra("aspectY", 4);
   
   intent.putExtra("output", Uri.fromFile(new File("SDCard/1.jpg")));//输出地址
   intent.putExtra("outputFormat", "JPEG");//返回格式 
   startActivityForResult(intent, REQUEST_CAMERA);


获取图片直接在onActivityForResult中

BitmapFactory.decodeFile(fileName, opts);

 

2.拍照完成后读取intent中的数据,在onActivityForResult中

Uri uri = data.getData();
ContentResolver cr = this.getContentResolver();
try {
	bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
} catch (FileNotFoundException e) {
	e.printStackTrace();
}

但是这种方法在测试过程中,海信手机会报空指针异常,也许是相机处理机制的问题,我没有深究

3.最后一种是当前项目正用到的方法 目前在各种手机上使用正常

String sdStatus = Environment.getExternalStorageState();
      if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
       LogUtils.i("TestFile",
         "SD card is not avaiable/writeable right now.");
       return;
      }
      String name = new DateFormat().format(
        "yyyyMMdd_hhmmss",
        Calendar.getInstance(Locale.CHINA))
        + ".jpg";
      Bundle bundle = data.getExtras();
      Bitmap bitmap = (Bitmap) bundle.get("data");//
      LogUtils.d(CommitCommentActivity.this,
        bitmap == null ? "bitmap is null"
          : "bitmap is not null");
      FileOutputStream fos = null;
      File file = new File(IMAGE_PATH);
      file.mkdirs();// 创建文件夹
      final String fileName = IMAGE_PATH + name;
      LogUtils.i("fangdd", "Onresult path:" + fileName);
      try {
       fos = new FileOutputStream(fileName);
       bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);// 把数据写入文件
      } catch (FileNotFoundException e) {
       e.printStackTrace();
      } finally {
       if (!bitmap.isRecycled()) {
        bitmap.recycle();
        System.gc();
       }
       try {
        fos.flush();
        fos.close();
       } catch (IOException e) {
        e.printStackTrace();
       }
      }

 这种方式是将图片资源取出之后存入文件,并不在activity中直接保存bitmap 仅在用到时加载 避免内存溢出

 

下面记录一下开发中遇到的问题,说道这里不得不吐槽一下三星的相机,调用之后系统会调用ondestroy导致activity被销毁重建,原因是系统调用了一次横竖屏切换,解决方法如下

方法一:刚开始调用了onSaveInstanceState(Bundle savedInstanceState)和onRestoreInstanceState(Bundle savedInstanceState)这个方法来实现,虽然方法比较笨,但是可以通过在onSaveInstanceState中保存一些你需要的变量,在onCreate()方法中判断savedInstanceState是否为null,不为null则调用onRestoreInstanceState()方法取出之前存的变量来使用,这相当于重新加载了一边当前activity。

方法二:上面的方法可行,但并不是解决问题的根本办法,后来通过查看发现在调用相机时,activity从竖屏切换到了横屏,在横竖屏切换导致了activity重新装载,找到根本原因后,在activity中通过android:configChanges="orientation|keyboardHidden" 这个属性,可以约束调用相机时,保持当前activity竖屏状态不变,从而解决了activity重新加载的问题。

 

 另外关于图片压缩的代码也一并贴在这里以便以后查看

private Bitmap getDiskBitmap(String pathString) {
		Bitmap bitmap = null;
		Bitmap bMapRotate = null;
		try {
			File file = new File(pathString);
			if (file.exists()) {
				BitmapFactory.Options opt = new BitmapFactory.Options();
				opt.inPreferredConfig = Bitmap.Config.RGB_565;
				opt.inPurgeable = true;
				opt.inInputShareable = true;
				opt.inTempStorage = new byte[1024 * 1024 * 10];
				long length = file.length();
				LogUtils.d(this, "file.length() = " + length);
				if (length / (1024 * 1024) > 4) {
					opt.inSampleSize = 16;
					LogUtils.d(this, "opt.inSampleSize = 16;");
				} else if (length / (1024 * 1024) >= 1) {
					opt.inSampleSize = 8;
					LogUtils.d(this, "opt.inSampleSize = 8;");
				} else if (length / (1024 * 512) >= 1) {
					opt.inSampleSize = 4;
					LogUtils.d(this, "opt.inSampleSize = 4;");
				} else if (length / (1024 * 256) >= 1) {
					opt.inSampleSize = 2;
					LogUtils.d(this, "opt.inSampleSize = 2;");
				} else {
					opt.inSampleSize = 1;
					LogUtils.d(this, "opt.inSampleSize = 1;");
				}
				bitmap = BitmapFactory.decodeFile(pathString, opt);
				LogUtils.i("fangdd", "图片旋转度数:" + readPictureDegree(pathString));
				// ///
				// if(pathString.contains("floor/imgs")){
				// YLog.i("fangdd", "处理旋转:"+isGetImage);
				int orientation = readPictureDegree(pathString);
				/*
				 * if(bitmap.getHeight() < bitmap.getWidth()){ orientation = 90;
				 * } else { orientation = 0; }
				 */
				if (orientation != 0) {
					Matrix matrix = new Matrix();
					matrix.postRotate(orientation);
					bMapRotate = Bitmap
							.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
									bitmap.getHeight(), matrix, true);
				} else {
					bMapRotate = Bitmap.createScaledBitmap(bitmap,
							bitmap.getWidth(), bitmap.getHeight(), true);
				}
				// }
				// //
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (bMapRotate != null) {
			return bMapRotate;
		}
		return bitmap;
	}


	/**
	 * 读取图片属性:旋转的角度
	 * 
	 * @param path
	 *            图片绝对路径
	 * @return degree旋转的角度
	 */
	public static int readPictureDegree(String path) {
		int degree = 0;
		try {
			ExifInterface exifInterface = new ExifInterface(path);
			int orientation = exifInterface.getAttributeInt(
					ExifInterface.TAG_ORIENTATION,
					ExifInterface.ORIENTATION_NORMAL);
			switch (orientation) {
			case ExifInterface.ORIENTATION_ROTATE_90:
				degree = 90;
				break;
			case ExifInterface.ORIENTATION_ROTATE_180:
				degree = 180;
				break;
			case ExifInterface.ORIENTATION_ROTATE_270:
				degree = 270;
				break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return degree;
	}


 

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值