├── .gitignore ├── .idea ├── assetWizardSettings.xml ├── caches │ └── build_file_checksums.ser ├── gradle.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── hora │ │ └── priyank │ │ └── trackingapp │ │ └── ExampleInstrumentedTest.java │ ├── debug │ └── res │ │ └── values │ │ └── google_maps_api.xml │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ │ └── com │ │ │ └── hora │ │ │ └── priyank │ │ │ └── trackingapp │ │ │ ├── data │ │ │ ├── FirebaseQueryLiveData.java │ │ │ ├── dao │ │ │ │ ├── Message.java │ │ │ │ ├── MyFragmentListenerImpl.java │ │ │ │ └── UserInterface.java │ │ │ └── model │ │ │ │ ├── Event.java │ │ │ │ └── User.java │ │ │ ├── init │ │ │ ├── TrackingApp.java │ │ │ └── UserSession.java │ │ │ ├── ui │ │ │ ├── activity │ │ │ │ ├── ChildrenActivity.java │ │ │ │ ├── DefaultActivity.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── SplashScreen.java │ │ │ │ └── TrackingActivity.java │ │ │ ├── adapter │ │ │ │ ├── EventAdapter.java │ │ │ │ └── TrackingChildrenAdapter.java │ │ │ ├── fragment │ │ │ │ ├── ChildTrackingFragment.java │ │ │ │ ├── EventListFragment.java │ │ │ │ ├── Login.java │ │ │ │ ├── NewChildFragment.java │ │ │ │ ├── NewPostFragment.java │ │ │ │ └── Signup.java │ │ │ └── viewmodel │ │ │ │ ├── ChildTrackViewModel.java │ │ │ │ └── EventListViewModel.java │ │ │ └── util │ │ │ ├── DateComparator.java │ │ │ ├── Utility.java │ │ │ └── Validation.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── bottom_color_nav.xml │ │ ├── ic_accessibility_black_24dp.xml │ │ ├── ic_delete_black_24dp.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_login_black_24dp.xml │ │ ├── ic_signin_black_24dp.xml │ │ ├── pencil_button.png │ │ └── placeholder.png │ │ ├── layout │ │ ├── activity_children.xml │ │ ├── activity_main.xml │ │ ├── activity_spash_screen.xml │ │ ├── activity_tracking.xml │ │ ├── child_track_fragment.xml │ │ ├── fragment_login.xml │ │ ├── fragment_signup.xml │ │ ├── message_item.xml │ │ ├── message_list_fragment.xml │ │ ├── new_child_fragment.xml │ │ ├── new_post_fragment.xml │ │ └── tracking_children.xml │ │ ├── menu │ │ ├── bottom_navigation.xml │ │ └── menu_main.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── reset.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── release │ └── res │ │ └── values │ │ └── google_maps_api.xml │ └── test │ └── java │ └── com │ └── hora │ └── priyank │ └── trackingapp │ └── ExampleUnitTest.java ├── build.gradle ├── build_version.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshot ├── eventCapture.jpeg ├── events.jpeg ├── login.jpeg ├── mapView.jpeg └── signup.jpeg └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /.idea/assetWizardSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 140 | 141 | -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/priyankjain28/trackingApp/42ba14a8f1b42a0c45eed390aec930cf56689d56/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Parent Child Tracker - MVVM, Firebase, Databinding, Google Map 2 | A prototype application for child safety that will work in dual modes - Parent and Child. 3 | Parent mode will display his child’s locations and Child mode will automatically track his geolocations and send them to associated parent . 4 | 5 | ## Features 6 | * User able to create a parent account/child account and log in. 7 | * When logged in, a parent account can see a list of his children and add more. 8 | * Parent account can select any of his connected child 9 | * When logged in, a user can see a list of places (or locations) he visited and checked in, also he should be able to CRUD them. 10 | * A checking-in place have a name (typed by user), a place category (i.e. ‘home’ / ‘work’ / ‘food’ etc, selected from a multiple choice list) a date and geolocation coordinates (automatically calculated by the app). 11 | 12 | ## Technical Feature 13 | This repository contains a tracking app that implements MVVM architecture using Databinding, Firebase Database, LiveData, Google Maps, Glide 14 | 15 | ## The app has following packages: 16 | * data: It contains all the data accessing and manipulating components. 17 | * ui: View classes along with their corresponding ViewModel. 18 | * init: Initialize instances and maintain user session 19 | * util: Utility classes. 20 | 21 | ##### Classes have been designed in such a way that it could be inherited and maximize the code reuse. 22 | 23 | ## Library Reference: 24 | * JetPack Architecture 25 | * Firebase 26 | * Google Maps 27 | * Glide 28 | 29 | ## Special Feature 30 | * Splash Screen - Handled User Session 31 | * Login/Signup - Used TextInputLayout to more interactive also handled validation 32 | * Parent Screen - Used Map to locate each and every child added, add child, display added child with last login and also you can delete child. 33 | * Child Screen - Add event, used static map Api to display the given location with the help of Glide, Card view to make more interactive, click on card view to update the existing event 34 | * Logout - Logout with the user session 35 | 36 | 37 | ## Screenshot 38 | ![alt text][login] ![alt text][signup] 39 | ![alt text][eventCapture] ![alt text][childTrack] 40 | 41 | [login]: https://github.com/priyankjain28/trackingApp/blob/master/screenshot/login.jpeg "Login Screen" 42 | [Signup]: https://github.com/priyankjain28/trackingApp/blob/master/screenshot/signup.jpeg "Signup Screen" 43 | [eventCapture]: https://github.com/priyankjain28/trackingApp/blob/master/screenshot/events.jpeg "Event Screen" 44 | [childTrack]: https://github.com/priyankjain28/trackingApp/blob/master/screenshot/mapView.jpeg "Child Tracker" 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "com.hora.priyank.trackingapp" 7 | minSdkVersion 16 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | dataBinding { 14 | enabled = true 15 | } 16 | compileOptions { 17 | targetCompatibility 1.8 18 | sourceCompatibility 1.8 19 | } 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | implementation pri.support.appcompat 31 | implementation pri.support.design 32 | implementation pri.support.cardview 33 | implementation pri.support.recyclerview 34 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 35 | 36 | //Lifecycle 37 | implementation "android.arch.lifecycle:extensions:1.1.1" 38 | annotationProcessor "android.arch.lifecycle:compiler:1.1.1" 39 | 40 | //Firebase 41 | implementation 'com.google.firebase:firebase-core:16.0.1' 42 | implementation 'com.google.firebase:firebase-database:16.0.1' 43 | implementation 'com.google.firebase:firebase-config:11.8.0' 44 | 45 | 46 | implementation("com.github.bumptech.glide:glide:4.8.0@aar") { 47 | transitive = true 48 | } 49 | // Glide v4 uses this new annotation processor -- see https://bumptech.github.io/glide/doc/generatedapi.html 50 | annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0' 51 | /* //Glide 52 | 53 | implementation 'com.github.bumptech.glide:glide:4.8.0' 54 | annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'*/ 55 | 56 | //Google Map 57 | implementation 'com.google.android.gms:play-services-maps:15.0.1' 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | apply plugin: 'com.google.gms.google-services' 63 | -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "435838678423", 4 | "firebase_url": "https://horatest-8710c.firebaseio.com", 5 | "project_id": "horatest-8710c", 6 | "storage_bucket": "horatest-8710c.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:435838678423:android:a3e8b2c8d17a107e", 12 | "android_client_info": { 13 | "package_name": "com.hora.priyank.trackingapp" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "435838678423-iq2e57r2bb8ikq9r546jsg85jr8jfd77.apps.googleusercontent.com", 19 | "client_type": 3 20 | } 21 | ], 22 | "api_key": [ 23 | { 24 | "current_key": "AIzaSyCx1PMx8rFxmagYnDXYHh07gradEvETbc4" 25 | } 26 | ], 27 | "services": { 28 | "analytics_service": { 29 | "status": 1 30 | }, 31 | "appinvite_service": { 32 | "status": 1, 33 | "other_platform_oauth_client": [] 34 | }, 35 | "ads_service": { 36 | "status": 2 37 | } 38 | } 39 | } 40 | ], 41 | "configuration_version": "1" 42 | } -------------------------------------------------------------------------------- /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 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/hora/priyank/trackingapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.hora.priyank.trackingapp", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/debug/res/values/google_maps_api.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | AIzaSyCnxb2V5k2RBzNVGThF4sChpcxXceJT8Kk 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 22 | 25 | 26 | 27 | 35 | 38 | 39 | 43 | 44 | 45 | 48 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/priyankjain28/trackingApp/42ba14a8f1b42a0c45eed390aec930cf56689d56/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/data/FirebaseQueryLiveData.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.data; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.os.Handler; 5 | import android.util.Log; 6 | 7 | import com.google.firebase.database.DataSnapshot; 8 | import com.google.firebase.database.DatabaseError; 9 | import com.google.firebase.database.DatabaseReference; 10 | import com.google.firebase.database.Query; 11 | import com.google.firebase.database.ValueEventListener; 12 | 13 | 14 | public class FirebaseQueryLiveData extends LiveData { 15 | private static final String LOG_TAG = "FirebaseQueryLiveData"; 16 | 17 | private final Query query; 18 | private final ValueEventListener valueListener = new mValueEventListener(); 19 | 20 | private boolean listenerRemovePending = false; 21 | private final Handler handler = new Handler(); 22 | private final Runnable removeListener = new Runnable() { 23 | @Override 24 | public void run() { 25 | query.removeEventListener(valueListener); 26 | listenerRemovePending = false; 27 | } 28 | }; 29 | 30 | public FirebaseQueryLiveData(Query query) { 31 | this.query = query; 32 | } 33 | 34 | public FirebaseQueryLiveData(DatabaseReference dbReference){ 35 | this.query = dbReference; 36 | } 37 | 38 | @Override 39 | protected void onActive() { 40 | if (listenerRemovePending) { 41 | handler.removeCallbacks(removeListener); 42 | } 43 | else { 44 | query.addValueEventListener(valueListener); 45 | } 46 | listenerRemovePending = false; 47 | } 48 | 49 | @Override 50 | protected void onInactive() { 51 | // Listener removal is schedule on a two second delay 52 | 53 | handler.postDelayed(removeListener, 2000); 54 | listenerRemovePending = true; 55 | } 56 | 57 | 58 | private class mValueEventListener implements ValueEventListener { 59 | 60 | @Override 61 | public void onDataChange(DataSnapshot dataSnapshot) { 62 | setValue(dataSnapshot); 63 | } 64 | 65 | @Override 66 | public void onCancelled(DatabaseError databaseError) { 67 | Log.e(LOG_TAG, "Cannot listen to query " + query, databaseError.toException()); 68 | } 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/data/dao/Message.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.data.dao; 2 | 3 | 4 | public interface Message { 5 | 6 | public String getTitle(); 7 | 8 | public void setTitle(String title); 9 | 10 | public String getUserName(); 11 | 12 | public void setUserName(String name); 13 | 14 | public String getType(); 15 | 16 | public void setType(String type); 17 | 18 | public Double getLat(); 19 | 20 | public void setLat(Double lat); 21 | 22 | public Double getLon(); 23 | 24 | public void setLon(Double lon); 25 | 26 | public String getCreateDate(); 27 | 28 | public void setCreateDate(String createDate); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/data/dao/MyFragmentListenerImpl.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.data.dao; 2 | 3 | public interface MyFragmentListenerImpl { 4 | void onFabButtonClicked(); 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/data/dao/UserInterface.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.data.dao; 2 | 3 | /** 4 | * Created by Priyank Jain on 30-09-2018. 5 | */ 6 | public interface UserInterface { 7 | public String getFirstName(); 8 | 9 | public void setFirstName(String firstName); 10 | 11 | public String getLastName(); 12 | 13 | public void setLastName(String lastName); 14 | 15 | public String getEmail(); 16 | 17 | public void setEmail(String email); 18 | 19 | public String getUserRole(); 20 | 21 | public void setUserRole(String userRole); 22 | 23 | public String getDateCreated(); 24 | 25 | public void setDateCreated(String dateCreated); 26 | 27 | public String getLastUpdate(); 28 | 29 | public void setLastUpdate(String lasteUpdate); 30 | 31 | public String getPassword(); 32 | 33 | public void setPassword(String password); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/data/model/Event.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.data.model; 2 | 3 | import com.hora.priyank.trackingapp.data.dao.Message; 4 | 5 | /** 6 | * Created by Priyank Jain on 27-09-2018. 7 | */ 8 | public class Event implements Message { 9 | private String userName; 10 | private String title; 11 | private String type; 12 | private Double lat; 13 | private Double lon; 14 | private String createDate; 15 | 16 | public Event() { 17 | } 18 | 19 | public Event(String username, String title, String type, Double lat, Double lon, String createDate) { 20 | this.userName = username; 21 | this.title = title; 22 | this.type = type; 23 | this.lat = lat; 24 | this.lon = lon; 25 | this.createDate = createDate; 26 | } 27 | 28 | public String getTitle() { 29 | return title; 30 | } 31 | 32 | public void setTitle(String title) { 33 | this.title = title; 34 | } 35 | 36 | @Override 37 | public String getUserName() { 38 | return userName; 39 | } 40 | 41 | @Override 42 | public void setUserName(String userName) { 43 | this.userName = userName; 44 | } 45 | 46 | public String getType() { 47 | return type; 48 | } 49 | 50 | public void setType(String type) { 51 | this.type = type; 52 | } 53 | 54 | public Double getLat() { 55 | return lat; 56 | } 57 | 58 | public void setLat(Double lat) { 59 | this.lat = lat; 60 | } 61 | 62 | public Double getLon() { 63 | return lon; 64 | } 65 | 66 | public void setLon(Double lon) { 67 | this.lon = lon; 68 | } 69 | 70 | public String getCreateDate() { 71 | return createDate; 72 | } 73 | 74 | public void setCreateDate(String createDate) { 75 | this.createDate = createDate; 76 | } 77 | 78 | @Override 79 | public String toString() { 80 | return "Event{" + 81 | "username='" + userName + '\'' + 82 | ", title='" + title + '\'' + 83 | ", type='" + type + '\'' + 84 | ", lat=" + lat + 85 | ", lon=" + lon + 86 | ", createDate='" + createDate + '\'' + 87 | '}'; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/data/model/User.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.data.model; 2 | 3 | import com.hora.priyank.trackingapp.data.dao.UserInterface; 4 | 5 | /** 6 | * Created by Priyank Jain on 27-09-2018. 7 | */ 8 | public class User implements UserInterface{ 9 | private String firstName; 10 | private String lastName; 11 | private String email; 12 | private String password; 13 | private String userRole; 14 | private String dateCreated; 15 | private String lastUpdate; 16 | 17 | public User() { 18 | } 19 | 20 | public User(String firstName, String lastName, String email, String password, String userRole, String dateCreated,String lastUpdate) { 21 | this.firstName = firstName; 22 | this.lastName = lastName; 23 | this.email = email; 24 | this.password = password; 25 | this.userRole = userRole; 26 | this.dateCreated = dateCreated; 27 | this.lastUpdate = lastUpdate; 28 | } 29 | 30 | public String getFirstName() { 31 | return firstName; 32 | } 33 | 34 | public void setFirstName(String firstName) { 35 | this.firstName = firstName; 36 | } 37 | 38 | public String getLastName() { 39 | return lastName; 40 | } 41 | 42 | public void setLastName(String lastName) { 43 | this.lastName = lastName; 44 | } 45 | 46 | public String getEmail() { 47 | return email; 48 | } 49 | 50 | public void setEmail(String email) { 51 | this.email = email; 52 | } 53 | 54 | public String getUserRole() { 55 | return userRole; 56 | } 57 | 58 | public void setUserRole(String userRole) { 59 | this.userRole = userRole; 60 | } 61 | 62 | public String getDateCreated() { 63 | return dateCreated; 64 | } 65 | 66 | public void setDateCreated(String dateCreated) { 67 | this.dateCreated = dateCreated; 68 | } 69 | 70 | public String getPassword() { 71 | return password; 72 | } 73 | 74 | public void setPassword(String password) { 75 | this.password = password; 76 | } 77 | 78 | public String getLastUpdate() { 79 | return lastUpdate; 80 | } 81 | 82 | public void setLastUpdate(String lastUpdate) { 83 | this.lastUpdate = lastUpdate; 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | return "User{" + 89 | "firstName='" + firstName + '\'' + 90 | ", lastName='" + lastName + '\'' + 91 | ", email='" + email + '\'' + 92 | ", password='" + password + '\'' + 93 | ", userRole='" + userRole + '\'' + 94 | ", dateCreated='" + dateCreated + '\'' + 95 | ", lastUpdate='" + lastUpdate + '\'' + 96 | '}'; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/init/TrackingApp.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.init; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.content.res.Configuration; 6 | 7 | import com.google.firebase.FirebaseApp; 8 | import com.google.firebase.database.FirebaseDatabase; 9 | 10 | 11 | public class TrackingApp extends Application { 12 | private static Context APP_CONTEXT=null; 13 | @Override 14 | public void onCreate() { 15 | super.onCreate(); 16 | TrackingApp.APP_CONTEXT = getApplicationContext(); 17 | if (!FirebaseApp.getApps(this).isEmpty()) { 18 | FirebaseDatabase.getInstance().setPersistenceEnabled(true); 19 | } 20 | } 21 | public static Context getAppContext() { 22 | return APP_CONTEXT; 23 | } 24 | 25 | @Override 26 | public void onConfigurationChanged(Configuration newConfig) { 27 | super.onConfigurationChanged(newConfig); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/init/UserSession.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.init; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.content.SharedPreferences; 6 | import android.content.SharedPreferences.Editor; 7 | 8 | import com.hora.priyank.trackingapp.ui.activity.MainActivity; 9 | import com.hora.priyank.trackingapp.util.Utility; 10 | 11 | import java.util.HashMap; 12 | 13 | public class UserSession { 14 | // Shared Preferences reference 15 | SharedPreferences pref; 16 | 17 | // Editor reference for Shared preferences 18 | Editor editor; 19 | 20 | // Context 21 | Context _context; 22 | 23 | // Shared preferences mode 24 | int PRIVATE_MODE = 0; 25 | 26 | // Shared preferences file name 27 | public static final String PREFER_NAME = Utility.TRACKING_APP; 28 | 29 | // All Shared Preferences Keys 30 | public static final String IS_USER_LOGIN = "IsUserLoggedIn"; 31 | 32 | // User name (make variable public to access from outside) 33 | public static final String KEY_NAME = "Name"; 34 | 35 | // Email address (make variable public to access from outside) 36 | public static final String KEY_EMAIL = "Email"; 37 | 38 | // password 39 | public static final String KEY_PASSWORD = "txtPassword"; 40 | 41 | public static final String KEY_USER_ROLE = "userRole"; 42 | 43 | 44 | // Constructor 45 | public UserSession(Context context) { 46 | this._context = context; 47 | pref = _context.getSharedPreferences(PREFER_NAME, PRIVATE_MODE); 48 | editor = pref.edit(); 49 | } 50 | 51 | //Create login session 52 | public void createUserLoginSession(String email, String uPassword, String uRole, String name) { 53 | // Storing login value as TRUE 54 | editor.putBoolean(IS_USER_LOGIN, true); 55 | 56 | // Storing username in preferences 57 | editor.putString(KEY_EMAIL, email); 58 | 59 | // Storing password in preferences 60 | editor.putString(KEY_PASSWORD, uPassword); 61 | 62 | // Storing role in preferences 63 | editor.putString(KEY_USER_ROLE, uRole); 64 | 65 | // Storing name in preferences 66 | editor.putString(KEY_NAME, name); 67 | 68 | // commit changes 69 | editor.commit(); 70 | } 71 | 72 | /** 73 | * Check login method will check user login status 74 | * If false it will redirect user to login page 75 | * Else do anything 76 | */ 77 | public boolean checkLogin() { 78 | // Check login status 79 | if (!this.isUserLoggedIn()) { 80 | 81 | // user is not logged in redirect him to Login Activity 82 | Intent i = new Intent(_context, MainActivity.class); 83 | 84 | // Closing all the Activities from stack 85 | i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 86 | 87 | // Add new Flag to start new Activity 88 | i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 89 | 90 | 91 | 92 | // Staring Login Activity 93 | _context.startActivity(i); 94 | 95 | return true; 96 | } 97 | return false; 98 | } 99 | 100 | 101 | /** 102 | * Get stored session data 103 | */ 104 | public HashMap getUserDetails() { 105 | 106 | //Use hashmap to store user credentials 107 | HashMap user = new HashMap(); 108 | 109 | // user name 110 | user.put(KEY_NAME, pref.getString(KEY_NAME, null)); 111 | 112 | // user email id 113 | user.put(KEY_EMAIL, pref.getString(KEY_EMAIL, null)); 114 | 115 | // user user role 116 | user.put(KEY_USER_ROLE, pref.getString(KEY_USER_ROLE, null)); 117 | // return user 118 | return user; 119 | } 120 | 121 | /** 122 | * Clear session details 123 | */ 124 | public void logoutUser() { 125 | 126 | // Clearing all user data from Shared Preferences 127 | editor.clear(); 128 | editor.commit(); 129 | 130 | // After logout redirect user to MainActivity 131 | Intent i = new Intent(_context, MainActivity.class); 132 | 133 | // Closing all the Activities 134 | i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 135 | 136 | // Add new Flag to start new Activity 137 | i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 138 | // Staring Login Activity 139 | _context.startActivity(i); 140 | } 141 | 142 | 143 | // Check for login 144 | public boolean isUserLoggedIn() { 145 | return pref.getBoolean(IS_USER_LOGIN, false); 146 | } 147 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/activity/ChildrenActivity.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.activity; 2 | 3 | import android.Manifest; 4 | import android.content.pm.PackageManager; 5 | import android.os.Bundle; 6 | import android.support.v4.app.ActivityCompat; 7 | 8 | import com.hora.priyank.trackingapp.R; 9 | import com.hora.priyank.trackingapp.data.dao.MyFragmentListenerImpl; 10 | import com.hora.priyank.trackingapp.ui.fragment.NewPostFragment; 11 | import com.hora.priyank.trackingapp.util.Utility; 12 | 13 | public class ChildrenActivity extends DefaultActivity implements MyFragmentListenerImpl { 14 | 15 | private final NewPostFragment mComposerFragment = new NewPostFragment(); 16 | private String username; 17 | private String TAG="ChildrenActivity"; 18 | Bundle bundle; 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_children); 24 | username = getIntent().getStringExtra(Utility.KEY_USER_NAME); 25 | if (getSupportActionBar() != null) getSupportActionBar().setTitle("Events Track"); 26 | } 27 | 28 | @Override 29 | public void onFabButtonClicked() { 30 | initializeBundleVariable(); 31 | newEvent(); 32 | checkLocationPermission(); 33 | } 34 | 35 | private void initializeBundleVariable() { 36 | bundle = new Bundle(); 37 | bundle.putString(Utility.KEY_USER_NAME, username); 38 | bundle.putString(Utility.KEY_NAME,getName()); 39 | } 40 | 41 | private void newEvent(){ 42 | bundle.putString(Utility.KEY_TRANSACTION,"new"); 43 | bundle.putString(Utility.KEY_TRANSACTION_TIME,String.valueOf(System.currentTimeMillis())); 44 | } 45 | 46 | public String getUserName(){ 47 | return username; 48 | }; 49 | public String getName(){ 50 | return getIntent().getStringExtra(Utility.KEY_NAME); 51 | }; 52 | 53 | 54 | //region Call New Post with Permission Check 55 | public void checkLocationPermission() { 56 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 57 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1); 58 | return; 59 | } else { 60 | mComposerFragment.setArguments(bundle); 61 | callNewPostFragment(); 62 | } 63 | } 64 | 65 | public void callNewPostFragment() { 66 | getSupportFragmentManager().beginTransaction() 67 | .replace(R.id.fragment_container, mComposerFragment) 68 | .addToBackStack(null) 69 | .commit(); 70 | } 71 | 72 | public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 73 | switch (requestCode) { 74 | case 1: { 75 | if (grantResults.length > 0 76 | && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 77 | callNewPostFragment(); 78 | } else { 79 | checkLocationPermission(); 80 | } 81 | return; 82 | } 83 | } 84 | } 85 | //endregion 86 | 87 | public void updateEvent(String createDate) { 88 | initializeBundleVariable(); 89 | bundle.putString(Utility.KEY_TRANSACTION,"update"); 90 | bundle.putString(Utility.KEY_TRANSACTION_TIME,createDate); 91 | mComposerFragment.setArguments(bundle); 92 | callNewPostFragment(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/activity/DefaultActivity.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.activity; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.view.Menu; 5 | import android.view.MenuInflater; 6 | import android.view.MenuItem; 7 | 8 | import com.hora.priyank.trackingapp.R; 9 | import com.hora.priyank.trackingapp.init.UserSession; 10 | 11 | /** 12 | * Created by Priyank Jain on 03-10-2018. 13 | */ 14 | public class DefaultActivity extends AppCompatActivity { 15 | private boolean doubleBackToExitPressedOnce = false; 16 | @Override 17 | public boolean onCreateOptionsMenu(Menu menu) { 18 | MenuInflater inflater = getMenuInflater(); 19 | inflater.inflate(R.menu.menu_main, menu); 20 | return super.onCreateOptionsMenu(menu); 21 | } 22 | 23 | @Override 24 | public boolean onOptionsItemSelected(MenuItem item) { 25 | int id = item.getItemId(); 26 | if (id == R.id.action_logout) { 27 | new UserSession(getApplicationContext()).logoutUser(); 28 | return true; 29 | } 30 | return super.onOptionsItemSelected(item); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.design.widget.BottomNavigationView; 6 | import android.support.v4.app.Fragment; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.view.MenuItem; 9 | 10 | import com.hora.priyank.trackingapp.R; 11 | import com.hora.priyank.trackingapp.ui.fragment.Login; 12 | import com.hora.priyank.trackingapp.ui.fragment.Signup; 13 | 14 | public class MainActivity extends AppCompatActivity { 15 | 16 | BottomNavigationView bottomNav; 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_main); 22 | bottomNav = (BottomNavigationView) findViewById(R.id.bottom_navigation); 23 | bottomNav.setOnNavigationItemSelectedListener(navListener); 24 | if (savedInstanceState == null) { 25 | getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, 26 | new Login()).commit(); 27 | } 28 | } 29 | 30 | 31 | private BottomNavigationView.OnNavigationItemSelectedListener navListener = 32 | new BottomNavigationView.OnNavigationItemSelectedListener() { 33 | @Override 34 | public boolean onNavigationItemSelected(@NonNull MenuItem item) { 35 | Fragment selectedFragment = null; 36 | 37 | switch (item.getItemId()) { 38 | case R.id.nav_login: 39 | selectedFragment = new Login(); 40 | break; 41 | case R.id.nav_signup: 42 | selectedFragment = new Signup(); 43 | break; 44 | } 45 | 46 | getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, 47 | selectedFragment).addToBackStack(null).commit(); 48 | 49 | return true; 50 | } 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/activity/SplashScreen.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.content.SharedPreferences; 6 | import android.os.Bundle; 7 | import android.os.Handler; 8 | import android.support.v7.app.AppCompatActivity; 9 | 10 | import com.hora.priyank.trackingapp.R; 11 | import com.hora.priyank.trackingapp.init.UserSession; 12 | import com.hora.priyank.trackingapp.util.Utility; 13 | 14 | import java.util.HashMap; 15 | 16 | public class SplashScreen extends AppCompatActivity { 17 | 18 | // Splash screen timer 19 | private static int SPLASH_TIME_OUT = 3000; 20 | private UserSession session; 21 | private SharedPreferences sharedPreferences; 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_spash_screen); 26 | 27 | // User Session Manager 28 | session = new UserSession(getApplicationContext()); 29 | sharedPreferences = getSharedPreferences(Utility.TRACKING_APP, Context.MODE_PRIVATE); 30 | new Handler().postDelayed(new Runnable() { 31 | 32 | /* 33 | * Showing splash screen with a timer. This will be useful when you 34 | * want to show case your app logo / company 35 | */ 36 | 37 | @Override 38 | public void run() { 39 | // This method will be executed once the timer is over 40 | // Start your app main activity 41 | Intent i = new Intent(SplashScreen.this, MainActivity.class); 42 | if(!session.checkLogin()){ 43 | HashMap userDetail = session.getUserDetails(); 44 | if(userDetail.get(UserSession.KEY_USER_ROLE).equals(Utility.CHILD_CONSTANT)) 45 | i=new Intent(SplashScreen.this,ChildrenActivity.class); 46 | else 47 | i=new Intent(SplashScreen.this,TrackingActivity.class); 48 | 49 | i.putExtra(Utility.KEY_USER_NAME, userDetail.get(UserSession.KEY_EMAIL)); 50 | i.putExtra(Utility.KEY_NAME, userDetail.get(UserSession.KEY_NAME)); 51 | } 52 | startActivity(i); 53 | 54 | // close this activity 55 | finish(); 56 | } 57 | }, SPLASH_TIME_OUT); 58 | } 59 | 60 | } 61 | 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/activity/TrackingActivity.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.activity; 2 | 3 | import android.os.Bundle; 4 | 5 | import com.hora.priyank.trackingapp.R; 6 | import com.hora.priyank.trackingapp.data.dao.MyFragmentListenerImpl; 7 | import com.hora.priyank.trackingapp.ui.fragment.NewChildFragment; 8 | import com.hora.priyank.trackingapp.util.Utility; 9 | 10 | 11 | public class TrackingActivity extends DefaultActivity implements MyFragmentListenerImpl { 12 | 13 | private final NewChildFragment mComposerFragment = new NewChildFragment(); 14 | 15 | private String username; 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_tracking); 21 | username = getIntent().getStringExtra(Utility.KEY_USER_NAME); 22 | if (getSupportActionBar() != null) getSupportActionBar().setTitle("Child Track"); 23 | } 24 | 25 | @Override 26 | public void onFabButtonClicked() { 27 | Bundle bundle = new Bundle(); 28 | bundle.putString(Utility.KEY_USER_NAME, username); 29 | bundle.putString(Utility.KEY_NAME,getName()); 30 | mComposerFragment.setArguments(bundle); 31 | getSupportFragmentManager().beginTransaction() 32 | .replace(R.id.fragment_tracking, mComposerFragment) 33 | .addToBackStack(null) 34 | .commit(); 35 | } 36 | 37 | public String getUserName() { 38 | return username; 39 | } 40 | 41 | public String getName(){ 42 | return getIntent().getStringExtra(Utility.KEY_NAME); 43 | } 44 | 45 | @Override 46 | public void onBackPressed() { 47 | if (getFragmentManager().getBackStackEntryCount() > 0) { 48 | getFragmentManager().popBackStack(); 49 | } 50 | super.onBackPressed(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/adapter/EventAdapter.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.adapter; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.databinding.DataBindingUtil; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | import com.bumptech.glide.Glide; 12 | import com.hora.priyank.trackingapp.R; 13 | import com.hora.priyank.trackingapp.data.model.Event; 14 | import com.hora.priyank.trackingapp.databinding.MessageItemBinding; 15 | import com.hora.priyank.trackingapp.ui.activity.ChildrenActivity; 16 | 17 | import java.util.List; 18 | 19 | 20 | 21 | public class EventAdapter extends RecyclerView.Adapter { 22 | //region Variable Declaration 23 | private List mEventList; 24 | private Context mContext; 25 | private Activity activity; 26 | public EventAdapter(Context mContext, Activity activity) { 27 | this.mContext = mContext; 28 | this.activity = activity; 29 | } 30 | //endregion 31 | 32 | //region Set Message List Data 33 | public void setMessageList(final List mEventList){ 34 | this.mEventList = mEventList; 35 | notifyDataSetChanged(); 36 | } 37 | //endregion 38 | 39 | //region Create View Holder 40 | @Override 41 | public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 42 | MessageItemBinding binding = DataBindingUtil 43 | .inflate(LayoutInflater.from(parent.getContext()), 44 | R.layout.message_item, 45 | parent, 46 | false); 47 | 48 | return new MessageViewHolder(binding); 49 | } 50 | //endregion 51 | 52 | //region Bind View Holder 53 | @Override 54 | public void onBindViewHolder(MessageViewHolder holder, int position) { 55 | Event event = mEventList.get(position); 56 | 57 | holder.binding.setMessage(mEventList.get(position)); 58 | holder.binding.title.setText(event.getTitle()); 59 | holder.binding.type.setText(event.getType()); 60 | String url = "http://maps.google.com/maps/api/staticmap?center=" + 61 | event.getLat() + 62 | "," + 63 | event.getLon() + 64 | "&zoom=20&size=900x400&sensor=false" + 65 | "&markers=color:red|" + 66 | event.getLat() + 67 | "," + 68 | event.getLon() + 69 | "&key="+mContext.getResources().getString(R.string.google_maps_key); 70 | 71 | Glide.with(mContext) 72 | .load(url) 73 | .into(holder.binding.mapView); 74 | 75 | holder.binding.dateTime.setText(event.getCreateDate()); 76 | holder.binding.eventLayout.setOnClickListener(new View.OnClickListener() { 77 | @Override 78 | public void onClick(View view) { 79 | ((ChildrenActivity) activity).updateEvent(event.getCreateDate()); 80 | } 81 | }); 82 | holder.binding.executePendingBindings(); 83 | } 84 | @Override 85 | public int getItemCount() { 86 | return mEventList == null ? 0 : mEventList.size(); 87 | } 88 | //endregion 89 | 90 | //region View Holder Class 91 | class MessageViewHolder extends RecyclerView.ViewHolder { 92 | 93 | private final MessageItemBinding binding; 94 | 95 | public MessageViewHolder(MessageItemBinding binding) { 96 | super(binding.getRoot()); 97 | this.binding = binding; 98 | } 99 | } 100 | //endregion 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/adapter/TrackingChildrenAdapter.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.adapter; 2 | 3 | import android.databinding.DataBindingUtil; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import com.hora.priyank.trackingapp.R; 10 | import com.hora.priyank.trackingapp.data.model.User; 11 | import com.hora.priyank.trackingapp.databinding.TrackingChildrenBinding; 12 | import com.hora.priyank.trackingapp.ui.fragment.ChildTrackingFragment; 13 | import com.hora.priyank.trackingapp.util.Utility; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | /** 19 | * Created by Priyank Jain on 28-09-2018. 20 | */ 21 | public class TrackingChildrenAdapter extends RecyclerView.Adapter { 22 | //region Vairable Declaration 23 | private List mUserList; 24 | private String parentEmail; 25 | private ChildTrackingFragment childTrackingFragment; 26 | public TrackingChildrenAdapter(ChildTrackingFragment childTrackingFragment) { 27 | this.childTrackingFragment = childTrackingFragment; 28 | } 29 | //endregion 30 | 31 | //region Set User List Data 32 | public void setUserList(final List mUserList, String parentEmail){ 33 | this.mUserList = mUserList; 34 | this.parentEmail = parentEmail; 35 | notifyDataSetChanged(); 36 | } 37 | //endregion 38 | 39 | //region Create View Holder 40 | @Override 41 | public TrackingChildrenAdapter.MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 42 | TrackingChildrenBinding binding = DataBindingUtil 43 | .inflate(LayoutInflater.from(parent.getContext()), 44 | R.layout.tracking_children, 45 | parent, 46 | false); 47 | 48 | return new MessageViewHolder(binding); 49 | } 50 | //endregion 51 | 52 | //region Bind View Holder 53 | @Override 54 | public void onBindViewHolder(TrackingChildrenAdapter.MessageViewHolder holder, int position) { 55 | holder.binding.setUser(mUserList.get(position)); 56 | holder.binding.childrenName.setText(mUserList.get(position).getFirstName()); 57 | holder.binding.lastUpdate.setText(Utility.dateTimeCoversion(mUserList.get(position).getLastUpdate())+""); 58 | holder.binding.deleteChild.setOnClickListener(new View.OnClickListener() { 59 | @Override 60 | public void onClick(View view) { 61 | childTrackingFragment.deleteRecord(parentEmail,mUserList.get(position).getEmail(),position); 62 | } 63 | }); 64 | holder.binding.childrenNameRelative.setOnClickListener(new View.OnClickListener() { 65 | @Override 66 | public void onClick(View view) { 67 | List uList = new ArrayList(); 68 | uList.add(mUserList.get(position)); 69 | childTrackingFragment.markChildrenOnMapView(uList); 70 | } 71 | }); 72 | holder.binding.executePendingBindings(); 73 | } 74 | 75 | @Override 76 | public int getItemCount() { 77 | return mUserList == null ? 0 : mUserList.size(); 78 | } 79 | //endregion 80 | 81 | //region Message View Holder Class 82 | class MessageViewHolder extends RecyclerView.ViewHolder { 83 | 84 | private final TrackingChildrenBinding binding; 85 | 86 | public MessageViewHolder(TrackingChildrenBinding binding) { 87 | super(binding.getRoot()); 88 | this.binding = binding; 89 | } 90 | } 91 | //endregion 92 | } 93 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/fragment/ChildTrackingFragment.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.fragment; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.arch.lifecycle.ViewModelProviders; 5 | import android.content.Context; 6 | import android.content.DialogInterface; 7 | import android.databinding.DataBindingUtil; 8 | import android.location.Location; 9 | import android.os.Bundle; 10 | import android.support.annotation.Nullable; 11 | import android.support.v4.app.Fragment; 12 | import android.support.v7.app.AlertDialog; 13 | import android.support.v7.widget.LinearLayoutManager; 14 | import android.text.Html; 15 | import android.util.Log; 16 | import android.view.LayoutInflater; 17 | import android.view.View; 18 | import android.view.ViewGroup; 19 | 20 | import com.google.android.gms.maps.CameraUpdateFactory; 21 | import com.google.android.gms.maps.GoogleMap; 22 | import com.google.android.gms.maps.OnMapReadyCallback; 23 | import com.google.android.gms.maps.SupportMapFragment; 24 | import com.google.android.gms.maps.model.BitmapDescriptorFactory; 25 | import com.google.android.gms.maps.model.LatLng; 26 | import com.google.android.gms.maps.model.LatLngBounds; 27 | import com.google.android.gms.maps.model.Marker; 28 | import com.google.android.gms.maps.model.MarkerOptions; 29 | import com.google.firebase.FirebaseApp; 30 | import com.hora.priyank.trackingapp.R; 31 | import com.hora.priyank.trackingapp.data.dao.MyFragmentListenerImpl; 32 | import com.hora.priyank.trackingapp.data.model.Event; 33 | import com.hora.priyank.trackingapp.data.model.User; 34 | import com.hora.priyank.trackingapp.databinding.ChildTrackFragmentBinding; 35 | import com.hora.priyank.trackingapp.ui.activity.TrackingActivity; 36 | import com.hora.priyank.trackingapp.ui.adapter.TrackingChildrenAdapter; 37 | import com.hora.priyank.trackingapp.ui.viewmodel.ChildTrackViewModel; 38 | import com.hora.priyank.trackingapp.ui.viewmodel.EventListViewModel; 39 | import com.hora.priyank.trackingapp.util.DateComparator; 40 | import com.hora.priyank.trackingapp.util.Utility; 41 | 42 | import java.util.ArrayList; 43 | import java.util.Collections; 44 | import java.util.HashMap; 45 | import java.util.List; 46 | import java.util.Random; 47 | import java.util.Set; 48 | 49 | /** 50 | * Created by Priyank Jain on 29-09-2018. 51 | */ 52 | public class ChildTrackingFragment extends Fragment implements OnMapReadyCallback { 53 | 54 | //region Variable declaration 55 | private static final String TAG = "ChildTrackingFragment"; 56 | private ChildTrackFragmentBinding mBinding; 57 | private ChildTrackViewModel childTrackViewModel; 58 | private MyFragmentListenerImpl mFragmentCallback; 59 | private SupportMapFragment mapFragment; 60 | private EventListViewModel eventModel; 61 | private GoogleMap mMap; 62 | private TrackingChildrenAdapter mTrackingChildrenAdapter; 63 | private TrackingActivity trackingActivity; 64 | private List latLngs; 65 | private int counter = 0; 66 | private HashMap userHashMap = new HashMap(); 67 | private LatLngBounds.Builder builder = new LatLngBounds.Builder(); 68 | //endregion 69 | 70 | //region Fragment Lifecycle component 71 | @Override 72 | public void onCreate(Bundle savedInstanceState) { 73 | super.onCreate(savedInstanceState); 74 | mTrackingChildrenAdapter = new TrackingChildrenAdapter(ChildTrackingFragment.this); 75 | childTrackViewModel = ViewModelProviders.of(getActivity()).get(ChildTrackViewModel.class); 76 | eventModel = ViewModelProviders.of(getActivity()).get(EventListViewModel.class); 77 | FirebaseApp.initializeApp(getActivity()); 78 | } 79 | 80 | @Nullable 81 | @Override 82 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 83 | @Nullable Bundle savedInstanceState) { 84 | mBinding = DataBindingUtil.inflate(inflater, R.layout.child_track_fragment, container, false); 85 | intializingView(); 86 | return mBinding.getRoot(); 87 | } 88 | 89 | @Override 90 | public void onAttach(Context context) { 91 | super.onAttach(context); 92 | trackingActivity = (TrackingActivity) context; 93 | try { 94 | mFragmentCallback = (MyFragmentListenerImpl) context; 95 | } catch (ClassCastException e) { 96 | throw new ClassCastException(context.toString() 97 | + " must implement OnHeadlineSelectedListener"); 98 | } 99 | } 100 | 101 | 102 | @Override 103 | public void onActivityCreated(@Nullable Bundle savedInstanceState) { 104 | super.onActivityCreated(savedInstanceState); 105 | mBinding.recyclerviewChild.setAdapter(mTrackingChildrenAdapter); 106 | setupDataAndMapView(); 107 | } 108 | 109 | @Override 110 | public void onResume() { 111 | super.onResume(); 112 | Log.d(TAG, "Peeru onResume"); 113 | } 114 | 115 | @Override 116 | public void onPause() { 117 | Log.d(TAG, "Peeru onPause"); 118 | super.onPause(); 119 | } 120 | //endregion 121 | 122 | //region Map setup and refresh 123 | @Override 124 | public void onMapReady(GoogleMap googleMap) { 125 | mMap = googleMap; 126 | } 127 | 128 | 129 | private void refreshMap() { 130 | mMap.clear(); 131 | mapFragment.onResume(); 132 | } 133 | //endregion 134 | 135 | //region Initializing view on Fragment 136 | private void intializingView() { 137 | mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map); 138 | mapFragment.getMapAsync(this); 139 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false); 140 | mBinding.recyclerviewChild.setLayoutManager(linearLayoutManager); 141 | mBinding.fabChild.setOnClickListener(v -> { 142 | mFragmentCallback.onFabButtonClicked(); 143 | }); 144 | mBinding.resetMapView.setOnClickListener(v -> { 145 | setupDataAndMapView(); 146 | }); 147 | } 148 | //endregion 149 | 150 | //region Set data on recycler view and map 151 | public void setupDataAndMapView() { 152 | // Update the list when the data changes 153 | if (childTrackViewModel != null) { 154 | LiveData> liveData = childTrackViewModel.getAssociateUserList(trackingActivity.getUserName()); 155 | liveData.observe(getActivity(), (List user) -> { 156 | if (user != null && !user.isEmpty()) { 157 | mBinding.childrenText.setText("You have "+user.size()+" children(s) "); 158 | mBinding.resetMapView.setVisibility(View.VISIBLE); 159 | mTrackingChildrenAdapter.setUserList(user, trackingActivity.getUserName()); 160 | counter = 0; 161 | markChildrenOnMapView(user); 162 | } else { 163 | refreshMap(); 164 | mBinding.childrenText.setText("No children's found"); 165 | mBinding.resetMapView.setVisibility(View.GONE); 166 | user.clear(); 167 | mTrackingChildrenAdapter.setUserList(user, trackingActivity.getUserName()); 168 | } 169 | }); 170 | } 171 | } 172 | //endregion 173 | 174 | //region Extract user name from User List 175 | private Set getAllUserNameFromList(List user) { 176 | userHashMap = new HashMap(); 177 | for (User u : user) { 178 | userHashMap.put(u.getEmail(), u); 179 | } 180 | return userHashMap.keySet(); 181 | } 182 | //endregion 183 | 184 | //region Mark children on map view 185 | public void markChildrenOnMapView(List uList) { 186 | refreshMap(); 187 | Set userList = getAllUserNameFromList(uList); 188 | counter = 0; 189 | latLngs = new ArrayList(); 190 | for (String email : userList) { 191 | displayDataOnMap(email, userList.size()); 192 | } 193 | } 194 | 195 | public void displayDataOnMap(String email, Integer userListSize) { 196 | int color = new Random().nextInt(360); 197 | if (eventModel != null) { 198 | LiveData> liveData = eventModel.getEventListLiveData(email); 199 | liveData.observe(getActivity(), (List mEntities) -> { 200 | counter++; 201 | if (mEntities.size() != 0) { 202 | Collections.sort(mEntities, new DateComparator()); 203 | for (Event e : mEntities) { 204 | LatLng position = new LatLng(e.getLat(), e.getLon()); 205 | latLngs.add(position); 206 | Marker marker = mMap.addMarker(new MarkerOptions() 207 | .position(position) 208 | .title(userHashMap.get(e.getUserName()).getFirstName()+"("+e.getTitle() + ", " + e.getType()+")") 209 | .snippet(Utility.dateTimeCoversion(e.getCreateDate())) 210 | .icon(BitmapDescriptorFactory.defaultMarker(color)) 211 | ); 212 | marker.showInfoWindow(); 213 | } 214 | } 215 | if (counter == userListSize) cameraUpdateCall(latLngs); 216 | }); 217 | } 218 | } 219 | //endregion 220 | 221 | // region Delete Record with Alert message 222 | public void deleteRecord(String parentEmail, String childEmail, int position) { 223 | AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getContext(), R.style.AppCompatAlertDialogStyle); 224 | alertDialogBuilder.setMessage("Are you sure you want to delete?"); 225 | alertDialogBuilder.setPositiveButton(Html.fromHtml("Yes"), 226 | new DialogInterface.OnClickListener() { 227 | @Override 228 | public void onClick(DialogInterface arg0, int arg1) { 229 | childTrackViewModel.deleteRecord(parentEmail, childEmail); 230 | mTrackingChildrenAdapter.notifyDataSetChanged(); 231 | //setupDataAndMapView(); 232 | } 233 | }); 234 | 235 | alertDialogBuilder.setNegativeButton(Html.fromHtml("No"), new DialogInterface.OnClickListener() { 236 | @Override 237 | public void onClick(DialogInterface dialog, int which) { 238 | dialog.dismiss(); 239 | } 240 | }); 241 | alertDialogBuilder.setCancelable(false); 242 | AlertDialog alertDialog = alertDialogBuilder.create(); 243 | alertDialog.show(); 244 | } 245 | //endregion 246 | 247 | //region Camera Bound with Area 248 | public void cameraUpdateCall(List latLngs) { 249 | if (latLngs.size() > 0) { 250 | builder = new LatLngBounds.Builder(); 251 | for (LatLng position : latLngs) 252 | builder.include(position); 253 | if (areBoundsTooSmall(builder.build(), 100)) { 254 | mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(builder.build().getCenter(), 14)); 255 | } else { 256 | mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 5)); 257 | } 258 | } 259 | } 260 | 261 | private boolean areBoundsTooSmall(LatLngBounds bounds, int minDistanceInMeter) { 262 | float[] result = new float[1]; 263 | Location.distanceBetween(bounds.southwest.latitude, bounds.southwest.longitude, bounds.northeast.latitude, bounds.northeast.longitude, result); 264 | return result[0] < minDistanceInMeter; 265 | } 266 | 267 | //endregion 268 | } 269 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/fragment/EventListFragment.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.fragment; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.arch.lifecycle.ViewModelProviders; 5 | import android.content.Context; 6 | import android.databinding.DataBindingUtil; 7 | import android.os.Bundle; 8 | import android.support.annotation.Nullable; 9 | import android.support.v4.app.Fragment; 10 | import android.support.v7.widget.LinearLayoutManager; 11 | import android.util.Log; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | 16 | import com.google.firebase.FirebaseApp; 17 | import com.hora.priyank.trackingapp.R; 18 | import com.hora.priyank.trackingapp.data.dao.MyFragmentListenerImpl; 19 | import com.hora.priyank.trackingapp.data.model.Event; 20 | import com.hora.priyank.trackingapp.databinding.MessageListFragmentBinding; 21 | import com.hora.priyank.trackingapp.ui.activity.ChildrenActivity; 22 | import com.hora.priyank.trackingapp.ui.adapter.EventAdapter; 23 | import com.hora.priyank.trackingapp.ui.viewmodel.EventListViewModel; 24 | import com.hora.priyank.trackingapp.util.DateComparator; 25 | import com.hora.priyank.trackingapp.util.Utility; 26 | 27 | import java.util.Collections; 28 | import java.util.List; 29 | 30 | 31 | public class EventListFragment extends Fragment { 32 | 33 | //region Variable Declaration 34 | private static final String TAG = "EventListFragment"; 35 | private MessageListFragmentBinding mBinding; 36 | private EventListViewModel mModel; 37 | private MyFragmentListenerImpl mFragmentCallback; 38 | private EventAdapter mEventAdapter; 39 | private ChildrenActivity childrenActivity; 40 | //endregion 41 | 42 | //region Fragment Lifecycle Component 43 | @Override 44 | public void onCreate(Bundle savedInstanceState) { 45 | super.onCreate(savedInstanceState); 46 | mEventAdapter = new EventAdapter(getContext(),getActivity()); 47 | mModel = ViewModelProviders.of(getActivity()).get(EventListViewModel.class); 48 | FirebaseApp.initializeApp(getActivity()); 49 | } 50 | 51 | @Nullable 52 | @Override 53 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 54 | @Nullable Bundle savedInstanceState) { 55 | 56 | mBinding = DataBindingUtil.inflate(inflater, R.layout.message_list_fragment, 57 | container, false); 58 | intializingView(); 59 | return mBinding.getRoot(); 60 | } 61 | 62 | @Override 63 | public void onAttach(Context context) { 64 | super.onAttach(context); 65 | childrenActivity = (ChildrenActivity) context; 66 | Log.d(TAG, "Peeru on attach"); 67 | try { 68 | mFragmentCallback = (MyFragmentListenerImpl) context; 69 | } catch (ClassCastException e) { 70 | throw new ClassCastException(context.toString() 71 | + " must implement OnHeadlineSelectedListener"); 72 | } 73 | } 74 | 75 | @Override 76 | public void onActivityCreated(@Nullable Bundle savedInstanceState) { 77 | super.onActivityCreated(savedInstanceState); 78 | mBinding.recyclerview.setAdapter(mEventAdapter); 79 | displayEventLiveData(); 80 | } 81 | 82 | 83 | @Override 84 | public void onResume() { 85 | super.onResume(); 86 | } 87 | 88 | @Override 89 | public void onPause() { 90 | super.onPause(); 91 | } 92 | //endregion 93 | 94 | //region Intializing view 95 | private void intializingView() { 96 | LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); 97 | mBinding.recyclerview.setLayoutManager(layoutManager); 98 | mBinding.fab.setOnClickListener(v -> { 99 | mFragmentCallback.onFabButtonClicked(); 100 | }); 101 | } 102 | //endregion 103 | 104 | //region Display Event List Data 105 | private void displayEventLiveData() { 106 | if (mModel != null) { 107 | LiveData> liveData = mModel.getEventListLiveData(childrenActivity.getUserName()); 108 | liveData.observe(getActivity(), (List mEntities) -> { 109 | Collections.sort(mEntities, new DateComparator()); 110 | if (mEntities.size() == 0 || mEntities.isEmpty()) { 111 | mBinding.noEntTag.setVisibility(View.VISIBLE); 112 | mBinding.noEntTag.setText("Hi " + childrenActivity.getName() + Utility.EVENT_ADD_NOTE); 113 | } else { 114 | mBinding.noEntTag.setVisibility(View.GONE); 115 | mEventAdapter.setMessageList(mEntities); 116 | } 117 | }); 118 | } 119 | } 120 | //endregion 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/fragment/Login.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.fragment; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.arch.lifecycle.LiveData; 5 | import android.arch.lifecycle.ViewModelProviders; 6 | import android.content.Intent; 7 | import android.databinding.DataBindingUtil; 8 | import android.os.Bundle; 9 | import android.support.annotation.Nullable; 10 | import android.support.v4.app.Fragment; 11 | import android.view.LayoutInflater; 12 | import android.view.View; 13 | import android.view.ViewGroup; 14 | import android.widget.Toast; 15 | 16 | import com.hora.priyank.trackingapp.R; 17 | import com.hora.priyank.trackingapp.data.model.User; 18 | import com.hora.priyank.trackingapp.databinding.FragmentLoginBinding; 19 | import com.hora.priyank.trackingapp.init.TrackingApp; 20 | import com.hora.priyank.trackingapp.init.UserSession; 21 | import com.hora.priyank.trackingapp.ui.activity.ChildrenActivity; 22 | import com.hora.priyank.trackingapp.ui.activity.TrackingActivity; 23 | import com.hora.priyank.trackingapp.ui.viewmodel.ChildTrackViewModel; 24 | import com.hora.priyank.trackingapp.util.Utility; 25 | 26 | /** 27 | * Created by Priyank Jain on 27-09-2018. 28 | */ 29 | @SuppressLint("ValidFragment") 30 | public class Login extends Fragment { 31 | //region Variable Declaration 32 | private ChildTrackViewModel childTrackViewModel; 33 | private UserSession session; 34 | private FragmentLoginBinding mBinding; 35 | private Intent intent; 36 | //endregion 37 | 38 | //region Fragment Lifecycle component 39 | @Nullable 40 | @Override 41 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 42 | mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, 43 | container, false); 44 | // User Session Manager 45 | session = new UserSession(TrackingApp.getAppContext()); 46 | childTrackViewModel = ViewModelProviders.of(getActivity()).get(ChildTrackViewModel.class); 47 | return mBinding.getRoot(); 48 | } 49 | 50 | @Override 51 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 52 | super.onViewCreated(view, savedInstanceState); 53 | initializeView(); 54 | setButtonClickListner(); 55 | } 56 | //endregion 57 | 58 | //region Intializing View 59 | private void initializeView() { 60 | Utility.textEventListner(mBinding.username, mBinding.login); 61 | Utility.textEventListner(mBinding.password, mBinding.login); 62 | } 63 | 64 | private void showToastMessge(String s) { 65 | Toast.makeText(getContext(), s, Toast.LENGTH_LONG).show(); 66 | } 67 | //endregion 68 | 69 | //region Login button to submit request 70 | private void setButtonClickListner() { 71 | mBinding.login.setOnClickListener(view -> { 72 | String username = mBinding.username.getText().toString(); 73 | String password = mBinding.password.getText().toString(); 74 | LiveData liveData = childTrackViewModel.getUserLiveData(username); 75 | intent = new Intent(getActivity(), TrackingActivity.class); 76 | liveData.observe(getActivity(), (User mEntities) -> { 77 | if (mEntities.getPassword() != null) { 78 | if (!mEntities.getPassword().equals(password)) { 79 | showToastMessge(Utility.INVALID_PASSWORD); 80 | return; 81 | } else if (mEntities.getUserRole().equals(Utility.CHILD_CONSTANT)) { 82 | intent = new Intent(getContext(), ChildrenActivity.class); 83 | } 84 | intent.putExtra(Utility.KEY_USER_NAME, username); 85 | intent.putExtra(Utility.KEY_NAME, mEntities.getFirstName()); 86 | session.createUserLoginSession(username, password, mEntities.getUserRole(), mEntities.getFirstName()); 87 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 88 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 89 | startActivity(intent); 90 | getActivity().finish(); 91 | } else { 92 | showToastMessge(Utility.USER_NOT_FOUND); 93 | } 94 | }); 95 | }); 96 | } 97 | //endregion 98 | 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/fragment/NewChildFragment.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.fragment; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.arch.lifecycle.ViewModelProviders; 5 | import android.content.Context; 6 | import android.databinding.DataBindingUtil; 7 | import android.os.Bundle; 8 | import android.support.annotation.Nullable; 9 | import android.support.v4.app.Fragment; 10 | import android.text.Editable; 11 | import android.text.TextWatcher; 12 | import android.util.Log; 13 | import android.view.LayoutInflater; 14 | import android.view.View; 15 | import android.view.ViewGroup; 16 | import android.view.inputmethod.InputMethodManager; 17 | import android.widget.Toast; 18 | 19 | import com.hora.priyank.trackingapp.R; 20 | import com.hora.priyank.trackingapp.data.model.User; 21 | import com.hora.priyank.trackingapp.databinding.NewChildFragmentBinding; 22 | import com.hora.priyank.trackingapp.ui.viewmodel.ChildTrackViewModel; 23 | import com.hora.priyank.trackingapp.util.Utility; 24 | 25 | /** 26 | * Created by Priyank Jain on 29-09-2018. 27 | */ 28 | public class NewChildFragment extends Fragment { 29 | //region Variable Declaration 30 | private NewChildFragmentBinding mBinding; 31 | private ChildTrackViewModel mViewModel; 32 | private String mUserName; 33 | private String TAG = "NewChildFragment"; 34 | //endregion 35 | 36 | //region Fragment Lifecycle Componenet 37 | @Override 38 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 39 | @Nullable Bundle savedInstanceState) { 40 | super.onCreateView(inflater, container, savedInstanceState); 41 | Log.d(TAG, "Hora onCreateView"); 42 | mBinding = DataBindingUtil.inflate(inflater, R.layout.new_child_fragment, container, false); 43 | initializeLayout(); 44 | setBindingVariableEvent(); 45 | setButtonClickListner(); 46 | return mBinding.getRoot(); 47 | } 48 | //endregion 49 | 50 | //region Intialize layout 51 | private void initializeLayout() { 52 | mUserName = getArguments().getString(Utility.KEY_USER_NAME); 53 | mViewModel = ViewModelProviders.of(getActivity()).get(ChildTrackViewModel.class); 54 | } 55 | //endregion 56 | 57 | //region Set variable and event handle 58 | private void setBindingVariableEvent() { 59 | mBinding.welcomeNote.append(getArguments().getString(Utility.KEY_NAME)); 60 | mBinding.childEmail.addTextChangedListener(new TextWatcher() { 61 | @Override 62 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 63 | } 64 | 65 | @Override 66 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 67 | if (charSequence.toString().trim().length() > 0) { 68 | mBinding.search.setEnabled(true); 69 | } else { 70 | mBinding.search.setEnabled(false); 71 | } 72 | } 73 | 74 | @Override 75 | public void afterTextChanged(Editable editable) { 76 | } 77 | }); 78 | } 79 | //endregion 80 | 81 | //region Submit new post 82 | private void setButtonClickListner() { 83 | mBinding.search.setOnClickListener(view -> { 84 | String childUser = mBinding.childEmail.getText().toString(); 85 | if (mViewModel != null) { 86 | LiveData liveData = mViewModel.getUserLiveData(childUser); 87 | liveData.observe(getActivity(), (User mEntities) -> { 88 | if (mEntities != null && mEntities.getEmail() != null) { 89 | if (mEntities.getUserRole().equals(Utility.CHILD_CONSTANT)) { 90 | mViewModel.createChildParentRelation(mUserName, mEntities); 91 | mBinding.childEmail.setText(""); 92 | dismissKeyboard(); 93 | getActivity().onBackPressed(); 94 | } else { 95 | Toast.makeText(getContext(), Utility.USER_ROLE_MISMATCH, Toast.LENGTH_LONG).show(); 96 | } 97 | } else { 98 | Toast.makeText(getContext(), Utility.CHILD_NOT_FOUND, Toast.LENGTH_LONG).show(); 99 | } 100 | }); 101 | } 102 | }); 103 | } 104 | //endregion 105 | 106 | //region Dismiss keyboard 107 | private void dismissKeyboard() { 108 | InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 109 | if (imm != null && null != getActivity().getCurrentFocus()) 110 | imm.hideSoftInputFromWindow(getActivity().getCurrentFocus() 111 | .getApplicationWindowToken(), 0); 112 | } 113 | //endregion 114 | } 115 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/fragment/NewPostFragment.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.fragment; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.arch.lifecycle.LiveData; 5 | import android.arch.lifecycle.ViewModelProviders; 6 | import android.content.Context; 7 | import android.databinding.DataBindingUtil; 8 | import android.location.Location; 9 | import android.location.LocationManager; 10 | import android.os.Bundle; 11 | import android.support.annotation.Nullable; 12 | import android.support.v4.app.Fragment; 13 | import android.text.Editable; 14 | import android.text.TextWatcher; 15 | import android.view.LayoutInflater; 16 | import android.view.View; 17 | import android.view.ViewGroup; 18 | import android.view.inputmethod.InputMethodManager; 19 | import android.widget.AdapterView; 20 | import android.widget.ArrayAdapter; 21 | import android.widget.EditText; 22 | import android.widget.Spinner; 23 | import android.widget.Toast; 24 | 25 | import com.hora.priyank.trackingapp.R; 26 | import com.hora.priyank.trackingapp.databinding.NewPostFragmentBinding; 27 | import com.hora.priyank.trackingapp.ui.viewmodel.EventListViewModel; 28 | import com.hora.priyank.trackingapp.util.Utility; 29 | 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | import java.util.Set; 33 | 34 | import static android.content.Context.LOCATION_SERVICE; 35 | 36 | 37 | public class NewPostFragment extends Fragment { 38 | //region Varaible Declaration 39 | private static final String SELECT_MESSAGE = "Please select category type"; 40 | private static final String OTHERS_VALUE = "Others"; 41 | private NewPostFragmentBinding mBinding; 42 | private EventListViewModel mViewModel; 43 | private String mUserName; 44 | private LocationManager locationManager; 45 | private Location location; 46 | private ArrayAdapter dataAdapter; 47 | private List eventType = new ArrayList(); 48 | private String title, type; 49 | private String TAG = "NewPostFragment"; 50 | private String transaction, createTime; 51 | //endregion 52 | 53 | //region Fragment Lifecycle component 54 | @Override 55 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 56 | @Nullable Bundle savedInstanceState) { 57 | super.onCreateView(inflater, container, savedInstanceState); 58 | mBinding = DataBindingUtil.inflate(inflater, R.layout.new_post_fragment, container, false); 59 | setInstruction(); 60 | return mBinding.getRoot(); 61 | } 62 | //endregion 63 | 64 | //region Set instruction 65 | private void setInstruction() { 66 | initializeLayout(); 67 | setBindingVariableEvent(); 68 | setAndLoadDataOnDataAdapter(); 69 | setButtonClickListner(); 70 | } 71 | //endregion 72 | 73 | //region Intialize Layout 74 | @SuppressLint("MissingPermission") 75 | private void initializeLayout() { 76 | eventType = new ArrayList(); 77 | mUserName = getArguments().getString(Utility.KEY_USER_NAME); 78 | transaction = getArguments().getString(Utility.KEY_TRANSACTION); 79 | createTime = getArguments().getString(Utility.KEY_TRANSACTION_TIME); 80 | mViewModel = ViewModelProviders.of(getActivity()).get(EventListViewModel.class); 81 | if (transaction.equals("new")) location = getLastKnownLocation(); 82 | } 83 | //endregion 84 | 85 | //region Set variable and event handling 86 | private void setBindingVariableEvent() { 87 | mBinding.welcome.append("" + getArguments().getString(Utility.KEY_NAME)); 88 | if (transaction.equals("update")) { 89 | mBinding.textStatic.setText(Utility.EVENT_UPDATE_NOTE); 90 | mBinding.sendButton.setText("Update"); 91 | } else { 92 | mBinding.textStatic.setText(Utility.EVENT_ADD_NOTE); 93 | mBinding.sendButton.setText("Submit"); 94 | } 95 | textEventListner(mBinding.titleEvent); 96 | textEventListner(mBinding.typeEvent); 97 | spinnerEventListner(mBinding.eventSpinner); 98 | } 99 | //endregion 100 | 101 | //region Track Location 102 | private Location getLastKnownLocation() { 103 | locationManager = (LocationManager) getContext().getSystemService(LOCATION_SERVICE); 104 | List providers = locationManager.getProviders(true); 105 | Location bestLocation = null; 106 | for (String provider : providers) { 107 | @SuppressLint("MissingPermission") Location l = locationManager.getLastKnownLocation(provider); 108 | if (l == null) { 109 | continue; 110 | } 111 | if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) { 112 | bestLocation = l; 113 | } 114 | } 115 | return bestLocation; 116 | } 117 | //endregion 118 | 119 | //region Set LiveData on Adapter 120 | private void setAndLoadDataOnDataAdapter() { 121 | if (mViewModel != null) { 122 | LiveData> liveData = mViewModel.getEventTypeList(); 123 | 124 | liveData.observe(getActivity(), (Set mEntities) -> { 125 | eventType.addAll(mEntities); 126 | eventType.add(OTHERS_VALUE); 127 | //eventType.notify(); 128 | }); 129 | } 130 | eventType.add(SELECT_MESSAGE); 131 | 132 | dataAdapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, eventType); 133 | dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 134 | 135 | } 136 | //endregion 137 | 138 | //region Send data on Firebase 139 | private void setButtonClickListner() { 140 | mBinding.eventSpinner.setAdapter(dataAdapter); 141 | mBinding.sendButton.setOnClickListener(view -> { 142 | if (type.equals(OTHERS_VALUE)) { 143 | type = mBinding.typeEvent.getText().toString(); 144 | mViewModel.createTypeAndSentToDataBase(type); 145 | } 146 | title = mBinding.titleEvent.getText().toString(); 147 | if (!type.equals(SELECT_MESSAGE)) { 148 | storeAndUpdateDataOnDatabase(); 149 | } else { 150 | Toast.makeText(getContext(), SELECT_MESSAGE + " or add category (Others)", Toast.LENGTH_LONG).show(); 151 | } 152 | }); 153 | } 154 | 155 | private void storeAndUpdateDataOnDatabase() { 156 | if (transaction.equals("new")) { 157 | mViewModel.createAndSendToDataBase( 158 | mUserName, 159 | title, 160 | type, 161 | location.getLatitude(), 162 | location.getLongitude(), 163 | String.valueOf(System.currentTimeMillis())); 164 | eventStoredBackToFragment(); 165 | } else if (transaction.equals("update")) { 166 | mViewModel.updateToDatabase( 167 | mUserName, 168 | title, 169 | type, 170 | createTime 171 | ); 172 | eventStoredBackToFragment(); 173 | } 174 | } 175 | 176 | private void eventStoredBackToFragment() { 177 | mBinding.typeEvent.setText(""); 178 | mBinding.titleEvent.setText(""); 179 | dismissKeyboard(); 180 | getActivity().onBackPressed(); 181 | } 182 | //endregion 183 | 184 | //region Spinner Listner 185 | private void spinnerEventListner(Spinner spinner) { 186 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 187 | @Override 188 | public void onItemSelected(AdapterView adapterView, View view, int i, long l) { 189 | type = adapterView.getSelectedItem().toString(); 190 | if (type.equals(OTHERS_VALUE)) { 191 | mBinding.typeEvent.setVisibility(View.VISIBLE); 192 | mBinding.sendButton.setEnabled(false); 193 | } else if (type.equals(SELECT_MESSAGE) || mBinding.titleEvent.getText().toString().trim().length() == 0) { 194 | mBinding.sendButton.setEnabled(false); 195 | } else { 196 | mBinding.typeEvent.setText(""); 197 | mBinding.sendButton.setEnabled(true); 198 | mBinding.typeEvent.setVisibility(View.INVISIBLE); 199 | } 200 | } 201 | 202 | @Override 203 | public void onNothingSelected(AdapterView adapterView) { 204 | 205 | } 206 | }); 207 | 208 | } 209 | //endregion 210 | 211 | //region Edittext Listner 212 | private void textEventListner(EditText editText) { 213 | editText.addTextChangedListener(new TextWatcher() { 214 | @Override 215 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 216 | } 217 | 218 | @Override 219 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 220 | if (charSequence.toString().trim().length() > 0) { 221 | mBinding.sendButton.setEnabled(true); 222 | } else { 223 | mBinding.sendButton.setEnabled(false); 224 | } 225 | } 226 | 227 | @Override 228 | public void afterTextChanged(Editable editable) { 229 | } 230 | }); 231 | 232 | } 233 | //endregion 234 | 235 | //region DismissKeyboard 236 | private void dismissKeyboard() { 237 | InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 238 | if (imm != null && null != getActivity().getCurrentFocus()) 239 | imm.hideSoftInputFromWindow(getActivity().getCurrentFocus() 240 | .getApplicationWindowToken(), 0); 241 | } 242 | //endregion 243 | } 244 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/fragment/Signup.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.fragment; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.arch.lifecycle.ViewModelProviders; 5 | import android.databinding.DataBindingUtil; 6 | import android.os.Bundle; 7 | import android.support.annotation.Nullable; 8 | import android.support.design.widget.TextInputLayout; 9 | import android.support.v4.app.Fragment; 10 | import android.text.Editable; 11 | import android.text.TextUtils; 12 | import android.text.TextWatcher; 13 | import android.view.LayoutInflater; 14 | import android.view.View; 15 | import android.view.ViewGroup; 16 | import android.view.WindowManager; 17 | import android.widget.Toast; 18 | 19 | import com.hora.priyank.trackingapp.R; 20 | import com.hora.priyank.trackingapp.data.model.User; 21 | import com.hora.priyank.trackingapp.databinding.FragmentSignupBinding; 22 | import com.hora.priyank.trackingapp.ui.viewmodel.ChildTrackViewModel; 23 | import com.hora.priyank.trackingapp.util.Utility; 24 | 25 | /** 26 | * Created by Priyank Jain on 27-09-2018. 27 | */ 28 | @SuppressLint("ValidFragment") 29 | public class Signup extends Fragment { 30 | //region Variable declaration 31 | FragmentSignupBinding mBinding; 32 | private ChildTrackViewModel childTrackViewModel; 33 | //endregion 34 | 35 | //region Fragment Lifecycle component 36 | @Nullable 37 | @Override 38 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 39 | mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_signup, 40 | container, false); 41 | childTrackViewModel = ViewModelProviders.of(getActivity()).get(ChildTrackViewModel.class); 42 | return mBinding.getRoot(); 43 | } 44 | 45 | @Override 46 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 47 | super.onViewCreated(view, savedInstanceState); 48 | intializeLayoutVariable(); 49 | setButtonClickListner(); 50 | } 51 | //endregion 52 | 53 | //region Intialize Layout Variable 54 | private void intializeLayoutVariable() { 55 | mBinding.firstName.addTextChangedListener(new MyTextWatcher(mBinding.firstName)); 56 | mBinding.lastName.addTextChangedListener(new MyTextWatcher(mBinding.lastName)); 57 | mBinding.email.addTextChangedListener(new MyTextWatcher(mBinding.email)); 58 | mBinding.ipassword.addTextChangedListener(new MyTextWatcher(mBinding.ipassword)); 59 | } 60 | 61 | private void setButtonClickListner() { 62 | mBinding.signup.setOnClickListener(view -> { 63 | submitForm(); 64 | }); 65 | } 66 | //endregion 67 | 68 | //region Validation Form 69 | private void submitForm() { 70 | if (!validateName(mBinding.firstnameWrapper)) { 71 | return; 72 | } 73 | 74 | if (!validateName(mBinding.lastnameWrapper)) { 75 | return; 76 | } 77 | 78 | 79 | if (!validateEmail()) { 80 | return; 81 | } 82 | 83 | if (!validatePassword()) { 84 | return; 85 | } 86 | 87 | 88 | if (!validateUserRole()) { 89 | return; 90 | } 91 | 92 | saveAndRegisterFormData(); 93 | // Toast.makeText(this, "Thank You!", Toast.LENGTH_SHORT).show(); 94 | } 95 | 96 | 97 | private boolean validateName(TextInputLayout inputLayoutName) { 98 | if (inputLayoutName.getEditText().getText().toString().trim().isEmpty()) { 99 | inputLayoutName.setError(getString(R.string.err_msg_name)); 100 | requestFocus(inputLayoutName.getEditText()); 101 | return false; 102 | } else { 103 | inputLayoutName.setErrorEnabled(false); 104 | } 105 | 106 | return true; 107 | } 108 | 109 | private boolean validateEmail() { 110 | String email = mBinding.email.getText().toString().trim(); 111 | 112 | if (email.isEmpty() || !isValidEmail(email)) { 113 | mBinding.emailWrapper.setError(getString(R.string.err_msg_email)); 114 | requestFocus(mBinding.email); 115 | return false; 116 | } else { 117 | mBinding.emailWrapper.setErrorEnabled(false); 118 | } 119 | 120 | return true; 121 | } 122 | 123 | private boolean validatePassword() { 124 | if (mBinding.ipassword.getText().toString().trim().isEmpty()) { 125 | mBinding.ipasswordWrapper.setError(getString(R.string.err_msg_password)); 126 | requestFocus(mBinding.ipassword); 127 | return false; 128 | } else { 129 | mBinding.ipasswordWrapper.setErrorEnabled(false); 130 | } 131 | 132 | return true; 133 | } 134 | 135 | private boolean validateUserRole() { 136 | if (mBinding.userRole.getSelectedItem().toString().equals("Select User Type")) { 137 | Toast.makeText(getContext(), Utility.USER_ROLE_MANDATORY, Toast.LENGTH_LONG).show(); 138 | return false; 139 | } 140 | 141 | return true; 142 | } 143 | 144 | private static boolean isValidEmail(String email) { 145 | return !TextUtils.isEmpty(email) && android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches(); 146 | } 147 | 148 | private void requestFocus(View view) { 149 | if (view.requestFocus()) { 150 | getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); 151 | } 152 | } 153 | 154 | //endregion 155 | 156 | //region Save and register user 157 | private void saveAndRegisterFormData() { 158 | User user = new User(); 159 | user.setFirstName(mBinding.firstName.getText().toString()); 160 | user.setLastName(mBinding.lastName.getText().toString()); 161 | user.setEmail(mBinding.email.getText().toString()); 162 | user.setPassword(mBinding.ipassword.getText().toString()); 163 | user.setUserRole(mBinding.userRole.getSelectedItem().toString()); 164 | user.setLastUpdate(String.valueOf(System.currentTimeMillis())); 165 | user.setDateCreated(String.valueOf(System.currentTimeMillis())); 166 | childTrackViewModel.creatNewUser(user, getActivity()); 167 | } 168 | //endregion 169 | 170 | //region TextWatcher Class to watch text 171 | private class MyTextWatcher implements TextWatcher { 172 | 173 | private View view; 174 | 175 | private MyTextWatcher(View view) { 176 | this.view = view; 177 | } 178 | 179 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 180 | } 181 | 182 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 183 | } 184 | 185 | public void afterTextChanged(Editable editable) { 186 | switch (view.getId()) { 187 | case R.id.first_name: 188 | validateName(mBinding.firstnameWrapper); 189 | break; 190 | case R.id.last_name: 191 | validateName(mBinding.lastnameWrapper); 192 | break; 193 | case R.id.email: 194 | validateEmail(); 195 | break; 196 | case R.id.ipassword: 197 | validatePassword(); 198 | break; 199 | } 200 | } 201 | } 202 | //endregion 203 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/viewmodel/ChildTrackViewModel.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.viewmodel; 2 | 3 | import android.app.Activity; 4 | import android.arch.core.util.Function; 5 | import android.arch.lifecycle.LiveData; 6 | import android.arch.lifecycle.Transformations; 7 | import android.arch.lifecycle.ViewModel; 8 | import android.support.annotation.NonNull; 9 | import android.widget.Toast; 10 | 11 | import com.google.firebase.database.DataSnapshot; 12 | import com.google.firebase.database.DatabaseError; 13 | import com.google.firebase.database.DatabaseReference; 14 | import com.google.firebase.database.FirebaseDatabase; 15 | import com.google.firebase.database.Query; 16 | import com.google.firebase.database.ValueEventListener; 17 | import com.hora.priyank.trackingapp.data.FirebaseQueryLiveData; 18 | import com.hora.priyank.trackingapp.data.model.User; 19 | import com.hora.priyank.trackingapp.init.TrackingApp; 20 | import com.hora.priyank.trackingapp.util.Utility; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | /** 26 | * Created by Priyank Jain on 28-09-2018. 27 | */ 28 | public class ChildTrackViewModel extends ViewModel { 29 | private DatabaseReference dataRef; 30 | private User user = new User(); 31 | private List uList = new ArrayList(); 32 | FirebaseQueryLiveData mLiveData; 33 | private Boolean flag = false; 34 | 35 | //region User List Live data 36 | @NonNull 37 | public LiveData getUserLiveData(String userName) { 38 | String childRef = Utility.CHILDTRACKING_USER; 39 | dataRef = FirebaseDatabase.getInstance().getReference().child(childRef); 40 | mLiveData = new FirebaseQueryLiveData(dataRef.orderByChild("email").equalTo(userName)); 41 | LiveData mUserData = Transformations.map(mLiveData, new DeserializerUser()); 42 | return mUserData; 43 | } 44 | //endregion 45 | 46 | //region Parent Child relation list 47 | public LiveData> getAssociateUserList(String userName) { 48 | userName = String.valueOf(userName).replace(".", "*"); 49 | String childRef = Utility.CHILDTRACKING_RELATION + userName; 50 | dataRef = FirebaseDatabase.getInstance().getReference().child(childRef); 51 | mLiveData = new FirebaseQueryLiveData(dataRef); 52 | 53 | LiveData> mEventLiveData = 54 | Transformations.map(mLiveData, new DeserializerUserList()); 55 | 56 | return mEventLiveData; 57 | } 58 | //endregion 59 | 60 | //region Deserializer to fetch records 61 | private class DeserializerUser implements Function { 62 | @Override 63 | public User apply(DataSnapshot dataSnapshot) { 64 | user = new User(); 65 | for (DataSnapshot snap : dataSnapshot.getChildren()) { 66 | user = snap.getValue(User.class); 67 | } 68 | return user; 69 | } 70 | } 71 | 72 | private class DeserializerUserList implements Function> { 73 | 74 | @Override 75 | public List apply(DataSnapshot dataSnapshot) { 76 | uList.clear(); 77 | for (DataSnapshot snap : dataSnapshot.getChildren()) { 78 | //Log.d("TAG","Peeru Value"+snap.getValue().toString()); 79 | User user = snap.getValue(User.class); 80 | uList.add(user); 81 | } 82 | return uList; 83 | } 84 | } 85 | //endregion 86 | /* 87 | private final MutableLiveData messageUploadIsSuccessful = new MutableLiveData<>(); 88 | 89 | public MutableLiveData getMessageUploadIsSuccessful() { 90 | return messageUploadIsSuccessful; 91 | }*/ 92 | 93 | //region Delete Relation 94 | public void deleteRecord(String parent, String children) { 95 | DatabaseReference ref = FirebaseDatabase.getInstance().getReference(); 96 | Query userQuery = ref.child(Utility.CHILDTRACKING_RELATION + Utility.dotToStarConverter(parent)).orderByChild("email").equalTo(children); 97 | userQuery.addListenerForSingleValueEvent(new ValueEventListener() { 98 | @Override 99 | public void onDataChange(DataSnapshot dataSnapshot) { 100 | for (DataSnapshot userRecord : dataSnapshot.getChildren()) { 101 | userRecord.getRef().removeValue(); 102 | } 103 | } 104 | 105 | @Override 106 | public void onCancelled(DatabaseError databaseError) { 107 | } 108 | }); 109 | 110 | } 111 | //endregion 112 | 113 | //region Create Parent Child Relation 114 | public void createChildParentRelation(String userName, User mEntities) { 115 | // push the new Child to Firebase 116 | userName = Utility.dotToStarConverter(userName); 117 | dataRef = FirebaseDatabase.getInstance().getReference().child(Utility.CHILDTRACKING_RELATION + userName); 118 | dataRef.addListenerForSingleValueEvent(new ValueEventListener() { 119 | @Override 120 | public void onDataChange(final DataSnapshot dataSnapshot) { 121 | Boolean exist = false; 122 | for (DataSnapshot data : dataSnapshot.getChildren()) { 123 | //If email exists then toast shows else store the data on new key 124 | if (data.getValue(User.class).getEmail().equals(user.getEmail())) { 125 | exist = true; 126 | Toast.makeText(TrackingApp.getAppContext(), Utility.CHILD_EXIST, Toast.LENGTH_SHORT).show(); 127 | break; 128 | } 129 | } 130 | if (!exist) { 131 | mEntities.setPassword("*********"); 132 | dataRef.child(Utility.dotToStarConverter(mEntities.getEmail())).setValue(mEntities); 133 | } 134 | 135 | } 136 | 137 | @Override 138 | public void onCancelled(final DatabaseError databaseError) { 139 | } 140 | }); 141 | } 142 | //endregion 143 | 144 | //region Create New User 145 | public void creatNewUser(final User user, Activity activity) { 146 | flag = false; 147 | dataRef = FirebaseDatabase.getInstance().getReference().child(Utility.CHILDTRACKING_USER); 148 | dataRef.addListenerForSingleValueEvent(new ValueEventListener() { 149 | @Override 150 | public void onDataChange(final DataSnapshot dataSnapshot) { 151 | Boolean exist = false; 152 | for (DataSnapshot data : dataSnapshot.getChildren()) { 153 | //If email exists then toast shows else store the data on new key 154 | if (data.getValue(User.class).getEmail().equals(user.getEmail())) { 155 | exist = true; 156 | Toast.makeText(TrackingApp.getAppContext(), "E-mail already exists.", Toast.LENGTH_SHORT).show(); 157 | break; 158 | } 159 | } 160 | if (!exist) { 161 | dataRef.child(Utility.dotToStarConverter(user.getEmail())).setValue(user); 162 | activity.onBackPressed(); 163 | } 164 | flag = !exist; 165 | } 166 | 167 | @Override 168 | public void onCancelled(final DatabaseError databaseError) { 169 | } 170 | }); 171 | } 172 | //endregion 173 | } 174 | 175 | 176 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/ui/viewmodel/EventListViewModel.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.ui.viewmodel; 2 | 3 | import android.arch.core.util.Function; 4 | import android.arch.lifecycle.LiveData; 5 | import android.arch.lifecycle.Transformations; 6 | import android.arch.lifecycle.ViewModel; 7 | import android.support.annotation.NonNull; 8 | 9 | import com.google.firebase.database.DataSnapshot; 10 | import com.google.firebase.database.DatabaseReference; 11 | import com.google.firebase.database.FirebaseDatabase; 12 | import com.hora.priyank.trackingapp.data.FirebaseQueryLiveData; 13 | import com.hora.priyank.trackingapp.data.model.Event; 14 | import com.hora.priyank.trackingapp.util.Utility; 15 | 16 | import java.util.ArrayList; 17 | import java.util.HashSet; 18 | import java.util.List; 19 | import java.util.Set; 20 | 21 | 22 | public class EventListViewModel extends ViewModel { 23 | private DatabaseReference dataRef; 24 | private List mList = new ArrayList<>(); 25 | private Set etList = new HashSet<>(); 26 | 27 | //region Event List Live Data 28 | @NonNull 29 | public LiveData> getEventListLiveData(String user) { 30 | user = String.valueOf(user).replace(".", "*"); 31 | String childRef = Utility.CHILDTRACKING_EVENT + user; 32 | dataRef = FirebaseDatabase.getInstance().getReference().child(childRef); 33 | FirebaseQueryLiveData mLiveData = new FirebaseQueryLiveData(dataRef); 34 | 35 | LiveData> mEventLiveData = 36 | Transformations.map(mLiveData, new Deserializer()); 37 | 38 | return mEventLiveData; 39 | } 40 | 41 | private class Deserializer implements Function> { 42 | @Override 43 | public List apply(DataSnapshot dataSnapshot) { 44 | mList.clear(); 45 | for (DataSnapshot snap : dataSnapshot.getChildren()) { 46 | Event msg = snap.getValue(Event.class); 47 | mList.add(msg); 48 | } 49 | return mList; 50 | } 51 | } 52 | //endregion 53 | 54 | 55 | //region Event type List 56 | @NonNull 57 | public LiveData> getEventTypeList() { 58 | String childRef = Utility.CHILDTRACKING_EVENT_TYPE; 59 | dataRef = FirebaseDatabase.getInstance().getReference().child(childRef); 60 | FirebaseQueryLiveData mLiveData = new FirebaseQueryLiveData(dataRef); 61 | 62 | LiveData> mEventTypeList = 63 | Transformations.map(mLiveData, new DeserializerEventType()); 64 | 65 | return mEventTypeList; 66 | } 67 | 68 | private class DeserializerEventType implements Function> { 69 | @Override 70 | public Set apply(DataSnapshot dataSnapshot) { 71 | etList.clear(); 72 | for (DataSnapshot snap : dataSnapshot.getChildren()) { 73 | String msg = snap.getValue(String.class); 74 | etList.add(msg); 75 | } 76 | return etList; 77 | } 78 | 79 | } 80 | //endregion 81 | 82 | /* 83 | private final MutableLiveData messageUploadIsSuccessful = new MutableLiveData<>(); 84 | 85 | public MutableLiveData getMessageUploadIsSuccessful() { 86 | return messageUploadIsSuccessful; 87 | } 88 | */ 89 | 90 | //region Create new event 91 | public void createAndSendToDataBase(String userName, String title, String type, Double lat, Double lon, String dateTime) { 92 | Event entity = new Event(userName, title, type, lat, lon, dateTime); 93 | final String user = String.valueOf(userName).replace(".", "*"); 94 | 95 | // push the new message to Firebase 96 | dataRef = FirebaseDatabase.getInstance().getReference().child(Utility.CHILDTRACKING_EVENT + user + "/" + dateTime); 97 | dataRef.setValue(entity); 98 | 99 | dataRef = FirebaseDatabase.getInstance().getReference().child(Utility.CHILDTRACKING_USER + user + "/lastUpdate"); 100 | dataRef.setValue(dateTime); 101 | } 102 | //endregion 103 | 104 | //region Update Event 105 | public void updateToDatabase(String userName, String title, String type, String dateTime) { 106 | final String user = String.valueOf(userName).replace(".", "*"); 107 | // push the new message to Firebase 108 | dataRef = FirebaseDatabase.getInstance().getReference().child(Utility.CHILDTRACKING_EVENT + user + "/" + dateTime); 109 | dataRef.child("title").setValue(title); 110 | dataRef.child("type").setValue(type); 111 | } 112 | //endregion 113 | 114 | //region Create Event type 115 | public void createTypeAndSentToDataBase(String type) { 116 | FirebaseDatabase.getInstance() 117 | .getReference() 118 | .child(Utility.CHILDTRACKING_EVENT_TYPE) 119 | .push() 120 | .setValue(type); 121 | } 122 | //endregion 123 | 124 | } 125 | 126 | 127 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/util/DateComparator.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.util; 2 | 3 | import com.hora.priyank.trackingapp.data.model.Event; 4 | 5 | import java.util.Comparator; 6 | 7 | public class DateComparator implements Comparator { 8 | public int compare(Event item1, Event item2) { 9 | Long l = Long.valueOf(item2.getCreateDate())-Long.valueOf(item1.getCreateDate()); 10 | return l.intValue(); 11 | } 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/util/Utility.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.util; 2 | 3 | import android.text.Editable; 4 | import android.text.TextWatcher; 5 | import android.widget.Button; 6 | import android.widget.EditText; 7 | 8 | import java.text.SimpleDateFormat; 9 | import java.util.Date; 10 | 11 | /** 12 | * Created by Priyank Jain on 29-09-2018. 13 | */ 14 | public class Utility { 15 | public static final String CHILD_CONSTANT = "Child"; 16 | public static final String PARENT_CONSTANT = "Parent"; 17 | public static final String INVALID_PASSWORD = "Please enter right password "; 18 | public static final String USER_NOT_FOUND = "User not exist"; 19 | public static final String KEY_USER_NAME = "username"; 20 | public static final String KEY_NAME = "name"; 21 | public static final String TRACKING_APP = "Track"; 22 | public static final String USER_ROLE_MANDATORY = "Please select user type its mandatory"; 23 | public static final String CHILD_NOT_FOUND = "Child not found"; 24 | public static final String USER_ROLE_MISMATCH = "Given user role is not Child" ; 25 | public static final String CHILD_EXIST = "Children already exist"; 26 | public static final String CHILD_ADDED = "Child added!!"; 27 | public static final String KEY_TRANSACTION = "transaction"; 28 | public static final String CHILDTRACKING_EVENT_TYPE = "ChildTracking/EventType/" ; 29 | public static final String CHILDTRACKING_EVENT = "ChildTracking/Event/" ; 30 | public static final String EVENT_ADD_NOTE = "\n"+"You are doing something..\n Please mark here to make it special"; 31 | public static final String KEY_TRANSACTION_TIME = "time"; 32 | public static final String EVENT_UPDATE_NOTE = "Update your existing event data..\n "; 33 | public static String CHILDTRACKING_USER = "ChildTracking/User/"; 34 | public static String CHILDTRACKING_RELATION = "ChildTracking/Relation/"; 35 | 36 | 37 | public static String dotToStarConverter(String s){ 38 | return String.valueOf(s).replace(".", "*"); 39 | } 40 | public static String dateTimeCoversion(String createDate) { 41 | try { 42 | long yourmilliseconds = Long.valueOf(createDate); 43 | SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm"); 44 | Date resultdate = new Date(yourmilliseconds); 45 | return sdf.format(resultdate).toString(); 46 | 47 | } catch (Exception e) { 48 | return ""; 49 | } 50 | } 51 | 52 | public static void textEventListner(EditText editText, Button button) { 53 | editText.addTextChangedListener(new TextWatcher() { 54 | @Override 55 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 56 | } 57 | 58 | @Override 59 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 60 | if (charSequence.toString().trim().length() > 0) { 61 | button.setEnabled(true); 62 | } else { 63 | button.setEnabled(false); 64 | } 65 | } 66 | 67 | @Override 68 | public void afterTextChanged(Editable editable) { 69 | } 70 | }); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/hora/priyank/trackingapp/util/Validation.java: -------------------------------------------------------------------------------- 1 | package com.hora.priyank.trackingapp.util; 2 | 3 | import android.text.TextUtils; 4 | 5 | /** 6 | * Created by Priyank Jain on 30-09-2018. 7 | */ 8 | public class Validation { 9 | 10 | public static boolean isValidEmail(String email) { 11 | return !TextUtils.isEmpty(email) && android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches(); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bottom_color_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_accessibility_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /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/ic_login_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_signin_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/pencil_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/priyankjain28/trackingApp/42ba14a8f1b42a0c45eed390aec930cf56689d56/app/src/main/res/drawable/pencil_button.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/priyankjain28/trackingApp/42ba14a8f1b42a0c45eed390aec930cf56689d56/app/src/main/res/drawable/placeholder.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_children.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 15 | 16 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_spash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_tracking.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/child_track_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 12 | 13 | 17 | 18 | 24 | 25 | 37 | 38 | 39 | 44 | 45 | 52 | 53 | 57 | 58 | 65 | 66 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 16 | 17 | 26 | 27 | 28 | 29 | 30 | 35 | 36 | 40 | 41 | 47 | 48 | 49 | 55 | 56 | 62 | 63 | 64 |