实现音乐播放器后台Service服务一直存在的解决思路

时间:2021-08-15 10:15:41

最近实现一个音乐播放器的小项目,实现后台播放歌曲的功能,即使退出程序也可以一直播放歌曲,服务不被停止。
实现这个功能的过程中遇到了有两个问题:
问题1、退出程序之后,service播放歌曲的服务在后台执行,但是当屏幕锁屏之后,播放一段时间后,服务被停止,歌曲停止播放。控制台打印输出下面的字符串“QCMediaPlayer mediaplayer NOT present”
问题2、锁屏后,唤醒屏幕,此时歌曲会停止播放,而不是一直播放。

这两个问题都有解决方案。

  • 第一个问题解决方法:

在启动播放service的时候,获取电源设备锁,等到停止服务的时候释放电源设备锁。
这个方法需要权限:
< uses-permission android:name=”android.permission.WAKE_LOCK”/>

实例代码如下:

@Override
public void onCreate() {
super.onCreate();
acquireWakeLock();//获取设备电源锁
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

MusicUtils.initMusicList();
mPlayingPosition = (Integer) SpUtils.get(this, Constants.PLAY_POS, 0);

Uri uri = Uri.parse(MusicUtils.sMusicList.get(
getPlayingPosition()).getUri());
mPlayer = MediaPlayer.create(PlayService.this,uri);
mPlayer.setOnCompletionListener(this);
// 开始更新进度的线程
mProgressUpdatedListener.execute(mPublishProgressRunnable);
}
// 申请设备电源锁
private void acquireWakeLock() {
L.l(TAG, "正在申请电源锁");
if (null == mWakeLock) {
PowerManager pm = (PowerManager) this
.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, "");
if (null != mWakeLock) {
mWakeLock.acquire();
L.l(TAG, "电源锁申请成功");
}
}
}

// 释放设备电源锁
private void releaseWakeLock() {
L.l(TAG, "正在释放电源锁");
if (null != mWakeLock) {
mWakeLock.release();
mWakeLock = null;
L.l(TAG, "电源锁释放成功");
}
}
  • 第二个问题解决方法:
/*这个问题是版本问题
4.0以上 不要new了
直接create*/

Uri uri = Uri.parse(MusicUtils.sMusicList.get(
getPlayingPosition()).getUri());
mPlayer = MediaPlayer.create(PlayService.this,uri);

解决方法就是:mplayer=new MediaPlayer();
改为:mPlayer = MediaPlayer.create(PlayService.this,uri);
即可。

另外值得一提同时,播放歌曲需要读取SD卡数据,所以需要权限:
< uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>

还有一点必须提醒,就是服务的开启,我们知道服务有两种方式启动,一种是startservice()方式启动,这种方式不随着Context的销毁而接触绑定导致服务停止,另一种方式是bindservice()方式,这种方式随着context的销毁而unbindservice,导致服务停止。

我们可以在application类中使用startservice启动所需的服务,然后到需要绑定该服务的Activity中使用bindservice再次绑定该服务,activity销毁时再unbindservice服务,此时并不会stopservice,除非显式调用stopservice方法才会导致服务停止。使用这中方法可以尽可能的提高服务的优先级,使服务一直在后台运行。

最后需要指出的是,以上措施并不能是服务很好的平稳运行,在我手机中采用了以上方法,但是,当我退出程序,app在后台运行,歌曲会一直播放,但是等一段时间后歌曲会停止播放,但是后台服务并没有调用ondestory方法,也就是说服务没有停止。

目前为止,本人了解到,一般开发者开发的app还不能做到一直在后台运行的服务,还不能像QQ,微信这样的APP做到服务一直在后台,无法销毁。这个原因是,一般开发的app并不是手机安全软件所识别,手机安全软件有白名单,这些白名单就是QQ,微信等应用,它的用户量非常多,所以手机安全软件是不会把这些app服务给销毁掉的,而一般app并不是用户所必须的,手机安全软件当然把一般的app服务给销毁掉,不然的话,一般开发者开发的app都能开发一直运行的服务在后台运行的话,手机本身都受不了了!所以在此提醒大家,不要费劲开发service服务一直在后台运行的了,能做到service服务在不清楚内存的情况下能够运行就可以了,而上面的那些方法说明是可以做到的!

上面的解决措施是我亲身测试过的,如果有什么疑问,大家留言,相互交流学习!!^_^【握手】