在Android中设置锁屏背景(如Spotify do)

在Android中设置锁屏背景(如Spotify do),android,Android,我知道这个话题已经讨论过了,答案似乎是不可能的 但我最近在Nexus4(4.4.2)中安装了Spotify,这似乎是可能的。当我在Spotify中听一首歌时,锁屏背景会随着我正在听的专辑封面发生变化(参见截图) 我的理论是: 当手机锁定时,他们会使用相册封面同时更改锁定屏幕背景,然后在手机解锁时将前一个背景设置回原位。但他们不是这样做的,因为在Spotify的权限列表中没有“android.permission.SET_WALLPAPER”…:( 他们是怎么做到的?一些理论 编辑: 下面的解决

我知道这个话题已经讨论过了,答案似乎是不可能的

但我最近在Nexus4(4.4.2)中安装了Spotify,这似乎是可能的。当我在Spotify中听一首歌时,锁屏背景会随着我正在听的专辑封面发生变化(参见截图)

我的理论是: 当手机锁定时,他们会使用相册封面同时更改锁定屏幕背景,然后在手机解锁时将前一个背景设置回原位。但他们不是这样做的,因为在Spotify的权限列表中没有“android.permission.SET_WALLPAPER”…:(

他们是怎么做到的?一些理论

编辑: 下面的解决方案仅适用于已注册为媒体控制器的应用程序,因此不播放音频的应用程序不能/不应该使用此机制更改锁屏墙纸


它可以使用,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,它提供了兼容性逻辑,使其能够在Android 4.0设备上启用远程控制客户端,同时继续支持设备返回到Android 2.1。”

此外,我希望将文本作为相册艺术。

因此,这里是新的“官方文档”

底部描述了锁屏的详细信息

另外,一旦我理解了所有术语和行话,本教程帮助我概述了MediaSessionCompat服务的一般结构

最后,有一个API的锁屏壁纸在牛轧糖和更大。 我现在无法理解为什么不支持lib。

正如我所解释的,关键是要将MediaMetadata对象传递给MediaSession。如果这些术语对您来说不熟悉,最好从顶部开始链接教程


我发现
.putbimat(MediaMetadata.METADATA\u KEY\u ART,bitmap)
行是将图像加载到锁屏背景的行。但请确保填充
.putbimat(mediametada.METADATA\u KEY\u ALBUM\u ART,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();
要工作,您必须在应用程序
build.gradle

砰!你可以走了。

我知道现在已经晚了,但仍然需要完美的答案。因此,要在Android中设置锁屏背景(如Spotify),我们必须执行以下步骤

1.将媒体会话设置为活动状态
mSession.setActive(true)
。如果会话未激活,则不会显示

2.设置播放状态

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());
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());
注意:当第一次播放状态设置为播放时,会显示锁屏图像,然后可以切换到其他状态

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设备上,但不显示在像素设备上,所以接下来是最后一点。

4.以媒体样式显示通知

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

有没有办法更新图像的大小,使其不是全屏的?@canistr我不能百分之百肯定地说,但由于应用程序只提供位图,没有提供相关参数的能力,我会说答案是否定的。有没有办法在歌曲没有封面时清除封面图像并设置手机默认锁屏?我的问题是旧的c从previos song开始显示/@AndrewS当当前歌曲没有封面时,您可以提供默认位图,这基本上就是Google Music正在做的事情util类在哪里?这应该是新的公认答案,因为远程控制客户端现在贬值了。mediasession.getSessionToken实际上我不知道如何设置这种类型通知请检查链接@VipulChauhan,我将我的项目迁移到Kotlin,但我已重新创建了一个代码,涵盖了您在其他测验中提出的问题。请在此处检查此代码:。您的代码对于新开发人员来说太难理解。请您为代码提供适当的解释,如…在哪里使用方法?如何使用w和处理行动?谢谢advance@VipulChauhan自从我将我的初始项目迁移到Kotlin之后,我用Java编写了另一个项目,并将整个源代码上传到了这里:同时,我正在发布一个详细的教程。我希望这会对你有很大帮助。干杯!!好的,非常感谢@Carlos Anyona,这肯定会对我有帮助