2017-04-21 187 views
-1

我已經和音樂列表和服務在後臺播放音樂,但是當我從列表中的音樂單擊它總是返回null音樂服務始終返回null

我從來沒有與音樂服務工作前,所以我也許在這裏做錯了 我是否在採用者或其他方面通過錯誤的立場?

服務

public class MusicService extends Service implements 
     MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, 
     MediaPlayer.OnCompletionListener { 

    //media player 
    private MediaPlayer player; 
    //song list 
    private ArrayList<SongModel> songs; 
    //current position 
    private int songPosn; 
    //binder 
    private final IBinder musicBind = new MusicBinder(); 
    //title of current song 
    private String songTitle = ""; 
    //notification id 
    private static final int NOTIFY_ID = 1; 
    //shuffle flag and random 
    private boolean shuffle = false; 
    private Random rand; 

    public void onCreate() { 
     //create the service 
     super.onCreate(); 
     //initialize position 
     songPosn = 0; 
     //random 
     rand = new Random(); 
     //create player 
     player = new MediaPlayer(); 
     //initialize 
     initMusicPlayer(); 
    } 

    public void initMusicPlayer() { 
     //set player properties 
     player.setWakeMode(getApplicationContext(), 
       PowerManager.PARTIAL_WAKE_LOCK); 
     player.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     //set listeners 
     player.setOnPreparedListener(this); 
     player.setOnCompletionListener(this); 
     player.setOnErrorListener(this); 
    } 

    //pass song list 
    public void setList(ArrayList<SongModel> theSongs) { 
     songs = theSongs; 
    } 

    //binder 
    public class MusicBinder extends Binder { 
     public MusicService getService() { 
      return MusicService.this; 
     } 
    } 

    //activity will bind to service 
    @Override 
    public IBinder onBind(Intent intent) { 
     return musicBind; 
    } 

    //release resources when unbind 
    @Override 
    public boolean onUnbind(Intent intent) { 
     player.stop(); 
     player.release(); 
     return false; 
    } 

    //play a song 
    public void playSong() { 
     //play 
     player.reset(); 
     //get song 
     SongModel playSong = songs.get(songPosn); 
     //get title 
     songTitle = playSong.getSongTitle(); 
     //get id 
     long currSong = playSong.getmSongID(); 
     //set uri 
     Uri trackUri = ContentUris.withAppendedId(
       android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
       currSong); 
     //set the data source 
     try { 
      player.setDataSource(getApplicationContext(), trackUri); 
     } catch (Exception e) { 
      Log.e("MUSIC SERVICE", "Error setting data source", e); 
     } 
     player.prepareAsync(); 
    } 

    //set the song 
    public void setSong(int songIndex) { 
     Log.e("click", " service" + songIndex); 
     for (int i = 0; i < songs.size(); i++) { 
      Log.e("click", songs.get(i).getArtistname() + " " + songs.get(i).getmSongID()); 
     } 
     songPosn = songIndex; 
    } 

    @Override 
    public void onCompletion(MediaPlayer mp) { 
     //check if playback has reached the end of a track 
     if (player.getCurrentPosition() > 0) { 
      mp.reset(); 
      playNext(); 
     } 
    } 

    @Override 
    public boolean onError(MediaPlayer mp, int what, int extra) { 
     Log.v("MUSIC PLAYER", "Playback Error"); 
     mp.reset(); 
     return false; 
    } 

    @Override 
    public void onPrepared(MediaPlayer mp) { 
     //start playback 
     mp.start(); 
     //notification 
     Intent notIntent = new Intent(this, MainActivity.class); 
     notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
     PendingIntent pendInt = PendingIntent.getActivity(this, 0, 
       notIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

     Notification.Builder builder = new Notification.Builder(this); 

     builder.setContentIntent(pendInt) 
       .setSmallIcon(R.mipmap.ic_play_circle_filled_black_24dp) 
       .setTicker(songTitle) 
       .setOngoing(true) 
       .setContentTitle("Playing") 
       .setContentText(songTitle); 
     Notification not = builder.build(); 
     startForeground(NOTIFY_ID, not); 
    } 

    //playback methods 
    public int getPosn() { 
     return player.getCurrentPosition(); 
    } 

    public int getDur() { 
     return player.getDuration(); 
    } 

    public boolean isPng() { 
     return player.isPlaying(); 
    } 

    public void pausePlayer() { 
     player.pause(); 
    } 

    public void seek(int posn) { 
     player.seekTo(posn); 
    } 

    public void go() { 
     player.start(); 
    } 

    //skip to previous track 
    public void playPrev() { 
     songPosn--; 
     if (songPosn < 0) songPosn = songs.size() - 1; 
     playSong(); 
    } 

    //skip to next 
    public void playNext() { 
     if (shuffle) { 
      int newSong = songPosn; 
      while (newSong == songPosn) { 
       newSong = rand.nextInt(songs.size()); 
      } 
      songPosn = newSong; 
     } else { 
      songPosn++; 
      if (songPosn >= songs.size()) songPosn = 0; 
     } 
     playSong(); 
    } 

    @Override 
    public void onDestroy() { 
     stopForeground(true); 
    } 

    //toggle shuffle 
    public void setShuffle() { 
     if (shuffle) shuffle = false; 
     else shuffle = true; 
    }} 

活動類

public static MusicService musicSrv; 
    private Intent playIntent; 
    private boolean musicBound=false; 

    public static ArrayList<SongModel> songList; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     load(); 
    @Override 
    protected void onStart() { 
     super.onStart(); 
     if(playIntent==null){ 
      playIntent = new Intent(this, MusicService.class); 
      bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE); 
      startService(playIntent); 
     } 
    } 

private ServiceConnection musicConnection = new ServiceConnection() { 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     MusicService.MusicBinder binder = (MusicService.MusicBinder) service; 
     //get service 
     musicSrv = binder.getService(); 
     //pass list 
     musicSrv.setList(songList); 
     musicBound = true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) { 
     musicBound = false; 
    } 
}; 

    private void initLayout() { 
     final Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
     final String[] cursor_cols = {MediaStore.Audio.Media._ID, 
       MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, 
       MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA, 
       MediaStore.Audio.Media.ALBUM_ID, 
       MediaStore.Audio.Media.DURATION}; 
     final String where = MediaStore.Audio.Media.IS_MUSIC + "=1"; 
     final Cursor cursor = getContentResolver().query(uri, 
       cursor_cols, where, null, null); 


     while (cursor.moveToNext()) { 
      String artist = cursor.getString(cursor 
        .getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)); 
      String album = cursor.getString(cursor 
        .getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)); 
      String track = cursor.getString(cursor 
        .getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)); 
      String data = cursor.getString(cursor 
        .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); 
      Long albumId = cursor.getLong(cursor 
        .getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)); 

      int duration = cursor.getInt(cursor 
        .getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)); 

      Uri sArtworkUri = Uri 
        .parse("content://media/external/audio/albumart"); 
      Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, albumId); 

      Log.e("art", albumArtUri.toString()); 
      /*Bitmap bitmap = null; 
      try { 
       bitmap = MediaStore.Images.Media.getBitmap(
         getActivity().getContentResolver(), albumArtUri); 
       bitmap = Bitmap.createScaledBitmap(bitmap, 30, 30, true); 

      } catch (FileNotFoundException exception) { 
       exception.printStackTrace(); 
       bitmap = BitmapFactory.decodeResource(getActivity().getResources(), 
         R.mipmap.ic_music_note_black_24dp); 
      } catch (IOException e) { 

       e.printStackTrace(); 
      }*/ 

      SongModel audioListModel = new SongModel(); 
      audioListModel.setArtistname(artist); 
      // audioListModel.setBitmap(bitmap); 
      audioListModel.setmSongTitle(album); 
      audioListModel.setmSongTitle(track); 
      audioListModel.setData(data); 
      audioListModel.setmSongID(albumId); 
      audioListModel.setSongLength(String.valueOf(duration)); 
      audioListModel.setUri(String.valueOf(albumArtUri)); 
      Log.e("data", "artist :" + artist + " album " + album + " track " + track + " data " + data + " " + "albumId " + albumId 
        + " " + "duration " + duration + " art: " + albumArtUri); 

      songList.add(audioListModel); 

     } 

    } 


    private class GetAudioListAsynkTask extends AsyncTask<Void, Void, Boolean> { 

     private Context context; 

     public GetAudioListAsynkTask(Context context) { 

      this.context = context; 
     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 

     } 

     @Override 
     protected Boolean doInBackground(Void... params) { 
      try { 
       initLayout(); 

       return true; 
      } catch (Exception e) { 
       return false; 

      } 

     } 

     @Override 
     protected void onPostExecute(Boolean result) { 
      Collections.sort(songList, new Comparator<SongModel>() { 
       public int compare(SongModel a, SongModel b) { 
        return a.getSongTitle().compareTo(b.getSongTitle()); 
       } 
      }); 

     } 
    } 

    public void load() { 
     songList = new ArrayList<>(); 
     new GetAudioListAsynkTask(this).execute((Void) null); 


    } 

適配器類

@Override 
public void onBindViewHolder(final Holder holder, final int position) { 
    final SongModel songModel = list.get(holder.getAdapterPosition()); 
    Glide.with(holder.itemView.getContext()).load(songModel.getUri()).error(R.mipmap.ic_music_note_black_24dp).into(holder.imageView); 
    holder.imageView.setImageURI(Uri.parse(songModel.getUri())); 
    holder.artistname.setText(songModel.getArtistname()); 
    holder.duration.setText(songModel.getSongLength()); 
    holder.songname.setText(songModel.getSongTitle()); 
    holder.itemView.setTag(position); 

    holder.itemView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      songPicked(position); 
     } 
    }); 


} 
private void songPicked(int position) { 
    musicSrv.setSong(position); 
    musicSrv.playSong(); 
} 

錯誤日誌

04-21 19:01:37.847 3983-29870/? E/DatabaseUtils: Writing exception to parcel 
               java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media/1 from pid=2608, uid=1000 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() 
                at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:646) 
                at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:493) 
                at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:484) 
                at android.content.ContentProvider$Transport.openFile(ContentProvider.java:380) 
                at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:240) 
                at android.os.Binder.execTransact(Binder.java:453) 


               [ 04-21 19:01:37.847 2264:16266 D/   ] 
               openContentUri(content://media/external/audio/media/1) caught exception -1 
04-21 19:01:37.847 2264-16266/? E/MediaPlayerService: Couldn't open fd for content://media/external/audio/media/1 
04-21 19:01:37.847 19273-19273/? E/MediaPlayer: Unable to create media player 
04-21 19:01:37.847 19273-19273/? E/MUSIC SERVICE: Error setting data source 
                java.io.IOException: setDataSource failed.: status=0x80000000 
                 at android.media.MediaPlayer.nativeSetDataSource(Native Method) 
                 at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1231) 
                 at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1215) 
                 at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1169) 
                 at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1105) 
                 at com.nowsip.musicplayer.service.MusicService.playSong(MusicService.java:118) 
                 at com.nowsip.musicplayer.adapter.SongAdapter.songPicked(SongAdapter.java:86) 
                 at com.nowsip.musicplayer.adapter.SongAdapter.access$000(SongAdapter.java:24) 
                 at com.nowsip.musicplayer.adapter.SongAdapter$1.onClick(SongAdapter.java:52) 
                 at android.view.View.performClick(View.java:5721) 
                 at android.view.View$PerformClick.run(View.java:22620) 
                 at android.os.Handler.handleCallback(Handler.java:739) 
                 at android.os.Handler.dispatchMessage(Handler.java:95) 
                 at android.os.Looper.loop(Looper.java:148) 
                 at android.app.ActivityThread.main(ActivityThread.java:7409) 
                 at java.lang.reflect.Method.invoke(Native Method) 
                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
04-21 19:01:37.847 19273-19273/? E/MediaPlayer: prepareAsync called in state 1 
04-21 19:01:37.847 19273-19273/? E/AndroidRuntime: FATAL EXCEPTION: main 
                Process: com.nowsip.musicplayer, PID: 19273 
                java.lang.IllegalStateException 
                 at android.media.MediaPlayer.prepareAsync(Native Method) 
                 at com.nowsip.musicplayer.service.MusicService.playSong(MusicService.java:122) 
                 at com.nowsip.musicplayer.adapter.SongAdapter.songPicked(SongAdapter.java:86) 
                 at com.nowsip.musicplayer.adapter.SongAdapter.access$000(SongAdapter.java:24) 
                 at com.nowsip.musicplayer.adapter.SongAdapter$1.onClick(SongAdapter.java:52) 
                 at android.view.View.performClick(View.java:5721) 
                 at android.view.View$PerformClick.run(View.java:22620) 
                 at android.os.Handler.handleCallback(Handler.java:739) 
                 at android.os.Handler.dispatchMessage(Handler.java:95) 
                 at android.os.Looper.loop(Looper.java:148) 
                 at android.app.ActivityThread.main(ActivityThread.java:7409) 
                 at java.lang.reflect.Method.invoke(Native Method) 
                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
04-21 19:01:37.887 19790-19790/? E/Zygote: v2 
04-21 19:01:37.887 2608-19795/? E/android.os.Debug: ro.product_ship = true 
04-21 19:01:37.887 2608-19795/? E/android.os.Debug: ro.debug_level = 0x4f4c 
04-21 19:01:37.887 2608-19795/? E/android.os.Debug: sys.mobilecare.preload = false 
04-21 19:01:37.897 19790-19790/? E/Zygote: accessInfo : 0 
04-21 19:01:37.897 2608-2803/? E/Qmage: isQIO : stream is not a QIO file 
04-21 19:01:38.457 11589-11589/? E/Qmage: isQIO : stream is not a QIO file 
04-21 19:01:38.497 11589-11589/? E/Qmage: isQIO : stream is not a QIO file 
04-21 19:01:38.497 11589-11589/? E/Qmage: isQIO : stream is not a QIO file 
+0

*音樂服務始終返回null *它不會自動的設置爲不爲空,並在你的代碼沒有分配新建分配FY – Selvin

+0

@Selvin讓我怎麼設置u能告訴我 – androidpie

+0

像往常一樣(和因爲它是在無數的教程/問題中說明)讓活頁夾在正確的位置,從活頁夾得到服務,分配 – Selvin

回答

0

確認時叫你的onServiceConnected方法和設置歌曲列表中的服務,在那個時候你songList是prapared與否?

我的意思是你的歌曲列表可能爲空,當你撥打下面的線。

//pass list 
    musicSrv.setList(songList); 

在當你initLayout方法之前完成業務接入的情況下。

更新

根據以下線的錯誤日誌,你需要在你的清單文件中添加READ_EXTERNAL_STORAGE權限。

java.lang.SecurityException異常:權限拒絕:讀取 com.android.providers.media.MediaProvider URI 內容://媒體/外部/音頻/媒體/ 1從PID = 2608,UID = 1000 需要android.permission.READ_EXTERNAL_STORAGE,或 grantUriPermission()使用文件FileDescriptor

集的數據源:

//play a song 
public void playSong() { 
    //play 
    player.reset(); 
    //get song 
    SongModel playSong = songs.get(songPosn); 
    //get title 
    songTitle = playSong.getSongTitle(); 
    //get id 
    long currSong = playSong.getmSongID(); 
    //set uri 
    Uri trackUri = ContentUris.withAppendedId(
      android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
      currSong); 
    //set the data source 
    try { 
     String filePath = getPathFromContentUri(context, trackUri); 
     File file = new File(filePath); 
     FileInputStream inputStream = new FileInputStream(file);  
     player.setDataSource(inputStream.getFD()); 
     inputStream.close(); 
    } catch (Exception e) { 
     Log.e("MUSIC SERVICE", "Error setting data source", e); 
    } 
    player.prepareAsync(); 
} 


public static String getPathFromContentUri(Context context, Uri contentUri) { 
    String[] proj = { MediaStore.Audio.Media.DATA }; 
    Cursor cursor = context.getContentResolver().query(contentUri, 
      proj, null, null, null); 
    cursor.moveToFirst(); 

    String path = cursor.getString(cursor 
      .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); 

    cursor.close(); 
    return path; 
} 

結帳this answer瞭解更多信息。這可能對你有所幫助。

+0

我試過同樣的錯誤 – androidpie

+0

O n您正在使用哪個設備和Android操作系統版本進行測試? –

+0

M和KITKAT測試 – androidpie

0

這不是音樂服務的問題就是權限問題

首先你需要給服務名爲Android清單 像

後,如果您在運行6。0或更多,那麼當第一次運行應用程序 在棒棒糖或套件kat或其他在安裝時給予許可但在棉花糖或更多的手動請求用戶

檢查了這一點 Storage permission error in Marshmallow