MediaProvider /铃声的外部存储权限问题

Ree*_*eed 5 android securityexception ringtone android-permissions

尝试在我的应用中选择铃声时,我的一些用户向Google Play报告了以下错误。(还有更多,但不相关)

java.lang.SecurityException: Permission Denial: 
reading com.android.providers.media.MediaProvider 
uri content://media/external/audio/media 
from pid=5738, uid=10122 requires android.permission.READ_EXTERNAL_STORAGE
Run Code Online (Sandbox Code Playgroud)

我认为此问题是由于外部存储上的某些提示而发生的。READ_EXTERNAL_STORAGE除非绝对必要,否则我不想在我的应用程序中包含许可。

有没有一种方法可以解决此问题,并且仅排除外部存储设备上可能出现的任何声音?

注意:我正在获取的铃声,RingtoneManager并在String和之间进行转换Uri。没有其他代码触及用户的媒体。

另外,我没有行号,因为stacktrace来自混淆的代码,并且重新映射堆栈跟踪没有提供行号。

ato*_*ode 3

刚刚遇到了同样的问题并提出了以下解决方案:

private Cursor createCursor()
{
    Uri uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;

    String[] columns = new String[]
    {
        MediaStore.Audio.Media._ID,
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.TITLE_KEY
    };

    String filter = createBooleanFilter(MediaStore.Audio.AudioColumns.IS_ALARM);
    String order = MediaStore.Audio.Media.DEFAULT_SORT_ORDER;

    return getContext().getContentResolver().query(uri, columns, filter, null, order);
}

private String createBooleanFilter(String... columns)
{
    if(columns.length > 0)
    {
        StringBuilder sb = new StringBuilder();
        sb.append("(");
        for(int i = columns.length - 1; i > 0; i--)
        {
            sb.append(columns[i]).append("=1 or ");
        }
        sb.append(columns[0]);
        sb.append(")");
        return sb.toString();
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

要获取铃声的 Uri,您需要将INTERNAL_CONTENT_URI_ID列值结合起来,您可以使用ContentUris类来执行此操作:

Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, cursor.getLong(0));
Run Code Online (Sandbox Code Playgroud)