问题描述
我正在用Android创建音乐播放器应用程序.它工作正常,但每当我在歌曲列表中滚动时,它便开始崩溃并给出此异常
I'm creating a music player application in Android. It works fine but whenever I scroll in songs list it starts crashing and gives this exception
Process: com.example.lenovo.musicplayer, PID: 31100
java.lang.SecurityException: External path: /storage/emulated/0/Android/data/com.android.providers.media/albumthumbs/1460104607336: Neither user 10294 nor current process has android.permission.WRITE_EXTERNAL_STORAGE.
at android.os.Parcel.readException(Parcel.java:1555)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:153)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:691)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1170)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:994)
at android.content.ContentResolver.openInputStream(ContentResolver.java:719)
at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:1110)
at com.example.lenovo.musicplayer.Adapter.getView(Adapter.java:119)
at android.widget.AbsListView.obtainView(AbsListView.java:2571)
at android.widget.ListView.makeAndAddView(ListView.java:1894)
at android.widget.ListView.fillDown(ListView.java:710)
at android.widget.ListView.fillGap(ListView.java:674)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5900)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:5378)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:825)
at android.view.Choreographer.doCallbacks(Choreographer.java:619)
at android.view.Choreographer.doFrame(Choreographer.java:578)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:811)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6102)
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:1028)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
当我在清单文件中授予写权限时,此问题消失了,但我不明白的是为什么,当我不向任何类型的文件写入任何内容时要求WriteExternalStoragePermission
贮存.据我了解,音乐播放器不需要写入外部存储"权限.
This problem goes away when I give write permission in manifest file but the thing I don't understand is why it is asking for WriteExternalStoragePermission
when I'm not writing anything to any types of storage.As far as I understand Music player doesn't require Write External Storage Permissions.
这是歌曲列表活动的代码
Here is the code for Songs List Activity
public class ActivitySongsList extends AppCompatActivity {
public static ArrayList<MusicBean>songsList;
ListView listView;
Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_songs_list);
toolbar= (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listView= (ListView) findViewById(R.id.lv_songs);
songsList=getAudioList();
Adapter adapter=new Adapter(this,songsList);
listView.setAdapter(adapter);
getSupportActionBar().setTitle("Songs");
toolbar.setTitleTextColor(Color.parseColor("#ffffff"));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent=new Intent(ActivitySongsList.this,ActivityMusicDetails.class);
intent.putExtra("song",songsList.get(position));
intent.putExtra("position",String.valueOf(position));
startActivity(intent);
}
});
}
private ArrayList<MusicBean> getAudioList() {
ArrayList<MusicBean> musicBeanArrayList=new ArrayList<>();
try {
final Cursor mCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID,MediaStore.Audio.Media.ARTIST,MediaStore.Audio.Media.TITLE}, null, null,
"LOWER(" + MediaStore.Audio.Media.TITLE + ") ASC");
int count = mCursor.getCount();
int i = 0;
if (mCursor.moveToFirst()) {
do {
String song=mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String path=mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
long album_id=mCursor.getLong(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
String artist=mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
Uri sArtworkUri = Uri
.parse("content://media/external/audio/albumart");
Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, album_id);
musicBeanArrayList.add(new MusicBean(song,path,albumArtUri.toString(),String.valueOf(album_id),artist));
/*songs[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
mAudioPath[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));*/
i++;
} while (mCursor.moveToNext());
}
mCursor.close();
}catch (Exception e)
{
e.printStackTrace();
}
return musicBeanArrayList;
}
}
它崩溃,但此行例外
bitmap = MediaStore.Images.Media.getBitmap(ctx.getContentResolver(), uri);
在此代码中,我将获得对应于mp3文件的专辑封面.但是此代码也仅从外部存储读取,因此这也不应该要求写许可权",因为我只是在读取位图而不是在写它.
In this code I'm getting Album Art for corresponding mp3 file.But this code is also reading from external storage only therefore this should also doesn't ask for Write Permission as I am only reading bitmap not writing it.
推荐答案
来自,用于处理"/media/external/audio/albumart"
From the MediaProvider code, which handles "/media/external/audio/albumart"
内部openFile(Uri uri, String mode)
try {
pfd = openFileAndEnforcePathPermissionsHelper(newUri, mode);
} catch (FileNotFoundException ex) {
// That didn't work, now try to get it from the specific file
pfd = getThumb(database, db, audiopath, albumid, null);
}
因此,如果找不到文件,它将调用getThumb
So if file not found, it calls getThumb
getThumb
调用makeThumbInternal
然后在某些条件下,它会调用
Then under certain conditions, it calls
writeAlbumArt(need_to_recompress, out, compressed, bm);
在最新版本中,writeAlbumArt调用
In the latest version, writeAlbumArt calls
final long identity = Binder.clearCallingIdentity();
在写之前,应该可以解决该问题.但是此修复程序已于2015年8月27日提交,因此只有棉花糖有机会获得此修复程序.
before writing, which is supposed to solve the problem. But the fix was committed on Aug 27, 2015, so only Marshmallow has a chance to get the fix.
这篇关于音乐播放器要求写入外部存储权限吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!