我知道这个话题已经讨论过here,here和here,答案似乎是不可能的。
但我最近在我的Nexus 4(4.4.2)中安装了Spotify,似乎有可能。当我在Spotify中听一首歌时,锁屏背景会改变我正在收听的专辑的封面(见截图)。
我的理论是:当手机被锁定时,他们将change the phone wallpaper与专辑封面一起改变锁定屏幕背景,然后他们在手机解锁时退回前一个。但这不是他们如何做到的,因为在Spotify的权限列表中没有“android.permission.SET_WALLPAPER”...... :(
他们是如何做到的呢?一些理论?
编辑:下面的解决方案仅适用于已注册为媒体控制器的应用程序,因此不播放音频的应用程序不能/不应使用此机制来更改锁屏壁纸。
它可以使用RemoteControlClient完成,这是Android自ICS以来的一部分。如果你想要一个有效的例子,请下载适用于Android的VLC并查看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();
}
}
对我来说,最有启发性的例子是在Random Music Player中提到的documentation about Android 4.0 APIs:
“有关示例实现,请参阅随机音乐播放器,它提供兼容性逻辑,以便在Android 4.0设备上启用远程控制客户端,同时继续支持设备返回到Android 2.1。”
另外,我converted text to bitmap有文字作为专辑艺术。
好吧,经过尝试,我在这里有一个简单的代码;尝试使用这种方法;
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();
要工作,你必须在你的应用程序implementation "com.android.support:support-v4:$latest_version"
和繁荣中包括build.gradle
!你已准备好出发。
所以这是新的“官方文档”
在底部,它描述了锁屏详细信息
作为替代方案,一旦我理解了所有术语和术语,本教程帮助我概述了MediaSessionCompat服务的一般结构。
https://code.tutsplus.com/tutorials/background-audio-in-android-with-mediasessioncompat--cms-27030
最后,还有一个用于Nougat和更大的锁屏壁纸的API。为什么这不支持lib在这个时候超出了我的范围。
正如here所解释的那样,关键是将MediaMetadata对象传递给MediaSession。如果这些术语对您来说陌生,最好从顶部开始链接教程。
我发现.putBitmap(MediaMetadata.METADATA_KEY_ART, bitmap)
线是用于将图像加载到锁屏背景的线。但一定要很好地填充.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bitmap)
as。