我正在开发Music-App,因此我的Notification使用MediaStyle,并且显示为与前台服务链接。

我的服务:

public class MusicService extends Service
        implements AudioManager.OnAudioFocusChangeListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener{

    //region Variables

    ...

    //endregion

    //region Service

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

        InitMediaPlayer();

        mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        mPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        iCurrentSongIndex = 0;
        iSeekTo = -1;

        bPlayingFromQueue = false;

        bStarted = bPreparing = bRestartAfterLoss = bControlReceiverRegistered = false;

        mPlayMode = PlayMode.PASS;

        mSongQueue = new ArrayList<>();

        nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        int iRequestResult = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);

        if (iRequestResult != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
            Toast.makeText(getApplicationContext(), "Couldn't gain the Permission to play music!", Toast.LENGTH_LONG).show();

            stopForeground(true);
            stopSelf();

            return;
        }

        mControlReceiver = new MediaControlReceiver();

        IntentFilter infNotification = new IntentFilter();
        infNotification.addAction(MediaControlReceiver.NOTIFY_PLAYPAUSE);
        infNotification.addAction(MediaControlReceiver.NOTIFY_PREVIOUS);
        infNotification.addAction(MediaControlReceiver.NOTIFY_NEXT);
        infNotification.addAction(MediaControlReceiver.NOTIFY_CANCEL);
        infNotification.addAction(Intent.ACTION_HEADSET_PLUG);

        if (!bControlReceiverRegistered) {
            registerReceiver(mControlReceiver, infNotification);

            bControlReceiverRegistered = true;
        }

        mRemoteControlComponent = new ComponentName(this, RemoteControlReceiver.class);

        mAudioManager.registerMediaButtonEventReceiver(mRemoteControlComponent);

        getTheme().applyStyle(RuntimeInfo.getThemeID(), true);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_NOT_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new MusicBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

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

        if (mMediaPlayer != null) {
            if (mMediaPlayer.isPlaying()) {
                mMediaPlayer.stop();
            }

            mMediaPlayer.reset();
            mMediaPlayer.release();

            mMediaPlayer = null;
        }

        if (bControlReceiverRegistered) {
            unregisterReceiver(mControlReceiver);

            mControlReceiver = null;
        }

        mAudioManager.unregisterMediaButtonEventReceiver(mRemoteControlComponent);

        mAudioManager = null;

        SharedPreferences.Editor mEditor = mPreferences.edit();

        mEditor.putString(Constants.Preferences.PLAYMODE, mPlayMode.toString());

        mEditor.apply();

        if (SleepTimer.isTimerRunning()) {
            SleepTimer.cancelTimer();
        }
    }

    @Override
    public void onAudioFocusChange(int focusChange) {
        if (isActive()) {
            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_GAIN:
                    if (bRestartAfterLoss) {
                        mMediaPlayer.setVolume(1.0f, 1.0f);

                        if (!isPlaying() && !isPreparing()) {
                            play();
                        }
                    }
                    break;
                case AudioManager.AUDIOFOCUS_LOSS:
                    bRestartAfterLoss = false;

                    if (isPlaying()) {
                        pause();
                    }
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    bRestartAfterLoss = true;

                    if (isPlaying()) {
                        pause();
                    }
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                    bRestartAfterLoss = true;

                    int duckFactor = mPreferences.getInt(getResources().getString(R.string.keyDuckVolume), 10);

                    float percent = (float) duckFactor / 100f;

                    mMediaPlayer.setVolume(percent, percent);
                    break;
            }
        }
    }

    //endregion

    //region Control-Methods

    public void play() {
        if (!bStarted) {
            playSong(iCurrentSongIndex);
        }
        else {
            mMediaPlayer.start();

            startForeground(NOTIFICATION_ID, Build_Notification());

            if (mCallback != null) {
                mCallback.onPlayPause(true);
            }
        }
    }

    public void pause() {
        mMediaPlayer.pause();

        nManager.notify(NOTIFICATION_ID, Build_Notification());

        if (mCallback != null) {
            mCallback.onPlayPause(false);
        }
    }

    //endregion

    //region MediaPlayer

    @Override
    public void onCompletion(MediaPlayer mp) {
        if (mSongQueue.size() > 0) {
            playSong(PLAY_QUEUE);
        }
        else {
            switch (mPlayMode) {
                default:
                case PASS:
                    if (iCurrentSongIndex++ < sSongs.length) {
                        playSong(iCurrentSongIndex);
                    }
                    else {
                        mNotification = null;

                        if (mCallback != null) {
                            mCallback.onCompleted(getCurrentSong());
                        }
                    }
                    break;
                case REPEAT_SINGLE:
                    playSong(iCurrentSongIndex);
                    break;
                case REPEAT_ALL:
                    next();
                    break;
                case SHUFFLE:
                    iCurrentSongIndex = new Random().nextInt(sSongs.length);

                    playSong(iCurrentSongIndex);
                    break;
            }
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        mp.reset();

        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        if (iSeekTo != -1) {
            mp.seekTo(iSeekTo);

            iSeekTo = -1;
        }

        mp.start();

        SharedPreferences.Editor editor = mPreferences.edit();
        editor.putLong(Constants.Preferences.LAST_SONG, getCurrentSong().getID());
        editor.apply();

        startForeground(NOTIFICATION_ID, Build_Notification());

        bPreparing = false;

        if (!bStarted) {
            bStarted = true;
        }
    }

    //endregion

    //region Methods

    private void InitMediaPlayer() {
        mMediaPlayer = new MediaPlayer();

        mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.setOnErrorListener(this);
    }

    private Notification Build_Notification() {
        NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(this);
        nBuilder.setShowWhen(false);

        TypedValue typedValue = new TypedValue();

        getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);

        int iPrimaryColor = typedValue.data;

        nBuilder.setColor(iPrimaryColor);

        Intent notIntent = new Intent(getApplicationContext(), MainActivity.class);

        PendingIntent notOpenOnClick = PendingIntent.getActivity(getApplicationContext(), 0, notIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        MediaSessionCompat mMediaSession = new MediaSessionCompat(getApplicationContext(), getPackageName());

        MediaMetadataCompat.Builder mMetaDataBuilder = new MediaMetadataCompat.Builder();

        mMetaDataBuilder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, getCurrentSong().getTitle())
                .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, getCurrentSong().getAlbum())
                .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, getCurrentSong().getArtist());

        if (isPreparing() || isPlaying()) {
            mMediaSession.setActive(true);
        }
        else {
            mMediaSession.setActive(false);
        }

        mMediaSession.setMetadata(mMetaDataBuilder.build());

        mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);

        nBuilder.setSmallIcon(R.drawable.not_icon)
                .setContentTitle(getCurrentSong().getTitle())
                .setContentText(getCurrentSong().getAlbum() + " - " + getCurrentSong().getArtist())
                .setLargeIcon(new ArtworkProvider(this).getAlbumArtwork(getCurrentSong().getAlbumID(), 100, 100))
                .setContentIntent(notOpenOnClick);

        Intent previous = new Intent(MediaControlReceiver.NOTIFY_PREVIOUS);
        Intent next = new Intent(MediaControlReceiver.NOTIFY_NEXT);
        Intent playpause = new Intent(MediaControlReceiver.NOTIFY_PLAYPAUSE);
        Intent cancel = new Intent(MediaControlReceiver.NOTIFY_CANCEL);

        PendingIntent pPrevious = PendingIntent.getBroadcast(getApplicationContext(), 0, previous, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent pPlayPause = PendingIntent.getBroadcast(getApplicationContext(), 0, playpause, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent pNext = PendingIntent.getBroadcast(getApplicationContext(), 0, next, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent pCancel = PendingIntent.getBroadcast(getApplicationContext(), 0, cancel, PendingIntent.FLAG_UPDATE_CURRENT);

        nBuilder.addAction(R.drawable.ic_previous_48dp, MediaControlReceiver.NOTIFY_PREVIOUS, pPrevious);

        if (isPreparing() || isPlaying()) {
            nBuilder.addAction(R.drawable.ic_pause_48dp, MediaControlReceiver.NOTIFY_PLAYPAUSE, pPlayPause);
        }
        else {
            nBuilder.addAction(R.drawable.ic_play_48dp, MediaControlReceiver.NOTIFY_PLAYPAUSE, pPlayPause);
        }

        nBuilder.addAction(R.drawable.ic_next_48dp, MediaControlReceiver.NOTIFY_NEXT, pNext);

        nBuilder.setStyle(new NotificationCompat.MediaStyle()
                .setMediaSession(mMediaSession.getSessionToken())
                .setShowActionsInCompactView(0, 1, 2)
                .setShowCancelButton(true)
                .setCancelButtonIntent(pCancel));

        mNotification = nBuilder.build();

        return mNotification;
    }

    //endregion

    public enum PlayMode {
        PASS, REPEAT_SINGLE, REPEAT_ALL, SHUFFLE
    }

    public class MusicBinder extends Binder {
        public MusicService getService() {
            return MusicService.this;
        }
    }
}


我没有将Notification属性“ OnGoing”设置为true,我已经尝试将其设置为false,但这并没有任何改变!

最佳答案

我犯了一个愚蠢的错误:

我忘了在pause()中调用stopForeground(false)。

这是我的工作代码:

public void pause() {
    mMediaPlayer.pause();

    stopForeground(false);

    nManager.notify(NOTIFICATION_ID, Build_Notification());

    if (mCallback != null) {
        mCallback.onPlayPause(false);
    }
}

关于java - 通知不可取消,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38032893/

10-10 13:51