MediaPlayer,打ze模式,唤醒锁定和前台服务 [英] MediaPlayer, Doze Mode, Wake Lock & Foreground Service

查看:102
本文介绍了MediaPlayer,打ze模式,唤醒锁定和前台服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了有关Android M中新的打ze"模式的几篇文章,以及Android开发者网站上的文章:

I have read several posts regarding the new 'Doze' Mode in Android M, also the article on Android developers website : https://developer.android.com/training/monitoring-device-state/doze-standby.html yet I still have an issue with a Foreground Service correctly running on a phone (Android 6.0.1).

问题:

我有一个服务,该服务使用MediaPlayer对象处理播放音乐,该服务实现onCompletiononPrepared MediaPlayer接口.

I have a Service which handles playing music using a MediaPlayer object, the Service Implements onCompletion and onPrepared MediaPlayer interfaces.

伪代码:

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

            // Class Variables/Methods etc...

            @Override
            public void onPrepared(MediaPlayer mp) {

                   mp.start();

                   // update notification using startForeground()
            }


            @Override
                public void onCompletion(MediaPlayer mp) {

                   // Go and get another music track in separate thread
                   // (Have used AsyncTask and RX Java/RX Android to test if problem is here - works fine)
            }

            @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {

                    // handleError

                    return false;
            }

    }

当手机已插入电源,屏幕处于打开状态或打开了应用程序且屏幕处于打开状态时,该应用程序运行良好.但是,当电话一直处于闲置状态并播放音乐(介于5至40分钟之间)时,一旦调用onCompletion(),服务将无法检索下一个曲目.

The app works well, when the phone is plugged into a power source, or when the screen is on, or app is open and screen is on. However when the phone has been sitting idle and playing music (between 5 - 40mins) the Service fails to retrieve the next track once onCompletion() is called.

该服务已设置并符合以下条件:

  • 服务通知从startForeground
  • 开始
  • MediaPlayer对象具有部分唤醒锁PARTIAL_WAKE_LOCK
  • 该服务在与主应用程序/UI分开的过程中运行
  • 所有媒体都使用prepareAsync()(逻辑以获取下一个轨道uri是在后台线程中执行,prepareAsync()仅在主线程中调用)
  • The Service Notification is started with startForeground
  • The MediaPlayer Object has a partial wakelock PARTIAL_WAKE_LOCK
  • The Service runs in a separate process to the main app/UI
  • All Media uses prepareAsync() (logic to get the next track uri is performed in background thread, prepareAsync() is called only in the Main thread)

我尝试过的事情:

  • 在主线程而不是后台线程中检索下一首歌(在onCompletion调用之后)
  • 在onCompletion()中获取一个单独的Partial WakeLock,然后在调用onPrepared()时按住并释放它.
  • 其他没什么大不了的事...

我有一个logcat输出,从手机离开时起,在屏幕关闭的状态下保持一段时间不变,然后松开了插头(logcat是在我重新插入并更新日志后获得的),这说明了问题所在.

I have a logcat output, from when the phone is left, untouched for a period of time with the screen off, and UNPLUGGED (logcat was obtained once I plugged it back in and it updated the log) which demonstrates the problem.

06-15 02:31:39.346 musicplayer:music_service E/MusicService: onPrepared : Tom Petty GH - 11 - You Got Lucky
06-15 02:31:39.548 musicplayer:music_service D/MusicService: Releasing wakelock
06-15 02:35:15.467 musicplayer:music_service E/MusicService: onCompletion called
06-15 02:35:15.467 musicplayer:music_service D/MusicService: Acquiring wakelock
06-15 02:35:15.514 musicplayer:music_service D/NextActionStrategy: Retrieving song - rx java - Main Ui Thread =false
06-15 02:35:15.870 musicplayer:music_service D/NextActionStrategy: Song Retrieved : Ten Years- Main Ui Thread = true
06-15 02:35:15.950 musicplayer:music_service E/MusicService: onPrepared : Ten Years
06-15 02:35:16.149 musicplayer:music_service D/MusicService: Releasing wakelock
06-15 02:38:59.002 musicplayer:music_service E/MusicService: onCompletion called
06-15 02:38:59.002 musicplayer:music_service D/MusicService: Acquiring wakelock
06-15 02:38:59.049 musicplayer:music_service D/NextActionStrategy: Retrieving song - rx java - Main Ui Thread =false
06-15 02:38:59.211 musicplayer:music_service D/NextActionStrategy: Song Retrieved : What Am I- Main Ui Thread = true
06-15 02:50:07.642 musicplayer:music_service E/MusicService: onPrepared : What Am I
06-15 02:50:07.976 musicplayer:music_service D/MusicService: Releasing wakelock
06-15 02:50:22.097 musicplayer:music_service D/MusicService: onStartCommand called : action.PAUSE

例程应为

  • 播放曲目
  • onCompletion()被称为
  • 获取唤醒锁以获取下一首曲目
  • PrepareAsync()
  • onPrepared调用-使用startForeground开始播放并更新通知

从日志中您可以在02:38:59.xxx看到onCompletion被调用,找到一条轨道,并返回到调用prepareAsync()的主线程,但是在12分钟内没有任何反应,直到我手动唤醒打电话,然后代码会继续,从哪里停止,然后开始播放曲目.

From the logs you can see at 02:38:59.xxx onCompletion is called, a track is found, and returns to the Main thread where prepareAsync() is called, but then nothing happens for 12mins until I manually wake the phone up, and at which point just code continues where is stopped and the track starts playing.

在这种情况下,我不认为其设备可以像我使用的其他音乐应用程序一样正常工作,但是我仅限于在一台真实设备上进行测试:(

I don't believe its the device as other music apps I use work fine in this situation, however I am limited to testing on one real device only :(

如果您有这么远的帮助,请多多关照!任何建议将不胜感激(希望有一个解决方案,而不是我的音乐品味!).

If you've got this far thanks for bearing with me! Any suggestions would be appreciated (hopefully regarding a solution and not my music tastes!).

推荐答案

我只是想让您了解我如何实现startForeground()方法.也许可以帮忙:

I just wanted you to see how I am implementing my startForeground() method. Maybe this can help:

 void setUpAsForeground(String text) {
    mNotificationManager = (NotificationManager)      this.getSystemService(Context.NOTIFICATION_SERVICE);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Main.class), 0);

    NotificationCompat.Builder noti = new NotificationCompat.Builder(this)
            .setContentTitle( "My App Title")
            .setContentText(text)
            .setSmallIcon(R.drawable.ic_stat_recording)
            .setStyle(new NotificationCompat.BigTextStyle()
                    .bigText(text))

            .setPriority(Notification.PRIORITY_MAX)
            .setContentIntent(contentIntent)
            .setOngoing(false);
    final Notification notification = noti.build();
    //mNotificationManager.notify(NOTIFICATION_ID, noti.build());
    startForeground(NOTIFICATION_ID, notification);

}

onCreate()中:

 @Override
 public void onCreate() {

    PowerManager powerManager = (PowerManager)      getSystemService(POWER_SERVICE);
    PowerManager.WakeLock wakeLock =      powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
            "MyWakelockTag");
    wakeLock.acquire();

    ***********
}

这篇关于MediaPlayer,打ze模式,唤醒锁定和前台服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆