Java 是否有方法通过media store访问特定于应用程序的外部存储文件夹?
正如标题所说,我正在我的应用程序指定的外部目录(android/data/com.xxx.xxx)中保存一些文件,主要是音频文件,现在我想通过Mediastore访问这些音频文件,但我不能,我该怎么做? media store是否可以访问这种私有目录 值得一提的是,整个数据目录都有一个.nomedia文件 更新: 文件保存在…/android/data/com.xxx.xxx/files/music wereJava 是否有方法通过media store访问特定于应用程序的外部存储文件夹?,java,android,storage,mediastore,android-10.0,Java,Android,Storage,Mediastore,Android 10.0,正如标题所说,我正在我的应用程序指定的外部目录(android/data/com.xxx.xxx)中保存一些文件,主要是音频文件,现在我想通过Mediastore访问这些音频文件,但我不能,我该怎么做? media store是否可以访问这种私有目录 值得一提的是,整个数据目录都有一个.nomedia文件 更新: 文件保存在…/android/data/com.xxx.xxx/files/music weregetExternalFilesDirstores文件中 mediastore找到其他音
getExternalFilesDir
stores文件中
mediastore找到其他音频文件,但无法访问该目录中的“我的文件”
context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
BASE_PROJECTION, selection, selectionValues, sortOrder);
更新2:
创建文件后在扫描后使用
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (files != null) for (String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File outFile = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC), filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
///////////////////////////////////////////////////////////////////////////////////
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this,
new String[] { outFile.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
Toast.makeText(MainActivity.this, "success", Toast.LENGTH_SHORT).show();
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// NOOP
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
// NOOP
}
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
在搜索和调试了一天半之后,我找到了这个解决方案: Media Store无权访问特定于应用程序的外部目录,为了让Media Store能够访问这些目录,您应该将文件复制到媒体目录,如下所示:
private void copyFiles() {
File directory = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC).toString());
File[] files = directory.listFiles();
for (int i = 0; i < files.length; i++)
{
String videoFileName = files[i].getName();
ContentValues valuesaudios;
valuesaudios = new ContentValues();
valuesaudios.put(MediaStore.Audio.Media.RELATIVE_PATH, "Music/" + "Folder");
valuesaudios.put(MediaStore.Audio.Media.TITLE, videoFileName);
valuesaudios.put(MediaStore.Audio.Media.DISPLAY_NAME, videoFileName);
valuesaudios.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mp3");
valuesaudios.put(MediaStore.Audio.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
valuesaudios.put(MediaStore.Audio.Media.DATE_TAKEN, System.currentTimeMillis());
valuesaudios.put(MediaStore.Audio.Media.IS_PENDING, 1);
ContentResolver resolver = getContentResolver();
Uri collection = MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
Uri uriSavedAudio = resolver.insert(collection, valuesaudios);
ParcelFileDescriptor pfd;
try {
pfd = getContentResolver().openFileDescriptor(uriSavedAudio, "w");
FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());
File storageDir = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC).toString());
File imageFile = new File(storageDir, files[i].getName());
FileInputStream in = new FileInputStream(imageFile);
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
pfd.close();
} catch (Exception e) {
e.printStackTrace();
}
valuesaudios.clear();
valuesaudios.put(MediaStore.Audio.Media.IS_PENDING, 0);
getContentResolver().update(uriSavedAudio, valuesaudios, null, null);
Toast.makeText(this, files[i].getName(), Toast.LENGTH_SHORT).show();
}
}
private void copyFiles(){
File directory=新文件(getExternalFilesDir(Environment.directory\u MUSIC.toString());
File[]files=目录.listFiles();
对于(int i=0;i0){
out.write(buf,0,len);
}
out.close();
in.close();
pfd.close();
}捕获(例外e){
e、 printStackTrace();
}
valuesaudios.clear();
值saudios.put(MediaStore.Audio.Media.IS_PENDING,0);
getContentResolver().update(uriSavedAudio,valuesaudios,null,null);
Toast.makeText(这个,文件[i].getName(),Toast.LENGTH_SHORT.show();
}
}
我的应用程序指定目录(android/data/com.xxx.xxx),
??这不是有效的路径。请给出完整的路径。使用的是哪一个Android版本?此外,您没有说明您希望如何访问文件的媒体存储。请重新措辞。我的问题不是实现代码,而是一切正常。我的问题是,media store是否可以访问此类私有目录?每个人都可以访问特定于应用程序的目录。远低于安卓Q的人可以。所以媒体商店也可以。为什么不呢?你仍然提到了一个无效路径。是的,他们确实这样做了,但音乐播放器中的媒体扫描仪也不会扫描那些我不知道的目录,可能是因为.nomedia文件,但我甚至在创建文件后使用了媒体扫描,仍然没有更改file storageDir=new file(getExternalFilesDir(Environment.DIRECTORY_music).toString();File imageFile=新文件(storageDir,files[i].getName());FileInputStream in=新的FileInputStream(imageFile)代码>?替换为FileInputStream in=newfileinputstream(files[i])代码>。。。为了让media store能够访问这些文件,您应该复制您的文件…
这是一个奇怪的解决方案。你复制。然后媒体商店就知道拷贝了。但媒体商店仍然不知道原始文件。我想知道你为什么首先把它们放在这样一个特定于应用程序的目录中。把它们放在你想要的地方。你可以直接在copyAssets()中完成。是的,我最终会这么做。这只是一个测试,我在real app中的资产中没有文件,因为android10不再允许在任何你想要的地方写入,所以我需要复制我的文件,使它们对mediastore可见