关于拍照权限问题
-
AndroidManifest.xml内必配置的 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> 6.0以上使用动态权限申请这两步基本操作(本来读写权限为一组,7.0分开了,动态申请需全部进行) 重要重要重要....关于Android Q版本需要在AndroidManifest.xml的application配置两个属性:
android:requestLegacyExternalStorage="true" tools:targetApi="q" 这样才能进行文件的操作
- 由于在安卓7.0以上要进行APP的自动升级,需用到FileProvider.getUriForFile方法共享安装包,在AndroidManifest.xml 添加
<provider android:name="androidx.core.content.FileProvider" android:authorities="com.msunhealth.recovery.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> 在src文件夹xml文件下建file_paths.xml内容如下
<?xml version="1.0" encoding="utf-8"?> <paths> <external-path path="." name="files_path" /> </paths> 注:external-path 表示:外存SDkAr 的跟目录 path 表示共享的子目录 name 表示出现在FileProvider.getUriForFile取得的路径的代替路径变量
到此前期工作做完.下面是关于调用系统拍照和录像
- 关于调用系统拍照问题
1.开启摄像头拍照
/**
* 拍照
*/
public static void takePhoto(Activity activity) {
//创建File对象,用于存储拍照后的图片
//将此图片存储于SD卡的根目录下
File outputImage = new File(activity.getExternalCacheDir(),
"tem.jpg");
//前面已经定义对文件的操作,这里就使用上了,传统的获取路径操作已不能使用会报
Uri uri;
if (Build.VERSION.SDK_INT >= 24) {
uri = FileProvider.getUriForFile(activity.getApplicationContext()
, "com.msunhealth.recovery.fileprovider", outputImage);
} else {
uri = Uri.fromFile(outputImage);
}
RxSPTool.putString(activity.getApplicationContext(), "filepath", outputImage.getAbsolutePath());
if (state.equals(Environment.MEDIA_MOUNTED)) {
Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");
getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
activity.startActivityForResult(getImageByCamera, TAKE_PHOTO);
} else {
Toast.makeText(activity.getApplicationContext(), "请确认已经插入SD卡", Toast.LENGTH_LONG).show();
}
}
2.拍照返回数据
mImageUri = Uri.fromFile(new File(filepath));
if (mImageUri != null) {
Bitmap bitmap = CameraUtil.getBitmapFromUri(this, mImageUri);
imageView.setImageBitmap(bitmap);
//跟新相册
MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "PHOTO", "");
}
//通知相册扫描展示
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mImageUri));
- 从相册获取图片
- 打开系统相册
/** * 选择图片 */ public static void selectPhoto(Activity activity) { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*");//相片类型 activity.startActivityForResult(intent, PICTURE_CAPTURE); }
- 现在照片后返回数据
// 拿到从相册选择截取后的剪切数据 mImageUri = data.getData(); if (mImageUri != null) { Bitmap bitmap = CameraUtil.getBitmapFromUri(this, mImageUri); imageView.setImageBitmap(bitmap); //跟新图片到相册 MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "IMG", ""); } //通知相册数据库跟新显示 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mImageUri));
- 关于拍照的一些小工具
- 调用系统图片剪切
/* * 图片裁剪 */ public static void startPhotoZoom(Activity activity, Uri uri, int i) { if (uri == null) { Toast.makeText(activity.getApplicationContext(), "选择图片出错!", Toast.LENGTH_SHORT).show(); } Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // 设置裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 600); intent.putExtra("outputY", 600); intent.putExtra("circleCrop", false); //是否是圆形 //是否bitmap显示,如果为true,则通过 Bitmap bmap = data.getParcelableExtra("data")取出数据 intent.putExtra("return-data", false); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); activity.startActivityForResult(intent, i); }
- 获取拍照保存图片真实地址
/** * 根据Uri获取文件真实地址 */ public static String getRealFilePath(Context context, Uri uri) { if (null == uri) return null; final String scheme = uri.getScheme(); String realPath = null; if (scheme == null) realPath = uri.getPath(); else if (ContentResolver.SCHEME_FILE.equals(scheme)) { realPath = uri.getPath(); } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) { Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Video.VideoColumns.DATA}, null, null, null); if (null != cursor) { if (cursor.moveToFirst()) { int index = cursor.getColumnIndex(MediaStore.Video.VideoColumns.DATA); if (index > -1) { realPath = cursor.getString(index); } } cursor.close(); } } if (TextUtils.isEmpty(realPath)) { if (uri != null) { String uriString = uri.toString(); int index = uriString.lastIndexOf("/"); String imageName = uriString.substring(index); File storageDir; // storageDir = Environment.getExternalStoragePublicDirectory( // Environment.DIRECTORY_PICTURES); storageDir = context.getExternalCacheDir(); File file = new File(storageDir, imageName); if (file.exists()) { realPath = file.getAbsolutePath(); } else { // storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); storageDir = context.getExternalCacheDir(); File file1 = new File(storageDir, imageName); realPath = file1.getAbsolutePath(); } } } return realPath; }
- 关于调用系统录像问题
- 开启摄像头录像
public static void openVideo(Activity activity) { Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); Uri fileUri = null; try { //fileUri=Uri.fromFile(createMediaFile());如果这样写会报错 fileUri = FileProvider.getUriForFile(activity.getApplicationContext() , "com.msunhealth.recovery.fileprovider", createMediaFile(activity)); } catch (IOException e) { e.printStackTrace(); } intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); activity.startActivityForResult(intent, TAKE_VIDEO); }
- 摄像头返回数据
Uri uri = data.getData(); // 视频地址获取缩略图展示imageview上 String videoPath = CameraUtil.getRealFilePath(this, uri); Bitmap bitmap = null; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { //根据url获取缩略图 retriever.setDataSource(this, uri); //获得第一帧图片 bitmap = retriever.getFrameAtTime(1); video.setImageBitmap(bitmap); } catch (IllegalArgumentException e) { e.printStackTrace(); } finally { retriever.release(); }
- 三种获取视频缩略图的方法
1.// Bitmap bitmap = null; // MediaMetadataRetriever retriever = new MediaMetadataRetriever(); // try { // //根据url获取缩略图 // retriever.setDataSource(this, uri); // //获得第一帧图片 // bitmap = retriever.getFrameAtTime(1); // video.setImageBitmap(bitmap); // } catch (IllegalArgumentException e) { // e.printStackTrace(); // } finally { // retriever.release(); // } 2.// LogUtils.e(this,videoPath); // //系统工具类ThumbnailUtils 获取视频的第一帧 // Bitmap videoThumbnail = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Video.Thumbnails.MICRO_KIND); // if(videoThumbnail != null){ // video.setImageBitmap(videoThumbnail); // video.setTag(videoPath); // }else{ // Toast.makeText(this, "获取缩略图失败拉!", Toast.LENGTH_SHORT).show(); // } 3.// 用Glide加载视频第一帧,速度快,效果不错 RequestOptions options = new RequestOptions(); // glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度 options.override(getResources().getDisplayMetrics().widthPixels / 3, getResources().getDisplayMetrics().widthPixels / 3); // glide 缓存 options.diskCacheStrategy(DiskCacheStrategy.ALL); // 裁剪中间部分显示 // options.fitCenter(); // 默认占位图 options.placeholder(R.drawable.img_placeholder_image_loading); Glide.with(this) .asBitmap() .load(Uri.fromFile(new File(videoPath))) .apply(options) .into(video); video.setScaleType(ImageView.ScaleType.CENTER_INSIDE); break;
- 对应录制的视频在相册显示方法(注意::真对7.0动态权限申请,读写权限都得申请)
//针对非系统影音资源文件夹 public static void insertIntoMediaStore(Context context, boolean isVideo, File saveFile, long createTime) { ContentResolver mContentResolver = context.getContentResolver(); if (createTime == 0) createTime = System.currentTimeMillis(); ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.TITLE, saveFile.getName()); values.put(MediaStore.MediaColumns.DISPLAY_NAME, saveFile.getName()); //值一样,但是还是用常量区分对待 values.put(isVideo ? MediaStore.Video.VideoColumns.DATE_TAKEN : MediaStore.Images.ImageColumns.DATE_TAKEN, createTime); values.put(MediaStore.MediaColumns.DATE_MODIFIED, System.currentTimeMillis()); values.put(MediaStore.MediaColumns.DATE_ADDED, System.currentTimeMillis()); if (!isVideo) values.put(MediaStore.Images.ImageColumns.ORIENTATION, 0); values.put(MediaStore.MediaColumns.DATA, saveFile.getAbsolutePath()); values.put(MediaStore.MediaColumns.SIZE, saveFile.length()); values.put(MediaStore.MediaColumns.MIME_TYPE, isVideo ? "video/mp4" : "image/jpeg"); //插入 mContentResolver.insert(isVideo ? MediaStore.Video.Media.EXTERNAL_CONTENT_URI : MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); } 大致内容就写到此了.对拍照和录视频折磨两天的总结吧!!!!!!!!!!
照片和视频调用系统预览方法
/** * 系统图片预览 * * @param activity * @param mUri */ public static void photoPreview(Activity activity, Uri mUri) { Intent it = new Intent(Intent.ACTION_VIEW); it.setDataAndType(mUri, "image/*"); activity.startActivity(it); } /** * 系统视频预览 * * @param activity * @param mUri */ public static void videoPreview(Activity activity, Uri mUri) { Intent it = new Intent(Intent.ACTION_VIEW); it.setDataAndType(mUri, "video/*"); activity.startActivity(it); }
- 三种获取视频缩略图的方法