package com.zjw.mymultimedia2; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.MediaStore; import android.support.v4.content.FileProvider; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.view.WindowManager; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; //8.3.1 p294 调用摄像头拍照 //布局里面一个Button调用摄像头,一个Image显示拍到的图片 //FileProvider要在清单文件注册 /* 代码如下 <provider android:authorities="com.zjw.mymultimedia2.fileprovider" android:name="android.support.v4.content.FileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_path"/> </provider> 其中 name属性值是固定的 authorities属性值要和getUriForFile()参数二里设置的唯一字符串相同 <meta-data/>标签用来指定Uri的共享路径,引用了file_path.xml资源 */ /* 创建file_path.xml资源 res下新建xml文件夹,里面创建file_path.xml文件 代码如下 <?xml version="1.0" encoding="utf-8"?> <Paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_images" path=""/> </Paths> 其中 external-path用来指定Uri共享 name属性可以随便填 path属性表示共享的具体路径,设置为空就是将整个SD卡进行共享 */ /* Android 4.0系统以前,访问SD卡应用关联目录需要声明权限,4.0后不用,做兼容还需声明 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> */ public class CallCamera extends AppCompatActivity { private Uri mImageUri; private static final int TAKE_PHOTO = 646; private Button mBtnTakePhoto; private ImageView mIvPicture; private static final String TAG = "zjw"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_call_camera); //找到控件 mBtnTakePhoto = (Button) findViewById(R.id.btn_take_photo); mIvPicture = (ImageView) findViewById(R.id.iv_picture); //点击事件 mBtnTakePhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //存储拍照后图片 //将它存放在手机SD卡的应用关联缓存目录下 //应用关联缓存目录:SD卡中专门用来存放当前应用缓存数据的位置 //getExternalCacheDir():/sdcard/Android/data/<package name>/cache //从Android6.0开始,读写SD卡被列为高危权限,只you使用应用关联目录可以跳过运行时权限处理 File outputImage = new File(getExternalCacheDir(), "output_image.jpg"); Log.d(TAG, "onClick: " + "1_" + getExternalCacheDir().getAbsolutePath()); try { if (outputImage.exists()) { outputImage.delete(); } outputImage.createNewFile(); } catch (IOException e) { e.printStackTrace(); } //Android7.0开始,直接使用本地这是路径Uri被认为是不safe的,会报FileUriExposedException异常 if (Build.VERSION.SDK_INT >= 24) { //FileProvider一种特殊的内容提供器,可以选择性的将封装过得Uri共享给外部 //getUriForFile()将File对象转换为一个封装过的Uri //参数一:Context //参数二:任意唯一字符串 //参数三刚刚创建的File对象 mImageUri = FileProvider.getUriForFile( CallCamera.this, "com.zjw.mymultimedia2.fileprovider", outputImage); } else {//版本低于Android7.0,这个Uri标识这张图片本地zhen实路径 mImageUri = Uri.fromFile(outputImage); Log.d(TAG, "onClick: " + "2_" + mImageUri); } //调用相机 //MediaStore.ACTION_IMAGE_CAPTURE //android.media.action.IMAGE_CAPTURE Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri); startActivityForResult(intent, TAKE_PHOTO); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case TAKE_PHOTO: if (resultCode == RESULT_OK) { //将照片显示出来 try { // InputStream is = getContentResolver().openInputStream(mImageUri); // Bitmap bitmap = BitmapFactory.decodeStream(is); // System.out.println(bitmap.getByteCount()+"czb"); //加载大图 InputStream is = getContentResolver().openInputStream(mImageUri); BitmapFactory.Options opts = new BitmapFactory.Options(); // 不读取像素数组到内存中,仅读取图片的信息 opts.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, opts); // 从Options中获取图片的分辨率 int imageHeight = opts.outHeight; int imageWidth = opts.outWidth; // 获取Android屏幕的服务 WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); // 获取屏幕的分辨率,getHeight()、getWidth已经被废弃掉了 // 应该使用getSize(),但是这里为了向下兼容所以依然使用它们 int windowHeight = wm.getDefaultDisplay().getHeight(); int windowWidth = wm.getDefaultDisplay().getWidth(); // 计算采样率 int scaleX = imageWidth / windowWidth; int scaleY = imageHeight / windowHeight; int scale = 1; // 采样率依照最大的方向为准 if (scaleX > scaleY && scaleY >= 1) { scale = scaleX; } if (scaleX < scaleY && scaleX >= 1) { scale = scaleY; } // 采样率 opts.inSampleSize = scale; // false表示读取图片像素数组到内存中,依照设定的采样率 opts.inJustDecodeBounds = false; is = getContentResolver().openInputStream(mImageUri); Bitmap bitmap = BitmapFactory.decodeStream(is, null, opts); Log.d(TAG, "onActivityResult: " + "3_" + bitmap.toString()); mIvPicture.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } break; default: break; } } private Toast mToast; public void showToast(String msg) { if (mToast == null) { mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT); } mToast.setText(msg); mToast.show(); } }
转载于:https://my.oschina.net/u/3620480/blog/1477315