├── .gitignore ├── .idea ├── .name ├── codeStyles │ └── Project.xml ├── gradle.xml ├── jarRepositories.xml ├── misc.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── kkwbustracking │ │ └── ExampleInstrumentedTest.java │ ├── debug │ └── res │ │ └── values │ │ └── google_maps_api.xml │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── kkwbustracking │ │ │ ├── DatabaseHelper.java │ │ │ ├── MapsActivity.java │ │ │ ├── Splash_Screen.java │ │ │ ├── about.java │ │ │ ├── driver_login.java │ │ │ ├── driver_tracklocation.java │ │ │ └── student_tracklocation.java │ └── res │ │ ├── drawable-v24 │ │ ├── bus_and_girl.jpeg │ │ ├── bus_marker.png │ │ ├── bus_tracking_logo.png │ │ ├── ic_launcher_foreground.xml │ │ ├── logo.png │ │ ├── splash_screen.jpg │ │ ├── tic_tac_toe.png │ │ └── tracking_app.png │ │ ├── drawable │ │ ├── button_background.xml │ │ ├── call_button_background.xml │ │ ├── confirmation_number.xml │ │ ├── details.xml │ │ ├── driver.xml │ │ ├── edit_location.xml │ │ ├── edittext_background.xml │ │ ├── email.xml │ │ ├── globe.xml │ │ ├── ic_launcher_background.xml │ │ ├── location.xml │ │ ├── phone.xml │ │ └── text_fields.xml │ │ ├── layout │ │ ├── about.xml │ │ ├── activity_maps.xml │ │ ├── driver_details_dialog.xml │ │ ├── driver_login.xml │ │ ├── driver_tracklocation.xml │ │ ├── splash_screen.xml │ │ └── student_tracklocation.xml │ │ ├── menu │ │ ├── menu.xml │ │ └── menu_withoutroute.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── release │ └── res │ │ └── values │ │ └── google_maps_api.xml │ └── test │ └── java │ └── com │ └── example │ └── kkwbustracking │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | KKW Bus Tracking -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bus Tracking App 2 | 3 | Keep track of your school buses in real-time with a comprehensive transport management solution 4 | 5 | Safety from the first stop to the very last 6 | 7 | No longer do your children have to wait in the dark, freezing temperatures, pouring rain or hot sun. With Here Comes the Bus parents will know when their child’s bus is arriving, reducing the time their children spend standing by the side of the road. 8 | 9 | ### Overview 10 | 11 | Student Bus Tracker is one of the best GPS tracking application for students and their parents. This application will let students track their school, college, or university van, and also they will be able to see the bus or van on the map with real time feature.In this way, parents will also be able to track their children and they will know where the bus is right now and also the direction and duration of which the bus will arrive at the destination. 12 | 13 | 14 | ### Features 15 | 16 | - Real time bus tracking in single map 17 | - Firebase as backend, 18 | - Simple coding style 19 | - Beautiful UI/UX with material design 20 | - Admob Ads with GDPR implementation 21 | - Easy to reskin 22 | - Complete documentation 23 | 24 | 25 | ### For Schools 26 | 27 | Keep track of your school buses in real-time with a comprehensive transport management solution. With features like speed alerts, geofencing of vehicles, and security notifications, you can secure the safety of your students outside the school as well. 28 | 29 | 30 | ### For Parents 31 | 32 | Keep your dear ones at arm’s length with real-time tracking of their school buses. Instant pickup and drop-off notifications with updated driver information will ensure your peace of mind when your kids are on the road. 33 | 34 | Safety for your children 35 | 36 | Mornings can be a hectic time. Getting ready for work. Getting the kids prepped for school. So what if – at least when it came to making sure your kids make it to the bus on time – you could remove some of that stress? 37 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.google.gms.google-services' 3 | 4 | android { 5 | compileSdkVersion 29 6 | buildToolsVersion "29.0.3" 7 | 8 | defaultConfig { 9 | applicationId "com.example.kkwbustracking" 10 | minSdkVersion 26 11 | targetSdkVersion 29 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | dependencies 27 | { 28 | implementation fileTree(dir: "libs", include: ["*.jar"]) 29 | implementation 'androidx.appcompat:appcompat:1.1.0' 30 | implementation 'com.google.android.gms:play-services-maps:17.0.0' 31 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 32 | implementation 'com.google.android.gms:play-services-location:17.0.0' 33 | implementation 'com.google.android.material:material:1.1.0' 34 | implementation 'com.google.firebase:firebase-database:19.3.1' 35 | implementation 'com.google.firebase:firebase-auth:19.3.1' 36 | testImplementation 'junit:junit:4.13' 37 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 38 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 39 | implementation 'com.github.jd-alexander:library:1.1.0' 40 | } -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "1086746948836", 4 | "firebase_url": "https://kkw-bus-tracking.firebaseio.com", 5 | "project_id": "kkw-bus-tracking", 6 | "storage_bucket": "kkw-bus-tracking.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:1086746948836:android:bdc9b9d38149c7c24e68f1", 12 | "android_client_info": { 13 | "package_name": "com.example.kkwbustracking" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "1086746948836-v5ccmnac4fm9nthuq30bn3al4v9jk3t5.apps.googleusercontent.com", 19 | "client_type": 1, 20 | "android_info": { 21 | "package_name": "com.example.kkwbustracking", 22 | "certificate_hash": "f5324b72407e17797ca6db503f3d1bcc30b66f89" 23 | } 24 | }, 25 | { 26 | "client_id": "1086746948836-cpv63va6a6bsk9gajmsnr1us4t80icks.apps.googleusercontent.com", 27 | "client_type": 3 28 | } 29 | ], 30 | "api_key": [ 31 | { 32 | "current_key": "AIzaSyCiJz4m-KvOJ4nNiR7cJDc6XCW6p0YQ22E" 33 | } 34 | ], 35 | "services": { 36 | "appinvite_service": { 37 | "other_platform_oauth_client": [ 38 | { 39 | "client_id": "1086746948836-cpv63va6a6bsk9gajmsnr1us4t80icks.apps.googleusercontent.com", 40 | "client_type": 3 41 | } 42 | ] 43 | } 44 | } 45 | } 46 | ], 47 | "configuration_version": "1" 48 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/kkwbustracking/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.kkwbustracking; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.example.kkwbustracking", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/debug/res/values/google_maps_api.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | AIzaSyCiJz4m-KvOJ4nNiR7cJDc6XCW6p0YQ22E 24 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | 22 | 23 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kkwbustracking/DatabaseHelper.java: -------------------------------------------------------------------------------- 1 | package com.example.kkwbustracking; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | import android.database.sqlite.SQLiteOpenHelper; 8 | import android.widget.Toast; 9 | 10 | public class DatabaseHelper extends SQLiteOpenHelper 11 | { 12 | public final static String DATABASE_NAME = "AKMAP Bus Tracker"; 13 | public final static String TABLE_NAME = "UserInfo"; 14 | public static final String COL_1 = "ID"; 15 | public static final String COL_2 = "name"; 16 | public static final String COL_3 = "phone"; 17 | public static final String COL_4 = "licence"; 18 | public static final String COL_5 = "email"; 19 | 20 | 21 | public DatabaseHelper(Context context) 22 | { 23 | super(context, DATABASE_NAME, null, 1); 24 | } 25 | 26 | @Override 27 | public void onCreate(SQLiteDatabase db) 28 | { 29 | // db.execSQL("CREATE TABLE IF NOT EXISTS "+TABLE_NAME+"("+COL_1+"INTEGER PRIMARY KEY AUTOINCREMENT,"+COL_2+"TEXT,"+COL_3+"TEXT,"+COL_4+"TEXT,"+COL_5+"TEXT)"); 30 | 31 | db.execSQL("CREATE TABLE IF NOT EXISTS "+TABLE_NAME+"(ID INTEGER PRIMARY KEY,NAME TEXT,PHONE TEXT,LICENCE TEXT,EMAIL TEXT)"); 32 | } 33 | 34 | @Override 35 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 36 | { 37 | db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME); 38 | onCreate(db); 39 | } 40 | 41 | public boolean insertData(String name, String phone,String licence_no,String email) 42 | { 43 | SQLiteDatabase db = this.getWritableDatabase(); 44 | ContentValues cv = new ContentValues(); 45 | cv.put(COL_2, name); 46 | cv.put(COL_3, phone); 47 | cv.put(COL_4, licence_no); 48 | cv.put(COL_5, email); 49 | 50 | long result = db.insert(TABLE_NAME, null, cv); 51 | if (result == -1) 52 | return false; 53 | else 54 | return true; 55 | } 56 | 57 | public Cursor getData(String id) 58 | { 59 | SQLiteDatabase db = this.getWritableDatabase(); 60 | String query="SELECT * FROM "+TABLE_NAME+" WHERE ID='"+id+"'"; 61 | Cursor cursor = db.rawQuery(query,null); 62 | return cursor; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kkwbustracking/MapsActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.kkwbustracking; 2 | 3 | import android.*; 4 | import android.Manifest; 5 | import android.app.ActionBar; 6 | import android.app.Dialog; 7 | import android.content.Context; 8 | import android.content.DialogInterface; 9 | import android.content.Intent; 10 | import android.content.IntentSender; 11 | import android.content.pm.PackageManager; 12 | import android.content.res.Resources; 13 | import android.graphics.Color; 14 | import android.location.Geocoder; 15 | import android.location.Location; 16 | import android.location.Address; 17 | import android.os.Build; 18 | 19 | import androidx.annotation.NonNull; 20 | import androidx.annotation.Nullable; 21 | import androidx.appcompat.app.AlertDialog; 22 | import androidx.appcompat.app.AppCompatActivity; 23 | import androidx.appcompat.widget.Toolbar; 24 | import androidx.core.app.ActivityCompat; 25 | import androidx.core.content.ContextCompat; 26 | import androidx.fragment.app.DialogFragment; 27 | import androidx.fragment.app.FragmentActivity; 28 | 29 | import android.os.Bundle; 30 | import android.os.Looper; 31 | import android.text.Editable; 32 | import android.text.Html; 33 | import android.util.Log; 34 | import android.view.Menu; 35 | import android.view.MenuItem; 36 | import android.view.View; 37 | import android.widget.Button; 38 | import android.widget.TextView; 39 | import android.widget.Toast; 40 | 41 | 42 | import com.google.android.gms.common.ConnectionResult; 43 | import com.google.android.gms.common.GoogleApiAvailability; 44 | import com.google.android.gms.common.api.GoogleApiClient; 45 | //import com.google.android.gms.identity.intents.Address; 46 | import com.google.android.gms.location.FusedLocationProviderClient; 47 | import com.google.android.gms.location.LocationCallback; 48 | import com.google.android.gms.location.LocationRequest; 49 | import com.google.android.gms.location.LocationResult; 50 | import com.google.android.gms.location.LocationServices; 51 | import com.google.android.gms.maps.CameraUpdateFactory; 52 | import com.google.android.gms.maps.GoogleMap; 53 | import com.google.android.gms.maps.OnMapReadyCallback; 54 | import com.google.android.gms.maps.SupportMapFragment; 55 | import com.google.android.gms.maps.model.BitmapDescriptorFactory; 56 | import com.google.android.gms.maps.model.LatLng; 57 | import com.google.android.gms.maps.model.Marker; 58 | import com.google.android.gms.maps.model.MarkerOptions; 59 | 60 | import com.google.android.gms.common.api.GoogleApiClient; 61 | import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; 62 | import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; 63 | import com.google.android.gms.tasks.OnCompleteListener; 64 | import com.google.android.gms.tasks.OnSuccessListener; 65 | import com.google.android.gms.tasks.Task; 66 | import com.google.android.material.snackbar.Snackbar; 67 | import com.google.android.material.textfield.TextInputEditText; 68 | import com.google.firebase.database.DatabaseReference; 69 | import com.google.firebase.database.FirebaseDatabase; 70 | 71 | 72 | import java.io.IOException; 73 | import java.security.Permission; 74 | import java.util.List; 75 | import java.util.Locale; 76 | 77 | //public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, ConnectionCallbacks, OnConnectionFailedListener, com.google.android.gms.location.LocationListener 78 | /*public class MapsActivity extends FragmentActivity 79 | { 80 | private GoogleMap mMap; 81 | SupportMapFragment mapFragment; 82 | private GoogleApiClient mGoogleApiClient; 83 | private Location mLocation; 84 | double lat, lng; 85 | private LocationRequest mLocationRequest; 86 | private FusedLocationProviderClient mFusedLocationClient; 87 | private LocationCallback mLocationCallback; 88 | 89 | // Better to use GoogleApiClient to show device location. I am using this way in my aap. 90 | 91 | // private AddressResultReceiver mResultReceiver; 92 | // removed here because cause wrong code when implemented and 93 | // its not necessary like the author says 94 | 95 | //Define fields for Google API Client 96 | private Location lastLocation; 97 | private LocationRequest locationRequest; 98 | 99 | 100 | private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 14; 101 | 102 | @Override 103 | protected void onCreate(@Nullable Bundle savedInstanceState) 104 | { 105 | super.onCreate(savedInstanceState); 106 | setContentView(R.layout.activity_maps); 107 | 108 | 109 | // mResultReceiver = new AddressResultReceiver(null); 110 | // cemented as above explained 111 | try { 112 | mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this); 113 | mFusedLocationClient.getLastLocation() 114 | .addOnSuccessListener(this, new OnSuccessListener() { 115 | @Override 116 | public void onSuccess(Location location) { 117 | // Got last known location. In some rare situations this can be null. 118 | // if (location != null) { 119 | // Logic to handle location object 120 | // txtLatitude.setText(String.valueOf(location.getLatitude())); 121 | //txtLongitude.setText(String.valueOf(location.getLongitude())); 122 | // if (mResultReceiver != null) 123 | // txtAddress.setText(mResultReceiver.getAddress()); 124 | // } 125 | } 126 | }); 127 | locationRequest = LocationRequest.create(); 128 | locationRequest.setInterval(5000); 129 | locationRequest.setFastestInterval(1000); 130 | //if (txtAddress.getText().toString().equals("")) 131 | locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 132 | // else 133 | // locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 134 | 135 | mLocationCallback = new LocationCallback() { 136 | @Override 137 | public void onLocationResult(LocationResult locationResult) { 138 | for (Location location : locationResult.getLocations()) { 139 | // Update UI with location data 140 | // txtLatitude.setText(String.valueOf(location.getLatitude())); 141 | // txtLongitude.setText(String.valueOf(location.getLongitude())); 142 | } 143 | } 144 | 145 | ; 146 | }; 147 | } catch (SecurityException ex) { 148 | ex.printStackTrace(); 149 | } catch (Exception e) { 150 | e.printStackTrace(); 151 | } 152 | } 153 | 154 | @Override 155 | public void onStart() { 156 | super.onStart(); 157 | 158 | if (!checkPermissions()) { 159 | startLocationUpdates(); 160 | requestPermissions(); 161 | } else { 162 | getLastLocation(); 163 | startLocationUpdates(); 164 | } 165 | } 166 | 167 | @Override 168 | public void onPause() { 169 | stopLocationUpdates(); 170 | super.onPause(); 171 | } 172 | 173 | /** 174 | * Return the current state of the permissions needed. 175 | */ 176 | /* private boolean checkPermissions() { 177 | int permissionState = ActivityCompat.checkSelfPermission(this, 178 | Manifest.permission.ACCESS_COARSE_LOCATION); 179 | return permissionState == PackageManager.PERMISSION_GRANTED; 180 | } 181 | 182 | private void startLocationPermissionRequest() { 183 | ActivityCompat.requestPermissions(this, 184 | new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 185 | REQUEST_PERMISSIONS_REQUEST_CODE); 186 | } 187 | 188 | 189 | private void requestPermissions() { 190 | boolean shouldProvideRationale = 191 | ActivityCompat.shouldShowRequestPermissionRationale(this, 192 | Manifest.permission.ACCESS_COARSE_LOCATION); 193 | 194 | // Provide an additional rationale to the user. This would happen if the user denied the 195 | // request previously, but didn't check the "Don't ask again" checkbox. 196 | if (shouldProvideRationale) { 197 | // Log.i(TAG, "Displaying permission rationale to provide additional context."); 198 | 199 | /* showSnackbar(R.string.permission_rationale, android.R.string.ok, 200 | new View.OnClickListener() { 201 | @Override 202 | public void onClick(View view) { 203 | // Request permission 204 | startLocationPermissionRequest(); 205 | } 206 | });*/ 207 | 208 | /* } else { 209 | // Log.i(TAG, "Requesting permission"); 210 | // Request permission. It's possible this can be auto answered if device policy 211 | // sets the permission in a given state or the user denied the permission 212 | // previously and checked "Never ask again". 213 | startLocationPermissionRequest(); 214 | } 215 | } 216 | 217 | /** 218 | * Callback received when a permissions request has been completed. 219 | */ 220 | /* @Override 221 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 222 | @NonNull int[] grantResults) { 223 | // Log.i(TAG, "onRequestPermissionResult"); 224 | if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) { 225 | if (grantResults.length <= 0) { 226 | // If user interaction was interrupted, the permission request is cancelled and you 227 | // receive empty arrays. 228 | // Log.i(TAG, "User interaction was cancelled."); 229 | } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 230 | // Permission granted. 231 | getLastLocation(); 232 | } else { 233 | // Permission denied. 234 | 235 | // Notify the user via a SnackBar that they have rejected a core permission for the 236 | // app, which makes the Activity useless. In a real app, core permissions would 237 | // typically be best requested during a welcome-screen flow. 238 | 239 | // Additionally, it is important to remember that a permission might have been 240 | // rejected without asking the user for permission (device policy or "Never ask 241 | // again" prompts). Therefore, a user interface affordance is typically implemented 242 | // when permissions are denied. Otherwise, your app could appear unresponsive to 243 | // touches or interactions which have required permissions. 244 | /* showSnackbar(R.string.permission_denied_explanation, R.string.settings, 245 | new View.OnClickListener() { 246 | @Override 247 | public void onClick(View view) { 248 | // Build intent that displays the App settings screen. 249 | Intent intent = new Intent(); 250 | intent.setAction( 251 | Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 252 | Uri uri = Uri.fromParts("package", 253 | BuildConfig.APPLICATION_ID, null); 254 | intent.setData(uri); 255 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 256 | startActivity(intent); 257 | } 258 | });*/ 259 | /* } 260 | } 261 | } 262 | 263 | 264 | /** 265 | * Provides a simple way of getting a device's location and is well suited for 266 | * applications that do not require a fine-grained location and that do not need location 267 | * updates. Gets the best and most recent location currently available, which may be null 268 | * in rare cases when a location is not available. 269 | *

270 | * Note: this method should be called after location permission has been granted. 271 | */ 272 | /* @SuppressWarnings("MissingPermission") 273 | private void getLastLocation() { 274 | mFusedLocationClient.getLastLocation() 275 | .addOnCompleteListener(this, new OnCompleteListener() { 276 | @Override 277 | public void onComplete(@NonNull Task task) { 278 | if (task.isSuccessful() && task.getResult() != null) { 279 | lastLocation = task.getResult(); 280 | 281 | // txtLatitude.setText(String.valueOf(lastLocation.getLatitude())); 282 | // txtLongitude.setText(String.valueOf(lastLocation.getLongitude())); 283 | 284 | } else { 285 | // Log.w(TAG, "getLastLocation:exception", task.getException()); 286 | // showSnackbar(getString(R.string.no_location_detected)); 287 | } 288 | } 289 | }); 290 | } 291 | 292 | private void stopLocationUpdates() { 293 | mFusedLocationClient.removeLocationUpdates(mLocationCallback); 294 | } 295 | 296 | private void startLocationUpdates() { 297 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 298 | // TODO: Consider calling 299 | // ActivityCompat#requestPermissions 300 | // here to request the missing permissions, and then overriding 301 | // public void onRequestPermissionsResult(int requestCode, String[] permissions, 302 | // int[] grantResults) 303 | // to handle the case where the user grants the permission. See the documentation 304 | // for ActivityCompat#requestPermissions for more details. 305 | return; 306 | } 307 | mFusedLocationClient.requestLocationUpdates(locationRequest, mLocationCallback, null); 308 | } 309 | 310 | // private void showSnackbar(final String text) { 311 | // if (canvasLayout != null) { 312 | // Snackbar.make(canvasLayout, text, Snackbar.LENGTH_LONG).show(); 313 | // } 314 | //} 315 | // this also cause wrong code and as I see it dont is necessary 316 | // because the same method which is really used 317 | 318 | 319 | private void showSnackbar(final int mainTextStringId, final int actionStringId, 320 | View.OnClickListener listener) 321 | { 322 | Snackbar.make(this.findViewById(android.R.id.content), 323 | getString(mainTextStringId), 324 | Snackbar.LENGTH_INDEFINITE) 325 | .setAction(getString(actionStringId), listener).show(); 326 | } 327 | } 328 | 329 | 330 | 331 | /* @Override 332 | protected void onCreate(Bundle savedInstanceState) 333 | { 334 | super.onCreate(savedInstanceState); 335 | setContentView(R.layout.activity_maps); 336 | // Obtain the SupportMapFragment and get notified when the map is ready to be used. 337 | mapFragment = (SupportMapFragment) getSupportFragmentManager() 338 | .findFragmentById(R.id.map); 339 | 340 | // Check runtime Permission // 341 | int Permission_All = 1; 342 | String[] Permissions = {android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}; 343 | if(!hasPermissions(this, Permissions)) 344 | { 345 | ActivityCompat.requestPermissions(this, Permissions, Permission_All); 346 | } 347 | 348 | createLocationRequest(); 349 | // make a buidler for GoogleApiClient // 350 | if(mGoogleApiClient == null) 351 | { 352 | mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext()) 353 | .addConnectionCallbacks(this) 354 | .addOnConnectionFailedListener(this) 355 | .addApi(LocationServices.API) 356 | .build(); 357 | } 358 | 359 | } 360 | 361 | protected void createLocationRequest() 362 | { 363 | if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED 364 | ||ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION)== PackageManager.PERMISSION_GRANTED ) 365 | { 366 | mLocationRequest = new LocationRequest(); 367 | mLocationRequest.setInterval(20000); // 20 seconds 368 | mLocationRequest.setFastestInterval(10000); //10 seconds 369 | mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 370 | } 371 | } 372 | 373 | 374 | @Override 375 | public void onMapReady(GoogleMap googleMap) 376 | { 377 | mMap = googleMap; 378 | 379 | // Add a marker in Sydney and move the camera 380 | LatLng sydney = new LatLng(lat, lng); 381 | String address = getAddress(this,lat,lng); 382 | mMap.addMarker(new MarkerOptions().position(sydney).title(address)); 383 | mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); 384 | } 385 | 386 | // Get Address from latitude and longitude // 387 | public String getAddress(Context ctx, double lat,double lng) 388 | { 389 | String fullAdd=null; 390 | try 391 | { 392 | Geocoder geocoder= new Geocoder(ctx, Locale.getDefault()); 393 | List addresses = geocoder.getFromLocation(lat,lng,1); 394 | if(addresses.size()>0) 395 | { 396 | Address address = addresses.get(0); 397 | fullAdd = address.getAddressLine(0); 398 | 399 | // if you want only city or pin code use following code // 400 | /* String Location = address.getLocality(); 401 | String zip = address.getPostalCode(); 402 | String Country = address.getCountryName(); 403 | } 404 | } 405 | catch(IOException ex) 406 | { 407 | ex.printStackTrace(); 408 | } 409 | return fullAdd; 410 | } 411 | 412 | 413 | // must declare methods // 414 | 415 | public void onStart() 416 | { 417 | mGoogleApiClient.connect(); 418 | super.onStart(); 419 | if(mGoogleApiClient.isConnected()) 420 | { 421 | startLocationUpdates(); 422 | } 423 | } 424 | public void onStop() 425 | { 426 | mGoogleApiClient.disconnect(); 427 | stopLocationUpdate(); 428 | super.onStop(); 429 | } 430 | public void onPause() 431 | { 432 | mGoogleApiClient.connect(); 433 | stopLocationUpdate(); 434 | super.onPause(); 435 | } 436 | public void onResume() 437 | { 438 | mGoogleApiClient.connect(); 439 | super.onResume(); 440 | if(mGoogleApiClient.isConnected()) 441 | { 442 | startLocationUpdates(); 443 | } 444 | } 445 | 446 | // create method for location update // 447 | protected void startLocationUpdates() 448 | { 449 | if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED 450 | ||ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION)== PackageManager.PERMISSION_GRANTED ) 451 | { 452 | LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 453 | } 454 | } 455 | 456 | protected void stopLocationUpdate() 457 | { 458 | LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 459 | 460 | 461 | 462 | mFusedLocationClient.removeLocationUpdates(mLocationCallback); 463 | } 464 | 465 | // Must Declare LocatonListener Methods // 466 | public void onLocationChanged(Location location) 467 | { 468 | if(location!=null) 469 | { 470 | lat = location.getLatitude(); 471 | lng = location.getLongitude(); 472 | mapFragment.getMapAsync(this); 473 | } 474 | } 475 | 476 | public void onConnectionSuspended(int arg0) 477 | { 478 | 479 | } 480 | public void onStatusChange(String provider, int status, Bundle extras) 481 | { 482 | 483 | } 484 | 485 | // Must Declare Callback Methods // 486 | public void onConnected(Bundle args0) 487 | { 488 | if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED 489 | ||ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION)== PackageManager.PERMISSION_GRANTED ) 490 | { 491 | mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 492 | if(mLocation!=null) 493 | { 494 | lat = mLocation.getLatitude(); 495 | lng = mLocation.getLatitude(); 496 | mapFragment.getMapAsync(this); 497 | } 498 | if(mGoogleApiClient.isConnected()) 499 | { 500 | startLocationUpdates(); 501 | } 502 | } 503 | } 504 | 505 | public static boolean hasPermissions(Context context, String... permissions) 506 | { 507 | if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M && context!=null && permissions!=null) 508 | { 509 | for(String permission: permissions) 510 | { 511 | if(ActivityCompat.checkSelfPermission(context, permission)!=PackageManager.PERMISSION_GRANTED) 512 | { 513 | return false; 514 | } 515 | } 516 | } 517 | return true; 518 | } 519 | 520 | /* // Request code to use when launching the resolution activity 521 | private static final int REQUEST_RESOLVE_ERROR = 1001; 522 | // Unique tag for the error dialog fragment 523 | private static final String DIALOG_ERROR = "dialog_error"; 524 | // Bool to track whether the app is already resolving an error 525 | private boolean mResolvingError = false; */ 526 | 527 | // ... 528 | /* 529 | @Override 530 | public void onConnectionFailed(ConnectionResult result) 531 | { 532 | /*if (mResolvingError) 533 | { 534 | // Already attempting to resolve an error. 535 | return; 536 | } 537 | else if (result.hasResolution()) 538 | { 539 | try { 540 | mResolvingError = true; 541 | result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR); 542 | } catch (IntentSender.SendIntentException e) { 543 | // There was an error with the resolution intent. Try again. 544 | mGoogleApiClient.connect(); 545 | } 546 | } else { 547 | // Show dialog using GoogleApiAvailability.getErrorDialog() 548 | showErrorDialog(result.getErrorCode()); 549 | mResolvingError = true; 550 | }*/ 551 | 552 | 553 | // The rest of this code is all about building the error dialog 554 | 555 | /* Creates a dialog for an error message */ 556 | /* private void showErrorDialog(int errorCode) 557 | { 558 | // Create a fragment for the error dialog 559 | ErrorDialogFragment dialogFragment = new ErrorDialogFragment(); 560 | // Pass the error that should be displayed 561 | Bundle args = new Bundle(); 562 | args.putInt(DIALOG_ERROR, errorCode); 563 | dialogFragment.setArguments(args); 564 | dialogFragment.show(getSupportFragmentManager(), "errordialog"); 565 | } 566 | 567 | /* Called from ErrorDialogFragment when the dialog is dismissed. */ 568 | /* public void onDialogDismissed() { 569 | mResolvingError = false; 570 | } 571 | 572 | /* A fragment to display an error dialog */ 573 | /* public static class ErrorDialogFragment extends DialogFragment { 574 | public ErrorDialogFragment() { } 575 | 576 | @Override 577 | public Dialog onCreateDialog(Bundle savedInstanceState) { 578 | // Get the error code and retrieve the appropriate dialog 579 | int errorCode = this.getArguments().getInt(DIALOG_ERROR); 580 | return GoogleApiAvailability.getInstance().getErrorDialog( 581 | this.getActivity(), errorCode, REQUEST_RESOLVE_ERROR); 582 | } 583 | 584 | /* @Override 585 | public void onDismiss(DialogInterface dialog) 586 | { 587 | ((MyActivity) getActivity()).onDialogDismissed(); 588 | }*/ 589 | 590 | 591 | 592 | public class MapsActivity extends AppCompatActivity 593 | { 594 | Button driver,student; 595 | 596 | @Override 597 | protected void onCreate(@Nullable Bundle savedInstanceState) 598 | { 599 | super.onCreate(savedInstanceState); 600 | setContentView(R.layout.activity_maps); 601 | 602 | driver = findViewById(R.id.driver); 603 | student = findViewById(R.id.student); 604 | 605 | driver.setOnClickListener(new View.OnClickListener() 606 | { 607 | @Override 608 | public void onClick(View v) 609 | { 610 | Intent intent = new Intent(MapsActivity.this,driver_login.class); 611 | startActivity(intent); 612 | } 613 | }); 614 | 615 | student.setOnClickListener(new View.OnClickListener() 616 | { 617 | @Override 618 | public void onClick(View v) 619 | { 620 | Intent intent = new Intent(MapsActivity.this,student_tracklocation.class); 621 | startActivity(intent); 622 | } 623 | }); 624 | 625 | Toolbar toolbar = findViewById(R.id.toolbar); 626 | toolbar.setTitle("AKMap Bus Tracker"); 627 | toolbar.setTitleTextColor(getResources().getColor(R.color.white,getTheme())); 628 | setSupportActionBar(toolbar); 629 | 630 | getWindow().setStatusBarColor(getResources().getColor(R.color.darkblue2, this.getTheme())); 631 | // getWindow().setNavigationBarColor(getResources().getColor(R.color.yellow,this.getTheme())); 632 | } 633 | 634 | @Override 635 | public boolean onCreateOptionsMenu(Menu menu) 636 | { 637 | // Inflate the menu; this adds items to the action bar if it is present. 638 | getMenuInflater().inflate(R.menu.menu_withoutroute, menu); 639 | return true; 640 | } 641 | 642 | @Override 643 | public boolean onOptionsItemSelected(MenuItem item) 644 | { 645 | int id = item.getItemId(); 646 | 647 | if(id == R.id.share) 648 | { 649 | Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); 650 | sharingIntent.setType("text/plain"); 651 | String shareBody = "Here is the share content body"; 652 | sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject Here"); 653 | sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody); 654 | startActivity(Intent.createChooser(sharingIntent, "Share via")); 655 | } 656 | else 657 | { 658 | Intent intent = new Intent(MapsActivity.this,about.class); 659 | startActivity(intent); 660 | } 661 | 662 | return super.onOptionsItemSelected(item); 663 | } 664 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kkwbustracking/Splash_Screen.java: -------------------------------------------------------------------------------- 1 | package com.example.kkwbustracking; 2 | 3 | import android.content.Intent; 4 | import android.database.Cursor; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.view.WindowManager; 8 | import android.view.animation.Animation; 9 | import android.view.animation.AnimationUtils; 10 | import android.widget.ImageView; 11 | import android.widget.TextView; 12 | import android.widget.Toast; 13 | 14 | import androidx.appcompat.app.AppCompatActivity; 15 | 16 | public class Splash_Screen extends AppCompatActivity 17 | { 18 | private static int SPLASH_SCREEN = 2000; 19 | 20 | Animation topAnim,bottomAnim; 21 | ImageView imageView; 22 | TextView logo,slogan; 23 | DatabaseHelper databaseHelper; 24 | String name; 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) 28 | { 29 | super.onCreate(savedInstanceState); 30 | 31 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 32 | 33 | setContentView(R.layout.splash_screen); 34 | 35 | // topAnim = AnimationUtils.loadAnimation(this,R.anim.top_animation); 36 | // bottomAnim = AnimationUtils.loadAnimation(this,R.anim.bottom_animation); 37 | 38 | databaseHelper = new DatabaseHelper(this); 39 | 40 | Cursor res = databaseHelper.getData("1"); 41 | if(res.moveToFirst()) 42 | name = res.getString(1); 43 | 44 | imageView = findViewById(R.id.imageview); 45 | logo = findViewById(R.id.text); 46 | 47 | // imageView.setAnimation(topAnim); 48 | // logo.setAnimation(bottomAnim); 49 | 50 | new Handler().postDelayed(new Runnable() 51 | { 52 | @Override 53 | public void run() 54 | { 55 | if(name == null) 56 | { 57 | Intent intent = new Intent(Splash_Screen.this, MapsActivity.class); 58 | startActivity(intent); 59 | finish(); 60 | } 61 | else 62 | { 63 | Intent intent = new Intent(Splash_Screen.this, driver_tracklocation.class); 64 | startActivity(intent); 65 | finish(); 66 | } 67 | } 68 | },SPLASH_SCREEN); 69 | } 70 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kkwbustracking/about.java: -------------------------------------------------------------------------------- 1 | package com.example.kkwbustracking; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.drawable.ColorDrawable; 5 | import android.os.Bundle; 6 | import android.text.method.LinkMovementMethod; 7 | import android.widget.TextView; 8 | 9 | import androidx.annotation.Nullable; 10 | import androidx.appcompat.app.ActionBar; 11 | import androidx.appcompat.app.AppCompatActivity; 12 | import androidx.appcompat.widget.Toolbar; 13 | 14 | public class about extends AppCompatActivity 15 | { 16 | @Override 17 | protected void onCreate(@Nullable Bundle savedInstanceState) 18 | { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.about); 21 | 22 | /*ActionBar actionBar = getSupportActionBar(); 23 | 24 | actionBar.setTitle("About");*/ 25 | 26 | 27 | 28 | /*Toolbar toolbar = findViewById(R.id.action_bar); 29 | if (toolbar!= null) 30 | { 31 | toolbar.setTitle("About"); 32 | toolbar.setTitleTextColor(Color.BLACK); 33 | }*/ 34 | 35 | Toolbar toolbar = findViewById(R.id.toolbar); 36 | toolbar.setTitle("About"); 37 | toolbar.setTitleTextColor(getResources().getColor(R.color.white,getTheme())); 38 | setSupportActionBar(toolbar); 39 | 40 | TextView textView = (TextView) findViewById(R.id.my_website); 41 | textView.setMovementMethod(LinkMovementMethod.getInstance()); 42 | 43 | getWindow().setStatusBarColor(getResources().getColor(R.color.darkblue2, this.getTheme())); 44 | // getWindow().setNavigationBarColor(getResources().getColor(R.color.yellow,this.getTheme())); 45 | } 46 | // For back button on toolbar 47 | @Override 48 | public boolean onSupportNavigateUp() 49 | { 50 | onBackPressed(); 51 | return true; 52 | } 53 | 54 | } 55 | 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kkwbustracking/driver_login.java: -------------------------------------------------------------------------------- 1 | package com.example.kkwbustracking; 2 | 3 | import android.content.DialogInterface; 4 | import android.content.Intent; 5 | import android.database.Cursor; 6 | import android.graphics.Color; 7 | import android.graphics.drawable.ColorDrawable; 8 | import android.os.Bundle; 9 | import android.text.TextUtils; 10 | import android.view.Menu; 11 | import android.view.MenuItem; 12 | import android.view.View; 13 | import android.widget.Button; 14 | import android.widget.EditText; 15 | import android.widget.Toast; 16 | 17 | import androidx.annotation.Nullable; 18 | import androidx.appcompat.app.ActionBar; 19 | import androidx.appcompat.app.AlertDialog; 20 | import androidx.appcompat.app.AppCompatActivity; 21 | import androidx.appcompat.widget.Toolbar; 22 | 23 | import com.google.android.material.textfield.TextInputEditText; 24 | 25 | public class driver_login extends AppCompatActivity 26 | { 27 | EditText licence_no_edittext,name_edittext,phone_edittext,email_edittext; 28 | Button login; 29 | String licence_no,name,phone,email; 30 | DatabaseHelper databaseHelper; 31 | 32 | @Override 33 | protected void onCreate(@Nullable Bundle savedInstanceState) 34 | { 35 | super.onCreate(savedInstanceState); 36 | setContentView(R.layout.driver_login); 37 | 38 | licence_no_edittext = findViewById(R.id.licence_no); 39 | phone_edittext = findViewById(R.id.phone); 40 | name_edittext = findViewById(R.id.name); 41 | email_edittext = findViewById(R.id.email); 42 | 43 | login = findViewById(R.id.login); 44 | databaseHelper = new DatabaseHelper(this); 45 | 46 | login.setOnClickListener(new View.OnClickListener() 47 | { 48 | @Override 49 | public void onClick(View v) 50 | { 51 | Intent intent = new Intent(driver_login.this, driver_tracklocation.class); 52 | 53 | name = name_edittext.getText().toString(); 54 | phone = phone_edittext.getText().toString(); 55 | licence_no = licence_no_edittext.getText().toString(); 56 | email = email_edittext.getText().toString(); 57 | 58 | if(TextUtils.isEmpty(name)) 59 | name_edittext.setError("Name is Mandatory"); 60 | if(TextUtils.isEmpty(phone)) 61 | phone_edittext.setError("Phone No. is Mandatory"); 62 | if(TextUtils.isEmpty(licence_no)) 63 | licence_no_edittext.setError("Licence No. is Mandatory"); 64 | if(!(TextUtils.isEmpty(name) && TextUtils.isEmpty(phone) && TextUtils.isEmpty(licence_no))) 65 | { 66 | databaseHelper.insertData(name, phone, licence_no, email); // Insert data into SqLite Database 67 | 68 | // intent.putExtra("licence_no",licence_no); 69 | // intent.putExtra("name",name); 70 | // intent.putExtra("phone",phone); 71 | //intent.putExtra("email",email); 72 | 73 | startActivity(intent); 74 | } 75 | } 76 | }); 77 | 78 | Toolbar toolbar = findViewById(R.id.toolbar); 79 | toolbar.setTitle("Driver Register"); 80 | toolbar.setTitleTextColor(getResources().getColor(R.color.white,getTheme())); 81 | setSupportActionBar(toolbar); 82 | 83 | toolbar.setNavigationOnClickListener(new View.OnClickListener() 84 | { 85 | @Override 86 | public void onClick(View v) 87 | { 88 | // back button pressed 89 | onBackPressed(); 90 | } 91 | }); 92 | 93 | getWindow().setStatusBarColor(getResources().getColor(R.color.darkblue2, this.getTheme())); 94 | // getWindow().setNavigationBarColor(getResources().getColor(R.color.yellow,this.getTheme())); 95 | } 96 | 97 | @Override 98 | public boolean onCreateOptionsMenu(Menu menu) 99 | { 100 | // Inflate the menu; this adds items to the action bar if it is present. 101 | getMenuInflater().inflate(R.menu.menu_withoutroute, menu); 102 | return true; 103 | } 104 | 105 | @Override 106 | public boolean onOptionsItemSelected(MenuItem item) 107 | { 108 | int id = item.getItemId(); 109 | 110 | if(id == R.id.share) 111 | { 112 | Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); 113 | sharingIntent.setType("text/plain"); 114 | String shareBody = "Here is the share content body"; 115 | sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject Here"); 116 | sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody); 117 | startActivity(Intent.createChooser(sharingIntent, "Share via")); 118 | } 119 | else 120 | { 121 | Intent intent = new Intent(driver_login.this,about.class); 122 | startActivity(intent); 123 | } 124 | 125 | return super.onOptionsItemSelected(item); 126 | } 127 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kkwbustracking/driver_tracklocation.java: -------------------------------------------------------------------------------- 1 | package com.example.kkwbustracking; 2 | 3 | import android.Manifest; 4 | import android.app.Notification; 5 | import android.app.NotificationChannel; 6 | import android.app.NotificationManager; 7 | import android.app.PendingIntent; 8 | import android.content.Context; 9 | import android.content.DialogInterface; 10 | import android.content.Intent; 11 | import android.content.pm.PackageManager; 12 | import android.database.Cursor; 13 | import android.graphics.BitmapFactory; 14 | import android.location.Location; 15 | import android.os.Build; 16 | import android.os.Bundle; 17 | import android.os.Looper; 18 | import android.util.Log; 19 | import android.view.LayoutInflater; 20 | import android.view.Menu; 21 | import android.view.MenuItem; 22 | import android.view.View; 23 | import android.widget.RemoteViews; 24 | import android.widget.Toast; 25 | 26 | import androidx.annotation.NonNull; 27 | import androidx.appcompat.app.AlertDialog; 28 | import androidx.appcompat.app.AppCompatActivity; 29 | import androidx.appcompat.widget.Toolbar; 30 | import androidx.core.app.ActivityCompat; 31 | import androidx.core.app.NotificationCompat; 32 | import androidx.core.app.NotificationManagerCompat; 33 | import androidx.core.content.ContextCompat; 34 | 35 | import com.google.android.gms.location.FusedLocationProviderClient; 36 | import com.google.android.gms.location.LocationCallback; 37 | import com.google.android.gms.location.LocationRequest; 38 | import com.google.android.gms.location.LocationResult; 39 | import com.google.android.gms.location.LocationServices; 40 | import com.google.android.gms.maps.CameraUpdateFactory; 41 | import com.google.android.gms.maps.GoogleMap; 42 | import com.google.android.gms.maps.OnMapReadyCallback; 43 | import com.google.android.gms.maps.SupportMapFragment; 44 | import com.google.android.gms.maps.model.BitmapDescriptorFactory; 45 | import com.google.android.gms.maps.model.LatLng; 46 | import com.google.android.gms.maps.model.Marker; 47 | import com.google.android.gms.maps.model.MarkerOptions; 48 | import com.google.android.gms.tasks.OnCompleteListener; 49 | import com.google.android.gms.tasks.Task; 50 | import com.google.firebase.database.DatabaseReference; 51 | import com.google.firebase.database.FirebaseDatabase; 52 | 53 | import java.util.List; 54 | 55 | public class driver_tracklocation extends AppCompatActivity implements OnMapReadyCallback 56 | { 57 | GoogleMap mGoogleMap; 58 | SupportMapFragment mapFrag; 59 | LocationRequest mLocationRequest; 60 | Location mLastLocation; 61 | Marker mCurrLocationMarker; 62 | FusedLocationProviderClient mFusedLocationClient; 63 | FirebaseDatabase database; // used for store URLs of uploaded files 64 | String licence_no,email,phone,name; 65 | DatabaseHelper databaseHelper; 66 | Location location; 67 | 68 | int route=0; 69 | boolean route_selected = false; 70 | 71 | private final String CHANNEL_ID = "simple_notification"; 72 | private final int NOTIFICATION_ID = 01; 73 | 74 | @Override 75 | protected void onCreate(Bundle savedInstanceState) 76 | { 77 | super.onCreate(savedInstanceState); 78 | setContentView(R.layout.driver_tracklocation); 79 | 80 | database = FirebaseDatabase.getInstance(); // returns an object of firebase database 81 | 82 | databaseHelper = new DatabaseHelper(this); 83 | 84 | Toolbar toolbar = findViewById(R.id.toolbar); 85 | toolbar.setTitle("My Current Location"); 86 | toolbar.setTitleTextColor(getResources().getColor(R.color.white,getTheme())); 87 | setSupportActionBar(toolbar); 88 | 89 | getWindow().setStatusBarColor(getResources().getColor(R.color.darkblue2, this.getTheme())); 90 | // getWindow().setNavigationBarColor(getResources().getColor(R.color.yellow,this.getTheme())); 91 | 92 | 93 | 94 | // licence_no = getIntent().getStringExtra("licence_no"); 95 | // phone = getIntent().getStringExtra("phone"); 96 | // email = getIntent().getStringExtra("email"); 97 | // name = getIntent().getStringExtra("name"); 98 | 99 | route_dialog(); 100 | 101 | mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this); 102 | 103 | mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); 104 | assert mapFrag != null; 105 | mapFrag.getMapAsync(this); 106 | } 107 | 108 | @Override 109 | public boolean onCreateOptionsMenu(Menu menu) 110 | { 111 | // Inflate the menu; this adds items to the action bar if it is present. 112 | getMenuInflater().inflate(R.menu.menu, menu); 113 | return true; 114 | } 115 | 116 | @Override 117 | public boolean onOptionsItemSelected(MenuItem item) 118 | { 119 | int id = item.getItemId(); 120 | 121 | if (id == R.id.route) 122 | route_dialog(); 123 | else if(id == R.id.share) 124 | { 125 | Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); 126 | sharingIntent.setType("text/plain"); 127 | String shareBody = "Here is the share content body"; 128 | sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject Here"); 129 | sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody); 130 | startActivity(Intent.createChooser(sharingIntent, "Share via")); 131 | } 132 | else 133 | { 134 | Intent intent = new Intent(driver_tracklocation.this,about.class); 135 | startActivity(intent); 136 | } 137 | 138 | return super.onOptionsItemSelected(item); 139 | } 140 | 141 | public void route_dialog() 142 | { 143 | // setup the alert builder 144 | final AlertDialog.Builder builder1 = new AlertDialog.Builder(this); 145 | builder1.setTitle("Choose a Route"); 146 | 147 | builder1.setCancelable(false); 148 | 149 | // add a radio button list 150 | String[] routes = {"Jail Road (1)", "Pune Road (2)", "Cidco (3)","College Road (4)","Gangapur Road (5)"}; 151 | 152 | int checkedItem = route-1; 153 | 154 | builder1.setSingleChoiceItems(routes, checkedItem, new DialogInterface.OnClickListener() 155 | { 156 | @Override 157 | public void onClick(DialogInterface dialog, int which) 158 | { 159 | // user checked an item 160 | switch(which) 161 | { 162 | case 0: route = 1; break; 163 | case 1: route = 2; break; 164 | case 2: route = 3; break; 165 | case 3: route = 4; break; 166 | case 4: route = 5; break; 167 | } 168 | } 169 | }); 170 | // add OK and Cancel buttons 171 | builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() 172 | { 173 | @Override 174 | public void onClick(DialogInterface dialog, int which) 175 | { 176 | // user clicked OK 177 | 178 | route_selected = true; 179 | 180 | Cursor res = databaseHelper.getData("1"); 181 | if(res.moveToFirst()) 182 | { 183 | name = res.getString(1); 184 | phone = res.getString(2); 185 | licence_no = res.getString(3); 186 | email = res.getString(4); 187 | } 188 | 189 | } 190 | }); 191 | builder1.setNegativeButton("Cancel", null); 192 | // create and show the alert dialog 193 | final AlertDialog dialog1 = builder1.create(); 194 | dialog1.show(); 195 | } 196 | 197 | @Override 198 | public void onPause() 199 | { 200 | super.onPause(); 201 | 202 | //stop location updates when Activity is no longer active 203 | // if (mFusedLocationClient != null) 204 | // { 205 | // mFusedLocationClient.removeLocationUpdates(mLocationCallback); 206 | // } 207 | } 208 | 209 | @Override 210 | protected void onStop() 211 | { 212 | super.onStop(); 213 | } 214 | 215 | @Override 216 | public void onMapReady(GoogleMap googleMap) 217 | { 218 | mGoogleMap = googleMap; 219 | mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 220 | 221 | mLocationRequest = new LocationRequest(); 222 | mLocationRequest.setInterval(10); 223 | mLocationRequest.setFastestInterval(10); 224 | mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 225 | 226 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) 227 | { 228 | //Location Permission already granted 229 | mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper()); 230 | mGoogleMap.setMyLocationEnabled(true); 231 | } 232 | else 233 | { 234 | //Request Location Permission 235 | checkLocationPermission(); 236 | } 237 | } 238 | 239 | LocationCallback mLocationCallback = new LocationCallback() 240 | { 241 | @Override 242 | public void onLocationResult(LocationResult locationResult) 243 | { 244 | List locationList = locationResult.getLocations(); 245 | if (locationList.size() > 0) 246 | { 247 | //The last location in the list is the newest 248 | location = locationList.get(locationList.size() - 1); 249 | Log.i("MapsActivity", "Location: " + location.getLatitude() + " " + location.getLongitude()); 250 | mLastLocation = location; 251 | if (mCurrLocationMarker != null) 252 | { 253 | mCurrLocationMarker.remove(); 254 | } 255 | 256 | //Place current location marker 257 | 258 | if(route_selected) 259 | { 260 | Toast.makeText(driver_tracklocation.this, "Location Sent : " + location.getLatitude() + " " + location.getLongitude(), Toast.LENGTH_LONG).show(); 261 | 262 | final DatabaseReference reference = database.getReference(); //return the path to the root 263 | 264 | reference.child(route + "").child("Latitude").setValue(location.getLatitude()).addOnCompleteListener(new OnCompleteListener() 265 | { 266 | @Override 267 | public void onComplete(@NonNull Task task) 268 | { 269 | if (task.isSuccessful()) 270 | { 271 | reference.child(route + "").child("Longitude").setValue(location.getLongitude()); 272 | reference.child(route + "").child("Name").setValue(name); 273 | reference.child(route + "").child("Phone").setValue(phone); 274 | reference.child(route + "").child("Licence_no").setValue(licence_no); 275 | reference.child(route + "").child("Email").setValue(email); 276 | } 277 | } 278 | }); 279 | } 280 | 281 | 282 | 283 | LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); 284 | MarkerOptions markerOptions = new MarkerOptions(); 285 | markerOptions.position(latLng); 286 | markerOptions.title("Current Position"); 287 | markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); 288 | 289 | DisplayNotification(); 290 | 291 | mCurrLocationMarker = mGoogleMap.addMarker(markerOptions); 292 | 293 | //move map camera 294 | mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18)); 295 | } 296 | } 297 | }; 298 | 299 | public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; 300 | private void checkLocationPermission() 301 | { 302 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) 303 | { 304 | // Should we show an explanation? 305 | if (ActivityCompat.shouldShowRequestPermissionRationale(this, 306 | Manifest.permission.ACCESS_FINE_LOCATION)) 307 | { 308 | // Show an explanation to the user *asynchronously* -- don't block 309 | // this thread waiting for the user's response! After the user 310 | // sees the explanation, try again to request the permission. 311 | new AlertDialog.Builder(this) 312 | .setTitle("Location Permission Needed") 313 | .setMessage("This app needs the Location permission, please accept to use location functionality") 314 | .setPositiveButton("OK", new DialogInterface.OnClickListener() 315 | { 316 | @Override 317 | public void onClick(DialogInterface dialogInterface, int i) 318 | { 319 | //Prompt the user once explanation has been shown 320 | ActivityCompat.requestPermissions(driver_tracklocation.this, 321 | new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 322 | MY_PERMISSIONS_REQUEST_LOCATION ); 323 | } 324 | }) 325 | .create() 326 | .show(); 327 | } 328 | else 329 | { 330 | // No explanation needed, we can request the permission. 331 | ActivityCompat.requestPermissions(this, 332 | new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 333 | MY_PERMISSIONS_REQUEST_LOCATION ); 334 | } 335 | } 336 | } 337 | 338 | @Override 339 | public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) 340 | { 341 | if (requestCode == MY_PERMISSIONS_REQUEST_LOCATION) 342 | {// If request is cancelled, the result arrays are empty. 343 | if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) 344 | { 345 | // permission was granted, yay! Do the 346 | // location-related task you need to do. 347 | if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) 348 | { 349 | mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper()); 350 | mGoogleMap.setMyLocationEnabled(true); 351 | } 352 | 353 | } 354 | else 355 | { 356 | // permission denied, boo! Disable the 357 | // functionality that depends on this permission. 358 | Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show(); 359 | } 360 | 361 | // other 'case' lines to check for other 362 | // permissions this app might request 363 | } 364 | } 365 | 366 | public void DisplayNotification() 367 | { 368 | Toast.makeText(this, "Atharva", Toast.LENGTH_SHORT).show(); 369 | 370 | createNotificationChannel(); 371 | NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID); 372 | builder.setSmallIcon(R.drawable.location); 373 | builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.phone)); 374 | builder.setContentTitle("Sharing Driver Location"); 375 | builder.setContentText(location.getLatitude()+" , "+location.getLongitude()); 376 | builder.setOngoing(true); 377 | builder.setPriority(NotificationCompat.PRIORITY_DEFAULT); 378 | NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(getApplicationContext()); 379 | notificationManagerCompat.notify(NOTIFICATION_ID, builder.build()); 380 | } 381 | 382 | //create notification channel if you target android 8.0 or higher version 383 | private void createNotificationChannel() 384 | { 385 | if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) 386 | { 387 | CharSequence name = "Simple Notification"; 388 | String description = "Include all the simple notification"; 389 | int importance = NotificationManager.IMPORTANCE_DEFAULT; 390 | 391 | NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID,name,importance); 392 | notificationChannel.setDescription(description); 393 | 394 | NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 395 | notificationManager.createNotificationChannel(notificationChannel); 396 | } 397 | } 398 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kkwbustracking/student_tracklocation.java: -------------------------------------------------------------------------------- 1 | package com.example.kkwbustracking; 2 | 3 | import android.Manifest; 4 | import android.content.DialogInterface; 5 | import android.content.Intent; 6 | import android.content.pm.PackageManager; 7 | import android.content.res.Resources; 8 | import android.graphics.Color; 9 | import android.location.Location; 10 | import android.net.Uri; 11 | import android.os.Bundle; 12 | import android.os.Looper; 13 | import android.text.Html; 14 | import android.util.Log; 15 | import android.view.LayoutInflater; 16 | import android.view.Menu; 17 | import android.view.MenuItem; 18 | import android.view.View; 19 | import android.widget.Button; 20 | import android.widget.ImageButton; 21 | import android.widget.TextView; 22 | import android.widget.Toast; 23 | 24 | import androidx.annotation.NonNull; 25 | import androidx.annotation.Nullable; 26 | import androidx.appcompat.app.AlertDialog; 27 | import androidx.appcompat.app.AppCompatActivity; 28 | import androidx.appcompat.widget.Toolbar; 29 | import androidx.core.app.ActivityCompat; 30 | import androidx.core.content.ContextCompat; 31 | 32 | import com.directions.route.AbstractRouting; 33 | import com.directions.route.Route; 34 | import com.directions.route.RouteException; 35 | import com.directions.route.Routing; 36 | import com.directions.route.RoutingListener; 37 | import com.google.android.gms.location.FusedLocationProviderClient; 38 | import com.google.android.gms.location.LocationCallback; 39 | import com.google.android.gms.location.LocationRequest; 40 | import com.google.android.gms.location.LocationResult; 41 | import com.google.android.gms.location.LocationServices; 42 | import com.google.android.gms.maps.CameraUpdate; 43 | import com.google.android.gms.maps.CameraUpdateFactory; 44 | import com.google.android.gms.maps.GoogleMap; 45 | import com.google.android.gms.maps.OnMapReadyCallback; 46 | import com.google.android.gms.maps.SupportMapFragment; 47 | import com.google.android.gms.maps.model.BitmapDescriptorFactory; 48 | import com.google.android.gms.maps.model.LatLng; 49 | import com.google.android.gms.maps.model.Marker; 50 | import com.google.android.gms.maps.model.MarkerOptions; 51 | import com.google.android.gms.maps.model.Polyline; 52 | import com.google.android.gms.maps.model.PolylineOptions; 53 | import com.google.android.gms.tasks.OnCompleteListener; 54 | import com.google.android.gms.tasks.Task; 55 | import com.google.android.material.floatingactionbutton.FloatingActionButton; 56 | import com.google.firebase.database.ChildEventListener; 57 | import com.google.firebase.database.DataSnapshot; 58 | import com.google.firebase.database.DatabaseError; 59 | import com.google.firebase.database.DatabaseReference; 60 | import com.google.firebase.database.FirebaseDatabase; 61 | 62 | import java.util.ArrayList; 63 | import java.util.List; 64 | 65 | public class student_tracklocation extends AppCompatActivity implements OnMapReadyCallback, RoutingListener { 66 | GoogleMap mGoogleMap; 67 | SupportMapFragment mapFrag; 68 | LocationRequest mLocationRequest; 69 | Location mLastLocation; 70 | Marker mCurrLocationMarker; 71 | FusedLocationProviderClient mFusedLocationClient; 72 | FirebaseDatabase database; // used for store URLs of uploaded files 73 | String licence_no = "Atharva2204"; 74 | int route = 0; 75 | double latitude, longitude; 76 | FloatingActionButton floatingActionButton; 77 | TextView name, phone, email, licence; 78 | String name1, phone1, email1, licence1; 79 | Button call; 80 | 81 | @Override 82 | protected void onCreate(Bundle savedInstanceState) { 83 | super.onCreate(savedInstanceState); 84 | setContentView(R.layout.student_tracklocation); 85 | 86 | database = FirebaseDatabase.getInstance(); // returns an object of firebase database 87 | 88 | //licence_no = getIntent().getStringExtra("licence_no"); 89 | 90 | final AlertDialog.Builder builder = new AlertDialog.Builder(this); 91 | builder.setCancelable(true); 92 | 93 | final AlertDialog alertDialog = builder.create(); 94 | 95 | LayoutInflater inflater = getLayoutInflater(); 96 | View dialoglayout = inflater.inflate(R.layout.driver_details_dialog, null); 97 | 98 | alertDialog.setView(dialoglayout); 99 | 100 | // Button no = dialoglayout.findViewById(R.id.close); 101 | 102 | floatingActionButton = findViewById(R.id.driver_details); 103 | name = dialoglayout.findViewById(R.id.name); 104 | phone = dialoglayout.findViewById(R.id.phone_no); 105 | email = dialoglayout.findViewById(R.id.email); 106 | licence = dialoglayout.findViewById(R.id.licence_no); 107 | call = dialoglayout.findViewById(R.id.call); 108 | 109 | call.setOnClickListener(new View.OnClickListener() 110 | { 111 | @Override 112 | public void onClick(View v) 113 | { 114 | String phone = phone1.substring(phone1.indexOf(':')+1); 115 | 116 | // Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone)); 117 | 118 | //Intent intent = new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phone, null)); 119 | 120 | // Intent intent = new Intent(Intent.ACTION_CALL); 121 | // intent.setData(Uri.parse("tel:"+phone.trim())); 122 | 123 | Intent callIntent = new Intent(Intent.ACTION_DIAL); 124 | callIntent.setData(Uri.parse("tel:"+Uri.encode(phone.trim()))); 125 | callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 126 | 127 | try 128 | { 129 | startActivity(callIntent); 130 | } 131 | catch(android.content.ActivityNotFoundException ex) 132 | { 133 | Toast.makeText(student_tracklocation.this, "Could not find an activity to place the call.", Toast.LENGTH_SHORT).show(); 134 | } 135 | 136 | 137 | /* if (ActivityCompat.checkSelfPermission(student_tracklocation.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) 138 | { 139 | // TODO: Consider calling ActivityCompat#requestPermissions 140 | // here to request the missing permissions, and then overriding 141 | // public void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults) 142 | // to handle the case where the user grants the permission. See the documentation 143 | // for ActivityCompat#requestPermissions for more details. 144 | return; 145 | }*/ 146 | // startActivity(intent); 147 | } 148 | }); 149 | 150 | Toolbar toolbar = findViewById(R.id.toolbar); 151 | toolbar.setTitle("Tracking Bus Location"); 152 | toolbar.setTitleTextColor(getResources().getColor(R.color.white,getTheme())); 153 | setSupportActionBar(toolbar); 154 | 155 | getWindow().setStatusBarColor(getResources().getColor(R.color.darkblue2, this.getTheme())); 156 | // getWindow().setNavigationBarColor(getResources().getColor(R.color.yellow,this.getTheme())); 157 | 158 | /*no.setOnClickListener(new View.OnClickListener() 159 | { 160 | @Override 161 | public void onClick(View v) 162 | { 163 | alertDialog.dismiss(); 164 | } 165 | });*/ 166 | 167 | floatingActionButton.setOnClickListener(new View.OnClickListener() 168 | { 169 | @Override 170 | public void onClick(View v) 171 | { 172 | DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child(route + "");//reference inside Uploads 173 | 174 | databaseReference.addChildEventListener(new ChildEventListener() 175 | { 176 | @Override 177 | public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) 178 | { 179 | String latlong = dataSnapshot.getKey(); 180 | 181 | if (latlong.contentEquals("Name")) 182 | name1 = dataSnapshot.getValue(String.class); 183 | if (latlong.contentEquals("Phone")) 184 | phone1 = dataSnapshot.getValue(String.class); 185 | if (latlong.contentEquals("Email")) 186 | email1 = dataSnapshot.getValue(String.class); 187 | if (latlong.contentEquals("Licence_no")) 188 | licence1 = dataSnapshot.getValue(String.class); 189 | 190 | name.setText("Name : "+name1); 191 | phone.setText("Phone No. : "+phone1); 192 | email.setText("Email : "+email1); 193 | licence.setText("Licence No. : "+licence1); 194 | } 195 | 196 | @Override 197 | public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) 198 | { 199 | } 200 | 201 | @Override 202 | public void onChildRemoved(@NonNull DataSnapshot snapshot) { 203 | 204 | } 205 | 206 | @Override 207 | public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) { 208 | 209 | } 210 | 211 | @Override 212 | public void onCancelled(@NonNull DatabaseError error) { 213 | 214 | } 215 | }); 216 | 217 | alertDialog.show(); 218 | } 219 | }); 220 | 221 | route_dialog(); 222 | 223 | mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this); 224 | 225 | mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); 226 | assert mapFrag != null; 227 | mapFrag.getMapAsync(this); 228 | } 229 | 230 | @Override 231 | public boolean onCreateOptionsMenu(Menu menu) 232 | { 233 | // Inflate the menu; this adds items to the action bar if it is present. 234 | getMenuInflater().inflate(R.menu.menu, menu); 235 | return true; 236 | } 237 | 238 | @Override 239 | public boolean onOptionsItemSelected(MenuItem item) 240 | { 241 | int id = item.getItemId(); 242 | 243 | if (id == R.id.route) 244 | route_dialog(); 245 | else if(id == R.id.share) 246 | { 247 | Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); 248 | sharingIntent.setType("text/plain"); 249 | String shareBody = "Here is the share content body"; 250 | sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject Here"); 251 | sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody); 252 | startActivity(Intent.createChooser(sharingIntent, "Share via")); 253 | } 254 | else 255 | { 256 | Intent intent = new Intent(student_tracklocation.this,about.class); 257 | startActivity(intent); 258 | } 259 | 260 | return super.onOptionsItemSelected(item); 261 | } 262 | 263 | public void route_dialog() 264 | { 265 | // setup the alert builder 266 | final AlertDialog.Builder builder1 = new AlertDialog.Builder(this); 267 | builder1.setTitle("Choose a Route"); 268 | 269 | builder1.setCancelable(false); 270 | 271 | // add a radio button list 272 | String[] routes = {"Jail Road (1)", "Pune Road (2)", "Cidco (3)","College Road (4)","Gangapur Road (5)"}; 273 | 274 | int checkedItem = route-1; 275 | 276 | builder1.setSingleChoiceItems(routes, checkedItem, new DialogInterface.OnClickListener() 277 | { 278 | @Override 279 | public void onClick(DialogInterface dialog, int which) 280 | { 281 | // user checked an item 282 | switch(which) 283 | { 284 | case 0: route = 1; break; 285 | case 1: route = 2; break; 286 | case 2: route = 3; break; 287 | case 3: route = 4; break; 288 | case 4: route = 5; break; 289 | } 290 | } 291 | }); 292 | // add OK and Cancel buttons 293 | builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() 294 | { 295 | @Override 296 | public void onClick(DialogInterface dialog, int which) 297 | { 298 | // user clicked OK 299 | 300 | // year_textInputEditText.setText(year); 301 | 302 | onMapReady(mGoogleMap); 303 | } 304 | }); 305 | builder1.setNegativeButton("Cancel", null); 306 | // create and show the alert dialog 307 | final AlertDialog dialog1 = builder1.create(); 308 | dialog1.show(); 309 | } 310 | 311 | @Override 312 | public void onPause() 313 | { 314 | super.onPause(); 315 | 316 | // stop location updates when Activity is no longer active 317 | if (mFusedLocationClient != null) 318 | { 319 | mFusedLocationClient.removeLocationUpdates(mLocationCallback); 320 | } 321 | } 322 | 323 | @Override 324 | public void onMapReady(GoogleMap googleMap) 325 | { 326 | mGoogleMap = googleMap; 327 | mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 328 | 329 | mLocationRequest = new LocationRequest(); 330 | mLocationRequest.setInterval(120000); // two minute interval 331 | mLocationRequest.setFastestInterval(120000); 332 | mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 333 | 334 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) 335 | { 336 | //Location Permission already granted 337 | mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper()); 338 | mGoogleMap.setMyLocationEnabled(true); 339 | } 340 | else 341 | { 342 | //Request Location Permission 343 | checkLocationPermission(); 344 | } 345 | } 346 | 347 | LocationCallback mLocationCallback = new LocationCallback() 348 | { 349 | @Override 350 | public void onLocationResult(LocationResult locationResult) 351 | { 352 | List locationList = locationResult.getLocations(); 353 | if (locationList.size() > 0) 354 | { 355 | //The last location in the list is the newest 356 | final Location location = locationList.get(locationList.size() - 1); 357 | Log.i("student_tracklocation", "Location: " + location.getLatitude() + " " + location.getLongitude()); 358 | mLastLocation = location; 359 | if (mCurrLocationMarker != null) 360 | { 361 | mCurrLocationMarker.remove(); 362 | } 363 | 364 | /* Polyline line1 = mGoogleMap.addPolyline(new PolylineOptions() 365 | .add(new LatLng(19.9958193, 73.7518029), new LatLng(20.7, 74.7518029)) 366 | .width(5) 367 | .color(0xFFFF0000)); //non transparent red*/ 368 | 369 | 370 | 371 | //Place current location marker 372 | 373 | DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child(route + "");//reference inside Uploads 374 | 375 | databaseReference.addChildEventListener(new ChildEventListener() 376 | { 377 | @Override 378 | public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) 379 | { 380 | String latlong = dataSnapshot.getKey(); 381 | 382 | if (latlong.contentEquals("Latitude")) 383 | latitude = dataSnapshot.getValue(Double.class); 384 | if (latlong.contentEquals("Longitude")) 385 | longitude = dataSnapshot.getValue(Double.class); 386 | 387 | LatLng latLng = new LatLng(latitude, longitude); 388 | MarkerOptions markerOptions = new MarkerOptions(); 389 | markerOptions.position(latLng); 390 | markerOptions.title("Current Position"); 391 | markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); 392 | 393 | // markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_marker)); 394 | 395 | mCurrLocationMarker = mGoogleMap.addMarker(markerOptions); 396 | 397 | //move map camera 398 | mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18)); 399 | } 400 | 401 | @Override 402 | public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) 403 | { 404 | String latlong = snapshot.getKey(); 405 | 406 | if (latlong.contentEquals("Latitude")) 407 | latitude = snapshot.getValue(Double.class); 408 | if (latlong.contentEquals("Longitude")) 409 | longitude = snapshot.getValue(Double.class); 410 | 411 | 412 | Polyline line2 = mGoogleMap.addPolyline(new PolylineOptions() 413 | .add(new LatLng(20.013173, 73.820034), new LatLng(latitude, longitude)) 414 | .width(10) 415 | .color(0x7F0000FF)); //semi-transparent blue 416 | 417 | 418 | LatLng latLng = new LatLng(latitude, longitude); 419 | MarkerOptions markerOptions = new MarkerOptions(); 420 | markerOptions.position(latLng); 421 | markerOptions.title("Current Position"); 422 | markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); 423 | 424 | // markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.)) 425 | 426 | mCurrLocationMarker = mGoogleMap.addMarker(markerOptions); 427 | 428 | //move map camera 429 | mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18)); 430 | } 431 | 432 | @Override 433 | public void onChildRemoved(@NonNull DataSnapshot snapshot) { 434 | 435 | } 436 | 437 | @Override 438 | public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) { 439 | 440 | } 441 | 442 | @Override 443 | public void onCancelled(@NonNull DatabaseError error) { 444 | 445 | } 446 | }); 447 | } 448 | } 449 | }; 450 | 451 | public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; 452 | private void checkLocationPermission() 453 | { 454 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) 455 | { 456 | // Should we show an explanation? 457 | if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) 458 | { 459 | // Show an explanation to the user *asynchronously* -- don't block 460 | // this thread waiting for the user's response! After the user 461 | // sees the explanation, try again to request the permission. 462 | new AlertDialog.Builder(this) 463 | .setTitle("Location Permission Needed") 464 | .setMessage("This app needs the Location permission, please accept to use location functionality") 465 | .setPositiveButton("OK", new DialogInterface.OnClickListener() 466 | { 467 | @Override 468 | public void onClick(DialogInterface dialogInterface, int i) 469 | { 470 | //Prompt the user once explanation has been shown 471 | ActivityCompat.requestPermissions(student_tracklocation.this, 472 | new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 473 | MY_PERMISSIONS_REQUEST_LOCATION); 474 | } 475 | }) 476 | .create() 477 | .show(); 478 | } 479 | else 480 | { 481 | // No explanation needed, we can request the permission. 482 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 483 | MY_PERMISSIONS_REQUEST_LOCATION ); 484 | } 485 | } 486 | } 487 | 488 | @Override 489 | public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) 490 | { 491 | if (requestCode == MY_PERMISSIONS_REQUEST_LOCATION) 492 | {// If request is cancelled, the result arrays are empty. 493 | if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) 494 | { 495 | // permission was granted, yay! Do the location-related task you need to do. 496 | if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) 497 | { 498 | // mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper()); 499 | mGoogleMap.setMyLocationEnabled(true); 500 | } 501 | 502 | } 503 | else 504 | { 505 | // permission denied, boo! Disable the functionality that depends on this permission. 506 | Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show(); 507 | } 508 | 509 | // other 'case' lines to check for other permissions this app might request 510 | } 511 | } 512 | 513 | /* @Override 514 | public boolean onMarkerClick(Marker marker) 515 | { 516 | Routing routing = new Routing.Builder() 517 | .travelMode(AbstractRouting.TravelMode.DRIVING) 518 | .withListener(student_tracklocation.this) 519 | .waypoints(new LatLng(latitude, longitude), marker.getPosition()) 520 | .key("AIzaSyDGvkmJ6osdJz7v8OSg7U") 521 | .build(); 522 | routing.execute(); 523 | return false; 524 | }*/ 525 | 526 | @Override 527 | public void onRoutingFailure(RouteException e) { 528 | Log.e("check", e.getMessage()); 529 | } 530 | 531 | @Override 532 | public void onRoutingStart() { 533 | Log.e("check", "onRoutingStart"); 534 | } 535 | 536 | @Override 537 | public void onRoutingSuccess(ArrayList route, int shortestRouteIndex) 538 | { 539 | 540 | Log.e("check", "onRoutingSuccess"); 541 | CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(latitude,longitude)); 542 | CameraUpdate zoom = CameraUpdateFactory.zoomTo(16); 543 | List polylines = new ArrayList<>(); 544 | 545 | mGoogleMap.moveCamera(center); 546 | 547 | if (polylines.size() > 0) 548 | { 549 | for (Polyline poly : polylines) 550 | { 551 | poly.remove(); 552 | } 553 | } 554 | 555 | polylines = new ArrayList<>(); 556 | //add route(s) to the map. 557 | for (int i = 0; i < route.size(); i++) 558 | { 559 | //In case of more than 5 alternative routes 560 | 561 | PolylineOptions polyOptions = new PolylineOptions(); 562 | polyOptions.color(getResources().getColor(R.color.blue,getTheme())); 563 | polyOptions.width(10 + i * 3); 564 | polyOptions.addAll(route.get(i).getPoints()); 565 | Polyline polyline = mGoogleMap.addPolyline(polyOptions); 566 | polylines.add(polyline); 567 | } 568 | } 569 | 570 | @Override 571 | public void onRoutingCancelled() { 572 | Log.e("check", "onRoutingCancelled"); 573 | } 574 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/bus_and_girl.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KulkarniAtharva/Bus_Tracking-Android/fc7919c3155eb2aa45cd78dd309466b404b62780/app/src/main/res/drawable-v24/bus_and_girl.jpeg -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/bus_marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KulkarniAtharva/Bus_Tracking-Android/fc7919c3155eb2aa45cd78dd309466b404b62780/app/src/main/res/drawable-v24/bus_marker.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/bus_tracking_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KulkarniAtharva/Bus_Tracking-Android/fc7919c3155eb2aa45cd78dd309466b404b62780/app/src/main/res/drawable-v24/bus_tracking_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KulkarniAtharva/Bus_Tracking-Android/fc7919c3155eb2aa45cd78dd309466b404b62780/app/src/main/res/drawable-v24/logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/splash_screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KulkarniAtharva/Bus_Tracking-Android/fc7919c3155eb2aa45cd78dd309466b404b62780/app/src/main/res/drawable-v24/splash_screen.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/tic_tac_toe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KulkarniAtharva/Bus_Tracking-Android/fc7919c3155eb2aa45cd78dd309466b404b62780/app/src/main/res/drawable-v24/tic_tac_toe.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/tracking_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KulkarniAtharva/Bus_Tracking-Android/fc7919c3155eb2aa45cd78dd309466b404b62780/app/src/main/res/drawable-v24/tracking_app.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/call_button_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/confirmation_number.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/details.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/driver.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/edit_location.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/edittext_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/email.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/globe.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/location.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/phone.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/text_fields.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/about.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 19 | 20 | 28 | 29 | 35 | 36 | 41 | 42 | 47 | 48 | 56 | 57 | 63 | 64 | 69 | 70 | 77 | 78 | 86 | 87 | 88 | 89 | 90 | 91 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_maps.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 17 | 18 | 26 | 27 | 32 | 33 | 39 | 40 |