@Override
  public void onClick(View v) {
    if (v == mPlayButton) {
      final int state = PlaybackProxy.getState();
      switch (state) {
        case PlaybackService.STATE_PLAYING:
        case PlaybackService.STATE_BUFFERING:
          PlaybackProxy.pause();
          break;

        default:
          PlaybackProxy.play();
          break;
      }
    } else if (v == mPreviousButton) {
      PlaybackProxy.previous();
    } else if (v == mSkipButton) {
      PlaybackProxy.next();
    } else if (v == mMapsButton) {
      startMaps();
    } else if (v == mVoiceButton) {
      setVoiceEmphasis(true, false);
      mVoiceRecognizer.startListening();
    }
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

    // Allow for BluetoothReceiver to kill the activity on BT disconnect
    registerReceiver(mBroadcastRcv, new IntentFilter(ACTION_FINISH));

    mDetector = new GestureDetector(this, this);

    mHandler = new DriveHandler(new WeakReference<>(this));
    mPlaybackCallback = new DrivePlaybackCallback();

    mVoiceCommander = new VoiceCommander(this);
    mVoiceRecognizer = new VoiceRecognizer(this);
    mVoiceHelper = new VoiceActionHelper(this);

    mVoiceRecognizer.setListener(
        new VoiceRecognizer.Listener() {
          @Override
          public void onReadyForSpeech() {
            setVoiceEmphasis(true, true);
            PlaybackProxy.pause();
          }

          @Override
          public void onBeginningOfSpeech() {}

          @Override
          public void onEndOfSpeech() {
            setVoiceEmphasis(false, true);
            PlaybackProxy.play();
            resetVoiceRms();
            mHandler.postDelayed(
                new Runnable() {
                  @Override
                  public void run() {
                    mPbVoiceLoading.setVisibility(View.GONE);
                  }
                },
                1000);
          }

          @Override
          public void onRmsChanged(float rmsdB) {
            setVoiceRms(rmsdB);
          }

          @Override
          public void onError(int error) {
            setVoiceEmphasis(false, true);
            resetVoiceRms();
            PlaybackProxy.play();
            mPbVoiceLoading.setVisibility(View.GONE);
            mTvArtist.setAlpha(1.0f);
            if (!mHandler.hasMessages(MSG_UPDATE_PLAYBACK_STATUS)) {
              mHandler.sendEmptyMessage(MSG_UPDATE_PLAYBACK_STATUS);
            }
          }

          @Override
          public void onResults(List<String> results) {
            if (results != null && results.size() > 0) {
              mTvArtist.setText(results.get(0));
              mTvArtist.setAlpha(1.0f);
              mVoiceCommander.processResult(results, mVoiceHelper);
              mPbVoiceLoading.setVisibility(View.VISIBLE);

              mHandler.postDelayed(
                  new Runnable() {
                    @Override
                    public void run() {
                      mPbVoiceLoading.setVisibility(View.GONE);
                      mHandler.sendEmptyMessage(MSG_UPDATE_PLAYBACK_STATUS);
                    }
                  },
                  2000);
            }
          }

          @Override
          public void onPartialResults(List<String> results) {
            if (results != null && results.size() > 0) {
              mTvArtist.setText(results.get(0));
              mTvArtist.setAlpha(0.7f);
              mPbVoiceLoading.setVisibility(View.VISIBLE);
            }
          }
        });

    setContentView(R.layout.activity_drive_mode);

    mDecorView = findViewById(R.id.rlDriveRoot);
    mPlayButton = (ImageView) findViewById(R.id.btnPlayPause);
    mPreviousButton = (ImageView) findViewById(R.id.btnPrevious);
    mSkipButton = (ImageView) findViewById(R.id.btnNext);
    mVoiceButton = (ImageView) findViewById(R.id.btnVoice);
    mMapsButton = (ImageView) findViewById(R.id.btnMaps);
    mTvTitle = (TextView) findViewById(R.id.tvTitle);
    mTvArtist = (TextView) findViewById(R.id.tvArtist);
    mTvAlbum = (TextView) findViewById(R.id.tvAlbum);
    mTvCurrentTime = (TextView) findViewById(R.id.tvCurrentTime);
    mIvAlbumArt = (AlbumArtImageView) findViewById(R.id.ivAlbumArt);
    mSeek = (SeekBar) findViewById(R.id.sbSeek);
    mPbVoiceLoading = (ProgressBar) findViewById(R.id.pbVoiceLoading);

    mPlayDrawable = new PlayPauseDrawable(getResources(), 1.5f, 1.6f);
    mPlayDrawable.setShape(PlayPauseDrawable.SHAPE_PLAY);
    mPlayButton.setImageDrawable(mPlayDrawable);

    mPlayButton.setOnClickListener(this);
    mPreviousButton.setOnClickListener(this);
    mSkipButton.setOnClickListener(this);
    mMapsButton.setOnClickListener(this);
    mVoiceButton.setOnClickListener(this);
    mSeek.setOnSeekBarChangeListener(this);

    mHandler.sendEmptyMessage(MSG_UPDATE_PLAYBACK_STATUS);
    mHandler.sendEmptyMessageDelayed(MSG_UPDATE_SEEKBAR, DELAY_SEEKBAR_UPDATE);
    mHandler.sendEmptyMessage(MSG_UPDATE_TIME);

    SharedPreferences prefs = getSharedPreferences(PREFS_DRIVE_MODE, 0);
    if (!prefs.getBoolean(PREF_ONBOARDING_DONE, false)) {
      mPausedForOnboarding = true;
      prefs.edit().putBoolean(PREF_ONBOARDING_DONE, true).apply();
      startActivity(new Intent(this, DriveTutorialActivity.class));
    }
  }