diff --git a/rit-driver-app/app/build.gradle b/rit-driver-app/app/build.gradle deleted file mode 100644 index 372c6e2..0000000 --- a/rit-driver-app/app/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'com.android.application' -} - -android { - namespace 'com.rit.driver' - compileSdk 34 - - defaultConfig { - applicationId "com.rit.driver" - minSdk 21 - targetSdk 34 - versionCode 1 - versionName "1.0" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 - } -} - -dependencies { - implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.11.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' -} diff --git a/rit-driver-app/app/src/main/AndroidManifest.xml b/rit-driver-app/app/src/main/AndroidManifest.xml deleted file mode 100644 index 951a4e6..0000000 --- a/rit-driver-app/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rit-driver-app/app/src/main/java/com/rit/driver/Config.java b/rit-driver-app/app/src/main/java/com/rit/driver/Config.java deleted file mode 100644 index 05e28ad..0000000 --- a/rit-driver-app/app/src/main/java/com/rit/driver/Config.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.rit.driver; - -public class Config { - - public static final String BACKEND_URL = "https://rit-services.in"; - - - public static final String DEFAULT_PIN = "RITDRIVER"; -} diff --git a/rit-driver-app/app/src/main/java/com/rit/driver/MainActivity.java b/rit-driver-app/app/src/main/java/com/rit/driver/MainActivity.java deleted file mode 100644 index 6d3512f..0000000 --- a/rit-driver-app/app/src/main/java/com/rit/driver/MainActivity.java +++ /dev/null @@ -1,202 +0,0 @@ -package com.rit.driver; - -import android.Manifest; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import java.util.ArrayList; -import java.util.List; - -public class MainActivity extends AppCompatActivity { - - private static final int PERMISSION_REQUEST_CODE = 888; - - private EditText etRouteNumber; - private EditText etDriverPin; - private Button btnStartSharing; - private Button btnStopSharing; - private TextView tvStatusHeader; - private TextView tvStatusLogs; - private LinearLayout statusCard; - - private boolean isServiceRunning = false; - - // Receive tracking updates from Foreground Service - private final BroadcastReceiver locationReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent != null) { - if (intent.hasExtra(TrackingService.EXTRA_STATUS)) { - String status = intent.getStringExtra(TrackingService.EXTRA_STATUS); - tvStatusHeader.setText("STATUS: " + (isServiceRunning ? "ACTIVE" : "INACTIVE")); - logStatus(status); - } - - if (intent.hasExtra(TrackingService.EXTRA_LATITUDE) && intent.hasExtra(TrackingService.EXTRA_LONGITUDE)) { - double lat = intent.getDoubleExtra(TrackingService.EXTRA_LATITUDE, 0.0); - double lng = intent.getDoubleExtra(TrackingService.EXTRA_LONGITUDE, 0.0); - float accuracy = intent.getFloatExtra(TrackingService.EXTRA_ACCURACY, 0.0f); - - String gpsInfo = String.format("GPS Coords: %.6f, %.6f\nAccuracy: ±%.1fm", lat, lng, accuracy); - logStatus(gpsInfo); - } - } - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - // Bind Views - etRouteNumber = findViewById(R.id.etRouteNumber); - etDriverPin = findViewById(R.id.etDriverPin); - etDriverPin.setText(Config.DEFAULT_PIN); - btnStartSharing = findViewById(R.id.btnStartSharing); - btnStopSharing = findViewById(R.id.btnStopSharing); - tvStatusHeader = findViewById(R.id.tvStatusHeader); - tvStatusLogs = findViewById(R.id.tvStatusLogs); - statusCard = findViewById(R.id.statusCard); - - btnStartSharing.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (checkAndRequestPermissions()) { - startTracking(); - } - } - }); - - btnStopSharing.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - stopTracking(); - } - }); - } - - @Override - protected void onResume() { - super.onResume(); - // Register receiver for service communication - IntentFilter filter = new IntentFilter(TrackingService.ACTION_LOCATION_BROADCAST); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - registerReceiver(locationReceiver, filter, Context.RECEIVER_EXPORTED); - } else { - registerReceiver(locationReceiver, filter); - } - } - - @Override - protected void onPause() { - // Unregister receiver - unregisterReceiver(locationReceiver); - super.onPause(); - } - - private void startTracking() { - String serverUrl = Config.BACKEND_URL; - String routeNumber = etRouteNumber.getText().toString().trim(); - String driverPin = etDriverPin.getText().toString().trim(); - if (routeNumber.isEmpty()) { - Toast.makeText(this, "Enter bus route number", Toast.LENGTH_SHORT).show(); - return; - } - if (driverPin.isEmpty()) { - Toast.makeText(this, "Enter security driver PIN", Toast.LENGTH_SHORT).show(); - return; - } - - Intent serviceIntent = new Intent(this, TrackingService.class); - serviceIntent.putExtra("server_url", serverUrl); - serviceIntent.putExtra("route_number", routeNumber); - serviceIntent.putExtra("driver_pin", driverPin); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForegroundService(serviceIntent); - } else { - startService(serviceIntent); - } - - isServiceRunning = true; - btnStartSharing.setVisibility(View.GONE); - btnStopSharing.setVisibility(View.VISIBLE); - tvStatusHeader.setText("STATUS: ACTIVE"); - logStatus("Foreground tracking service started."); - } - - private void stopTracking() { - Intent serviceIntent = new Intent(this, TrackingService.class); - stopService(serviceIntent); - - isServiceRunning = false; - btnStartSharing.setVisibility(View.VISIBLE); - btnStopSharing.setVisibility(View.GONE); - tvStatusHeader.setText("STATUS: INACTIVE"); - logStatus("Tracking stopped by driver."); - } - - private void logStatus(String msg) { - String currentText = tvStatusLogs.getText().toString(); - tvStatusLogs.setText(msg + "\n\n" + currentText); - } - - private boolean checkAndRequestPermissions() { - boolean hasFine = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; - boolean hasCoarse = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; - - List listPermissionsNeeded = new ArrayList<>(); - - if (!hasFine && !hasCoarse) { - listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION); - listPermissionsNeeded.add(Manifest.permission.ACCESS_COARSE_LOCATION); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { - listPermissionsNeeded.add(Manifest.permission.POST_NOTIFICATIONS); - } - } - - if (!listPermissionsNeeded.isEmpty()) { - ActivityCompat.requestPermissions( - this, - listPermissionsNeeded.toArray(new String[0]), - PERMISSION_REQUEST_CODE - ); - return false; - } - - return true; - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - if (requestCode == PERMISSION_REQUEST_CODE) { - boolean hasFine = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; - boolean hasCoarse = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; - - if (hasFine || hasCoarse) { - startTracking(); - } else { - Toast.makeText(this, "Location permission (Precise or Approximate) is required to track the bus.", Toast.LENGTH_LONG).show(); - } - } - } -} diff --git a/rit-driver-app/app/src/main/java/com/rit/driver/NetworkHelper.java b/rit-driver-app/app/src/main/java/com/rit/driver/NetworkHelper.java deleted file mode 100644 index 0dc4e50..0000000 --- a/rit-driver-app/app/src/main/java/com/rit/driver/NetworkHelper.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.rit.driver; - -import android.util.Log; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -public class NetworkHelper { - - private static final String TAG = "NetworkHelper"; - - public interface Callback { - void onSuccess(); - void onFailure(String error); - } - - public static void postLocation(final String serverUrl, final String routeNumber, final double lat, final double lng, final String pin, final Callback callback) { - new Thread(new Runnable() { - @Override - public void run() { - HttpURLConnection conn = null; - try { - // Clean URL trailing slash and route mapping - String cleanUrl = serverUrl; - if (cleanUrl.endsWith("/")) { - cleanUrl = cleanUrl.substring(0, cleanUrl.length() - 1); - } - String targetUrl = cleanUrl + "/api/bus-locations/" + routeNumber; - - URL url = new URL(targetUrl); - conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "application/json"); - conn.setDoOutput(true); - conn.setConnectTimeout(8000); - conn.setReadTimeout(8000); - - // Build JSON string payload using Locale.US to ensure dot decimals in JSON - String jsonInputString = String.format( - java.util.Locale.US, - "{\"latitude\": %.6f, \"longitude\": %.6f, \"pin\": \"%s\"}", - lat, lng, pin - ); - - try (OutputStream os = conn.getOutputStream()) { - byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8); - os.write(input, 0, input.length); - } - - int code = conn.getResponseCode(); - if (code == 200 || code == 201) { - Log.d(TAG, "Location uploaded successfully: " + code); - if (callback != null) { - callback.onSuccess(); - } - } else { - String errMsg = "HTTP error code " + code; - Log.w(TAG, errMsg); - if (callback != null) { - callback.onFailure(errMsg); - } - } - } catch (Exception e) { - String errMsg = "Upload failed: " + e.getMessage(); - Log.e(TAG, errMsg, e); - if (callback != null) { - callback.onFailure(errMsg); - } - } finally { - if (conn != null) { - conn.disconnect(); - } - } - } - }).start(); - } -} diff --git a/rit-driver-app/app/src/main/java/com/rit/driver/TrackingService.java b/rit-driver-app/app/src/main/java/com/rit/driver/TrackingService.java deleted file mode 100644 index 9ef824f..0000000 --- a/rit-driver-app/app/src/main/java/com/rit/driver/TrackingService.java +++ /dev/null @@ -1,253 +0,0 @@ -package com.rit.driver; - -import android.annotation.SuppressLint; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.os.Build; -import android.os.Bundle; -import android.os.IBinder; -import android.os.PowerManager; -import android.util.Log; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; - -public class TrackingService extends Service { - - private static final String TAG = "TrackingService"; - private static final String CHANNEL_ID = "TrackingServiceChannel"; - private static final int NOTIFICATION_ID = 444; - - private LocationManager locationManager; - private PowerManager.WakeLock wakeLock; - - private String serverUrl = ""; - private String routeNumber = ""; - private String driverPin = ""; - - // Broadcast action for MainActivity to update UI coordinates - public static final String ACTION_LOCATION_BROADCAST = "com.rit.driver.LOCATION_BROADCAST"; - public static final String EXTRA_LATITUDE = "extra_latitude"; - public static final String EXTRA_LONGITUDE = "extra_longitude"; - public static final String EXTRA_ACCURACY = "extra_accuracy"; - public static final String EXTRA_STATUS = "extra_status"; - - private final LocationListener locationListener = new LocationListener() { - @Override - public void onLocationChanged(Location location) { - double lat = location.getLatitude(); - double lng = location.getLongitude(); - float accuracy = location.getAccuracy(); - - Log.d(TAG, "Location updated: " + lat + ", " + lng + " (Accuracy: " + accuracy + "m)"); - - // Broadcast updates locally to MainActivity UI - Intent broadcastIntent = new Intent(ACTION_LOCATION_BROADCAST); - broadcastIntent.setPackage(getPackageName()); - broadcastIntent.putExtra(EXTRA_LATITUDE, lat); - broadcastIntent.putExtra(EXTRA_LONGITUDE, lng); - broadcastIntent.putExtra(EXTRA_ACCURACY, accuracy); - broadcastIntent.putExtra(EXTRA_STATUS, "Broadcasting Location..."); - sendBroadcast(broadcastIntent); - - // Upload location to backend - NetworkHelper.postLocation(serverUrl, routeNumber, lat, lng, driverPin, new NetworkHelper.Callback() { - @Override - public void onSuccess() { - Log.d(TAG, "Uploaded location successfully"); - Intent statusIntent = new Intent(ACTION_LOCATION_BROADCAST); - statusIntent.setPackage(getPackageName()); - statusIntent.putExtra(EXTRA_STATUS, "Upload Success: Location synced."); - sendBroadcast(statusIntent); - } - - @Override - public void onFailure(String error) { - Log.e(TAG, "Upload failed: " + error); - Intent statusIntent = new Intent(ACTION_LOCATION_BROADCAST); - statusIntent.setPackage(getPackageName()); - statusIntent.putExtra(EXTRA_STATUS, "Upload Failed: " + error); - sendBroadcast(statusIntent); - } - }); - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) {} - - @Override - public void onProviderEnabled(String provider) {} - - @Override - public void onProviderDisabled(String provider) { - Intent statusIntent = new Intent(ACTION_LOCATION_BROADCAST); - statusIntent.setPackage(getPackageName()); - statusIntent.putExtra(EXTRA_STATUS, "GPS Provider Disabled. Please turn on Location/GPS."); - sendBroadcast(statusIntent); - } - }; - - @Override - public void onCreate() { - super.onCreate(); - Log.d(TAG, "onCreate: Service starting"); - createNotificationChannel(); - } - - private android.os.Handler handler = new android.os.Handler(android.os.Looper.getMainLooper()); - private Runnable periodicUploader = new Runnable() { - @Override - public void run() { - try { - Location loc = null; - if (locationManager != null) { - try { - Location gpsLoc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); - Location netLoc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); - Location pasLoc = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER); - - // Find newest location fix - if (gpsLoc != null) loc = gpsLoc; - if (netLoc != null && (loc == null || netLoc.getTime() > loc.getTime())) loc = netLoc; - if (pasLoc != null && (loc == null || pasLoc.getTime() > loc.getTime())) loc = pasLoc; - } catch (SecurityException ignored) {} - } - - // If indoors with zero GPS fix, fallback to campus location fix - if (loc == null) { - loc = new Location("IndoorFallback"); - loc.setLatitude(13.0118); - loc.setLongitude(80.0214); - loc.setAccuracy(15.0f); - loc.setTime(System.currentTimeMillis()); - } - - locationListener.onLocationChanged(loc); - } catch (Exception e) { - Log.e(TAG, "Error in periodic uploader: " + e.getMessage()); - } finally { - handler.postDelayed(this, 5000); - } - } - }; - - @SuppressLint("InvalidWakeLockTag") - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "onStartCommand: Service active"); - - if (intent != null) { - serverUrl = intent.getStringExtra("server_url"); - routeNumber = intent.getStringExtra("route_number"); - driverPin = intent.getStringExtra("driver_pin"); - } - - // 1. Show Foreground Notification - Intent notificationIntent = new Intent(this, MainActivity.class); - PendingIntent pendingIntent = PendingIntent.getActivity( - this, 0, notificationIntent, - PendingIntent.FLAG_IMMUTABLE - ); - - Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID) - .setContentTitle("RIT Driver Tracker") - .setContentText("Active Journey: Route " + routeNumber + " is currently tracking...") - .setSmallIcon(android.R.drawable.ic_menu_compass) - .setContentIntent(pendingIntent) - .setPriority(NotificationCompat.PRIORITY_HIGH) - .build(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - startForeground(NOTIFICATION_ID, notification, android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION); - } else { - startForeground(NOTIFICATION_ID, notification); - } - - // 2. Acquire Power CPU WakeLock - PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - if (pm != null) { - wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TrackingService::WakeLock"); - wakeLock.acquire(); - Log.d(TAG, "WakeLock acquired successfully"); - } - - // 3. Register Location Listeners (both GPS and Network for indoors/outdoors) - locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); - try { - if (locationManager != null) { - if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { - try { - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0.0f, locationListener); - } catch (SecurityException ignored) {} - } - if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { - try { - locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0.0f, locationListener); - } catch (SecurityException ignored) {} - } - } - } catch (Exception e) { - Log.e(TAG, "Location permission warning", e); - Intent statusIntent = new Intent(ACTION_LOCATION_BROADCAST); - statusIntent.setPackage(getPackageName()); - statusIntent.putExtra(EXTRA_STATUS, "Location Warning: " + e.getMessage()); - sendBroadcast(statusIntent); - } - - // 4. Start periodic 5-second uploader - handler.removeCallbacks(periodicUploader); - handler.post(periodicUploader); - - return START_REDELIVER_INTENT; - } - - @Override - public void onDestroy() { - Log.d(TAG, "onDestroy: Stopping service cleanups"); - - // Stop periodic uploader timer - if (handler != null && periodicUploader != null) { - handler.removeCallbacks(periodicUploader); - } - - // 1. Remove GPS Listener - if (locationManager != null) { - locationManager.removeUpdates(locationListener); - } - - // 2. Release CPU WakeLock - if (wakeLock != null && wakeLock.isHeld()) { - wakeLock.release(); - Log.d(TAG, "WakeLock released cleanly"); - } - - super.onDestroy(); - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - return null; - } - - private void createNotificationChannel() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel serviceChannel = new NotificationChannel( - CHANNEL_ID, - "RIT Driver Tracker Channel", - NotificationManager.IMPORTANCE_DEFAULT - ); - NotificationManager manager = getSystemService(NotificationManager.class); - if (manager != null) { - manager.createNotificationChannel(serviceChannel); - } - } - } -} diff --git a/rit-driver-app/app/src/main/res/drawable/ic_launcher.xml b/rit-driver-app/app/src/main/res/drawable/ic_launcher.xml deleted file mode 100644 index 059591d..0000000 --- a/rit-driver-app/app/src/main/res/drawable/ic_launcher.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/rit-driver-app/app/src/main/res/layout/activity_main.xml b/rit-driver-app/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index 3543859..0000000 --- a/rit-driver-app/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - -