编辑: 下面的解决方案仅适用于已将自身注册为媒体控制器的应用程序,因此不播放音频的应用程序不能/不应使用此机制更改锁屏壁纸。
可以使用 Android 自 ICS 以来的 RemoteControlClient 完成此操作。如果您想要一个可用的示例,请下载 VLC for Android 并查看 org.videolan.vlc.AudioService
:
这部分代码是拦截媒体控件。
/**
* Set up the remote control and tell the system we want to be the default receiver for the MEDIA buttons
* @see http://android-developers.blogspot.fr/2010/06/allowing-applications-to-play-nicer.html
*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public void setUpRemoteControlClient() {
Context context = VLCApplication.getAppContext();
AudioManager audioManager = (AudioManager)context.getSystemService(AUDIO_SERVICE);
if(Util.isICSOrLater()) {
audioManager.registerMediaButtonEventReceiver(mRemoteControlClientReceiverComponent);
if (mRemoteControlClient == null) {
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setComponent(mRemoteControlClientReceiverComponent);
PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(context, 0, mediaButtonIntent, 0);
// create and register the remote control client
mRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
audioManager.registerRemoteControlClient(mRemoteControlClient);
}
mRemoteControlClient.setTransportControlFlags(
RemoteControlClient.FLAG_KEY_MEDIA_PLAY |
RemoteControlClient.FLAG_KEY_MEDIA_PAUSE |
RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS |
RemoteControlClient.FLAG_KEY_MEDIA_NEXT |
RemoteControlClient.FLAG_KEY_MEDIA_STOP);
} else if (Util.isFroyoOrLater()) {
audioManager.registerMediaButtonEventReceiver(mRemoteControlClientReceiverComponent);
}
}
此部分用于更新艺术品等信息:
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void updateRemoteControlClientMetadata() {
if(!Util.isICSOrLater()) // NOP check
return;
if (mRemoteControlClient != null) {
MetadataEditor editor = mRemoteControlClient.editMetadata(true);
editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, getCurrentMedia().getAlbum());
editor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, getCurrentMedia().getArtist());
editor.putString(MediaMetadataRetriever.METADATA_KEY_GENRE, getCurrentMedia().getGenre());
editor.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, getCurrentMedia().getTitle());
editor.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, getCurrentMedia().getLength());
editor.putBitmap(MetadataEditor.BITMAP_KEY_ARTWORK, getCover());
editor.apply();
}
}
好的,经过尝试,我有一个简单的代码在这里; 尝试使用这种方法;
private void updateMetaData() {
mediaSession =new MediaSessionCompat(context,"BXPlayer");
Bitmap cover = BitmapFactory.decodeResource(context.getResources(),
R.drawable.cover2);
mediaSession.setMetadata(new MediaMetadataCompat.Builder()
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, cover)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mSelectedSong.getArtist())
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, mSelectedSong.getAlbum())
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mSelectedSong.getTitle())
.build());
}
然后在您的通知中,您需要将样式设置为android.support.v4.media.app.NotificationCompat.MediaStyle()
并将媒体会话令牌设置为使用当前元数据。
请检查下面的代码片段;
builder.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0, 1, 2)
.setMediaSession(mediaSession.getSessionToken()));
return builder.build();
对我来说,最有启示性的例子是随机音乐播放器,它被提及在Android 4.0 API文档中:
"要查看示例实现,请参见随机音乐播放器,它提供了兼容逻辑,使其在Android 4.0设备上启用远程控制客户端的同时,继续支持从Android 2.1开始的设备。"
此外,我将文本转换为位图以将文本作为专辑艺术品。
如此处所解释的那样,关键是将MediaMetadata对象传递给您的MediaSession。如果这些术语对您来说很陌生,最好从链接的教程顶部开始。
我发现.putBitmap(MediaMetadata.METADATA_KEY_ART, bitmap)
行是用于加载图像到锁屏背景的代码行。但一定要填充.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bitmap)
。
这里是新的“官方文档”
底部描述了锁屏细节
作为一种替代方案,一旦我理解了所有术语和行话,这个教程帮助我概述了MediaSessionCompat服务的一般结构。https://code.tutsplus.com/tutorials/background-audio-in-android-with-mediasessioncompat--cms-27030
最终,在Nougat及更高版本中,有一个锁屏壁纸的API。为什么这不支持库,目前我还不清楚。
mSession.setActive(true)
。如果会话未处于活动状态,则不会显示。playBackStateBuilder = new PlaybackStateCompat.Builder()
.setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_SKIP_TO_NEXT
| PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
| PlaybackStateCompat.ACTION_STOP | PlaybackStateCompat.ACTION_PLAY_PAUSE);`
`mSession.setPlaybackState(playBackStateBuilder.setState(PlaybakStateCompate.STATE_PLAYING, 0, 0).build());
注意:当第一次播放状态设置为播放时,锁屏图像会显示,然后可以切换到其他状态。
3. 设置元数据
mSession.setMetadata(new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap)
.build());
在编程中,KEY_ALBUM_ART是必需的,因为它是在锁屏界面上显示的图片。
通过设置以上三个内容,它已经在我的Galaxy设备上显示了,但在Pixel设备上没有显示,因此需要遵循最后一个步骤。
4. 使用媒体样式显示通知
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID);
builder.setStyle(
new androidx.media.app.NotificationCompat.MediaStyle()
);
mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(121, builder.build());