1

我正在使用 Content Provider 获取设备中的所有音乐文件并将其显示在列表中,但是,我现在不希望特定文件夹“X”中的文件出现在我的列表中。

我目前正在使用它从 SD 卡中获取所有音频文件。

private static final String[] EXTERNAL_COLUMNS = new String[] {
            MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DATA,
            MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST,
            MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.IS_RINGTONE,
            MediaStore.Audio.Media.IS_MUSIC,
            "\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\"" };

private Cursor getExternalAudioCursor(String selection,
            String[] selectionArgs) {
        return managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                EXTERNAL_COLUMNS, selection, selectionArgs,
                MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
    }

Cursor c = new MergeCursor(new Cursor[] {
            getExternalAudioCursor(selection, argsArray)};

同样来自Android docs,我读到了这个......

公共静态最终字符串 MEDIA_IGNORE_FILENAME

自:API 级别 9 指示媒体扫描器忽略包含目录及其子目录中的媒体的文件名称。开发人员应该使用它来避免应用程序图形出现在画廊中,同样防止应用程序声音和音乐出现在音乐应用程序中。常数值:“.nomedia”

但我不能具体说明文件名,因为我事先并不知道它们。

所以我的问题是我可以对一个文件夹做类似的事情,这样它的所有内容都不会出现在我的列表中吗?

如果没有,那么我还有其他方法可以做到这一点吗?

4

3 回答 3

1

.nomedia通过将文件放入文件夹中,我已成功防止图像文件被系统索引。

根据此链接,它也应该适用于音乐文件。也许这种技术可以让你朝着正确的方向前进……

(明文链接:http ://androinica.com/2009/08/how-to-hide-non-music-audio-files-from-appearing-in-android-media-players/ )

于 2012-05-09T13:23:08.573 回答
1

可以将 .nomedia 文件添加到该文件夹​​,但这并不是真正的编程解决方案,您可能只能在 SDCARD 上执行此操作。

不幸的是,这也会阻止其他媒体扫描应用程序从该文件夹中获取任何文件。如果没有别的,你可以添加它,扫描,然后删除它。但这是一个非常丑陋/骇人的解决方案。

http://lifehacker.com/5793803/disable-media-scanning-in-specific-android-directories-by-creating-a-nomedia-file

编辑:显然,以句点开头的文件夹对系统是隐藏的。同样,这似乎不是最好的主意。

临时修改目录/添加 .nomedia 文件,扫描,然后删除它的前提似乎并不那么邪恶,但是如果您的应用程序在您有机会将文件/文件夹重置回其原始文件之前崩溃怎么办状态?如果一个应用程序修改了我的目录,而现在其他应用程序无法正常运行(可能),我将是一个相当沮丧的用户。

这些解决方案似乎是面向消费者/用户而不是开发人员的。

于 2012-05-09T13:29:10.257 回答
0

我已经找到了我上面提出的问题的解决方案。

显然有一种简单的方法可以让特定文件夹中的文件不显示在您的应用程序中......

我之前犯的错误是我曾经Environment.getExternalStorageDirectory();将所有应用程序文件直接写入sd卡,它们出现在我的列表中。

我不得不使用Context.getExternalFilesDir("FolderName");并且文件现在没有显示在列表中,原因是该文件夹现在是您的应用程序的本地文件夹,媒体无法访问。

请阅读 getExternalFilesDir 的完整 Java 文档以熟悉该类。

public File getExternalFilesDir(字符串类型)

自:API 8 级

返回外部文件系统上目录的绝对路径(即 Environment.getExternalStorageDirectory() 上的某个位置),应用程序可以在其中放置它拥有的持久文件。这些文件对于应用程序是私有的,并且通常不作为媒体对用户可见。

这就像 getFilesDir() 一样,在卸载应用程序时这些文件将被删除,但是有一些重要的区别:

外部文件并不总是可用:如果用户在计算机上安装或移除外部存储,它们就会消失。有关存储状态的信息,请参阅环境 API。这些文件没有强制执行安全性。所有应用程序都可以读取和写入放置在此处的文件。以下是在应用程序的私有存储中操作文件的典型代码示例:

void createExternalStoragePrivateFile() {
    // Create a path where we will place our private file on external
    // storage.
    File file = new File(getExternalFilesDir(null), "DemoFile.jpg");

try {
    // Very simple code to copy a picture from the application's
    // resource into the external file.  Note that this code does
    // no error checking, and assumes the picture is small (does not
    // try to copy it in chunks).  Note that if external storage is
    // not currently mounted this will silently fail.
    InputStream is = getResources().openRawResource(R.drawable.balloons);
    OutputStream os = new FileOutputStream(file);
    byte[] data = new byte[is.available()];
    is.read(data);
    os.write(data);
    is.close();
    os.close();
} catch (IOException e) {
    // Unable to create file, likely because external storage is
    // not currently mounted.
    Log.w("ExternalStorage", "Error writing " + file, e);
}
}

void deleteExternalStoragePrivateFile() {
    // Get path for the file on external storage.  If external
    // storage is not currently mounted this will fail.
    File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
    if (file != null) {
        file.delete();
    }
}

boolean hasExternalStoragePrivateFile() {
    // Get path for the file on external storage.  If external
    // storage is not currently mounted this will fail.
    File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
    if (file != null) {
        return file.exists();
    }
    return false;
}

如果您为此函数提供非空类型,则返回的文件将是给定类型的子目录的路径。尽管媒体扫描仪不会自动扫描这些文件,但您可以使用MediaScannerConnection.scanFile. 请注意,这与Environment.getExternalStoragePublicDirectory()提供所有应用程序共享的媒体目录的 不同。此处返回的目录归应用所有,卸载应用时会删除其内容。与 Environment.getExternalStoragePublicDirectory() 不同,此处返回的目录将自动为您创建。

下面是一个典型代码示例,用于操作应用程序私有存储中的图片并将其添加到媒体数据库:

void createExternalStoragePrivatePicture() {
    // Create a path where we will place our picture in our own private
    // pictures directory.  Note that we don't really need to place a
    // picture in DIRECTORY_PICTURES, since the media scanner will see
    // all media in these directories; this may be useful with other
    // media types such as DIRECTORY_MUSIC however to help it classify
    // your media for display to the user.
    File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File file = new File(path, "DemoPicture.jpg");
try {
    // Very simple code to copy a picture from the application's
    // resource into the external file.  Note that this code does
    // no error checking, and assumes the picture is small (does not
    // try to copy it in chunks).  Note that if external storage is
    // not currently mounted this will silently fail.
    InputStream is = getResources().openRawResource(R.drawable.balloons);
    OutputStream os = new FileOutputStream(file);
    byte[] data = new byte[is.available()];
    is.read(data);
    os.write(data);
    is.close();
    os.close();

    // Tell the media scanner about the new file so that it is
    // immediately available to the user.
    MediaScannerConnection.scanFile(this,
            new String[] { file.toString() }, null,
            new MediaScannerConnection.OnScanCompletedListener() {
        public void onScanCompleted(String path, Uri uri) {
            Log.i("ExternalStorage", "Scanned " + path + ":");
            Log.i("ExternalStorage", "-> uri=" + uri);
        }
    });
} catch (IOException e) {
    // Unable to create file, likely because external storage is
    // not currently mounted.
    Log.w("ExternalStorage", "Error writing " + file, e);
}
}

void deleteExternalStoragePrivatePicture() {
    // Create a path where we will place our picture in the user's
    // public pictures directory and delete the file.  If external
    // storage is not currently mounted this will fail.
    File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    if (path != null) {
        File file = new File(path, "DemoPicture.jpg");
        file.delete();
    }
}

boolean hasExternalStoragePrivatePicture() {
    // Create a path where we will place our picture in the user's
    // public pictures directory and check if the file exists.  If
    // external storage is not currently mounted this will think the
    // picture doesn't exist.
    File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    if (path != null) {
        File file = new File(path, "DemoPicture.jpg");
        return file.exists();
    }
    return false;
}

参数 type 要返回的文件目录的类型。对于文件目录的根目录或子目录的以下环境常量之一可能为 null:DIRECTORY_MUSIC、DIRECTORY_PODCASTS、DIRECTORY_RINGTONES、DIRECTORY_ALARMS、DIRECTORY_NOTIFICATIONS、DIRECTORY_PICTURES 或 DIRECTORY_MOVIES。

返回 返回外部存储上保存应用程序文件的目录的路径。如果当前未安装外部存储,则返回 null,因此无法确保路径存在;当它可用时,您将需要再次调用此方法。

于 2012-05-29T11:03:37.937 回答