在Android服务中,列表在启动服务后的某个时间变为空
我正在开发android MusicPlayer。我已经创建了扩展服务的服务类。在我的主要活动中,我使用startService()方法调用服务类,同时以意图传递音乐list。在Android服务中,列表在启动服务后的某个时间变为空,android,service,android-mediaplayer,media,Android,Service,Android Mediaplayer,Media,我正在开发android MusicPlayer。我已经创建了扩展服务的服务类。在我的主要活动中,我使用startService()方法调用服务类,同时以意图传递音乐list。 private void sendDatatoService() { if (playIntent == null) { playIntent = new Intent(this, MusicService.class); playIntent.putParcelableArray
private void sendDatatoService() {
if (playIntent == null) {
playIntent = new Intent(this, MusicService.class);
playIntent.putParcelableArrayListExtra("songList",list);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
private final ServiceConnection musicConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.PlayerBinder binder = (MusicService.PlayerBinder) service;
serviceMusic = binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("serviceMusic::","onServiceDisconnected");
}
};
我的MusicPlayer可以正常工作一段时间,但当我暂停一会儿,试图再次播放一些歌曲时,它崩溃了,说我的歌曲列表是空的。这里发生了什么,当Android停止我的服务时,我应该启动什么样的服务来保持我的数据可供服务使用或重新获得列表来播放
@Override
public void onCreate() {
super.onCreate();
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// TODO: Done // creating a channel before creating a notification, needs channel to show notification in Android-O+ OS
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
initChannel();
}
//initializing media player, to play the music using MediaPlayer Api/class we need it to play the music
initMediaPlayer();
notificationCompatBuilder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
initNoisyReceiver();
}
public void initMediaPlayer() {
if (mPlayer == null) {
mPlayer = new MediaPlayer();
mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setOnPreparedListener(this);
mPlayer.setOnCompletionListener(this);
mPlayer.setOnErrorListener(this);
}
}
public void updateNotification(String updatedSongName, int songPos) {
setBitmapImage(mListOfSongs.get(songPos).getAlbumArt());
mNotification = notificationCompatBuilder
.setSmallIcon(R.drawable.play_logo)
.setLargeIcon(bitmapImage)
.setOngoing(true)
.setColorized(true)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setDefaults(Notification.DEFAULT_ALL)
.build();
mNotification.contentView.setTextViewText(R.id.notify_song_name, updatedSongName);
notificationManager.notify(NOTIFICATION_ID, mNotification);
String updatedAlbumName = mListOfSongs.get(songPos).getSongAlbumName();
String updatedArtistName = mListOfSongs.get(songPos).getSongArtist();
String updatedAlbumArt = mListOfSongs.get(songPos).getAlbumArt();
String updatedSongDuration = mListOfSongs.get(songPos).getSongDuration();
mCallback.onupdateClick(songPos, updatedSongName, updatedAlbumName, updatedArtistName, updatedAlbumArt, updatedSongDuration);
}
public class PlayerBinder extends Binder {
public MusicService getService() {
Log.d("test", "getService()");
return MusicService.this;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d("test", "onBind Called");
return musicBind;
}
@Override
public boolean onUnbind(Intent intent) {
if (mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
//mAudioManager.abandonAudioFocus(this);
notificationManager.cancel(NOTIFICATION_ID);
return false;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
mListOfSongs = intent.getParcelableArrayListExtra("songList");
String Action = intent.getAction();
if (!TextUtils.isEmpty(Action)) {
switch (Action) {
case ACTION_PAUSE:
playPauseSong();
break;
case ACTION_NEXT:
nextSong();
break;
case ACTION_PREVIOUS:
previousSong();
break;
case ACTION_STOP:
stopSong();
stopSelf();
break;
}
}
}
return START_STICKY;
}
private void stopSong() {
if (mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
if (mPlayer != null) {
if (mPlayer.isPlaying()) {
mPlayer.stop();
mPlayer.release();
} else {
mPlayer.release();
}
}
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(NOTIFICATION_ID);
System.exit(0);
}
public void previousSong() {
try {
if (SONG_POS == 0) {
Toast.makeText(this, "No Previous Song", Toast.LENGTH_SHORT).show();
return;
}
SONG_POS--;
startSong(Uri.parse(mListOfSongs.get(SONG_POS).getSongUri()), mListOfSongs.get(SONG_POS).getSongName(), SONG_POS);
} catch (Exception e) {
}
}
public void nextSong() {
// TODO: 10/1/2017 check if mListOfSongs is not empty otherwise it will show an error
if (mListOfSongs == null) {
Toast.makeText(this, "Restart the App", Toast.LENGTH_SHORT).show();
return;
}
if (SONG_POS >= mListOfSongs.size() - 1) {
SONG_POS = -1;
}
try {
SONG_POS++;
startSong(Uri.parse(mListOfSongs.get(SONG_POS).getSongUri()), mListOfSongs.get(SONG_POS).getSongName(), SONG_POS
);
} catch (Exception e) {
Toast.makeText(this, "No Next Song", Toast.LENGTH_SHORT).show();
startSong(Uri.parse(mListOfSongs.get(SONG_POS).getSongUri()), mListOfSongs.get(SONG_POS).getSongName(), SONG_POS);
}
}
public void startSong(Uri parseSongUri, String songName, int SONG_POS) {
//checkAudioFocus();
if (!successfullyRetrievedAudioFocus()) {
return;
}
mPlayer.reset();
mState = STATE_PLAYING;
mSongUri = parseSongUri;
try {
mPlayer.setDataSource(getApplicationContext(), mSongUri);
} catch (Exception e) {
Log.e("MUSIC SERVICE", "ERROR SETTING DATA SOURCE", e);
}
mPlayer.prepareAsync();
updateNotification(songName, SONG_POS);
}
public void playPauseSong() {
if (mPlayer == null) {
initMediaPlayer();
}
if (mState == STATE_PAUSED) {
mState = STATE_PLAYING;
mPlayer.start();
} else {
mState = STATE_PAUSED;
mPlayer.pause();
}
}
//starting media player when media player is ready
@Override
public void onPrepared(MediaPlayer mp) {
mPlayer.start();
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return false;
}
@Override
public void onCompletion(MediaPlayer mp) {
mPlayer.reset();
try {
if (SONG_POS < mListOfSongs.size() - 1) {
nextSong();
} else {
SONG_POS = 0;
mPlayer.setDataSource(getApplicationContext(), Uri.parse(mListOfSongs.get(SONG_POS).getSongUri()));
}
} catch (Exception e) {
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
}
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_LOSS: {
if (mPlayer.isPlaying()) {
mPlayer.stop();
}
break;
}
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: {
mPlayer.pause();
break;
}
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: {
if (mPlayer != null) {
mPlayer.setVolume(0.3f, 0.3f);
}
break;
}
case AudioManager.AUDIOFOCUS_GAIN: {
if (mPlayer != null) {
if (!mPlayer.isPlaying()) {
mPlayer.start();
}
mPlayer.setVolume(1.0f, 1.0f);
}
break;
}
}
}
private void setSongURI(Uri mSongUri) {
this.mSongUri = mSongUri;
}
private void setBitmapImage(String albumArt) {
// Drawable img = Drawable.createFromPath(albumArt);
if (!albumArt.equals("null")) {
bitmapImage = BitmapFactory.decodeFile(albumArt);
} else {
bitmapImage = BitmapFactory.decodeResource(getResources(), R.drawable.beat_box_logo);
}
}
public void setSelectedSong(int pos, int notification_id, Context context, UpdateFromService listner) {
SONG_POS = pos;
this.mCallback = listner;
NOTIFICATION_ID = notification_id;
setSongURI(Uri.parse(mListOfSongs.get(SONG_POS).getSongUri()));
setBitmapImage(mListOfSongs.get(SONG_POS).getAlbumArt());
ShowNotification();
startSong(Uri.parse(mListOfSongs.get(SONG_POS).getSongUri()), mListOfSongs.get(SONG_POS).getSongName(), SONG_POS);
}
private void ShowNotification() {
PendingIntent pendingIntent, pendingIntentStop;
Intent intentStop, intentPause, intentPrevious, intentNext;
RemoteViews notificationView = new RemoteViews(getPackageName(), R.layout.notification_mediacontroller);
notificationView.setTextViewText(R.id.notify_song_name, mListOfSongs.get(SONG_POS).getSongName());
intentStop = new Intent(ACTION_STOP);
pendingIntentStop = PendingIntent.getService(getApplicationContext(), REQUEST_CODE_STOP, intentStop, PendingIntent.FLAG_CANCEL_CURRENT);
intentPause = new Intent(ACTION_PAUSE);
pendingIntent = PendingIntent.getService(getApplicationContext(), REQUEST_CODE_PAUSE, intentPause, PendingIntent.FLAG_UPDATE_CURRENT);
notificationView.setOnClickPendingIntent(R.id.notify_btn_pause, pendingIntent);
intentPrevious = new Intent(ACTION_PREVIOUS);
pendingIntent = PendingIntent.getService(getApplicationContext(), REQUEST_CODE_PREVIOUS, intentPrevious, PendingIntent.FLAG_UPDATE_CURRENT);
notificationView.setOnClickPendingIntent(R.id.notify_btn_previous, pendingIntent);
intentNext = new Intent(ACTION_NEXT);
pendingIntent = PendingIntent.getService(getApplicationContext(), REQUEST_CODE_NEXT, intentNext, PendingIntent.FLAG_UPDATE_CURRENT);
notificationView.setOnClickPendingIntent(R.id.notify_btn_next, pendingIntent);
//this intent and pending intent using to open the app when user click on Notification
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity(this, NOTIFICATION_ID,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent intent = new Intent(getBaseContext(), MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(getApplicationContext());
stackBuilder.addNextIntent(intent);
PendingIntent pendingIntent2 = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_CANCEL_CURRENT);
mNotification = notificationCompatBuilder
.setColorized(true)
.setContent(notificationView)
/* .setContentIntent(pendingIntent2)*/ //opens activity when user click on notification
.setCustomContentView(notificationView)
.setDefaults(Notification.COLOR_DEFAULT)
.setDeleteIntent(pendingIntentStop)
.setLargeIcon(bitmapImage)
.setOngoing(true)
.setSmallIcon(R.drawable.play_logo)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.build();
startForeground(NOTIFICATION_ID, mNotification);
}
private void initChannel() {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationChannel = new NotificationChannel(CHANNEL_ID,
CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setVibrationPattern(new long[]{0});
notificationChannel.setDescription("BeatBox Notification");
notificationChannel.enableLights(false);
notificationChannel.enableVibration(false);
notificationChannel.canShowBadge();
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
notificationManager.createNotificationChannel(notificationChannel);
}
}
private void initNoisyReceiver() {
//Handles headphones coming unplugged. cannot be done through a manifest receiver
IntentFilter filter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
registerReceiver(mNoisyReceiver, filter);
}
private BroadcastReceiver mNoisyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (mPlayer != null && mPlayer.isPlaying()) {
mPlayer.pause();
}
}
};
private boolean successfullyRetrievedAudioFocus() {
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
return result == AudioManager.AUDIOFOCUS_GAIN;
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mNoisyReceiver);
notificationManager.cancel(NOTIFICATION_ID);
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
notificationManager.cancel(NOTIFICATION_ID);
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
}
}
@覆盖
public void onCreate(){
super.onCreate();
notificationManager=(notificationManager)getSystemService(Context.NOTIFICATION\u服务);
//TODO:Done//在创建通知之前创建通道,需要通道在Android-O+OS中显示通知
if(android.os.Build.VERSION.SDK\u INT>=Build.VERSION\u code.O){
initChannel();
}
//初始化媒体播放器,要使用媒体播放器Api/类播放音乐,我们需要它来播放音乐
initMediaPlayer();
notificationCompatBuilder=新建NotificationCompat.Builder(getApplicationContext(),通道ID);
InitNoiserReceiver();
}
公共媒体播放器(){
if(mPlayer==null){
mPlayer=新媒体播放器();
mPlayer.setWakeMode(getApplicationContext(),PowerManager.PARTIAL_WAKE_LOCK);
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setOnPreparedListener(此);
mPlayer.setOnCompletionListener(此);
mPlayer.setOneErrorListener(此);
}
}
public void updateNotification(字符串updatedSongName,int-songPos){
setBitmapImage(mListOfSongs.get(songPos.getAlbumArt());
mNotification=通知compativebuilder
.setSmallIcon(右可绘制播放标志)
.setLargeIcon(位图图像)
.正在进行(正确)
.setColorized(真)
.setStyle(新通知Compat.DecoratedCustomViewStyle())
.setDefaults(通知.DEFAULT\u全部)
.build();
mNotification.contentView.setTextViewText(R.id.notify\u song\u name,updatedSongName);
notificationManager.notify(通知ID、通知);
String updatedAlbumName=mListOfSongs.get(songPos.getSongAlbumName();
String updatedArtistName=mListOfSongs.get(songPos.getSongArtister();
字符串updatedAlbumArt=mListOfSongs.get(songPos.getAlbumArt();
String updatedSongDuration=mListOfSongs.get(songPos.getSongDuration();
onupdateClick(songPos、updatedSongName、updatedAlbumName、updatedArtistName、updatedAlbumArt、updatedSongDuration);
}
公共类PlayerBinder扩展绑定器{
公共音乐服务getService(){
Log.d(“test”,“getService()”);
返回MusicService.this;
}
}
@可空
@凌驾
公共IBinder onBind(意向){
Log.d(“测试”,“调用onBind”);
返回音乐绑定;
}
@凌驾
公共布尔onUnbind(意图){
if(mgr!=null){
监听经理(phoneStateListener,phoneStateListener.listen\u NONE);
}
//mAudioManager.Focus(本);
notificationManager.cancel(通知ID);
返回false;
}
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
if(intent!=null){
mListOfSongs=intent.getParcelableArrayListExtra(“歌曲列表”);
String Action=intent.getAction();
如果(!TextUtils.isEmpty(操作)){
开关(动作){
案例行动暂停:
playPauseSong();
打破
下一步行动:
nextSong();
打破
以前的案件行动:
上一首歌();
打破
个案行动(停止):
停止歌曲();
stopSelf();
打破
}
}
}
返回开始时间;
}
私人电台{
if(mgr!=null){
监听经理(phoneStateListener,phoneStateListener.listen\u NONE);
}
if(mPlayer!=null){
if(mPlayer.isPlaying()){
mPlayer.stop();
mPlayer.release();
}否则{
mPlayer.release();
}
}
NotificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION\u服务);
经理。取消(通知\u ID);
系统出口(0);
}
公开作废前一首歌(){
试一试{
如果(SONG_POS==0){
Toast.makeText(这首“没有以前的歌曲”,Toast.LENGTH_SHORT).show();
返回;
}
宋(右);
startSong(Uri.parse(mListOfSongs.get(SONG_POS.getSongUri()),mListOfSongs.get(SONG_POS.getSongName(),SONG_POS));
}捕获(例外e){
}
}
下松公共图书馆(){
//TODO:10/1/2017检查mListOfSongs是否为空,否则将显示错误
if(mListOfSongs==null){
Toast.makeText(这是“重新启动应用程序”,Toast.LENGTH_SHORT).show();
返回;
}
如果(SONG_POS>=mListOfSongs.size()-1){
宋_POS=-1;
}
试一试{
SONG_POS++;
startSong(Uri.parse(mListOfSongs.get(SONG_POS.getSongUri()),mListOfSongs.get(SONG_POS.getSongName(),SONG_POS
);
}捕获(例外e){
Toast.makeText(这是“没有下一首歌”,Toast.LENGTH_SHORT).show();
startSong(Uri.parse(mListOfSongs.get(SONG_POS.getSongUri()),mListOfSongs.get(SONG_POS.getSongName(),SONG_POS));
}
}
public void startSong(Uri parseSongUri,字符串songName,int SONG_POS){
//检查音频焦点();
如果(!successfullyRetrievedAudioFocus()){
返回;
}
mPlayer.reset();
mState=播放状态;
mSongUri=parseSongUri;
试一试{
setDataSource(getApplicationContext(),mSongUri);
}捕获(例外e){
Log.e(“音乐服务”,“设置DA时出错”
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
.....
return START_REDELIVER_INTENT;
}