Android阅读外部存储器给出securityException

我正在尝试获取设备中的音乐文件。 这是我做的:

public ArrayList<Track> getAllSongsFromSDCARD() { allTracks = new ArrayList<Track>(); String[] STAR = { "*" }; Uri allsongsuri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0"; Cursor cursor = mContext.getApplicationContext().getContentResolver().query(allsongsuri, STAR, selection, null, null); if (cursor != null) { if (cursor.moveToFirst()) { do { String song_name = cursor .getString(cursor .getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)); int song_id = cursor.getInt(cursor .getColumnIndex(MediaStore.Audio.Media._ID)); String fullpath = cursor.getString(cursor .getColumnIndex(MediaStore.Audio.Media.DATA)); String album_name = cursor.getString(cursor .getColumnIndex(MediaStore.Audio.Media.ALBUM)); int album_id = cursor.getInt(cursor .getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)); String artist_name = cursor.getString(cursor .getColumnIndex(MediaStore.Audio.Media.ARTIST)); int artist_id = cursor.getInt(cursor .getColumnIndex(MediaStore.Audio.Media.ARTIST_ID)); String duration = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)); int[] splitTime = null; String hours, minutes, seconds, formattedTime; try{ splitTime = splitToComponentTimes(BigDecimal.valueOf(Long.valueOf(duration)/1000)); hours = String.valueOf(splitTime[0]); minutes = String.valueOf(splitTime[1]); seconds = String.valueOf(splitTime[2]); if(hours.equals("0")){ formattedTime = minutes + ":" + seconds; }else{ formattedTime = hours + ":" + minutes + ":" + seconds; } }catch (Exception e){ formattedTime = "00:00"; } allTracks.add(new Track(song_name, song_id, fullpath, album_name, album_id, artist_name, artist_id, formattedTime)); } while (cursor.moveToNext()); } sortTracksAlphabetically(allTracks); cursor.close(); } return allTracks; } 

我在清单中拥有以下权限:

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

当我在Android版本4.3的设备上运行该代码时,它工作正常。 但是,当我运行Android 5.0.2版本的设备上它给

“java.lang.SecurityException:权限拒绝:阅读com.android.providers.media.MediaProvider uri内容:// media / external / audio / media from pid = 5701,uid = 10054 requires android.permission.READ_EXTERNAL_STORAGE”

谁能告诉我为什么? 这是完整的堆栈跟踪:

 02-14 19:25:52.812 5701-5701/com.yrazlik.musicplayer E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.yrazlik.musicplayer, PID: 5701 java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media from pid=5701, uid=10054 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() at android.os.Parcel.readException(Parcel.java:1540) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137) at android.content.ContentProviderProxy.query(ContentProviderNative.java:420) at android.content.ContentResolver.query(ContentResolver.java:478) at android.content.ContentResolver.query(ContentResolver.java:422) at com.yrazlik.musicplayer.dialogs.AllSongsDialog.getAllSongsFromSDCARD(AllSongsDialog.java:74) at com.yrazlik.musicplayer.dialogs.AllSongsDialog.onCreate(AllSongsDialog.java:59) at android.app.Dialog.dispatchOnCreate(Dialog.java:373) at android.app.Dialog.show(Dialog.java:274) at com.yrazlik.musicplayer.fragments.PlaylistFragment$1.onClick(PlaylistFragment.java:86) at android.view.View.performClick(View.java:4756) at android.view.View$PerformClick.run(View.java:19749) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

谢谢。

Solutions Collecting From Web of "Android阅读外部存储器给出securityException"

我在清单中拥有以下权限

通常情况下,如果清单中有<uses-permission>元素,即使您获得权限错误,也是因为元素在清单中的位置不正确。 他们需要是<manifest>直接子代,作为<application>同辈。

但是,为什么我的android 4.3设备没有问题,但它是在5.0.2设备的问题?

在Android 4.4之前, READ_EXTERNAL_STORAGE要么不存在要么在普通设备上没有执行。

在其他链接上的“CommonsWare”非常好的答案

现在没有得到你的许可的主要原因是你的项目的targetSdkVersion是23或者更高,你所要求的权限是“危险的”。 在Android 6.0中,这包括:

ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ADD_VOICEMAIL
BODY_SENSORS
CALL_PHONE
相机
GET_ACCOUNTS
PROCESS_OUTGOING_CALLS
function(6)
READ_CALL_LOG
READ_CELL_BROADCASTS
READ_CONTACTS
READ_EXTERNAL_STORAGE
READ_PHONE_STATE
READ_SMS
RECEIVE_MMS
RECEIVE_SMS
RECEIVE_WAP_PUSH
录制audio
发简讯
USE_SIP
WRITE_CALENDAR
WRITE_CALL_LOG WRITE_CONTACTS
WRITE_EXTERNAL_STORAGE

对于这些权限,您的targetSdkVersion 23+应用程序不仅需要具有<uses-permission>元素,还必须在运行时从Android 6.0+设备上请求这些权限,方法是使用checkSelfPermission ()和requestPermissions()。

作为临时解决方法,请将targetSdkVersion降至23以下。

然而,最终,你会有一些理由希望你的targetSdkVersion是23或更高。 那时,您将需要调整您的应用程序以使用新的运行时权限系统。 Android 6.0预览文档有一个专门用于此主题的页面。

现在我把我的targetSdkVersion从23退化到了21,但是这只是一个临时的解决scheme。