android 11及以上保存图片视频到相册
短信预约 -IT技能 免费直播动态提醒
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; } } 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 @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 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 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; }}
来源地址:https://blog.csdn.net/yzwfeng/article/details/127768671
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341