我刚刚开始android开发,对于如何将媒体文件保存到外部存储的自定义文件夹非常困惑。我读过关于内窥镜存储,纵隔,但我还是不明白。
我正在尝试将文件保存到外部存储中自己的文件夹中(就像外部存储中的Whatsapp文件夹一样)。我希望结构是这样的:
(EXTERNAL STORAGE ROOT)
|--- (RandomFolder)
|--- (Whatsapp)
|--- (MyFolder)
|---(Images)
|---(Videos)
|--- ...
我不希望媒体文件存储在默认媒体目录(如Pictures/或DCIM/)中。我有些问题:
其他信息:
那么应该采取哪种方法呢?
您可以将图像和其他媒体文件保存到外部存储中,但是,为了让这些文件显示在其他应用程序中,比如Gallery应用程序中,您需要将它们注册到纵隔存储中。你是怎么保存文件的?您是从头开始创建文件,还是简单地从另一个目录复制文件?
下面是一个如何将位图对象(jpg或png)保存到外部存储器并将其注册到纵隔器中的示例。首先,从纵隔存储中删除文件的任何现有记录,然后使用ContentResolver.Insert()方法将位图保存到外部存储。
请注意,纵隔中的数据列指的是文件的完整路径。
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Objects;
public class SaveImageToMediaStore
{
public static boolean saveImage(
Context context, Bitmap bitmap,
int jpgQuality, int pngQuality, String fileFullPath)
{
try
{
deleteFileFromMediaStore(context, fileFullPath);
saveImageAndInsertIntoMediaStore(context, fileFullPath, bitmap, jpgQuality, pngQuality);
return true;
}
catch (Exception ex) { return false; }
}
public static boolean saveImageAndInsertIntoMediaStore(
Context context, String fileFullPath,
Bitmap bitmap, int jpgQuality, int pngQuality)
{
try
{
Bitmap.CompressFormat format;
int quality;
String mimeType;
if (fileFullPath.toLowerCase().endsWith(".jpg") ||
fileFullPath.toLowerCase().endsWith(".jpeg"))
{
format = Bitmap.CompressFormat.JPEG;
quality = jpgQuality;
mimeType = "image/jpg";
}
else if (fileFullPath.toLowerCase().endsWith(".png"))
{
format = Bitmap.CompressFormat.PNG;
quality = pngQuality;
mimeType = "image/png";
}
else
{
return false;
}
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, getShortName(fileFullPath));
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
contentValues.put(MediaStore.MediaColumns.DATA, fileFullPath);
ContentResolver resolver = context.getContentResolver();
Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
OutputStream out = resolver.openOutputStream(Objects.requireNonNull(uri));
bitmap.compress(format, quality, out);
Objects.requireNonNull(out).close();
return true;
}
catch (Exception ex) { return false; }
}
public static boolean deleteFileFromMediaStore(
Context context, String fileFullPath)
{
File file = new File(fileFullPath);
String absolutePath, canonicalPath;
try { absolutePath = file.getAbsolutePath(); }
catch (Exception ex) { absolutePath = null; }
try { canonicalPath = file.getCanonicalPath(); }
catch (Exception ex) { canonicalPath = null; }
ArrayList<String> paths = new ArrayList<>();
if (absolutePath != null) paths.add(absolutePath);
if (canonicalPath != null && !canonicalPath.equalsIgnoreCase(absolutePath))
paths.add(canonicalPath);
if (paths.size() == 0) return false;
ContentResolver resolver = context.getContentResolver();
Uri uri = MediaStore.Files.getContentUri("external");
boolean deleted = false;
for (String path : paths)
{
int result = resolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?",
new String[] { path });
if (result != 0) deleted = true;
}
return deleted;
}
public static String getShortName(String path)
{
if (path.endsWith("/")) path = path.substring(0, path.length() - 1);
int pos = path.lastIndexOf('/');
if (pos == -1) return path;
return path.substring(pos + 1);
}
}