/**
   * Build a new notification. To update the progress on the notification, use {@link
   * #updateProgress(int, int)} instead.
   *
   * @param episode The episode playing.
   * @param paused Playback state, <code>true</code> for paused.
   * @param canSeek If the currently played media is seekable.
   * @param position The current playback progress.
   * @param duration The length of the current episode.
   * @param session The media session representing current playback.
   * @return The notification to display.
   */
  @NonNull
  public Notification build(
      Episode episode,
      boolean paused,
      boolean canSeek,
      int position,
      int duration,
      MediaSessionCompat session) {
    // 0. Prepare the main intent (leading back to the app)
    appIntent.putExtra(PODCAST_URL_KEY, episode.getPodcast().getUrl());
    appIntent.putExtra(EPISODE_URL_KEY, episode.getMediaUrl());
    final PendingIntent backToAppIntent =
        PendingIntent.getActivity(context, 0, appIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    // 1. Create the notification builder and set values
    notificationBuilder = new NotificationCompat.Builder(context);
    notificationBuilder
        .setContentIntent(backToAppIntent)
        .setTicker(episode.getName())
        .setSmallIcon(R.drawable.ic_stat)
        .setContentTitle(episode.getName())
        .setContentText(episode.getPodcast().getName())
        .setWhen(0)
        .setProgress(duration, position, false)
        .setOngoing(true);

    // 2. Load large image if available, see onBitmapLoaded() below
    if (episode.getPodcast().hasLogoUrl())
      Picasso.with(context)
          .load(episode.getPodcast().getLogoUrl())
          .resizeDimen(
              android.R.dimen.notification_large_icon_width,
              android.R.dimen.notification_large_icon_height)
          .into(this);

    // 3. Add actions to notification
    notificationBuilder.addAction(stopAction);
    if (canSeek) notificationBuilder.addAction(rewindAction);
    if (paused) notificationBuilder.addAction(playAction);
    else notificationBuilder.addAction(pauseAction);
    if (canSeek) notificationBuilder.addAction(forwardAction);

    // 4. Apply other notification features
    NotificationCompat.MediaStyle style =
        new NotificationCompat.MediaStyle().setMediaSession(session.getSessionToken());
    // Make sure not to show rew/ff icons for live streams
    if (canSeek) style.setShowActionsInCompactView(1, 2, 3); // rewind, toggle play, forward
    else style.setShowActionsInCompactView(0, 1); // stop, toggle play

    notificationBuilder.setStyle(style);
    notificationBuilder.setColor(ContextCompat.getColor(context, R.color.theme_dark));
    notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
    notificationBuilder.setCategory(NotificationCompat.CATEGORY_TRANSPORT);

    return notificationBuilder.build();
  }
 /**
  * Returns a token to this object's MediaSession. The MediaSession should only be used for
  * notifications at the moment.
  *
  * @return The MediaSessionCompat.Token object.
  */
 public MediaSessionCompat.Token getSessionToken() {
   return mediaSession.getSessionToken();
 }
  /*
   * (non-Javadoc)
   * @see android.app.Service#onCreate()
   */
  @Override
  public void onCreate() {
    super.onCreate();
    LogHelper.d(TAG, "onCreate");

    mPlayingQueue = new ArrayList<>();
    mMusicProvider = new MusicProvider();
    mPackageValidator = new PackageValidator(this);

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

    Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
    mediaButtonIntent.setComponent(mediaButtonReceiver);
    PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);

    // Start a new MediaSessionCompat
    mSession =
        new MediaSessionCompat(this, "MusicService", mediaButtonReceiver, mediaPendingIntent);

    /*
    final MediaSessionCallback cb = new MediaSessionCallback();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Shouldn't really have to do this but the MediaSessionCompat method uses
        // an internal proxy class, which doesn't forward events such as
        // onPlayFromMediaId when running on Lollipop.
        final MediaSession session = (MediaSession) mSession.getMediaSession();
        session.setCallback(new MediaSessionCallbackProxy(cb));
    } else {
        mSession.setCallback(cb);
    }
    */

    setSessionToken(mSession.getSessionToken());
    mSession.setCallback(new MediaSessionCallback());
    mSession.setFlags(
        MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
            | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);

    mPlayback = new LocalPlayback(this, mMusicProvider);
    mPlayback.setState(PlaybackStateCompat.STATE_NONE);
    mPlayback.setCallback(this);
    mPlayback.start();

    Context context = getApplicationContext();
    Intent intent = new Intent(context, NowPlayingActivity.class);
    PendingIntent pi =
        PendingIntent.getActivity(
            context, 99 /*request code*/, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    mSession.setSessionActivity(pi);

    mSessionExtras = new Bundle();
    CarHelper.setSlotReservationFlags(mSessionExtras, true, true, true);
    WearHelper.setSlotReservationFlags(mSessionExtras, true, true);
    WearHelper.setUseBackgroundFromTheme(mSessionExtras, true);
    mSession.setExtras(mSessionExtras);

    updatePlaybackState(null);

    mMediaNotificationManager = new MediaNotificationManager(this);
    mCastManager = VideoCastManager.getInstance();
    mCastManager.addVideoCastConsumer(mCastConsumer);
    mMediaRouter = MediaRouter.getInstance(getApplicationContext());

    IntentFilter filter = new IntentFilter(CarHelper.ACTION_MEDIA_STATUS);
    mCarConnectionReceiver =
        new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
            String connectionEvent = intent.getStringExtra(CarHelper.MEDIA_CONNECTION_STATUS);
            mIsConnectedToCar = CarHelper.MEDIA_CONNECTED.equals(connectionEvent);
            LogHelper.i(
                TAG,
                "Connection event to Android Auto: ",
                connectionEvent,
                " isConnectedToCar=",
                mIsConnectedToCar);
          }
        };
    registerReceiver(mCarConnectionReceiver, filter);
  }