android 11及以上保存图片视频到相册

android 11及以上保存图片视频到相册

Android 10之前版本主要步骤

请求读写权限图片/视频下载到/storage/emulated/0/Android/data/包名/xxx复制到系统相册目录下扫描媒体库Android 10及以上版本主要步骤

请求读写权限图片/视频下载到/storage/emulated/0/Android/data/包名/xxx创建ContentValues,写入要保存的信息调用ContentResolver插入ContentValues到相册中,此时会返回新创建的相册uri将原先的文件复制到该uri中(android11及以上必须这么干)发送广播,扫描媒体库关键代码:

public class SaveUtils {

private static final String TAG = "SaveUtils";

/**

* 将图片文件保存到系统相册

*/

public static boolean saveImgFileToAlbum(Context context, String imageFilePath) {

Log.d(TAG, "saveImgToAlbum() imageFile = [" + imageFilePath + "]");

try {

Bitmap bitmap = BitmapFactory.decodeFile(imageFilePath);

return saveBitmapToAlbum(context, bitmap);

} catch (Exception e) {

e.printStackTrace();

return false;

}

}

/**

* 将bitmap保存到系统相册

*/

public static boolean saveBitmapToAlbum(Context context, Bitmap bitmap) {

if (bitmap == null) return false;

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {

return saveBitmapToAlbumBeforeQ(context, bitmap);

} else {

return saveBitmapToAlbumAfterQ(context, bitmap);

}

}

@RequiresApi(api = Build.VERSION_CODES.Q)

private static boolean saveBitmapToAlbumAfterQ(Context context, Bitmap bitmap) {

Uri contentUri;

if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

} else {

contentUri = MediaStore.Images.Media.INTERNAL_CONTENT_URI;

}

ContentValues contentValues = getImageContentValues(context);

Uri uri = context.getContentResolver().insert(contentUri, contentValues);

if (uri == null) {

return false;

}

OutputStream os = null;

try {

os = context.getContentResolver().openOutputStream(uri);

bitmap.compress(Bitmap.CompressFormat.JPEG, 50, os);

// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

// Files.copy(bitmapFile.toPath(), os);

// }

contentValues.clear();

contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);

context.getContentResolver().update(uri, contentValues, null, null);

return true;

} catch (Exception e) {

context.getContentResolver().delete(uri, null, null);

e.printStackTrace();

return false;

} finally {

try {

if (os != null) {

os.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

private static boolean saveBitmapToAlbumBeforeQ(Context context, Bitmap bitmap) {

File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);

File destFile = new File(picDir, context.getPackageName() + File.separator + System.currentTimeMillis() + ".jpg");

// FileUtils.copy(imageFile, destFile.getAbsolutePath());

OutputStream os = null;

boolean result = false;

try {

if (!destFile.exists()) {

destFile.getParentFile().mkdirs();

destFile.createNewFile();

}

os = new BufferedOutputStream(new FileOutputStream(destFile));

result = bitmap.compress(Bitmap.CompressFormat.JPEG, 50, os);

if (!bitmap.isRecycled()) bitmap.recycle();

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

if (os != null) {

os.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

MediaScannerConnection.scanFile(

context,

new String[]{destFile.getAbsolutePath()},

new String[]{"image/*"},

(path, uri) -> {

Log.d(TAG, "saveImgToAlbum: " + path + " " + uri);

// Scan Completed

});

return result;

}

/**

* 获取图片的ContentValue

*

* @param context

*/

@RequiresApi(api = Build.VERSION_CODES.Q)

public static ContentValues getImageContentValues(Context context) {

ContentValues contentValues = new ContentValues();

contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, System.currentTimeMillis() + ".jpg");

contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/*");

contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM + File.separator + context.getPackageName());

contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1);

contentValues.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());

contentValues.put(MediaStore.Images.Media.DATE_MODIFIED, System.currentTimeMillis());

contentValues.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());

return contentValues;

}

/**

* 将视频保存到系统相册

*/

public static boolean saveVideoToAlbum(Context context, String videoFile) {

Log.d(TAG, "saveVideoToAlbum() videoFile = [" + videoFile + "]");

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {

return saveVideoToAlbumBeforeQ(context, videoFile);

} else {

return saveVideoToAlbumAfterQ(context, videoFile);

}

}

private static boolean saveVideoToAlbumAfterQ(Context context, String videoFile) {

try {

ContentResolver contentResolver = context.getContentResolver();

File tempFile = new File(videoFile);

ContentValues contentValues = getVideoContentValues(context, tempFile, System.currentTimeMillis());

Uri uri = contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues);

copyFileAfterQ(context, contentResolver, tempFile, uri);

contentValues.clear();

contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);

context.getContentResolver().update(uri, contentValues, null, null);

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));

return true;

} catch (Exception e) {

e.printStackTrace();

return false;

}

}

private static boolean saveVideoToAlbumBeforeQ(Context context, String videoFile) {

File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);

File tempFile = new File(videoFile);

File destFile = new File(picDir, context.getPackageName() + File.separator + tempFile.getName());

FileInputStream ins = null;

BufferedOutputStream ous = null;

try {

ins = new FileInputStream(tempFile);

ous = new BufferedOutputStream(new FileOutputStream(destFile));

long nread = 0L;

byte[] buf = new byte[1024];

int n;

while ((n = ins.read(buf)) > 0) {

ous.write(buf, 0, n);

nread += n;

}

MediaScannerConnection.scanFile(

context,

new String[]{destFile.getAbsolutePath()},

new String[]{"video/*"},

(path, uri) -> {

Log.d(TAG, "saveVideoToAlbum: " + path + " " + uri);

// Scan Completed

});

return true;

} catch (Exception e) {

e.printStackTrace();

return false;

} finally {

try {

if (ins != null) {

ins.close();

}

if (ous != null) {

ous.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

private static void copyFileAfterQ(Context context, ContentResolver localContentResolver, File tempFile, Uri localUri) throws IOException {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&

context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q) {

//拷贝文件到相册的uri,android10及以上得这么干,否则不会显示。可以参考ScreenMediaRecorder的save方法

OutputStream os = localContentResolver.openOutputStream(localUri);

Files.copy(tempFile.toPath(), os);

os.close();

tempFile.delete();

}

}

/**

* 获取视频的contentValue

*/

public static ContentValues getVideoContentValues(Context context, File paramFile, long timestamp) {

ContentValues localContentValues = new ContentValues();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

localContentValues.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM

+ File.separator + context.getPackageName());

}

localContentValues.put(MediaStore.Video.Media.TITLE, paramFile.getName());

localContentValues.put(MediaStore.Video.Media.DISPLAY_NAME, paramFile.getName());

localContentValues.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");

localContentValues.put(MediaStore.Video.Media.DATE_TAKEN, timestamp);

localContentValues.put(MediaStore.Video.Media.DATE_MODIFIED, timestamp);

localContentValues.put(MediaStore.Video.Media.DATE_ADDED, timestamp);

localContentValues.put(MediaStore.Video.Media.SIZE, paramFile.length());

return localContentValues;

}

}

← 上一篇: 那些中文输入法
下一篇: 打卡管理软件的种类有哪些?打卡管理软件推荐 →

相关推荐