Search code examples
androidfirebasetimer

Implement CountUp timer in Firebase


I am developing an android application for hiring bicycles which uses firebase database(realtime) and google maps.

Now i want to add a CountUp timer(in HH:mm:ss format) which tracks the ride time in server.

Why this requirement ?

As the ride time will be started by the customer once the ride is successfully booked, but will be ended only by the person managing the cycles at cycle stand from his app, when the bike is returned. (To ensure that the cycle has been returned safely)

How do i implement this timer in Firebase?

Till now i am implementing a CountUp Timer only at the customer end which uses Broadcast receiver to track the time in background.

One approach to solve this could be, that the customer ends the trip(only when customer is in 20 meters vicinity of cycle stand) and the same time be stored to firebase and the same be accessed by the person managing the cycle stand.

But there are some drawback to this approach:

What if a person ends the trip from outside stand and returns it after an hour, the time calculated will be wrong and will also hamper the availability status for next users.

   //Service Class
    public class BroadcastService extends Service {
        private Intent intent;
        public static final String BROADCAST_ACTION = "com.xyz";

        private Handler handler = new Handler();
        private long initial_time;
        long timeInMilliseconds = 0L;


        @Override
        public void onCreate() {
            super.onCreate();
            initial_time = SystemClock.uptimeMillis();
            intent = new Intent(BROADCAST_ACTION);
            handler.removeCallbacks(sendUpdatesToUI);
            handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
        }

        private Runnable sendUpdatesToUI = new Runnable() {
            public void run() {
                DisplayLoggingInfo();
                handler.postDelayed(this, 1000); // 1 seconds
            }
        };

        private void DisplayLoggingInfo() {

            timeInMilliseconds = SystemClock.uptimeMillis() - initial_time;

            int timer = (int) timeInMilliseconds / 1000;
            intent.putExtra("time", timer);
            sendBroadcast(intent);

        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            handler.removeCallbacks(sendUpdatesToUI);

        }

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

    // Java class which runs when ride is active and shows the timer 

    public class RideIsActive extends AppCompatActivity {


        private TextView timer;
        private Button endRide;

        Intent intent;
        long timeSwapBuff = 0L;
        long updatedTime = 0L;

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_ride_is_active);

            timer  = findViewById(R.id.timer);
            endRide = findViewById(R.id.endRide);

            startService(new Intent(this, BroadcastService.class));

            endRide.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    unregisterReceiver(broadcastReceiver);
                    stopService(intent);
                }
            });

        }

        private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

                updateUI(intent);
            }
        };

        private void updateUI(Intent intent) {
            int time = intent.getIntExtra("time", 0);

            Log.d("Hello", "Time " + time);

            int hrs = time/3600;
            int mins = time / 60;
            int secs = time % 60;
            timer.setText(String.format("%02d", hrs) + ":" + String.format("%02d", mins) + ":"
                    + String.format("%02d", secs));
        }

        @Override
        protected void onResume() {
            super.onResume();
            registerReceiver(broadcastReceiver, new IntentFilter(BroadcastService.BROADCAST_ACTION));
        }



    //Layout

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".RideIsActive">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/timer"
            android:layout_centerInParent="true"
            android:textSize="25dp"
            android:textColor="#000000"
            android:text="00:00:00"/>

        <Button
            android:id="@+id/endRide"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:text="End Ride"
            android:textColor="@color/textBlack"
            android:background="@color/quantum_orange500"/>


    </RelativeLayout>

Solution

  • Each bike must have an id so under that id:

    store the userStartTime in firebase

    Store the userEndTime in firebase then also have the manager store the cycleStandEndTime.

    You then have all the data in 3 fields in firebase and you can do whatever calculations you want.

    totalUserUseTime = userEndTime - userStartTime

    totalBikeRentalTime = cycleStandEndTime - userStartTime