将图像添加到媒体库 - Android
Add image to Media Gallery - Android
我正在尝试向图库中添加一张新图片。我通过意图选择了一个已经存在的图像,然后调整大小并压缩它。
然后我存储生成的位图:
public static File compressAndSaveImage(Context ctx, Uri imageUri) throws FileNotFoundException {
File file = null;
if (imageUri != null) {
ContextWrapper cw = new ContextWrapper(ctx);
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
file = new File(directory, imageUri.getLastPathSegment());
System.out.println("storing to " + file);
InputStream input = ctx.getContentResolver().openInputStream(imageUri);
Bitmap b = ImageManager.resize(BitmapFactory.decodeStream(input),
ctx.getResources().getDimension(R.dimen.player_thumb_w),
ctx.getResources().getDimension(R.dimen.player_thumb_h));
FileOutputStream fos = new FileOutputStream(file);
if (b.compress(Bitmap.CompressFormat.PNG, 100, fos)) {
System.out.println("Compression success");// bmp is your Bitmap instance
}
addPictureToGallery(ctx, file);
}
return file;
}
但是当我尝试将图像添加到图库时,我没有收到任何错误消息,也没有添加图像。我已经尝试了以下两种方法:
private static void addPictureToGallery(Context ctx, File filepath) {
// Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
// System.out.println("Publish: " + filepath.exists());
// System.out.println("Publish: " + filepath.getAbsolutePath());
// Uri contentUri = Uri.fromFile(filepath);
// mediaScanIntent.setData(contentUri);
// ctx.sendBroadcast(mediaScanIntent);
MediaScannerConnection.scanFile(
ctx,
new String[]{filepath.getAbsolutePath()},
null,
new MediaScannerConnection.OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
Log.w("mydebug", "file " + path + " was scanned successfully: " + uri);
}
});
}
}
回调打印以下行:
file /data/data/test.myapps.appname/app_imageDir/6045564126748266738 was scanned successfully: content://media/external/file/7838
我错过了什么?
我会把它作为评论,因为我没有时间真正深入了解事情的细节,但它显然太长了。尝试这样的事情(我用它来将位图存储到画廊)。请注意,除了扫描图像之外,您似乎没有做任何事情。现在看来您正在将文件存储到内部存储,而不是手机内容(图库)。
假设我们是 运行 来自 ActivityA.class 的 Activity
/**
* Will save our card (currently set as a bitmap) as a jpeg and save it into our devices
* native photo gallery. Unfortunately, the default method for this will add the image to the bottom
* of the gallery by default, that is no good. This more complex method that utilizes Android's
* native methods will allow us to store the bitmap at the top of the gallery by setting it's
* meta data to today's date.
*/
public class SaveBitmapToDevice extends AsyncTask<Bitmap, Void, String>{
private final ShareType type;
public SaveBitmapToDevice(ShareType type){
this.type = type;
}
@Override
protected String doInBackground(Bitmap... cards) {
return insertImageIntoGallery(getContentResolver(), cards[0], getString(R.string.card_gallery_title),
getString(R.string.card_gallery_label));
}
/**
* A copy of the Android internals insertImage method, this method populates the
* meta data with DATE_ADDED and DATE_TAKEN. This fixes a common problem where media
* that is inserted manually gets saved at the end of the gallery (because date is not populated).
* @see android.provider.MediaStore.Images.Media#insertImage(android.content.ContentResolver, Bitmap, String, String).
* If the MediaStore not available, we will redirect the file to our alternative source, the SD card.
*/
public String insertImageIntoGallery(ContentResolver cr, Bitmap source, String title, String description) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, title);
values.put(MediaStore.Images.Media.DISPLAY_NAME, title);
values.put(MediaStore.Images.Media.DESCRIPTION, description);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
// Add the date meta data to ensure the image is added at the front of the gallery
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
Uri url = null;
String stringUrl = null; /* value to be returned */
try {
url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (source != null) {
OutputStream imageOut = cr.openOutputStream(url);
try {
source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
} finally {
imageOut.close();
}
long id = ContentUris.parseId(url);
// Wait until MINI_KIND thumbnail is generated.
Bitmap miniThumb = MediaStore.Images.Thumbnails.getThumbnail(cr, id, MediaStore.Images.Thumbnails.MINI_KIND, null);
// This is for backward compatibility.
storeThumbnail(cr, miniThumb, id, 50F, 50F, MediaStore.Images.Thumbnails.MICRO_KIND);
} else {
cr.delete(url, null, null);
return storeToAlternateSd(source, title);
// url = null;
}
} catch (Exception e) {
if (url != null) {
cr.delete(url, null, null);
return storeToAlternateSd(source, title);
// url = null;
}
}
savedOnSD = false;
if (url != null) {
stringUrl = url.toString();
}
return stringUrl;
}
/**
* A copy of the Android internals StoreThumbnail method, it used with the insertImage to
* populate the android.provider.MediaStore.Images.Media#insertImage with all the correct
* meta data. The StoreThumbnail method is private so it must be duplicated here.
* @see android.provider.MediaStore.Images.Media (StoreThumbnail private method).
*/
private Bitmap storeThumbnail(
ContentResolver cr,
Bitmap source,
long id,
float width,
float height,
int kind) {
// create the matrix to scale it
Matrix matrix = new Matrix();
float scaleX = width / source.getWidth();
float scaleY = height / source.getHeight();
matrix.setScale(scaleX, scaleY);
Bitmap thumb = Bitmap.createBitmap(source, 0, 0,
source.getWidth(),
source.getHeight(), matrix,
true
);
ContentValues values = new ContentValues(4);
values.put(MediaStore.Images.Thumbnails.KIND,kind);
values.put(MediaStore.Images.Thumbnails.IMAGE_ID,(int)id);
values.put(MediaStore.Images.Thumbnails.HEIGHT,thumb.getHeight());
values.put(MediaStore.Images.Thumbnails.WIDTH,thumb.getWidth());
Uri url = cr.insert(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, values);
try {
OutputStream thumbOut = cr.openOutputStream(url);
thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut);
thumbOut.close();
return thumb;
} catch (FileNotFoundException ex) {
Log.e("IMAGE_COMPRESSION_ERROR", "File not found");
ex.printStackTrace();
return null;
} catch (IOException ex) {
Log.e("IMAGE_COMPRESSION_ERROR", "IO Exception");
ex.printStackTrace();
return null;
}
}
/**
* If we have issues saving into our MediaStore, save it directly to our SD card. We can then interact with this file
* directly, opposed to pulling from the MediaStore. Again, this is a backup method if things don't work out as we
* would expect (seeing as most devices will have a MediaStore).
*
* @param src
* @param title
* @return - the file's path
*/
private String storeToAlternateSd(Bitmap src, String title){
if(src == null)
return null;
File sdCardDirectory = new File(Environment.getExternalStorageDirectory() + File.separator + "My Cards");
if(!sdCardDirectory.exists())
sdCardDirectory.mkdir();
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy - (hh.mm.a)", Locale.US);
File image = new File(sdCardDirectory, title + " -- [" + sdf.format(new Date()) + "].jpg");
try {
FileOutputStream imageOut = new FileOutputStream(image);
src.compress(Bitmap.CompressFormat.JPEG, 100, imageOut);
imageOut.close();
savedOnSD = true;
return image.getAbsolutePath();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
return null;
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
}
@Override
public void onPostExecute(String url){
if(url != null){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
if(savedOnSD){
File file = new File(url);
if(file.exists())
intent.setDataAndType(Uri.fromFile(file), "image/jpeg");
else
return;
}
else
intent.setDataAndType(Uri.parse(url), "image/jpeg");
ActivityA.this.startActivity(intent);
}
else
Toast.makeText(ActivityA.this, getString(R.string.error_compressing), Toast.LENGTH_SHORT).show();
}
}
感谢@zgc7009,你让我走上了正确的轨道。我使用了您的一些代码,这是其他任何想要解决的人的最终结果。
问题确实是我将图像存储在应用程序的本地存储中。
File storedImagePath = generateImagePath("player", "png");
if (!compressAndSaveImage(storedImagePath, bitmap)) {
return null;
}
Uri url = addImageToGallery(context.getContentResolver(), "png", storedImagePath);
其中使用的三种方法是:
生成路径
private static File getImagesDirectory() {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + IMAGE_DIR);//Environment.getExternalStorageDirectory()
if (!file.mkdirs() && !file.isDirectory()) {
Log.e("mkdir", "Directory not created");
}
return file;
}
public static File generateImagePath(String title, String imgType) {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss");
return new File(getImagesDirectory(), title + "_" + sdf.format(new Date()) + "." + imgType);
}
压缩并保存
public boolean compressAndSaveImage(File file, Bitmap bitmap) {
boolean result = false;
try {
FileOutputStream fos = new FileOutputStream(file);
if (result = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)) {
Log.w("image manager", "Compression success");
}
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
添加到图库
public Uri addImageToGallery(ContentResolver cr, String imgType, File filepath) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "player");
values.put(MediaStore.Images.Media.DISPLAY_NAME, "player");
values.put(MediaStore.Images.Media.DESCRIPTION, "");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/" + imgType);
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.DATA, filepath.toString());
return cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
您也可以使用 MediaStore 的静态方法...
public String addImageToGallery(ContentResolver cr, File filepath) {
try {
return MediaStore.Images.Media.insertImage(cr, filepath.toString(),
filepath.getName(), "Image Description");
} catch (FileNotFoundException e) {
e.printStackTrace();
return e.getMessage();
}
}
从 insertImage
返回的 String
与在接受的答案中对 Uri
对象调用 toString()
相同。
我知道这是一个较旧的 post 但我希望这可以帮助仍然在这里找到路的其他人。
Android 10 引入了分区存储,因此您将在尝试写入这些文件夹时遇到找不到文件的 EACCESS 错误。这里是 kotlin 中的解决方案,遵循当前的 android 文档。
fun addImageToGallery(b: Bitmap): Uri {
val resolver = context.applicationContext.contentResolver
val pictureCollection = MediaStore.Images.Media
.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val pictureDetails = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, "CurrentAlbumArt.png")
put(MediaStore.Audio.Media.IS_PENDING, 1)
}
val pictureContentUri = resolver.insert(pictureCollection, pictureDetails)!!
resolver.openFileDescriptor(pictureContentUri, "w", null).use { pfd ->
try {
pfd?.let {
val fos = FileOutputStream(it.fileDescriptor)
b.compress(Bitmap.CompressFormat.PNG, 100, fos)
fos.close()
}
} catch (e: IOException) {
e.printStackTrace()
}
}
pictureDetails.clear()
pictureDetails.put(MediaStore.Images.Media.IS_PENDING, 0)
resolver.update(pictureContentUri, pictureDetails, null, null)
return pictureContentUri
}
注意:我覆盖了旧文件(相同的文件名)并根据我的情况需要插入作为替换。
我正在尝试向图库中添加一张新图片。我通过意图选择了一个已经存在的图像,然后调整大小并压缩它。
然后我存储生成的位图:
public static File compressAndSaveImage(Context ctx, Uri imageUri) throws FileNotFoundException {
File file = null;
if (imageUri != null) {
ContextWrapper cw = new ContextWrapper(ctx);
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
file = new File(directory, imageUri.getLastPathSegment());
System.out.println("storing to " + file);
InputStream input = ctx.getContentResolver().openInputStream(imageUri);
Bitmap b = ImageManager.resize(BitmapFactory.decodeStream(input),
ctx.getResources().getDimension(R.dimen.player_thumb_w),
ctx.getResources().getDimension(R.dimen.player_thumb_h));
FileOutputStream fos = new FileOutputStream(file);
if (b.compress(Bitmap.CompressFormat.PNG, 100, fos)) {
System.out.println("Compression success");// bmp is your Bitmap instance
}
addPictureToGallery(ctx, file);
}
return file;
}
但是当我尝试将图像添加到图库时,我没有收到任何错误消息,也没有添加图像。我已经尝试了以下两种方法:
private static void addPictureToGallery(Context ctx, File filepath) {
// Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
// System.out.println("Publish: " + filepath.exists());
// System.out.println("Publish: " + filepath.getAbsolutePath());
// Uri contentUri = Uri.fromFile(filepath);
// mediaScanIntent.setData(contentUri);
// ctx.sendBroadcast(mediaScanIntent);
MediaScannerConnection.scanFile(
ctx,
new String[]{filepath.getAbsolutePath()},
null,
new MediaScannerConnection.OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
Log.w("mydebug", "file " + path + " was scanned successfully: " + uri);
}
});
}
}
回调打印以下行:
file /data/data/test.myapps.appname/app_imageDir/6045564126748266738 was scanned successfully: content://media/external/file/7838
我错过了什么?
我会把它作为评论,因为我没有时间真正深入了解事情的细节,但它显然太长了。尝试这样的事情(我用它来将位图存储到画廊)。请注意,除了扫描图像之外,您似乎没有做任何事情。现在看来您正在将文件存储到内部存储,而不是手机内容(图库)。
假设我们是 运行 来自 ActivityA.class 的 Activity
/**
* Will save our card (currently set as a bitmap) as a jpeg and save it into our devices
* native photo gallery. Unfortunately, the default method for this will add the image to the bottom
* of the gallery by default, that is no good. This more complex method that utilizes Android's
* native methods will allow us to store the bitmap at the top of the gallery by setting it's
* meta data to today's date.
*/
public class SaveBitmapToDevice extends AsyncTask<Bitmap, Void, String>{
private final ShareType type;
public SaveBitmapToDevice(ShareType type){
this.type = type;
}
@Override
protected String doInBackground(Bitmap... cards) {
return insertImageIntoGallery(getContentResolver(), cards[0], getString(R.string.card_gallery_title),
getString(R.string.card_gallery_label));
}
/**
* A copy of the Android internals insertImage method, this method populates the
* meta data with DATE_ADDED and DATE_TAKEN. This fixes a common problem where media
* that is inserted manually gets saved at the end of the gallery (because date is not populated).
* @see android.provider.MediaStore.Images.Media#insertImage(android.content.ContentResolver, Bitmap, String, String).
* If the MediaStore not available, we will redirect the file to our alternative source, the SD card.
*/
public String insertImageIntoGallery(ContentResolver cr, Bitmap source, String title, String description) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, title);
values.put(MediaStore.Images.Media.DISPLAY_NAME, title);
values.put(MediaStore.Images.Media.DESCRIPTION, description);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
// Add the date meta data to ensure the image is added at the front of the gallery
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
Uri url = null;
String stringUrl = null; /* value to be returned */
try {
url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (source != null) {
OutputStream imageOut = cr.openOutputStream(url);
try {
source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
} finally {
imageOut.close();
}
long id = ContentUris.parseId(url);
// Wait until MINI_KIND thumbnail is generated.
Bitmap miniThumb = MediaStore.Images.Thumbnails.getThumbnail(cr, id, MediaStore.Images.Thumbnails.MINI_KIND, null);
// This is for backward compatibility.
storeThumbnail(cr, miniThumb, id, 50F, 50F, MediaStore.Images.Thumbnails.MICRO_KIND);
} else {
cr.delete(url, null, null);
return storeToAlternateSd(source, title);
// url = null;
}
} catch (Exception e) {
if (url != null) {
cr.delete(url, null, null);
return storeToAlternateSd(source, title);
// url = null;
}
}
savedOnSD = false;
if (url != null) {
stringUrl = url.toString();
}
return stringUrl;
}
/**
* A copy of the Android internals StoreThumbnail method, it used with the insertImage to
* populate the android.provider.MediaStore.Images.Media#insertImage with all the correct
* meta data. The StoreThumbnail method is private so it must be duplicated here.
* @see android.provider.MediaStore.Images.Media (StoreThumbnail private method).
*/
private Bitmap storeThumbnail(
ContentResolver cr,
Bitmap source,
long id,
float width,
float height,
int kind) {
// create the matrix to scale it
Matrix matrix = new Matrix();
float scaleX = width / source.getWidth();
float scaleY = height / source.getHeight();
matrix.setScale(scaleX, scaleY);
Bitmap thumb = Bitmap.createBitmap(source, 0, 0,
source.getWidth(),
source.getHeight(), matrix,
true
);
ContentValues values = new ContentValues(4);
values.put(MediaStore.Images.Thumbnails.KIND,kind);
values.put(MediaStore.Images.Thumbnails.IMAGE_ID,(int)id);
values.put(MediaStore.Images.Thumbnails.HEIGHT,thumb.getHeight());
values.put(MediaStore.Images.Thumbnails.WIDTH,thumb.getWidth());
Uri url = cr.insert(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, values);
try {
OutputStream thumbOut = cr.openOutputStream(url);
thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut);
thumbOut.close();
return thumb;
} catch (FileNotFoundException ex) {
Log.e("IMAGE_COMPRESSION_ERROR", "File not found");
ex.printStackTrace();
return null;
} catch (IOException ex) {
Log.e("IMAGE_COMPRESSION_ERROR", "IO Exception");
ex.printStackTrace();
return null;
}
}
/**
* If we have issues saving into our MediaStore, save it directly to our SD card. We can then interact with this file
* directly, opposed to pulling from the MediaStore. Again, this is a backup method if things don't work out as we
* would expect (seeing as most devices will have a MediaStore).
*
* @param src
* @param title
* @return - the file's path
*/
private String storeToAlternateSd(Bitmap src, String title){
if(src == null)
return null;
File sdCardDirectory = new File(Environment.getExternalStorageDirectory() + File.separator + "My Cards");
if(!sdCardDirectory.exists())
sdCardDirectory.mkdir();
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy - (hh.mm.a)", Locale.US);
File image = new File(sdCardDirectory, title + " -- [" + sdf.format(new Date()) + "].jpg");
try {
FileOutputStream imageOut = new FileOutputStream(image);
src.compress(Bitmap.CompressFormat.JPEG, 100, imageOut);
imageOut.close();
savedOnSD = true;
return image.getAbsolutePath();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
return null;
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
}
@Override
public void onPostExecute(String url){
if(url != null){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
if(savedOnSD){
File file = new File(url);
if(file.exists())
intent.setDataAndType(Uri.fromFile(file), "image/jpeg");
else
return;
}
else
intent.setDataAndType(Uri.parse(url), "image/jpeg");
ActivityA.this.startActivity(intent);
}
else
Toast.makeText(ActivityA.this, getString(R.string.error_compressing), Toast.LENGTH_SHORT).show();
}
}
感谢@zgc7009,你让我走上了正确的轨道。我使用了您的一些代码,这是其他任何想要解决的人的最终结果。
问题确实是我将图像存储在应用程序的本地存储中。
File storedImagePath = generateImagePath("player", "png");
if (!compressAndSaveImage(storedImagePath, bitmap)) {
return null;
}
Uri url = addImageToGallery(context.getContentResolver(), "png", storedImagePath);
其中使用的三种方法是:
生成路径
private static File getImagesDirectory() {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + IMAGE_DIR);//Environment.getExternalStorageDirectory()
if (!file.mkdirs() && !file.isDirectory()) {
Log.e("mkdir", "Directory not created");
}
return file;
}
public static File generateImagePath(String title, String imgType) {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss");
return new File(getImagesDirectory(), title + "_" + sdf.format(new Date()) + "." + imgType);
}
压缩并保存
public boolean compressAndSaveImage(File file, Bitmap bitmap) {
boolean result = false;
try {
FileOutputStream fos = new FileOutputStream(file);
if (result = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)) {
Log.w("image manager", "Compression success");
}
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
添加到图库
public Uri addImageToGallery(ContentResolver cr, String imgType, File filepath) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "player");
values.put(MediaStore.Images.Media.DISPLAY_NAME, "player");
values.put(MediaStore.Images.Media.DESCRIPTION, "");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/" + imgType);
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.DATA, filepath.toString());
return cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
您也可以使用 MediaStore 的静态方法...
public String addImageToGallery(ContentResolver cr, File filepath) {
try {
return MediaStore.Images.Media.insertImage(cr, filepath.toString(),
filepath.getName(), "Image Description");
} catch (FileNotFoundException e) {
e.printStackTrace();
return e.getMessage();
}
}
从 insertImage
返回的 String
与在接受的答案中对 Uri
对象调用 toString()
相同。
我知道这是一个较旧的 post 但我希望这可以帮助仍然在这里找到路的其他人。
Android 10 引入了分区存储,因此您将在尝试写入这些文件夹时遇到找不到文件的 EACCESS 错误。这里是 kotlin 中的解决方案,遵循当前的 android 文档。
fun addImageToGallery(b: Bitmap): Uri {
val resolver = context.applicationContext.contentResolver
val pictureCollection = MediaStore.Images.Media
.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val pictureDetails = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, "CurrentAlbumArt.png")
put(MediaStore.Audio.Media.IS_PENDING, 1)
}
val pictureContentUri = resolver.insert(pictureCollection, pictureDetails)!!
resolver.openFileDescriptor(pictureContentUri, "w", null).use { pfd ->
try {
pfd?.let {
val fos = FileOutputStream(it.fileDescriptor)
b.compress(Bitmap.CompressFormat.PNG, 100, fos)
fos.close()
}
} catch (e: IOException) {
e.printStackTrace()
}
}
pictureDetails.clear()
pictureDetails.put(MediaStore.Images.Media.IS_PENDING, 0)
resolver.update(pictureContentUri, pictureDetails, null, null)
return pictureContentUri
}
注意:我覆盖了旧文件(相同的文件名)并根据我的情况需要插入作为替换。