我已经制作了一个音乐列表和一个在后台播放音乐的服务但是当我点击列表中的音乐时它总是返回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 :(得分:0)
确认当您的onServiceConnected
方法被调用并且您在服务中设置了歌曲列表时,那时您的songList
是否已经过了?
我的意思是当你在线下打电话时,你的歌曲列表可能为空。
//pass list
musicSrv.setList(songList);
如果在initLayout
方法完成之前连接了服务。
<强>更新强>
根据以下错误日志行,您需要在清单文件中添加READ_EXTERNAL_STORAGE
权限。
java.lang.SecurityException:Permission Denial:read com.android.providers.media.MediaProvider uri content:// media / external / audio / media / 1 from 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了解详情。它可能对你有帮助。
答案 1 :(得分:0)
这不是音乐服务问题,即权限问题
首先,你需要为android manifest提供服务名称 喜欢
之后如果您运行6.0或更高版本,则需要在第一次运行应用程序时请求用户写入读取外部存储的权限 在棒棒糖或套件kat或其他在安装时给予许可但在棉花糖或更多的情况下你手动询问用户