Android"O"(Oreo,8)和更高版本的媒体按钮问题 [英] Android "O" (Oreo, 8) and higher media buttons issue

查看:60
本文介绍了Android"O"(Oreo,8)和更高版本的媒体按钮问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Text-to-Speech应用程序中使用的用于处理耳机中的媒体按钮的代码在Android API 22至25下非常有效(在旧版Android中,它们是通过其他现已贬值的方式处理的).但是,在公开测试版和最终版本的Android 8"Oreo"下,它均无法正常工作.这是相关代码:

The code for handling media buttons from headsets that I use in my Text-to-Speech app works great under Android API 22 through 25 (in older versions of Android they are handled by other, now depreciated means). However under Android 8 "Oreo", both public beta and final release, it does not work. Here is the relevant code:

服务启动时,我创建MediaSessionCompact对象:

When the service starts, I create MediaSessionCompact object:

        mSession = new MediaSessionCompat(getApplicationContext(), "my.package.name._player_session");
        mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
        mSession.setActive(true);
        mSession.setCallback(myMediaSessionCallback);
        PlaybackStateCompat state = new PlaybackStateCompat.Builder()
                .setActions(ACTION_PLAY_PAUSE | ACTION_PLAY | ACTION_PAUSE |
                        ACTION_SKIP_TO_NEXT | ACTION_SKIP_TO_PREVIOUS |
                        ACTION_FAST_FORWARD | ACTION_REWIND
                )
                .setState(PlaybackStateCompat.STATE_PAUSED, 0 /*PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN*/, 1f)
                .build();
        mSession.setPlaybackState(state);

当然定义了会话媒体回调:

There is of course session media callback defined:

private MediaSessionCompat.Callback myMediaSessionCallback = new MediaSessionCompat.Callback() {
    @Override
    public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
        // The log output below never appears on "Oreo", nothing comes here.
        Log.d(TAG, "callback onMediaButtonEvent() Compat");
        MediaButtonIntentReceiver.handleIntent(mediaButtonIntent.getAction(), (KeyEvent) mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT));
        return true;
    }

    @Override
    public void onSkipToNext() {
        //...
    }
    // etc. other overrides
};

我还尝试了PendingIntent,使用MediaButtonReceiver.buildMediaButtonPendingIntent()并为我感兴趣的所有动作设置mSession.setMediaButtonReceiver(pendingIntent),然后在我的服务onStartCommand()中调用MediaButtonReceiver.handleIntent(mSession,intent):

I also experimented with PendingIntent, using MediaButtonReceiver.buildMediaButtonPendingIntent() and set mSession.setMediaButtonReceiver(pendingIntent) for all the actions I'm interested in, then in my service onStartCommand() I call MediaButtonReceiver.handleIntent(mSession, intent):

// still in the same service:            
mSession.setMediaButtonReceiver(
            MediaButtonReceiver.buildMediaButtonPendingIntent(
                this,
                mMediaButtonReceiverComponentName,
                ACTION_PLAY));


mSession.setMediaButtonReceiver(
            MediaButtonReceiver.buildMediaButtonPendingIntent(
                this,
                mMediaButtonReceiverComponentName,
                ACTION_PAUSE));


mSession.setMediaButtonReceiver(
            MediaButtonReceiver.buildMediaButtonPendingIntent(
                this,
                mMediaButtonReceiverComponentName,
                ACTION_PLAY_PAUSE));

并在服务onStartCommand()中:

and in the service onStartCommand():

@Override 
public int onStartCommand(Intent intent, int flags, int startId) {
    // ...
    if (intent != null) {
        MediaButtonReceiver.handleIntent(mSession, intent);
        // ...
    }
    return START_NOT_STICKY;
}

没什么,对媒体按钮按下事件完全是愚蠢的."O"或我的代码在那里有什么问题???我完全感到困惑.

Nothing, it's completely dumb to media buttons press events. What's wrong with "O" or my code there??? I'm completely baffled.

更新8/32/2017

我还创建了一个微不足道但可以正常工作的应用程序项目来演示该问题,请参阅: https://github.com/gregko/PlayerServiceSample .在Android 5.x至7.x下的耳机上按下媒体按钮时,此项目显示LogCat输出,但在Android 8"Oreo"下完全失败.

I also created a trivial but working app project that demonstrates the problem, please see: https://github.com/gregko/PlayerServiceSample. This project displays LogCat output when a media button is pressed on a headset under Android 5.x to 7.x, but fails completely under Android 8 "Oreo".

更新9/1/2017 我对此提交的Android问题跟踪器上存在一个未解决的问题,该问题已通过 https://issuetracker.google提交.com/issues/65175978 .媒体按钮仍然可以在我在Oreo上测试的几个音乐播放器应用程序中正常工作,我只是想不出它们在使它们正常工作方面有何不同...我的应用程序的上下文不是在播放音乐,而是在朗读文本.语音服务,因此Music Player示例中的许多代码都不适用.

Update 9/1/2017 There is now an open issue on Android Issue Tracker about this, which I submitted, at https://issuetracker.google.com/issues/65175978. Still the media buttons work in several music player apps I tested on Oreo, I just can't figure out what do they do differently to make them work... The context of my app is not playing music, but reading aloud text with Text to Speech service, so a lot of code from Music Player examples does not apply.

推荐答案

已解决.在" Android 8.0行为更改"上;我们在Google页面上找到以下文本:

Solved. On "Android 8.0 Behavior Changes" Google page we find this text:

在Android 8.0(API级别26)中,媒体按钮事件的处理方式不同:

In Android 8.0 (API level 26) the handling of media button events is different:

  1. UI活动中媒体按钮的处理未更改:前台活动在处理媒体按钮事件方面仍然具有优先权.
  2. 如果前台活动未处理媒体按钮事件,则系统会将事件路由到最近在本地播放音频的应用程序.确定哪个应用程序接收媒体按钮事件时,不会考虑媒体会话的活动状态,标志和播放状态.
  3. 如果已释放应用程序的媒体会话,则系统会将媒体按钮事件发送到应用程序的MediaButtonReceiver(如果有的话).
  4. 对于其他每种情况,系统都会丢弃媒体按钮事件.

要做一些琐碎的样本工作,我要做的就是用MediaPlayer播放一些声音.显然,使用Text-to-Speech API播放声音没有资格,我认为这是一个错误.

All I had to do to make my trivial sample work was to play some sound with MediaPlayer. Apparently playing sound with Text-to-Speech API does not qualify, which in my opinion is a bug.

这是我添加到普通示例中以使其工作的代码,它在Raw resources目录中播放了非常简短且无提示的WAV文件:

Here is the code I added to my trivial sample to make it work, playing a very brief and silent WAV file from Raw resources directory:

    final MediaPlayer mMediaPlayer;
    mMediaPlayer = MediaPlayer.create(this, R.raw.silent_sound);
    mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            mMediaPlayer.release();
        }
    });
    mMediaPlayer.start();

更新

通过 https://issuetracker.google.com/issues/65344811将错误报告提交给Android问题跟踪器

更新2,2017年10月10日

Google现在说,在这方面,奥利奥行为是有意设计的".并不会解决.阅读上面问题跟踪器帖子结尾附近的回复.我必须说我很失望.

Google now says that Oreo behavior in this respect is "by design" and won't fix it. Read the reply near the end of the issue tracker post above. I must say I'm disappointed.

这篇关于Android"O"(Oreo,8)和更高版本的媒体按钮问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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