android7.0以上调用系统相机拍照并显示到ImageView上
/* * 第一步:新建文件 res/xml/file_paths.xml <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path path="." name="camera_photos" /> </paths> * 第二步:AndroidManifest.xml文件的application标签中插入下边 <provider android:name="androidx.core.content.FileProvider" android:authorities="com.lrogzin.memo.fileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> * 第三步:在你需要的地方调用startCamera() * 第四步:在你的onActivityResult()中加入: * * */ public class UseSysCameraUtil { public static final int CAMERA_CODE = 110; public static Uri takePictureUri;//拍照图片uri private static Uri cropPictureTempUri;//裁剪图片uri private static File takePictureFile;//拍照图片File public static void startCamera(Activity activity, String displayName) { takePictureUri = createImagePathUri(activity, displayName); if (takePictureUri != null) { Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); i.putExtra(MediaStore.EXTRA_OUTPUT, takePictureUri);//输出路径(拍照后的保存路径) activity.startActivityForResult(i, CAMERA_CODE); } else { Toast.makeText(activity, "打开相机失败", Toast.LENGTH_LONG).show(); } } public static Uri createImagePathUri(Activity activity, String displayName) { //适配 Android=Q Android=7 API=29 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { //图片名称 //String displayName = String.valueOf(System.currentTimeMillis()); //String displayName = "head"; ContentValues values = new ContentValues(2); values.put(MediaStore.Images.Media.DISPLAY_NAME, displayName); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); //SD 卡是否可用,可用则用 SD 卡,否则用内部存储 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { takePictureUri = activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); } else { takePictureUri = activity.getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, values); } } else { String pathName = new StringBuffer().append(FileUtils.getExtPicturesPath()).append(File.separator) .append(System.currentTimeMillis()).append(".jpg").toString(); takePictureFile = new File(pathName); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //解决Android 7.0 拍照出现FileUriExposedException的问题 String authority = activity.getPackageName() + ".fileProvider"; takePictureUri = FileProvider.getUriForFile(activity, authority, takePictureFile); } else { takePictureUri = Uri.fromFile(takePictureFile); } } return takePictureUri; } public static void onCameraRes(int requestCode, int resultCode, Activity activity) { try { if (requestCode == CAMERA_CODE && resultCode == activity.RESULT_OK) { Bitmap headBitmap = BitmapFactory.decodeStream(activity.getContentResolver().openInputStream(takePictureUri)); //mainAvatar.setImageBitmap(headBitmap); } } catch (Exception e) { //throw new RuntimeException(e); e.printStackTrace(); } } public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); //质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 image.compress(Bitmap.CompressFormat.JPEG, 100, baos); int options = 100; //循环判断如果压缩后图片是否大于100kb,大于继续压缩 while (baos.toByteArray().length / 1024 > 100) { baos.reset();//重置baos即清空baos //第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差 ,第三个参数:保存压缩后的数据的流 image.compress(Bitmap.CompressFormat.JPEG, options, baos); //这里压缩options,把压缩后的数据存放到baos中 //每次都减少10 options -= 10; if (options <= 0) break; } //把压缩后的数据baos存放到ByteArrayInputStream中 ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); //把ByteArrayInputStream数据生成图片 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null); return bitmap; } static int CROP_CODE = 3; //调用系统的裁剪功能的实现 /* * onActivityResult() * case CROP_CODE: //裁剪返回的 if (data != null) { Bundle extras = data.getExtras(); headBitmap = extras.getParcelable("data"); if (headBitmap != null) { mainAvatar.setImageBitmap(headBitmap);// 用ImageView显示出来 dialogAvatar.setImageBitmap(headBitmap); } } */ public static void cropPhoto(Uri uri, Activity activity) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 150); intent.putExtra("outputY", 150); intent.putExtra("return-data", true); activity.startActivityForResult(intent, CROP_CODE); } int PERMISSIONS_REQUEST_CAMERA = 1111; // 请求相机权限 private void requestCameraPermission(Activity activity) { if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, PERMISSIONS_REQUEST_CAMERA); } else { //goCamera(); //jumpToTakePhoto(); //startCamera(); } } /*@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSIONS_REQUEST_CAMERA) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限被授予,执行拍照操作 //goCamera(); //jumpToTakePhoto(); startCamera(); } else { // 权限被拒绝 Toast.makeText(activity, "Camera permission is required to take a photo.", Toast.LENGTH_SHORT).show(); } } }*/ /** * 获取图片路径 * * @param context Context * @param uri 图片 Uri * @return 图片路径 */ public static String getImagePath(Context context, Uri uri) { Cursor cursor = null; try { String[] proj = {MediaStore.Images.Media.DATA}; cursor = context.getContentResolver().query(uri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String s = cursor.getString(column_index); return s; } finally { if (cursor != null) { cursor.close(); } } } /** * 获取图片 Uri * * @param context Context * @param path 图片路径 * @return 图片 Uri */ public static Uri getImageUri(Context context, String path) { Cursor cursor = context.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ", new String[]{path}, null); if (cursor != null && cursor.moveToFirst()) { int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); Uri baseUri = Uri.parse("content://media/external/images/media"); return Uri.withAppendedPath(baseUri, "" + id); } else { if (new File(path).exists()) { ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DATA, path); return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); } else { return null; } } } }
public final class FileUtils { /** * 得到SD卡根目录,SD卡不可用则获取内部存储的根目录 */ public static File getRootPath() { File path = null; if (sdCardIsAvailable()) { path = Environment.getExternalStorageDirectory(); //SD卡根目录 /storage/emulated/0 } else { path = Environment.getDataDirectory();//内部存储的根目录 /data } return path; } /** * 获取图片目录 * * @return 图片目录(/storage/emulated/0/Pictures) */ public static File getExtPicturesPath() { File extPicturesPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); if (!extPicturesPath.exists()) { extPicturesPath.mkdir(); } return extPicturesPath; } /** * 获取缓存图片的目录 * * @param context Context * @return 缓存图片的目录 */ public static String getImageCacheDir(Context context) { String cachePath; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { cachePath = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getPath(); } else { cachePath = context.getCacheDir().getPath(); } return cachePath; } /** * 删除缓存图片目录中的全部图片 * * @param context */ public static void deleteAllCacheImage(Context context) { String cacheImagePath = getImageCacheDir(context); File cacheImageDir = new File(cacheImagePath); File[] files = cacheImageDir.listFiles(); if (files != null) { for (File file : files) { if (file.isFile()) { file.delete(); } } } } /** * SD卡是否可用 */ public static boolean sdCardIsAvailable() { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File sd = new File(Environment.getExternalStorageDirectory().getPath()); return sd.canWrite(); } else return false; } /** * 判断目录是否存在,不存在则判断是否创建成功 * * @param dirPath 文件路径 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败 */ public static boolean createOrExistsDir(String dirPath) { return createOrExistsDir(getFileByPath(dirPath)); } /** * 判断目录是否存在,不存在则判断是否创建成功 * * @param file 文件 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败 */ public static boolean createOrExistsDir(File file) { // 如果存在,是目录则返回true,是文件则返回false,不存在则返回是否创建成功 return file != null && (file.exists() ? file.isDirectory() : file.mkdirs()); } /** * 根据文件路径获取文件 * * @param filePath 文件路径 * @return 文件 */ public static File getFileByPath(String filePath) { return isSpace(filePath) ? null : new File(filePath); } /** * 判断字符串是否为 null 或全为空白字符 * * @param s * @return */ private static boolean isSpace(final String s) { if (s == null) return true; for (int i = 0, len = s.length(); i < len; ++i) { if (!Character.isWhitespace(s.charAt(i))) { return false; } } return true; } }