/* * 第一步:新建文件 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标签中插入下边<providerandroid:name="androidx.core.content.FileProvider"android:authorities="com.lrogzin.memo.fileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid: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;//拍照图片uriprivate static Uri cropPictureTempUri;//裁剪图片uriprivate static File takePictureFile;//拍照图片Filepublic 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=29if (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中//每次都减少10options -= 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(); }}/*@Overridepublic 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();} elsereturn 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;}}