android - 如何为媒体播放器制作锁屏通知

标签 android android-mediaplayer media-player android-notifications lockscreen

我正在尝试在手机中获取锁定屏幕,我能够让所有功能正常工作,例如通知和我的应用程序的其他功能,但是当我尝试显示锁定屏幕时,它对 android M 根本不起作用。

private void initMediaSession() throws RemoteException {
    if (mediaSessionManager != null) return; //mediaSessionManager exists
    ComponentName mediaButtonReceiver = new ComponentName(getApplicationContext(), MediaButtonReceiver.class);

    mediaSession = new MediaSessionCompat(getApplicationContext(), "AudioPlayer", mediaButtonReceiver, null);
    //Get MediaSessions transport controls
    transportControls = mediaSession.getController().getTransportControls();
    //set MediaSession -> ready to receive media commands
    mediaSession.setActive(true);
    //indicate that the MediaSession handles transport control commands
    // through its MediaSessionCompat.Callback.
    mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
    Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
    mediaButtonIntent.setClass(this, MediaButtonReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
    mediaSession.setMediaButtonReceiver(pendingIntent);
    //Set mediaSession's MetaData
    updateMetaData();
    // passing the data


    // Attach Callback to receive MediaSession updates
    mediaSession.setCallback(new MediaSessionCompat.Callback() {
        // Implement callbacks
        @Override
        public void onPlay() {
            super.onPlay();
            messagesent();
            a = false;
            resumeMedia();
            buildNotification(PlaybackStatus.PLAYING);
        }

        @Override
        public void onPause() {
            super.onPause();
            messagesent();
            a = true;
            pauseMedia();
            buildNotification(PlaybackStatus.PAUSED);
        }

        @Override
        public void onSkipToNext() {
            super.onSkipToNext();

            skipToNext();
            updateMetaData();
            buildNotification(PlaybackStatus.PLAYING);
        }

        @Override
        public void onSkipToPrevious() {
            super.onSkipToPrevious();

            skipToPrevious();
            updateMetaData();
            buildNotification(PlaybackStatus.PLAYING);
        }

        @Override
        public void onStop() {
            super.onStop();
            removeNotification();
            //Stop the service
            pauseMedia();
            messagesent();
            stopSelf();
        }

        @Override
        public void onSeekTo(long position) {
            super.onSeekTo(position);
        }
    });
}

private void updateMetaData() {
    //replace with medias albumArt
    // Update the current metadata
    MediaMetadataCompat.Builder metadataBuilder = new MediaMetadataCompat.Builder();

    String artist;
    if (activeAudio.getArtist() != null) {
        artist = activeAudio.getArtist();
    } else {
        artist = "unknown";
    }
    String album;
    if (activeAudio.getAlbum() != null) {
        album = activeAudio.getAlbum();
    } else {
        album = "Album";
    }
    Bitmap albumArt;
    Uri myUri = Uri.parse(activeAudio.getAlbum_art());
    try {
        InputStream image_stream = getContentResolver().openInputStream(myUri);
        Bitmap bitmap = BitmapFactory.decodeStream(image_stream);
        if (bitmap != null) {
            albumArt = bitmap;
        } else {
            albumArt = BitmapFactory.decodeResource(getResources(),
                    R.drawable.music);
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
        albumArt = BitmapFactory.decodeResource(getResources(),
                R.drawable.music);
    }
    metadataBuilder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, albumArt);
    metadataBuilder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt);

    //lock screen icon for pre lollipop
    metadataBuilder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, albumArt);
    metadataBuilder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, activeAudio.getTitle());
    metadataBuilder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, activeAudio.getAlbum());
    metadataBuilder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, album);
    metadataBuilder.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, 1);
    metadataBuilder.putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, 1);

    mediaSession.setMetadata(metadataBuilder.build());
}

private void buildNotification(PlaybackStatus playbackStatus) {

    /**
     * Notification actions -> playbackAction()
     *  0 -> Play
     *  1 -> Pause
     *  2 -> Next track
     *  3 -> Previous track
     */

    MediaControllerCompat controller = mediaSession.getController();
    MediaMetadataCompat mediaMetadata = controller.getMetadata();
    MediaDescriptionCompat description = mediaMetadata.getDescription();

    RemoteViews views = new RemoteViews(getPackageName(),
            R.layout.customnotification);


    if (playbackStatus == PlaybackStatus.PLAYING || Singleton.getInstance().getMedia() == 1) {
        views.setImageViewResource(R.id.imageButton2,
                R.drawable.ic_pause_circle_outline_white_48dp);

        messagesent();

        views.setOnClickPendingIntent(R.id.imageButton2, playbackAction(1));

    } else if (playbackStatus == PlaybackStatus.PAUSED || Singleton.getInstance().getMedia() == 2) {
        views.setImageViewResource(R.id.imageButton2,
                R.drawable.ic_play_circle_outline_white_48dp);
        messagesent();

        views.setOnClickPendingIntent(R.id.imageButton2, playbackAction(0));

    }

    views.setViewVisibility(R.id.imageView, View.VISIBLE);

    // Intent notificationIntent = new Intent(this, Main2Activity.class);

    // PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
    //         notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);


    views.setOnClickPendingIntent(R.id.imageButton3, playbackAction(3));
    views.setOnClickPendingIntent(R.id.imageButton4, playbackAction(2));

    views.setImageViewResource(R.id.imageButton3,
            R.drawable.ic_skip_previous_circle_outline_white_36dp);
    views.setImageViewResource(R.id.imageButton4,
            R.drawable.ic_skip_next_circle_outline_white_36dp);
    views.setTextViewText(R.id.textView, description.getTitle());
    views.setTextViewText(R.id.textView2, description.getSubtitle());
    views.setImageViewBitmap(R.id.imageView, description.getIconBitmap());


   NotificationCompat.Builder sta = new NotificationCompat.Builder(this);
   //  sta.setContentIntent(pendingIntent);
    sta.setContent(views);
    sta.setSmallIcon(R.drawable.ic_audiotrack_white_24dp);
    sta.setStyle(new NotificationCompat.MediaStyle().setShowActionsInCompactView(0).setMediaSession(mediaSession.getSessionToken()));


    startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, sta.build());



}


public PendingIntent playbackAction(int actionNumber) {
    Intent playbackAction = new Intent(this, MediaService.class);
    switch (actionNumber) {
        case 0:
            // Play
            playbackAction.setAction(ACTION_PLAY);
            return PendingIntent.getService(this, actionNumber, playbackAction, 0);
        case 1:
            // Pause
            playbackAction.setAction(ACTION_PAUSE);
            return PendingIntent.getService(this, actionNumber, playbackAction, 0);
        case 2:
            // Next track
            playbackAction.setAction(ACTION_NEXT);
            return PendingIntent.getService(this, actionNumber, playbackAction, 0);
        case 3:
            // Previous track
            playbackAction.setAction(ACTION_PREVIOUS);
            return PendingIntent.getService(this, actionNumber, playbackAction, 0);
        case 4:
            playbackAction.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
            return PendingIntent.getService(this, actionNumber, playbackAction, 0);
        default:
            break;
    }
    return null;
}

我试图设置通知 .setstyle 但它显示了一些错误。 我关注了 ian lake 的视频,但它仍然无法正常工作,有人可以帮助我做错什么吗

最佳答案

我遵循了以下教程并获得了输出。

private Notification createNotification() {  
if (mMetadata == null || mPlaybackState == null) {
    return null;
}

Notification.Builder notificationBuilder = new Notification.Builder(mService);
int playPauseButtonPosition = 0;

// If skip to previous action is enabled
if ((mPlaybackState.getActions() & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) {
    notificationBuilder.addAction(R.drawable.ic_prev_gray,
            mService.getString(R.string.label_previous), mPreviousIntent);

    // If there is a "skip to previous" button, the play/pause button will
    // be the second one. We need to keep track of it, because the MediaStyle notification
    // requires to specify the index of the buttons (actions) that should be visible
    // when in compact view.
    playPauseButtonPosition = 1;
}

addPlayPauseAction(notificationBuilder);

// If skip to next action is enabled
if ((mPlaybackState.getActions() & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
    notificationBuilder.addAction(R.drawable.ic_next_gray,
            mService.getString(R.string.label_next), mNextIntent);
}

MediaDescription description = mMetadata.getDescription();

String fetchArtUrl = null;
Bitmap art = null;
if (description.getIconUri() != null) {
    // This sample assumes the iconUri will be a valid URL formatted String, but
    // it can actually be any valid Android Uri formatted String.
    // async fetch the album art icon
    String artUrl = description.getIconUri().toString();
    if (art == null) {
        fetchArtUrl = artUrl;
        // use a placeholder art while the remote art is being downloaded
        art = BitmapFactory.decodeResource(mService.getResources(), R.mipmap.ic_launcher);
    }
}

notificationBuilder
        .setStyle(new Notification.MediaStyle()
            .setShowActionsInCompactView(new int[]{playPauseButtonPosition})  // show only play/pause in compact view
            .setMediaSession(mSessionToken))
        .setColor(mNotificationColor)
        .setSmallIcon(R.drawable.ic_notification)
        .setVisibility(Notification.VISIBILITY_PUBLIC)
        .setUsesChronometer(true)
        .setContentIntent(createContentIntent(description)) // Create an intent that would open the UI when user clicks the notification
        .setContentTitle(description.getTitle())
        .setContentText(description.getSubtitle())
        .setLargeIcon(art);

setNotificationPlaybackState(notificationBuilder);
if (fetchArtUrl != null) {
    fetchBitmapFromURLAsync(fetchArtUrl, notificationBuilder);
}

return notificationBuilder.build();

并尝试跟随 tutorial 因为在 android 版本中没有问题,所以它也没有在 Lollipop 中显示通知。或者您甚至可以复制以下教程 tutorial

   Notification.MediaStyle style = new Notification.MediaStyle();

Intent intent = new Intent( getApplicationContext(), MediaPlayerService.class );
intent.setAction( ACTION_STOP );
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
Notification.Builder builder = new Notification.Builder( this )
        .setSmallIcon( R.drawable.ic_launcher )
        .setContentTitle( "Media Title" )
        .setContentText( "Media Artist" )
        .setDeleteIntent( pendingIntent )
        .setStyle( style );

如果您能够获得锁定屏幕自动显示的样式,请尝试使用问题所在的通知样式。

关于android - 如何为媒体播放器制作锁屏通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45251734/

相关文章:

java - 错误 Gradle 同步失败 : For input string: "12" when apply plugin: 'com.google.gms.google-services'

java - android.content.res.Resources$NotFoundException : String resource ID #0x2 Database

java - 如何通过服务控制媒体播放器?

java - 启动/停止媒体播放器 android studio

android - 录制 + 播放问题(MediaRecorder + MediaPlayer)

android - 当服务调用 Activity 时唤醒手机并播放 MediaPlayer,Android

java - 在android中获取带有url的html

java - 如何在 Android 运行时运行 JUnit 测试?

android - ExoPlayer 下载后从缓存/离线播放文件

ios - 混合解码和硬件解码之间的区别