音乐服务总是返回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

确认当您的onServiceConnected方法调用并在服务中设置歌曲列表时,您的songList是PRAPARED?

我的意思是您的歌曲列表可能是无效的。

    //pass list
    musicSrv.setList(songList);

如果在完成initLayout方法之前连接服务何时连接。

update

根据下面的错误日志,您需要在清单文件中添加 READ_EXTERNAL_STORAGE权限。

java.lang.securityexception:允许拒绝:阅读 com.android.providers.media.mediaprovider uri 内容://pid = 2608,uid = 1000 需要android.permission.read_external_storage或 GrantUriPermession((

使用文件fileedescriptor设置数据源:

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

查看此答案以获取更多信息。这可能对您有帮助。

不是音乐服务问题,这是权限问题

首先,您需要为Android清单提供服务名称喜欢

之后,如果您运行6.0或更多,则需要征求使用权限,以便用户在第一次运行应用程序时写读取的外部存储在棒棒糖或套件kat或其他在安装时允许的许可中,但在棉花糖或您手动向用户询问用户

的更多信息中

检查一下棉花糖的存储权限错误

最新更新