Android 通过操作将图像从内部存储器保存到图库
我有一个聊天应用程序。如果用户发送图像,我会将该图像保存到应用程序的内部存储器中Android 通过操作将图像从内部存储器保存到图库,android,kotlin,android-fileprovider,android-internal-storage,Android,Kotlin,Android Fileprovider,Android Internal Storage,我有一个聊天应用程序。如果用户发送图像,我会将该图像保存到应用程序的内部存储器中 data/data/package_name/.... 因此,如果用户单击该图像,我会向系统发送打开该图像的意图 val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, File(it.localUri)) val intent = Intent(Intent.ACTION_VIEW).apply {
data/data/package_name/....
因此,如果用户单击该图像,我会向系统发送打开该图像的意图
val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, File(it.localUri))
val intent = Intent(Intent.ACTION_VIEW).apply {
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
setDataAndType(uri, "image/*")
}
startActivity(intent)
问题是,在图像查看器中,没有选择将文件保存在手机的公共存储器中,即在多媒体资料中。
有没有办法在不更改“我的应用”中图像的内部存储默认保存位置的情况下执行此操作?如果您对此感兴趣,您可以使用
MediaStore
以编程方式将来自内部存储的图片保存到图库中
代码
你可以使用以下代码,我在我的应用程序中成功地使用了这些代码
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "MyPicture.jpg");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
}
ContentResolver resolver = myContext.getContentResolver();
Bitmap bitmap;
Uri uri;
try {
// Requires permission WRITE_EXTERNAL_STORAGE
bitmap = BitmapFactory.decodeFile(currentPhotoPath);
uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
} catch (Exception e) {
Log.e(LOG_TAG, "Error inserting picture in MediaStore: " + e.getMessage());
return;
}
try (OutputStream stream = resolver.openOutputStream(uri)) {
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream) {
throw new IOException("Error compressing the picture.");
}
} catch (Exception e) {
if (uri != null) {
resolver.delete(uri, null, null);
}
Log.e(LOG_TAG, "Error adding picture to gallery: " + e.getMessage());
}
将文件
转换为位图
和使用 <代码>媒体商店
笔记
需要运行时权限BitmapFactory.decodeFile()
WRITE\u EXTERNAL\u STORAGE
- 随着Android 10中作用域内存的引入(Android 11将强制使用,请参阅)
可能是将图片保存到多媒体资料中的唯一可靠方法MediaStore
- 范围存储的结果是,是的,您应该继续使用内部存储来缓存图片副本
targetSdkVersion
29在以下设备/操作系统组合上测试了此代码
- 三星Galaxy S10/API 29
- 三星Galaxy S9/API 29
- 华为Nexus 6P/API 27
MediaStore
以编程方式将内部存储器中的图片保存到多媒体资料中
代码
你可以使用以下代码,我在我的应用程序中成功地使用了这些代码
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "MyPicture.jpg");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
}
ContentResolver resolver = myContext.getContentResolver();
Bitmap bitmap;
Uri uri;
try {
// Requires permission WRITE_EXTERNAL_STORAGE
bitmap = BitmapFactory.decodeFile(currentPhotoPath);
uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
} catch (Exception e) {
Log.e(LOG_TAG, "Error inserting picture in MediaStore: " + e.getMessage());
return;
}
try (OutputStream stream = resolver.openOutputStream(uri)) {
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream) {
throw new IOException("Error compressing the picture.");
}
} catch (Exception e) {
if (uri != null) {
resolver.delete(uri, null, null);
}
Log.e(LOG_TAG, "Error adding picture to gallery: " + e.getMessage());
}
将文件
转换为位图
和使用 <代码>媒体商店
笔记
需要运行时权限BitmapFactory.decodeFile()
WRITE\u EXTERNAL\u STORAGE
- 随着Android 10中作用域内存的引入(Android 11将强制使用,请参阅)
可能是将图片保存到多媒体资料中的唯一可靠方法MediaStore
- 范围存储的结果是,是的,您应该继续使用内部存储来缓存图片副本
targetSdkVersion
29在以下设备/操作系统组合上测试了此代码
- 三星Galaxy S10/API 29
- 三星Galaxy S9/API 29
- 华为Nexus 6P/API 27
这是一个非常好的答案。然而,我认为你不理解我的问题。在我的例子中,当我点击照片时,我不使用ImageViewer的自定义活动。相反,我用Android手机的默认图像查看器打开照片。那么我应该在哪里写上面的代码呢?@james04谢谢!我理解这一点,这就是为什么我说“如果这是你感兴趣的东西”。如果你能在聊天中的每张图片旁边放一个小按钮,那么我的答案可能会有用。不幸的是,如果您必须坚持使用默认的图像查看器,我就无法帮助您使用它。@james04 AFAIK,因为系统决定哪个应用程序将处理
意图。ACTION\u VIEW
(如果有更多,则允许您选择一个)您不能期望在每个平台上都有相同的行为。如果您想将图片保存到多媒体资料中,而不必使用wiewing,则可以使用Intent.ACTION\u MEDIA\u SCANNER\u SCAN\u FILE
(Android Q中已弃用)。但我认为,没有任何Intent
能够保证在所有平台上都能始终如一地执行这两种操作。这是一个非常好的答案。然而,我认为你不理解我的问题。在我的例子中,当我点击照片时,我不使用ImageViewer的自定义活动。相反,我用Android手机的默认图像查看器打开照片。那么我应该在哪里写上面的代码呢?@james04谢谢!我理解这一点,这就是为什么我说“如果这是你感兴趣的东西”。如果你能在聊天中的每张图片旁边放一个小按钮,那么我的答案可能会有用。不幸的是,如果您必须坚持使用默认的图像查看器,我就无法帮助您使用它。@james04 AFAIK,因为系统决定哪个应用程序将处理意图。ACTION\u VIEW
(如果有更多,则允许您选择一个)您不能期望在每个平台上都有相同的行为。如果您想将图片保存到多媒体资料中,而不必使用wiewing,则可以使用Intent.ACTION\u MEDIA\u SCANNER\u SCAN\u FILE
(Android Q中已弃用)。但我认为,没有任何Intent
可以保证在所有平台上都能始终如一地执行这两种操作。