首页 文章

Android Notification.MediaStyle没有响应MediaSession更新

提问于
浏览
0

根据 Notification.MediaStyle doc,将 MediaSession.Token 附加到给定的MediaStyle应该将其挂钩到关联的 MediaSession 对象 .

引用如下:

最后,如果使用setMediaSession(MediaSession.Token)附加MediaSession.Token,系统UI可以将其识别为表示活动媒体会话的通知并相应地做出响应(例如,通过在锁屏中显示专辑图片) .

然后,doc会在通知中提供使用MediaStyle的代码片段,如下所示:

Notification noti = new Notification.Builder()
    .setSmallIcon(R.drawable.ic_stat_player)
    .setContentTitle("Track title")     // these three lines are optional
    .setContentText("Artist - Album")   // if you use
    .setLargeIcon(albumArtBitmap))      // setMediaSession(token)
    .setStyle(new Notification.MediaStyle()
        .setMediaSession(mySession))
    .build();

清楚地说明(从单词 optional ),当与令牌对象一起使用时,ContentTitle / ContentText参数是不必要的(可能由MediaStyle实例自动填充) .

在尝试将此MediaStyle实现到我正在构建的音乐播放器时,我注意到尽管音乐播放器在整个过程中反复更新元数据和播放状态,但使用MediaStyle设置的通知根本没有更新 . 唯一存在的是一个空白通知,其中包含通知的“小图标”,当视图扩展时,它会超出与大图标的比例 .

为了说明这个问题,我在下面创建了一个小测试应用程序,其中包含两个按钮一个按钮更新通知(使用MediaStyle创建一个新通知并发送到通知管理器) . 另一个按钮生成元数据和假播放状态以模拟播放 . 我注意到无论按什么顺序按下什么按钮组合,通知都不会更新我希望它更新的样式 .

以下表示代表我的测试用例的活动类 . 大多数是样板活动代码,最后两个方法 updateNotification()updateState() 链接到两个按钮的onClick属性,并作为OnClickListeners .

public class MediaStyleTestActivity extends Activity {

    private MediaSession mSession;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media_style_test);

        mSession = new MediaSession(this, "TestSession");
        mSession.setActive(true);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        mSession.release();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_media_style_test, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void updateState(View v){
        MediaMetadata.Builder mMetaBuilder = new MediaMetadata.Builder();

        mMetaBuilder.putText(MediaMetadata.METADATA_KEY_TITLE, "Blue Jeans");
        mMetaBuilder.putText(MediaMetadata.METADATA_KEY_ALBUM, "Born to Die");
        mMetaBuilder.putText(MediaMetadata.METADATA_KEY_ARTIST, "Lana Del Rey");
        mMetaBuilder.putText(MediaMetadata.METADATA_KEY_ALBUM_ARTIST, "Lana Del Rey");
        mMetaBuilder.putLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER, 3);
        mMetaBuilder.putLong(MediaMetadata.METADATA_KEY_NUM_TRACKS, 15);
        mMetaBuilder.putLong(MediaMetadata.METADATA_KEY_DISC_NUMBER, 1);

        Bitmap albumArt = BitmapFactory.decodeResource(getResources(), R.drawable.album_art);

        mMetaBuilder.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, albumArt);

        PlaybackState.Builder stateBuilder = new PlaybackState.Builder();

        stateBuilder.setActiveQueueItemId(MediaSession.QueueItem.UNKNOWN_ID);

        long actions = PlaybackState.ACTION_PLAY_PAUSE | PlaybackState.ACTION_STOP | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS;

        stateBuilder.setActions(actions);
        stateBuilder.setState(PlaybackState.STATE_PLAYING, 0, 1.0f);

        mSession.setMetadata(mMetaBuilder.build());
        mSession.setPlaybackState(stateBuilder.build());
    }

    public void updateNotification(View v){
        Notification.Builder nBuilder = new Notification.Builder(this);

        nBuilder.setOngoing(true);
        nBuilder.setShowWhen(false);
        nBuilder.setVisibility(Notification.VISIBILITY_PUBLIC);

        nBuilder.setSmallIcon(android.R.drawable.ic_media_play);
        nBuilder.setStyle(new Notification.MediaStyle().setMediaSession(mSession.getSessionToken()));

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(100, nBuilder.build());
    }
}

请忽略MediaSession在此处的不当使用,这仅用于演示目的 .

我的设备上显示的应用:

Screenshot of demonstration app

我注意到锁屏正在使用专辑封面进行更新,但不再是:

Lockscreen containing album art as background

如上所述,无论我尝试使用MediaSession / MediaStyle / Notification更新的哪种组合,似乎都没有导致通知的内容视图填充所提供的元数据(包括设置示例中未显示的有效 MediaSession.QueueItem ) . 即使在详细信息下,Logcat也没有显示任何内容,因为通知不顺利或失败 .

除非我在这里遗漏了一些非常明显的东西,否则我做错了什么?


就像附加信息一样,我使用任何兼容性库来进行通知和MediaSession . 我的应用程序的这个组件仅适用于API 21,因此不需要向后兼容性支持 .

在我的 生产环境 代码中,实际的MediaSession保存在前台服务中,我尝试从各种线程(UI /任何媒体线程android使用/我自己的自定义线程)进行更新无济于事 .

1 回答

  • 0

    你是对的 . 截至今天, setContentTitlesetContextText 以及 setLargeIcon 需要显示通知 Headers ,文字和图像 . (正在处理的doc问题)

    旁白:还要注意你应该拨打 mediaSession.setActive(true)

相关问题