Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing lock screen background programmatically [duplicate]

Tags:

android

I know that this topic has been already discussed here, here and here, and the answer seems to be that it is not possible.

But I recently installed Spotify in my Nexus 4 (4.4.2), and it seems to be possible. When I listen a song in Spotify the lock screen background change with the cover of the album that I'm listening (see screenshots).

My theory was: when the phone is locked they change the phone wallpaper with the album cover in order to change also the lock screen background, then they set back the previous one when the phone is unlocked. But this is not how they do it, because in the permissions list of Spotify there is no "android.permission.SET_WALLPAPER"... :(

How do they do it? Some theory?

Screenshot lock screenScreenshot lock screen

like image 824
Nifhel Avatar asked Mar 09 '14 11:03

Nifhel


People also ask

Can you change lock screen with wallpaper engine?

The Windows lock screen is a protected area of Windows which does not allow for live and dynamic wallpapers. Microsoft has purposefully built it this way as a security measure. However, you can still configure Wallpaper Engine to override the static lock screen image with a snapshot of your current live wallpaper.

How do you make your lock screen wallpaper change automatically Windows 10?

Select Start > Settings . Select Personalization > Lock screen. Select the list for Personalize your lock screen, then do one of the following: Select Windows spotlight for beautiful photography that displays automatically.


3 Answers

Edit: The solution below only works for applications that have registered itself as a media controller, so apps that don't play audio can't/shouldn't use this mechanism to change the lockscreen wallpaper.


It can be done using RemoteControlClient, part of Android since ICS. If you want a working example, download VLC for Android and check out org.videolan.vlc.AudioService:

This part of the code is to intercept media controls.

/**
 * 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);
    }
}

This part is to update artwork, among other info:

@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();
    }
}
like image 104
Kai Avatar answered Oct 07 '22 23:10

Kai


For me, the most instructive example was Random Music Player, mentioned in documentation about Android 4.0 APIs:

"For a sample implementation, see the Random Music Player, which provides compatibility logic such that it enables the remote control client on Android 4.0 devices while continuing to support devices back to Android 2.1."

In addition, I converted text to bitmap to have text as album art.

like image 34
Juuso Ohtonen Avatar answered Oct 08 '22 00:10

Juuso Ohtonen


Well, after trying some ways, I have a simple code here; Try using this method;

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

then in your notification you need to set style to android.support.v4.media.app.NotificationCompat.MediaStyle() and set the media session token to use the current metadata. Check this snippet below;

builder.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
            .setShowActionsInCompactView(0, 1, 2)
    .setMediaSession(mediaSession.getSessionToken()));
    return builder.build();

To work, you must include implementation "com.android.support:support-v4:$latest_version" in your app build.gradle And boom! you are good to go.

like image 39
Carlos Anyona Avatar answered Oct 07 '22 23:10

Carlos Anyona