5

アプリのロック画面プレーヤー コントロールとメタ データを追加するために、MediaSessionCompat を使用しようとしています。私が試したことはすべてうまくいきません。プレイ中は、ロック画面にコントロールやメタデータは表示されません。以下の私の現在のコードをご覧ください。

StreamService.java:

public class StreamService extends Service implements MediaPlayer.OnCuePointReceivedListener, MediaPlayer.OnStateChangedListener,
        MediaPlayer.OnInfoListener, AudioManager.OnAudioFocusChangeListener {

    private WifiManager.WifiLock wifiLock;
    private static String LOG_TAG = "StreamService";
    public static final String BROADCAST_PLAYER_STATE = "com.test.BROADCAST_PLAYER_STATE";
    public static final String BROADCAST_PLAYER_META = "com.test.BROADCAST_PLAYER_META";
    public static final String BROADCAST_PLAYER_ALBUM = "com.test.BROADCAST_PLAYER_ALBUM";
    public static final int NOTIFICATION_ID = 999999;
    private MediaSessionCompat mediaSession;
    private boolean audioInterrupted = false;

    public StreamService() {
    }

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

        setupMediaPlayer();

        setupMediaSession();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public boolean onUnbind(Intent intent){
        releasePlayer();
        return false;
    }

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

    private void setupMediaPlayer() {
        // Recreate player
        Bundle playerSettings = (BrandedApplication.getContext().getmTritonPlayer() == null) ? null : BrandedApplication.getContext().getmTritonPlayer().getSettings();
        Bundle inputSettings = createPlayerSettings();

        if (!Utility.bundleEquals(inputSettings, playerSettings)) {
            releasePlayer();
            createPlayer(inputSettings);
        }

        // Start the playback
        play();
    }

    private void setupMediaSession() {
        ComponentName receiver = new ComponentName(getPackageName(), RemoteReceiver.class.getName());
        mediaSession = new MediaSessionCompat(this, "StreamService", receiver, null);
        mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
                MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
        mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
                .setState(PlaybackStateCompat.STATE_PAUSED, 0, 0)
                .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE)
                .build());
        mediaSession.setMetadata(new MediaMetadataCompat.Builder()
                .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "Test Artist")
                .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, "Test Album")
                .putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Test Track Name")
                .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 10000)
                .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART,
                        BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                //.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Test Artist")
                .build());

        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        audioManager.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener() {
            @Override
            public void onAudioFocusChange(int focusChange) {
                // Ignore
            }
        }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);

        mediaSession.setActive(true);
    }

    synchronized private void play() {
        audioInterrupted = false;
        BrandedApplication.getContext().getmTritonPlayer().play();
        if(wifiLock != null) {
            wifiLock.acquire();
        }

        if(mediaSession != null) {
            mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
                    .setState(PlaybackStateCompat.STATE_PLAYING, 0, 1.0f)
                    .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE).build());
        }
    }

    synchronized private void stop() {
        BrandedApplication.getContext().getmTritonPlayer().stop();
        if(wifiLock != null) {
            wifiLock.release();
        }

        if(mediaSession != null) {
            mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
                    .setState(PlaybackStateCompat.STATE_PAUSED, 0, 0.0f)
                    .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE).build());
        }
    }

    private void createPlayer(Bundle settings)
    {
        BrandedApplication.getContext().setmTritonPlayer(new TritonPlayer(this, settings));
        wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
                .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN);
        BrandedApplication.getContext().getmTritonPlayer().setOnCuePointReceivedListener(this);
        BrandedApplication.getContext().getmTritonPlayer().setOnInfoListener(this);
        BrandedApplication.getContext().getmTritonPlayer().setOnStateChangedListener(this);
    }


    protected void releasePlayer() {
        if (BrandedApplication.getContext().getmTritonPlayer() != null) {
            if(BrandedApplication.getContext().isPlaying()) {
                stop();
            }
            BrandedApplication.getContext().getmTritonPlayer().release();
            BrandedApplication.getContext().setmTritonPlayer(null);
        }
        stopForeground(true);
    }

    protected Bundle createPlayerSettings() {
        // Player Settings
        Bundle settings = new Bundle();
        // AAC
        settings.putString(TritonPlayer.SETTINGS_STATION_MOUNT, getResources().getString(R.string.station_stream_mount) + "AAC");
        // MP3
        //settings.putString(TritonPlayer.SETTINGS_STATION_MOUNT, mountID);
        settings.putString(TritonPlayer.SETTINGS_STATION_BROADCASTER, getResources().getString(R.string.app_name));
        settings.putString(TritonPlayer.SETTINGS_STATION_NAME, getResources().getString(R.string.app_name));
        return settings;
    }

    @Override
    public void onCuePointReceived(MediaPlayer mediaPlayer, Bundle bundle) {
        //System.out.println("TRITON PLAYER BUNDLE " + bundle);
        String trackName = "";
        String artistName = "";
        if(bundle != null) {
            if(bundle.containsKey("cue_title") && bundle.containsKey("track_artist_name")) {
                if (!bundle.getString("cue_title").isEmpty()) {
                    trackName = bundle.getString("cue_title");
                }
                if (!bundle.getString("track_artist_name").isEmpty()) {
                    artistName = bundle.getString("track_artist_name");
                }
            }
        }
        // broadcast out the meta data
        Intent i = new Intent(BROADCAST_PLAYER_META);
        i.putExtra("trackName", trackName);
        i.putExtra("artistName", artistName);
        sendBroadcast(i);

        // send notification and start as foreground service
        PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
        Bitmap icon = BitmapFactory.decodeResource(getResources(),
                R.drawable.logo);
        String tickerString = "";
        String contentString = "Playing";
        if(!artistName.isEmpty() && !trackName.isEmpty()) {
            tickerString = artistName + " - " + trackName;
            contentString += ": " + artistName + " - " + trackName;
        }

        Intent pauseIntent = new Intent(BROADCAST_PLAYER_PAUSE);
    PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 0, pauseIntent, 0);

    NotificationCompat.Builder notification = new NotificationCompat.Builder(this)
            .setContentTitle(getResources().getString(R.string.app_name))
            .setTicker(tickerString)
            .setContentText(contentString)
            .setSmallIcon(R.drawable.ic_launcher)
            //.setAutoCancel(true)
            //.setLargeIcon(
            //        Bitmap.createScaledBitmap(icon, 128, 128, false))
            .addAction(R.drawable.ic_media_pause, "Pause", pausePendingIntent)
            .setContentIntent(pi)
            .setStyle(new android.support.v7.app.NotificationCompat.MediaStyle()
                    //.setShowActionsInCompactView(0)
                    .setMediaSession(mediaSession.getSessionToken()))
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .setOngoing(true);
    //notification.setPriority(Notification.PRIORITY_MIN);
    notification.setPriority(Notification.PRIORITY_DEFAULT);
    startForeground(NOTIFICATION_ID, notification.build());
    }

    @Override
    public void onInfo(MediaPlayer mediaPlayer, int i, int i1) {

    }

    @Override
    public void onStateChanged(MediaPlayer mediaPlayer, int state) {
        Log.i(LOG_TAG, "onStateChanged: " + TritonPlayer.debugStateToStr(state));
        // broadcast out the player state
        Intent i = new Intent(BROADCAST_PLAYER_STATE);
        i.putExtra("state", state);
        sendBroadcast(i);
    }

    @Override
    public void onAudioFocusChange(int focusChange) {
        switch (focusChange) {
            case AudioManager.AUDIOFOCUS_GAIN:
                // resume playback
                System.out.println("AUDIO FOCUS GAIN");
                if(audioInterrupted) {
                    audioInterrupted = false;
                    if (BrandedApplication.getContext().getmTritonPlayer() == null) {
                        setupMediaPlayer();
                    } else if (!BrandedApplication.getContext().isPlaying()) {
                        setupMediaPlayer();
                    }
                }
                break;

            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
            case AudioManager.AUDIOFOCUS_LOSS:
                System.out.println("AUDIO FOCUS LOSS");
                // Lost focus for an unbounded amount of time: stop playback and release media player
                if (BrandedApplication.getContext().isPlaying()) {
                    audioInterrupted = true;
                    releasePlayer();
                }
                break;
        }
    }

    @Override
    public void onDestroy() {
        System.out.println("SERVICE STOPPED");
        releasePlayer();
        mediaSession.release();
    }
}

RemoteReceiver.java は次のとおりです。

public class RemoteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
            final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);

            if (event != null && event.getAction() == KeyEvent.ACTION_DOWN) {
                switch (event.getKeyCode()) {
                    case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                        context.startService(new Intent(context, StreamService.class));
                        break;
                }
            }
        }
    }
}
4

2 に答える 2