5

Sto creando un'applicazione di lettore musicale in Android. Funziona bene ma ogni volta che scorrere nelle canzoni lista comincia crash e dà questa eccezioneLettore musicale che richiede la scrittura di autorizzazione di archiviazione esterna?

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) 

Questo problema va via quando mi danno il permesso di scrittura nel file manifesto, ma la cosa che non capisco è il motivo per cui è chiedendo WriteExternalStoragePermission quando non sto scrivendo nulla su alcun tipo di archiviazione. Per quanto ne so, il lettore musicale non richiede la scrittura di autorizzazioni di archiviazione esterne.

Qui è il codice per Canzoni Lista attività

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; 
    } 
} 

Si blocca con l'eccezione su questa linea

bitmap = MediaStore.Images.Media.getBitmap(ctx.getContentResolver(), uri);

In questo codice mi sto Album Art for corrispondente file mp3. Ma questo codice sta anche leggendo da una memoria esterna, quindi anche questo non dovrebbe chiedere permessi di scrittura visto che sto leggendo solo bitmap e non scriverlo.

risposta

9

Da the MediaProvider code, che gestisce "/ media/esterno/audio/albumart"

All'interno 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); 
} 

Quindi, se il file non trovato, si chiama getThumb

getThumb chiamate makeThumbInternal

Quindi, in determinate condizioni, chiama

writeAlbumArt(need_to_recompress, out, compressed, bm); 

Nell'ultima versione, writeAlbumArt chiama

final long identity = Binder.clearCallingIdentity(); 

prima di scrivere, che dovrebbe risolvere il problema. Ma la correzione è stata commessa il 27 agosto 2015, quindi solo Marshmallow ha la possibilità di ottenere la soluzione.

+1

Posso eseguire il debug per questo? –

-1

Dichiarare il permesso nel file manifesto come di seguito:

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


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

Hai letto la domanda o solo il titolo? –

+0

sì ho letto correttamente la domanda che devi dare almeno android.permission.READ_EXTERNAL_STORAGE –

+0

Ho già detto che è per questo che sto ricevendo la lista dei brani –

0

E 'necessario perché MediaStore lo richiede, non c'è sola lettura; MediaStore sta accedendo a file esterni sul tuo comportamento, quindi stai facendo la lettura.

+0

ma non scrivendo –

Problemi correlati