繁体   English   中英

MediaPlayer,打盹模式,唤醒锁定和前台服务

[英]MediaPlayer, Doze Mode, Wake Lock & Foreground Service

我已经阅读了几篇关于Android M中新的“Doze”模式的帖子,以及Android开发者网站上的文章: https//developer.android.com/training/monitoring-device-state/doze-standby.html但我仍然在手机上正确运行Foreground Service时遇到问题(Android 6.0.1)。

问题:

我有一个Service,它使用MediaPlayer对象,Service Implements onCompletiononPrepared MediaPlayer接口处理播放音乐。

伪代码:

    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(),服务就无法检索下一个音轨。

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

  • 服务通知以startForeground启动
  • MediaPlayer对象具有部分唤醒PARTIAL_WAKE_LOCK
  • 该服务在与主app / UI分开的进程中运行
  • 所有媒体都使用prepareAsync() (获取下一个轨道的逻辑uri在后台线程中执行,prepareAsync()仅在主线程中调用)

我尝试过的事情:

  • 在主线程而不是后台线程中检索下一首歌曲(在调用onCompletion之后)
  • 在onCompletion()中获取单独的部分WakeLock,并在调用onPrepared()时保持然后释放它。
  • 很少有其他琐碎的事情没有什么区别......

我有一个logcat输出,从手机离开时,在屏幕关闭的情况下保持一段时间不动,并且UNPLUGGED(一旦我将其重新插入并且更新了日志就获得了logcat),这表明了问题。

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()调用
  • 获取wakelock获得下一首曲目
  • PrepareAsync()
  • onPrepared调用 - 使用startForeground开始播放和更新通知

从日志中你可以看到02:38:59.xxx onCompletion被调用,找到一个轨道,然后返回到调用prepareAsync()的主线程,但是在我手动唤醒手机之前12分钟没有任何反应,然后只需要代码继续停止的地方并开始播放曲目。

我不相信它的设备与我使用的其他音乐应用程序在这种情况下工作正常,但是我仅限于在一个真实设备上进行测试:(

如果你有这个远,感谢与我的关系! 任何建议将不胜感激(希望有关解决方案,而不是我的音乐品味!)。

我只是想让你看看我是如何实现我的startForeground()方法的。 也许这可以帮助:

 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();

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM