有没有办法通过媒体存储访问 app-specific 外部存储文件夹?
Is there a way to access app-specific external storage folder with media store?
正如标题所说,我正在我的应用程序指定的外部目录 (android/data/com.xxx.xxx) 中保存一些文件——主要是音频文件,现在我想使用 Mediastore 访问这些音频文件但我不能我应该怎么做?
media store可以访问这种私有目录吗?
值得一提的是整个数据目录都有一个.nomedia文件
更新:
文件保存在.../android/data/com.xxx.xxx/files/music 是 getExternalFilesDir
存储文件
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);
}
}
好的,经过一天半的搜索和调试,我找到了这个解决方案:
媒体商店无权访问特定于应用程序的外部目录,为了媒体商店可以访问它们,您应该将文件复制到媒体目录,如下所示:
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();
}
}
正如标题所说,我正在我的应用程序指定的外部目录 (android/data/com.xxx.xxx) 中保存一些文件——主要是音频文件,现在我想使用 Mediastore 访问这些音频文件但我不能我应该怎么做? media store可以访问这种私有目录吗?
值得一提的是整个数据目录都有一个.nomedia文件
更新:
文件保存在.../android/data/com.xxx.xxx/files/music 是 getExternalFilesDir
存储文件
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);
}
}
好的,经过一天半的搜索和调试,我找到了这个解决方案: 媒体商店无权访问特定于应用程序的外部目录,为了媒体商店可以访问它们,您应该将文件复制到媒体目录,如下所示:
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();
}
}