Using CountDown Timer
<p>I'm using a <code>CountDownTimer</code> but it doesn't seem to be working properly.  I need to capture speed; if it goes above a certain speed, do nothing.. I'm just logging speed.  But if it goes under a certain speed, I need to fire up a notification after a three minute countdown timer.</p>

<p>Can someone look at my code and see what I'm doing wrong? If the speed goes above, it's fine.. it does not run the timer, but the issue is when it goes under a certain speed.  Sometimes the timer works, other times, no.  Sometimes it just logs 0 and doesn't show the timer.</p>

<p>I know it's in the conditions, I've just been looking at it over and over, and I can't see what may be wrong.  Four eyes are better than two?</p>

<p>Any help is appreciated.  Thanks.</p>

<pre><code>public class SpeedManagerService extends Service implements IBaseGpsListener {

    private static final String TAG = "SpeedCheckerService";
    public boolean vehicleStopped = false;
    public boolean timer_started = true;

    float nCurrentSpeed = 0;

    CountDownTimer timer = new CountDownTimer( 180000, 1000 ) {

        // If speed increases again, cancel timer.
        public void onTick(long millisUntilFinished) {
            Log.i( "Current Ride", "Timer countdown: " + millisUntilFinished / 1000 +
                    " seconds." );
            if (vehicleStopped) {
                // Vehicle should have stopped, but it has started moving again
                if (nCurrentSpeed &gt; 0) {
                    timer.cancel();
                    timer_started = false;
                }
            } else if (nCurrentSpeed == 0) {
                // If vehicle has just slowed down,
                // once speed drops to zero we have stopped
                vehicleStopped = true;
            }
        }

        public void onFinish() {
            Intent resultIntent = new Intent( SpeedManagerService.this, CurrentRide.class );
            NotificationCompat.Builder builder = new NotificationCompat
                    .Builder( SpeedManagerService.this );
            builder.setContentText( "Click to save Current Ride info" );
            builder.setSmallIcon( R.mipmap.ic_launcher );
            builder.setContentTitle( "Did you just pay for a Ride?" );
            builder.setContentIntent( PendingIntent.getActivity( SpeedManagerService.this, 0,
                    resultIntent, 0 ) );
            NotificationManagerCompat.from( SpeedManagerService.this ).notify( 0,
                    builder.build() );
            timer.start();
        }
    }
            .start();

    @Override
    public void onCreate() {
        Log.i( TAG, "in onCreate()" );

        LocationManager locationManager = (LocationManager) this.
                getSystemService( Context.LOCATION_SERVICE );
        if (ActivityCompat.checkSelfPermission( this, android.Manifest.permission
                .ACCESS_FINE_LOCATION )
                != PackageManager.PERMISSION_GRANTED &amp;&amp; ActivityCompat.checkSelfPermission( this,
                android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager
                .PERMISSION_GRANTED) {

            return;
        }
        locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, this );
        SpeedManagerService.this.updateSpeed( null );
    }

    // On start, run speed service, and return sticky so if error, service will restart
    // on its own
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand( intent, flags, startId );
        Log.i( TAG, "Service onStartCommand" );
                if (nCurrentSpeed == 0) {
            timer_started = false;
        }
        updateSpeed( null );
        return Service.START_STICKY;
    }

    public void updateSpeed(SpeedLocation location) {
        Log.i( "Current Ride ", "User is in a Vehicle. Speed is: " +
                Math.round( nCurrentSpeed ) + " mph. " );

        // If a location exists, get speed
        if (location != null) {
            nCurrentSpeed = location.getSpeed();
        }

        // In meters/second, if speed goes above 8 mph, then it will just log the
        // speed as miles/hour.
        if (nCurrentSpeed &gt;= 8) {
        }

        // However, if speed falls below 5 mph, then countdown timer
        // of 3 minutes will begin.
        if (nCurrentSpeed &lt;= 5 &amp;&amp; !timer_started) {
            // Flag to indicate if vehicle has come to a complete stop
            vehicleStopped = (nCurrentSpeed == 0);
            // Indicate the timer is running
            timer_started = true;
            timer.start();
        }
    }

    @Override
    public void onDestroy() {

        timer.cancel();
        Log.i( TAG, "Timer cancelled" );

        super.onDestroy();
    }

    // Binder returns null because it's not used
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    // If location changes, update location and speed.
    @Override
    public void onLocationChanged(Location location) {
        if (location != null) {
            SpeedLocation myLocation = new SpeedLocation( location, false );
            this.updateSpeed( myLocation );
        }
    }

    // If provider is disabled, timer won't run either
    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }

    @Override
    public void onGpsStatusChanged(int event) {
    }
}
</code></pre>

<p>Here's a part of the logcat I get:</p>

<pre><code>07-05 17:42:17.742 17023-17023/ I/Current Ride:: User is in a Vehicle. Speed is: 3 mph. 
07-05 17:42:17.752 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.752 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.762 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
07-05 17:42:17.772 17023-17023/ I/Current Ride: Timer countdown: 179 seconds.
</code></pre>

<p>and it will do this like 25 times before the next mileage is shown.</p>