/*
* 第一步:新建文件 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;
}
}