├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_car.png
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_car.png
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_car.png
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_car.png
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_car.png
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── drawable-hdpi
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-mdpi
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-xhdpi
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-hdpi-v11
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-hdpi-v9
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-mdpi-v11
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-mdpi-v9
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-xhdpi-v9
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-xhdpi-v11
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-xxhdpi-v11
│ │ │ │ └── ic_trans_notifi.png
│ │ │ ├── drawable-xxhdpi-v9
│ │ │ │ └── ic_trans_notifi.png
│ │ │ └── layout
│ │ │ │ └── activity_main.xml
│ │ ├── ic_car-web.png
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── marty
│ │ │ │ └── track
│ │ │ │ ├── BroadcastLocationChange.java
│ │ │ │ ├── ConnectionDetector.java
│ │ │ │ ├── UploadLocationService.java
│ │ │ │ ├── ServiceCall.java
│ │ │ │ ├── LocationJobService.java
│ │ │ │ └── MainActivity.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── marty
│ │ │ └── track
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── marty
│ │ └── track
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
├── build.gradle
└── app.iml
├── settings.gradle
├── bgservice.jpeg
├── mainpage.jpeg
├── notification.jpeg
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
├── .idea
├── libraries
│ ├── android_android_27.xml
│ ├── Gradle__android_android_27.xml
│ ├── com_google_code_findbugs_jsr305_2_0_1_jar.xml
│ ├── Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml
│ ├── com_android_support_constraint_constraint_layout_solver_1_0_2_jar.xml
│ ├── Gradle__com_android_support_constraint_constraint_layout_solver_1_0_2_jar.xml
│ ├── com_android_support_support_v4_25_2_0.xml
│ ├── junit_junit_4_12_jar.xml
│ ├── Gradle__com_android_support_support_v4_25_2_0.xml
│ ├── Gradle__junit_junit_4_12_jar.xml
│ ├── com_google_android_gms_play_services_base_11_0_1.xml
│ ├── com_google_android_gms_play_services_maps_11_0_1.xml
│ ├── com_google_android_gms_play_services_tasks_11_0_1.xml
│ ├── com_android_support_constraint_constraint_layout_1_0_2.xml
│ ├── Gradle__com_google_android_gms_play_services_base_11_0_1.xml
│ ├── Gradle__com_google_android_gms_play_services_maps_11_0_1.xml
│ ├── com_google_android_gms_play_services_basement_11_0_1.xml
│ ├── com_google_android_gms_play_services_location_11_0_1.xml
│ ├── javax_inject_javax_inject_1_jar.xml
│ ├── Gradle__com_android_support_constraint_constraint_layout_1_0_2.xml
│ ├── Gradle__com_google_android_gms_play_services_tasks_11_0_1.xml
│ ├── android_arch_core_common_1_0_0_jar.xml
│ ├── com_squareup_javawriter_2_1_1_jar.xml
│ ├── Gradle__com_google_android_gms_play_services_basement_11_0_1.xml
│ ├── Gradle__com_google_android_gms_play_services_location_11_0_1.xml
│ ├── Gradle__javax_inject_javax_inject_1_jar.xml
│ ├── org_hamcrest_hamcrest_core_1_3_jar.xml
│ ├── Gradle__android_arch_core_common_1_0_0_jar.xml
│ ├── Gradle__com_squareup_javawriter_2_1_1_jar.xml
│ ├── android_arch_lifecycle_common_1_0_3_jar.xml
│ ├── Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml
│ ├── org_hamcrest_hamcrest_library_1_3_jar.xml
│ ├── Gradle__android_arch_lifecycle_common_1_0_3_jar.xml
│ ├── Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml
│ ├── org_hamcrest_hamcrest_integration_1_3_jar.xml
│ ├── Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml
│ ├── javax_annotation_javax_annotation_api_1_2_jar.xml
│ ├── Gradle__javax_annotation_javax_annotation_api_1_2_jar.xml
│ ├── com_android_support_support_annotations_27_0_2_jar.xml
│ ├── Gradle__com_android_support_support_annotations_27_0_2_jar.xml
│ ├── android_arch_lifecycle_runtime_1_0_3.xml
│ ├── Gradle__android_arch_lifecycle_runtime_1_0_3.xml
│ ├── com_android_support_appcompat_v7_27_0_2.xml
│ ├── com_android_support_support_compat_27_0_2.xml
│ ├── Gradle__com_android_support_appcompat_v7_27_0_2.xml
│ ├── com_android_support_support_core_ui_27_0_2.xml
│ ├── com_android_support_support_fragment_27_0_2.xml
│ ├── Gradle__com_android_support_support_compat_27_0_2.xml
│ ├── Gradle__com_android_support_support_core_ui_27_0_2.xml
│ ├── com_android_support_support_core_utils_27_0_2.xml
│ ├── Gradle__com_android_support_support_fragment_27_0_2.xml
│ ├── Gradle__com_android_support_support_core_utils_27_0_2.xml
│ ├── com_android_support_support_vector_drawable_27_0_2.xml
│ ├── com_android_support_animated_vector_drawable_27_0_2.xml
│ ├── Gradle__com_android_support_support_vector_drawable_27_0_2.xml
│ ├── Gradle__com_android_support_animated_vector_drawable_27_0_2.xml
│ ├── com_android_support_test_rules_0_5.xml
│ ├── com_android_support_test_runner_0_5.xml
│ ├── Gradle__com_android_support_test_rules_0_5.xml
│ ├── Gradle__com_android_support_test_runner_0_5.xml
│ ├── com_android_support_test_espresso_espresso_core_2_2_2.xml
│ ├── com_android_support_support_media_compat_25_2_0.xml
│ ├── Gradle__com_android_support_test_espresso_espresso_core_2_2_2.xml
│ ├── Gradle__com_android_support_support_media_compat_25_2_0.xml
│ ├── com_android_support_test_espresso_espresso_idling_resource_2_2_2.xml
│ ├── Gradle__com_android_support_test_espresso_espresso_idling_resource_2_2_2.xml
│ ├── com_android_support_test_exposed_instrumentation_api_publish_0_5.xml
│ └── Gradle__com_android_support_test_exposed_instrumentation_api_publish_0_5.xml
└── codeStyles
│ └── Project.xml
├── local.properties
├── gradle.properties
├── tracking-location-provider-android.iml
└── README.md
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/bgservice.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/bgservice.jpeg
--------------------------------------------------------------------------------
/mainpage.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/mainpage.jpeg
--------------------------------------------------------------------------------
/notification.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/notification.jpeg
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Track Demo
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/ic_car-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/ic_car-web.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-hdpi/ic_car.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-mdpi/ic_car.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-xhdpi/ic_car.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_car.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_car.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-hdpi/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-mdpi/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-xhdpi/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi-v11/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-hdpi-v11/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi-v9/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-hdpi-v9/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi-v11/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-mdpi-v11/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi-v9/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-mdpi-v9/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v9/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-xhdpi-v9/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-xxhdpi/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v11/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-xhdpi-v11/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v11/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-xxhdpi-v11/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v9/ic_trans_notifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinraj/tracking-location-provider-android/HEAD/app/src/main/res/drawable-xxhdpi-v9/ic_trans_notifi.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jul 31 12:25:15 IST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/.idea/libraries/android_android_27.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__android_android_27.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/com_google_code_findbugs_jsr305_2_0_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_constraint_constraint_layout_solver_1_0_2_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_constraint_constraint_layout_solver_1_0_2_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/test/java/com/marty/track/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.marty.track;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | #Sun Jan 21 02:08:51 IST 2018
11 | sdk.dir=C\:\\Users\\lenovo\\AppData\\Local\\Android\\Sdk
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_v4_25_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/junit_junit_4_12_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/marty/track/BroadcastLocationChange.java:
--------------------------------------------------------------------------------
1 | package com.marty.track;
2 |
3 | import android.app.IntentService;
4 | import android.content.Intent;
5 | import android.support.annotation.Nullable;
6 |
7 | /**
8 | * Created by Marty on 11/25/2017.
9 | */
10 |
11 | class BroadcastLocationChange extends IntentService{
12 |
13 | public BroadcastLocationChange(String name) {
14 | super(name);
15 | }
16 |
17 | @Override
18 | protected void onHandleIntent(@Nullable Intent intent) {
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_support_v4_25_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__junit_junit_4_12_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/com_google_android_gms_play_services_base_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/com_google_android_gms_play_services_maps_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/com_google_android_gms_play_services_tasks_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_constraint_constraint_layout_1_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_google_android_gms_play_services_base_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_google_android_gms_play_services_maps_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/com_google_android_gms_play_services_basement_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/com_google_android_gms_play_services_location_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/javax_inject_javax_inject_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_constraint_constraint_layout_1_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_google_android_gms_play_services_tasks_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/android_arch_core_common_1_0_0_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/com_squareup_javawriter_2_1_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_google_android_gms_play_services_basement_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_google_android_gms_play_services_location_11_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__javax_inject_javax_inject_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/org_hamcrest_hamcrest_core_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__android_arch_core_common_1_0_0_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/android_arch_lifecycle_common_1_0_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/org_hamcrest_hamcrest_library_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__android_arch_lifecycle_common_1_0_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/org_hamcrest_hamcrest_integration_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/javax_annotation_javax_annotation_api_1_2_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__javax_annotation_javax_annotation_api_1_2_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_annotations_27_0_2_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_support_annotations_27_0_2_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/android_arch_lifecycle_runtime_1_0_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__android_arch_lifecycle_runtime_1_0_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_appcompat_v7_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_compat_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_appcompat_v7_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_core_ui_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_fragment_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_support_compat_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_support_core_ui_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_core_utils_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_support_fragment_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_support_core_utils_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_vector_drawable_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_animated_vector_drawable_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_support_vector_drawable_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_animated_vector_drawable_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_rules_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_runner_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_test_rules_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_test_runner_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/marty/track/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.marty.track;
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 | * Instrumentation 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() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.marty.track", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_espresso_espresso_core_2_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_media_compat_25_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_test_espresso_espresso_core_2_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_support_media_compat_25_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in M:\android\studiosdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/marty/track/ConnectionDetector.java:
--------------------------------------------------------------------------------
1 | package com.marty.track;
2 |
3 | /**
4 | * Created by Marty on 8/25/2015.
5 | */
6 | import android.content.Context;
7 | import android.net.ConnectivityManager;
8 | import android.net.NetworkInfo;
9 |
10 | public class ConnectionDetector {
11 |
12 | private Context _context;
13 |
14 | public ConnectionDetector(Context context){
15 | this._context = context;
16 | }
17 |
18 | public boolean isConnectingToInternet(){
19 | ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
20 | if (connectivity != null)
21 | {
22 | NetworkInfo networkInfo = connectivity.getActiveNetworkInfo();
23 | if (networkInfo != null && networkInfo.isConnected()) {
24 | // Network is present and connected
25 | return true;
26 | }else{
27 | return false;
28 | }
29 | }
30 | return false;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_espresso_espresso_idling_resource_2_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_test_espresso_espresso_idling_resource_2_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_exposed_instrumentation_api_publish_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_android_support_test_exposed_instrumentation_api_publish_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | buildToolsVersion "27.0.1"
6 | defaultConfig {
7 | applicationId "com.marty.track"
8 | minSdkVersion 19
9 | targetSdkVersion 27
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | compile 'com.android.support:appcompat-v7:27.0.2'
28 | compile 'com.android.support.constraint:constraint-layout:1.0.2'
29 | compile 'com.google.android.gms:play-services-location:11.0.1'
30 | compile 'com.google.android.gms:play-services-maps:11.0.1'
31 | testCompile 'junit:junit:4.12'
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
27 |
33 |
34 |
--------------------------------------------------------------------------------
/tracking-location-provider-android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
17 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
35 |
36 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/marty/track/UploadLocationService.java:
--------------------------------------------------------------------------------
1 | package com.marty.track;
2 |
3 | import android.app.IntentService;
4 | import android.content.Intent;
5 | import android.location.Location;
6 | import android.os.Bundle;
7 | import android.support.annotation.Nullable;
8 | import android.util.Log;
9 |
10 | import org.json.JSONArray;
11 | import org.json.JSONObject;
12 |
13 | import java.net.MalformedURLException;
14 | import java.net.URL;
15 | import java.util.ArrayList;
16 |
17 |
18 | /**
19 | * Created by Marty on 12/20/2017.
20 | */
21 |
22 | public class UploadLocationService extends IntentService{
23 |
24 | ArrayList points;
25 |
26 | public UploadLocationService(){
27 | super("UploadLocationService");
28 | }
29 | public UploadLocationService(String name) {
30 | super(name);
31 | }
32 |
33 | @Override
34 | protected void onHandleIntent(@Nullable Intent intent) {
35 | if(intent !=null) {
36 | Bundle b = intent.getExtras();
37 | if (b != null) {
38 | points = intent.getParcelableArrayListExtra("points");
39 | URL url;
40 | try {
41 | url = new URL("http://localhost:8000/trackdrivertrip/update"); // set your server url
42 | sendLocation(url,"");
43 | } catch (MalformedURLException e) {
44 | e.printStackTrace();
45 | }
46 | }
47 | }
48 | }
49 |
50 | private void sendLocation(URL url,String token){
51 | try {
52 | String jsonResp;
53 | int code = 0;
54 | JSONObject jsonObject = new JSONObject();
55 | jsonObject.put("id","userid");
56 | JSONArray pointsArray = new JSONArray();
57 | for (int i = 0; i < points.size(); i++) {
58 | pointsArray.put(new JSONArray().put(points.get(i).getLongitude()).put(points.get(i).getLatitude()));
59 | }
60 | jsonObject.put("coordinates",pointsArray);
61 | Log.d("data sent", jsonObject.toString());
62 | if (pointsArray.length() != 0) {
63 | jsonResp = ServiceCall.doServerCall("POST", url, pointsArray.toString(), token);
64 | if (jsonResp != null && jsonResp.equals(ServiceCall.TIME_OUT)) {
65 | code = 500;
66 | return;
67 | } else if (jsonResp == null) {
68 | code = 500;
69 | return;
70 | }
71 | // Log.d("resp", jsonResp);
72 | // JSONObject json = new JSONObject(jsonResp);
73 | // code = Integer.parseInt(json.getString("code"));
74 | } else {
75 | code = 100;
76 | }
77 |
78 | } catch (Exception e){
79 | e.printStackTrace();
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/com/marty/track/ServiceCall.java:
--------------------------------------------------------------------------------
1 | package com.marty.track;
2 |
3 | import android.util.Log;
4 |
5 | import org.json.JSONArray;
6 | import org.json.JSONObject;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.BufferedWriter;
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.io.InputStreamReader;
13 | import java.io.OutputStreamWriter;
14 | import java.io.Writer;
15 | import java.net.HttpURLConnection;
16 | import java.net.SocketTimeoutException;
17 | import java.net.URL;
18 |
19 | /**
20 | * Created by Marty on 3/20/2017.
21 | */
22 |
23 | public class ServiceCall {
24 | public static final String TIME_OUT="timeout";
25 | public static String doServerCall(String method, URL url, String jsonData, String token){
26 | HttpURLConnection connection = null;
27 | Boolean postPut;
28 | postPut = method.equals("POST") || method.equals("PUT") || method.equals("DELETE");
29 | try {
30 | connection = (HttpURLConnection)url.openConnection();
31 | connection.setRequestMethod(method);
32 | connection.setRequestProperty("Accept", "application/json");
33 | connection.setRequestProperty("Content-Type", "application/json");
34 | connection.setRequestProperty("token", token);
35 | connection.setDoOutput(postPut);
36 | connection.setConnectTimeout(60000);
37 | connection.setReadTimeout(60000);
38 | if(postPut) {
39 | if(jsonData!=null) {
40 | Writer writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
41 | writer.write(jsonData);
42 | writer.close();
43 | }else{
44 | Log.d("json data "," null");
45 | }
46 | }
47 | BufferedReader reader;
48 | InputStream inputStream = null;
49 | int status = connection.getResponseCode();
50 |
51 | if(status == 200)
52 | inputStream = connection.getInputStream();
53 | else
54 | inputStream = connection.getErrorStream();
55 |
56 | StringBuilder buffer = new StringBuilder();
57 | if (inputStream == null) {
58 | // Nothing to do.
59 | return null;
60 | }
61 | reader = new BufferedReader(new InputStreamReader(inputStream));
62 |
63 | String inputLine;
64 | while ((inputLine = reader.readLine()) != null)
65 | buffer.append(inputLine).append("\n");
66 | if (buffer.length() == 0) {
67 | // Stream was empty. No point in parsing.
68 | return null;
69 | }
70 | return buffer.toString();
71 | } catch (SocketTimeoutException e){
72 | return TIME_OUT;
73 | }
74 | catch (IOException e){
75 | e.printStackTrace();
76 | }finally{
77 | if(connection != null)
78 | connection.disconnect();
79 | }
80 | return null;
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tracking-location-provider-android
2 |
3 | In this demo, I have covered both foreground tracking and background tracking.
4 |
5 | ## Foreground Tracking
6 |
7 | Foreground Tracking will work **only if app is in foreground.** To start foreground tracking, tap on the "START FOREGROUND TRACKING" button. Before requesting for location updates, check location settings of the device as below.
8 |
9 |
10 | ```
11 | mLocationRequest = new LocationRequest();
12 | mLocationRequest.setInterval(30000);
13 | mLocationRequest.setFastestInterval(15000);
14 | mLocationRequest.setSmallestDisplacement(50); // set this as 100 to 200 if user use app while driving or motor riding
15 | mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
16 | LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
17 | .addLocationRequest(mLocationRequest);
18 | SettingsClient client = LocationServices.getSettingsClient(this);
19 | Task task = client.checkLocationSettings(builder.build());
20 | task.addOnSuccessListener(this, new OnSuccessListener() {
21 | @Override
22 | public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
23 | // All location settings are satisfied. The client can initialize
24 | // location requests here.
25 | // ...
26 | bService.setVisibility(View.GONE);
27 | startLocationUpdates();
28 | }
29 | });
30 | task.addOnFailureListener(this, new OnFailureListener() {
31 | @Override
32 | public void onFailure(@NonNull Exception e) {
33 | int statusCode = ((ApiException) e).getStatusCode();
34 | switch (statusCode) {
35 | case CommonStatusCodes.RESOLUTION_REQUIRED:
36 | // Location settings are not satisfied, but this can be fixed
37 | // by showing the user a dialog.
38 | try {
39 | // Show the dialog by calling startResolutionForResult(),
40 | // and check the result in onActivityResult().
41 | ResolvableApiException resolvable = (ResolvableApiException) e;
42 | resolvable.startResolutionForResult(MainActivity.this,
43 | REQUEST_CHECK_SETTINGS);
44 | } catch (IntentSender.SendIntentException sendEx) {
45 | // Ignore the error.
46 | }
47 | break;
48 | case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
49 | // Location settings are not satisfied. However, we have no way
50 | // to fix the settings so we won't show the dialog.
51 | break;
52 | }
53 | }
54 | });
55 | ```
56 |
57 |
58 | Note: No need to show notication, as location is taken when the app is in foreground.
59 |
60 | ## Background Tracking
61 |
62 | Background Tracking is need when you want to track user location even after your app is closed or killed from task. For background tracking you must notify users via foreground notification while getting location. For this purpose we are using foreground service named(LocationJobService.java). Android versions > 7.1 restricts background location process even though foreground service is used. You cannot override this, and you will get 3 0r 4 location updates for 1 hour period. For more information, [refer here](https://developer.android.com/about/versions/oreo/background-location-limits)
63 |
64 | ## Screenshots
65 | 
66 | 
67 | 
68 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | generateDebugSources
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/app/src/main/java/com/marty/track/LocationJobService.java:
--------------------------------------------------------------------------------
1 | package com.marty.track;
2 |
3 | import android.Manifest;
4 | import android.app.Notification;
5 | import android.app.NotificationChannel;
6 | import android.app.NotificationManager;
7 | import android.app.job.JobParameters;
8 | import android.app.job.JobService;
9 | import android.content.BroadcastReceiver;
10 | import android.content.Context;
11 | import android.content.Intent;
12 | import android.content.IntentFilter;
13 | import android.content.pm.PackageManager;
14 | import android.location.Location;
15 | import android.media.RingtoneManager;
16 | import android.os.Build;
17 | import android.os.Bundle;
18 | import android.os.Handler;
19 | import android.support.annotation.NonNull;
20 | import android.support.annotation.Nullable;
21 | import android.support.annotation.RequiresApi;
22 | import android.support.v4.app.ActivityCompat;
23 | import android.support.v4.app.NotificationCompat;
24 | import android.support.v4.content.ContextCompat;
25 | import android.support.v4.content.LocalBroadcastManager;
26 | import android.util.Log;
27 | import android.widget.Toast;
28 |
29 | import com.google.android.gms.common.ConnectionResult;
30 | import com.google.android.gms.common.api.GoogleApiClient;
31 | import com.google.android.gms.location.FusedLocationProviderClient;
32 | import com.google.android.gms.location.LocationCallback;
33 | import com.google.android.gms.location.LocationRequest;
34 | import com.google.android.gms.location.LocationResult;
35 | import com.google.android.gms.location.LocationServices;
36 | import com.google.android.gms.location.LocationSettingsRequest;
37 | import com.google.android.gms.location.LocationSettingsResponse;
38 | import com.google.android.gms.location.SettingsClient;
39 | import com.google.android.gms.tasks.OnSuccessListener;
40 | import com.google.android.gms.tasks.Task;
41 |
42 | import java.util.ArrayList;
43 |
44 | import static com.marty.track.MainActivity.JOB_STATE_CHANGED;
45 | import static com.marty.track.MainActivity.LOCATION_ACQUIRED;
46 |
47 | /**
48 | * Created by Marty on 11/25/2017.
49 | */
50 |
51 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
52 | public class LocationJobService extends JobService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
53 |
54 | Handler handler;
55 | ConnectionDetector cd;
56 | FusedLocationProviderClient mFusedLocationProviderClient;
57 | public static final int LOCATION_SERVICE_JOB_ID = 111;
58 | LocationRequest mLocationRequest;
59 | LocationCallback mLocationCallback;
60 | JobParameters jobParameters;
61 | public static boolean isJobRunning = false;
62 | GoogleApiClient mGoogleApiClient;
63 | ArrayList updatesList = new ArrayList<>();
64 |
65 | public static final String ACTION_STOP_JOB = "actionStopJob";
66 |
67 | private BroadcastReceiver stopJobReceiver = new BroadcastReceiver() {
68 |
69 | @Override
70 | public void onReceive(Context context, Intent intent) {
71 | if(intent.getAction()!=null && intent.getAction().equals(ACTION_STOP_JOB)) {
72 | Log.d("unregister"," job stop receiver");
73 | /*try {
74 | unregisterReceiver(this); //Unregister receiver to avoid receiver leaks exception
75 | }catch (Exception e){
76 | e.printStackTrace();
77 | }*/
78 | onJobFinished();
79 | }
80 | }
81 | };
82 |
83 | private void onJobFinished() {
84 | Log.d("job finish"," called");
85 | isJobRunning = false;
86 | stopLocationUpdates();
87 | jobFinished(jobParameters,false);
88 | }
89 |
90 | @Override
91 | public boolean onStartJob(JobParameters jobParameters) {
92 | handler = new Handler();
93 | this.jobParameters = jobParameters;
94 | /*th = new LocationThread();
95 | handler.post(th);*/
96 | buildGoogleApiClient();
97 | config();
98 | isJobRunning = true;
99 | return true;
100 | }
101 |
102 | private void config() {
103 | mLocationRequest = new LocationRequest();
104 | mLocationRequest.setInterval(10000);
105 | mLocationRequest.setFastestInterval(5000);
106 | mLocationRequest.setSmallestDisplacement(10);
107 | mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
108 | cd = new ConnectionDetector(getApplicationContext());
109 | startLocationUpdates();
110 | LocalBroadcastManager.getInstance(LocationJobService.this).registerReceiver(stopJobReceiver , new IntentFilter(ACTION_STOP_JOB));
111 | }
112 |
113 | private void startLocationUpdates() {
114 | mLocationCallback = new LocationCallback() {
115 | @Override
116 | public void onLocationResult(LocationResult locationResult) {
117 | for (Location location : locationResult.getLocations()) {
118 | // Update UI with location data
119 | // ...
120 | // Toast.makeText(getBaseContext(),"new point",Toast.LENGTH_SHORT).show();
121 | Intent i = new Intent(LOCATION_ACQUIRED);
122 | i.putExtra("location",location);
123 |
124 | LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(i);
125 |
126 | if(cd.isConnectingToInternet()) { // check whether internet is available or not
127 | updatesList.add(location); //if available add latest location point and send list to server
128 | Intent i1 = new Intent(LocationJobService.this, UploadLocationService.class);
129 | i1.putParcelableArrayListExtra("points", updatesList);
130 | // startService(i1); //i have disabled the call as the server URL in intent service is dummy URL. Change the URL to your server URL and call this intent service
131 | updatesList.clear();
132 | }else{ // if there is no internet connection
133 | updatesList.add(location); // add location points to the list
134 | }
135 | }
136 | }
137 |
138 | ;
139 | };
140 | if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
141 | // TODO: Consider calling
142 | // ActivityCompat#requestPermissions
143 | // here to request the missing permissions, and then overriding
144 | // public void onRequestPermissionsResult(int requestCode, String[] permissions,
145 | // int[] grantResults)
146 | // to handle the case where the user grants the permission. See the documentation
147 | // for ActivityCompat#requestPermissions for more details.
148 | Toast.makeText(getApplicationContext(),"permission required !!",Toast.LENGTH_SHORT).show();
149 | return;
150 | }
151 | mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(LocationJobService.this);
152 | mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,
153 | mLocationCallback,
154 | null /* Looper */);
155 | getSharedPreferences("track",MODE_PRIVATE).edit().putBoolean("isServiceStarted",true).apply();
156 | Intent jobStartedMessage = new Intent(JOB_STATE_CHANGED);
157 | jobStartedMessage.putExtra("isStarted",true);
158 | Log.d("send broadcast"," as job started");
159 | LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(jobStartedMessage);
160 | createNotification();
161 | Toast.makeText(getApplicationContext(),"Location job service started",Toast.LENGTH_SHORT).show();
162 | }
163 |
164 | private void buildGoogleApiClient() {
165 | if(mGoogleApiClient==null) {
166 | mGoogleApiClient = new GoogleApiClient.Builder(this)
167 | .addApi(LocationServices.API)
168 | .addConnectionCallbacks(this)
169 | .addOnConnectionFailedListener(this)
170 | .build();
171 | mGoogleApiClient.connect();
172 | }else{
173 | Log.e("api client","not null");
174 | }
175 | }
176 |
177 |
178 |
179 | @Override
180 | public boolean onStopJob(JobParameters jobParameters) {
181 | Log.d("job","stopped");
182 | if(mGoogleApiClient!=null){
183 | mGoogleApiClient.disconnect();
184 | }
185 | isJobRunning = false;
186 | stopLocationUpdates();
187 | /*try {
188 | LocalBroadcastManager.getInstance(getBaseContext()).unregisterReceiver(stopJobReceiver);
189 | }catch (Exception e){
190 | e.printStackTrace();
191 | }*/
192 | return true;
193 | }
194 |
195 | @Override
196 | public void onConnected(@Nullable Bundle bundle) {
197 | Log.i("track.JobService","google API client connected");
198 | }
199 |
200 | @Override
201 | public void onConnectionSuspended(int i) {
202 | Log.i("track.JobService","google API client suspended");
203 | }
204 |
205 | @Override
206 | public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
207 | Log.i("track.JobService","google API client failed");
208 | }
209 |
210 | private void createNotification() {
211 | Notification.Builder mBuilder = new Notification.Builder(
212 | getBaseContext());
213 | Notification notification = null;
214 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
215 | notification = mBuilder.setSmallIcon(R.drawable.ic_trans_notifi).setTicker("Tracking").setWhen(0)
216 | .setAutoCancel(false)
217 | .setCategory(Notification.EXTRA_BIG_TEXT)
218 | .setContentTitle("Tracking")
219 | .setContentText("Your trip in progress")
220 | .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
221 | .setColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimaryDark))
222 | .setStyle(new Notification.BigTextStyle()
223 | .bigText("Track in progress"))
224 | .setChannelId("track_marty")
225 | .setShowWhen(true)
226 | .setOngoing(true)
227 | .build();
228 | }else{
229 | notification = mBuilder.setSmallIcon((Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)? R.drawable.ic_trans_notifi:R.mipmap.ic_launcher).setTicker("Tracking").setWhen(0)
230 | .setAutoCancel(false)
231 | .setCategory(Notification.EXTRA_BIG_TEXT)
232 | .setContentTitle("Tracking")
233 | .setContentText("Track in progress")
234 | .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
235 | .setColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimaryDark))
236 | .setStyle(new Notification.BigTextStyle()
237 | .bigText("Track in progress"))
238 | .setPriority(Notification.PRIORITY_HIGH)
239 | .setShowWhen(true)
240 | .setOngoing(true)
241 | .build();
242 | }
243 | NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
244 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
245 | NotificationChannel mChannel = new NotificationChannel("track_marty", "Track", NotificationManager.IMPORTANCE_HIGH);
246 | assert notificationManager != null;
247 | notificationManager.createNotificationChannel(mChannel);
248 | }
249 | /*assert notificationManager != null;
250 | notificationManager.notify(0, notification);*/
251 | startForeground(1,notification); //for foreground service, don't use 0 as id. it will not work.
252 | }
253 |
254 | private void removeNotification(){
255 | /*NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
256 | assert notificationManager != null;
257 | notificationManager.cancel(0);*/ //use this for normal service
258 | stopForeground(true); // use this for foreground service
259 | }
260 |
261 | private void stopLocationUpdates() {
262 |
263 | // It is a good practice to remove location requests when the activity is in a paused or
264 | // stopped state. Doing so helps battery performance and is especially
265 | // recommended in applications that request frequent location updates.
266 | Log.d("stop location "," updates called");
267 | if(mLocationCallback!=null && mFusedLocationProviderClient!=null) {
268 | mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback);
269 | Toast.makeText(getApplicationContext(), "Location job service stopped.", Toast.LENGTH_SHORT).show();
270 | }
271 | getSharedPreferences("track",MODE_PRIVATE).edit().putBoolean("isServiceStarted",false).apply();
272 | Intent jobStoppedMessage = new Intent(JOB_STATE_CHANGED);
273 | jobStoppedMessage.putExtra("isStarted",false);
274 | Log.d("broadcasted","job state change");
275 | removeNotification();
276 | LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(jobStoppedMessage);
277 | }
278 | }
279 |
--------------------------------------------------------------------------------
/app/src/main/java/com/marty/track/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.marty.track;
2 |
3 | import android.Manifest;
4 | import android.animation.Animator;
5 | import android.animation.ObjectAnimator;
6 | import android.animation.TypeEvaluator;
7 | import android.app.Activity;
8 | import android.app.IntentService;
9 | import android.app.job.JobInfo;
10 | import android.app.job.JobScheduler;
11 | import android.content.BroadcastReceiver;
12 | import android.content.ComponentName;
13 | import android.content.Context;
14 | import android.content.Intent;
15 | import android.content.IntentFilter;
16 | import android.content.IntentSender;
17 | import android.content.pm.PackageManager;
18 | import android.location.Location;
19 | import android.os.Build;
20 | import android.os.Handler;
21 | import android.os.PersistableBundle;
22 | import android.os.ResultReceiver;
23 | import android.support.annotation.NonNull;
24 | import android.support.annotation.Nullable;
25 | import android.support.annotation.RequiresApi;
26 | import android.support.v4.app.ActivityCompat;
27 | import android.support.v4.app.FragmentTransaction;
28 | import android.support.v4.content.LocalBroadcastManager;
29 | import android.support.v7.app.AppCompatActivity;
30 | import android.os.Bundle;
31 | import android.util.Log;
32 | import android.util.Property;
33 | import android.view.View;
34 | import android.widget.Button;
35 | import android.widget.Toast;
36 |
37 | import com.google.android.gms.common.api.ApiException;
38 | import com.google.android.gms.common.api.CommonStatusCodes;
39 | import com.google.android.gms.common.api.ResolvableApiException;
40 | import com.google.android.gms.location.FusedLocationProviderClient;
41 | import com.google.android.gms.location.LocationCallback;
42 | import com.google.android.gms.location.LocationRequest;
43 | import com.google.android.gms.location.LocationResult;
44 | import com.google.android.gms.location.LocationServices;
45 | import com.google.android.gms.location.LocationSettingsRequest;
46 | import com.google.android.gms.location.LocationSettingsResponse;
47 | import com.google.android.gms.location.LocationSettingsStatusCodes;
48 | import com.google.android.gms.location.SettingsClient;
49 | import com.google.android.gms.maps.CameraUpdate;
50 | import com.google.android.gms.maps.CameraUpdateFactory;
51 | import com.google.android.gms.maps.GoogleMap;
52 | import com.google.android.gms.maps.OnMapReadyCallback;
53 | import com.google.android.gms.maps.SupportMapFragment;
54 | import com.google.android.gms.maps.model.BitmapDescriptor;
55 | import com.google.android.gms.maps.model.BitmapDescriptorFactory;
56 | import com.google.android.gms.maps.model.LatLng;
57 | import com.google.android.gms.maps.model.Marker;
58 | import com.google.android.gms.maps.model.MarkerOptions;
59 | import com.google.android.gms.tasks.OnFailureListener;
60 | import com.google.android.gms.tasks.OnSuccessListener;
61 | import com.google.android.gms.tasks.Task;
62 |
63 |
64 | public class MainActivity extends AppCompatActivity {
65 | FusedLocationProviderClient mFusedLocationProviderClient;
66 | protected static final int REQUEST_CHECK_SETTINGS = 0x1;
67 | LocationRequest mLocationRequest;
68 | LocationCallback mLocationCallback;
69 | Button button,bService;
70 | SupportMapFragment mapFragment;
71 | GoogleMap mMap;
72 | boolean mapLoaded = false;
73 | Marker carMarker;
74 | static MoveThread moveThread;
75 | static Handler handler;
76 | Location oldLocation;
77 | float bearing;
78 | boolean registered = false, isServiceStarted=false;
79 | public static final String JOB_STATE_CHANGED = "jobStateChanged";
80 | public static final String LOCATION_ACQUIRED = "locAcquired";
81 |
82 | @Override
83 | protected void onCreate(Bundle savedInstanceState) {
84 | super.onCreate(savedInstanceState);
85 | setContentView(R.layout.activity_main);
86 | mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
87 | button = (Button) findViewById(R.id.b_action);
88 | bService = (Button) findViewById(R.id.b_service);
89 | mapFragment = SupportMapFragment.newInstance();
90 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
91 | transaction.add(R.id.map_fragment, mapFragment).commitAllowingStateLoss();
92 | handler = new Handler();
93 | mapFragment.getMapAsync(new OnMapReadyCallback() {
94 | @Override
95 | public void onMapReady(GoogleMap googleMap) {
96 | mMap = googleMap;
97 | CameraUpdate point = CameraUpdateFactory.newLatLngZoom(new LatLng(13.0827,80.2707),8);
98 | mMap.moveCamera(point);
99 | mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
100 | @Override
101 | public void onMapLoaded() {
102 | mapLoaded = true;
103 | mMap.getUiSettings().setAllGesturesEnabled(true);
104 | mMap.getUiSettings().setZoomControlsEnabled(true);
105 | }
106 | });
107 | }
108 | });
109 | isServiceStarted = getSharedPreferences("track",MODE_PRIVATE).getBoolean("isServiceStarted",false);
110 | /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
111 | isServiceStarted = LocationJobService.isJobRunning;
112 | }else{
113 | isServiceStarted = false;
114 | }*/
115 | changeServiceButton(isServiceStarted);
116 | if(!registered&&isServiceStarted) {
117 | IntentFilter i = new IntentFilter(JOB_STATE_CHANGED);
118 | i.addAction(LOCATION_ACQUIRED);
119 | LocalBroadcastManager.getInstance(this).registerReceiver(jobStateChanged, i);
120 | }
121 |
122 | }
123 |
124 | public void OnButtonClick(View view) {
125 | switch (view.getId()) {
126 | case R.id.b_action:
127 | if (view.getTag().equals("s")) {
128 | createLocationRequest();
129 | } else {
130 | Log.d("clicked", "button");
131 | stopLocationUpdates();
132 | }
133 | break;
134 | case R.id.b_service:
135 | if(view.getTag().equals("s")){
136 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
137 | Log.d("registered"," on start service");
138 | startBackgroundService();
139 | }else{
140 | Toast.makeText(getBaseContext(),"service for pre lollipop will be available in next update",Toast.LENGTH_LONG).show();
141 | }
142 | }else{
143 | stopBackgroundService();
144 | }
145 | break;
146 | }
147 | }
148 |
149 | private BroadcastReceiver jobStateChanged = new BroadcastReceiver() {
150 |
151 | @Override
152 | public void onReceive(Context context, Intent intent) {
153 | if(intent.getAction()==null){
154 | return;
155 | }
156 | if(intent.getAction().equals(JOB_STATE_CHANGED)) {
157 | changeServiceButton(intent.getExtras().getBoolean("isStarted"));
158 | }else if (intent.getAction().equals(LOCATION_ACQUIRED)){
159 | if(intent.getExtras()!=null){
160 | Bundle b = intent.getExtras();
161 | Location l = b.getParcelable("location");
162 | updateMarker(l);
163 | }else{
164 | Log.d("intent","null");
165 | }
166 | }
167 | }
168 | };
169 |
170 | private void changeServiceButton(boolean isStarted) {
171 | if(isStarted){
172 | bService.setTag("f");
173 | bService.setText("STOP BACKGROUND TRACKING");
174 | button.setVisibility(View.GONE);
175 | }else{
176 | bService.setTag("s");
177 | bService.setText("START BACKGROUND TRACKING");
178 | button.setVisibility(View.VISIBLE);
179 | }
180 | }
181 |
182 | private void stopBackgroundService() {
183 | if(getSharedPreferences("track",MODE_PRIVATE).getBoolean("isServiceStarted",false)){
184 | Log.d("registered"," on stop service");
185 | Intent stopJobService = null;
186 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
187 | stopJobService = new Intent(LocationJobService.ACTION_STOP_JOB);
188 | LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(stopJobService);
189 | changeServiceButton(false);
190 | }else{
191 | Toast.makeText(getApplicationContext(),"yet to be coded - stop service",Toast.LENGTH_SHORT).show();
192 | }
193 | }
194 | }
195 |
196 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
197 | private void startBackgroundService() {
198 | if(!registered) {
199 | IntentFilter i = new IntentFilter(JOB_STATE_CHANGED);
200 | i.addAction(LOCATION_ACQUIRED);
201 | LocalBroadcastManager.getInstance(this).registerReceiver(jobStateChanged, i);
202 | }
203 | JobScheduler jobScheduler =
204 | (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
205 | assert jobScheduler != null;
206 | jobScheduler.schedule(new JobInfo.Builder(LocationJobService.LOCATION_SERVICE_JOB_ID,
207 | new ComponentName(this, LocationJobService.class))
208 | .setOverrideDeadline(500)
209 | .setPersisted(true)
210 | .setRequiresDeviceIdle(false)
211 | .build());
212 | }
213 |
214 | protected void createLocationRequest() {
215 | mLocationRequest = new LocationRequest();
216 | mLocationRequest.setInterval(30000);
217 | mLocationRequest.setFastestInterval(15000);
218 | mLocationRequest.setSmallestDisplacement(50);
219 | mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
220 | LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
221 | .addLocationRequest(mLocationRequest);
222 | SettingsClient client = LocationServices.getSettingsClient(this);
223 | Task task = client.checkLocationSettings(builder.build());
224 | task.addOnSuccessListener(this, new OnSuccessListener() {
225 | @Override
226 | public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
227 | // All location settings are satisfied. The client can initialize
228 | // location requests here.
229 | // ...
230 | bService.setVisibility(View.GONE);
231 | startLocationUpdates();
232 | }
233 | });
234 | task.addOnFailureListener(this, new OnFailureListener() {
235 | @Override
236 | public void onFailure(@NonNull Exception e) {
237 | int statusCode = ((ApiException) e).getStatusCode();
238 | switch (statusCode) {
239 | case CommonStatusCodes.RESOLUTION_REQUIRED:
240 | // Location settings are not satisfied, but this can be fixed
241 | // by showing the user a dialog.
242 | try {
243 | // Show the dialog by calling startResolutionForResult(),
244 | // and check the result in onActivityResult().
245 | ResolvableApiException resolvable = (ResolvableApiException) e;
246 | resolvable.startResolutionForResult(MainActivity.this,
247 | REQUEST_CHECK_SETTINGS);
248 | } catch (IntentSender.SendIntentException sendEx) {
249 | // Ignore the error.
250 | }
251 | break;
252 | case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
253 | // Location settings are not satisfied. However, we have no way
254 | // to fix the settings so we won't show the dialog.
255 | break;
256 | }
257 | }
258 | });
259 | }
260 |
261 | private void startLocationUpdates() {
262 | mLocationCallback = new LocationCallback() {
263 | @Override
264 | public void onLocationResult(LocationResult locationResult) {
265 | for (Location location : locationResult.getLocations()) {
266 | // Update UI with location data
267 | // ...
268 | updateMarker(location);
269 | }
270 | }
271 |
272 | ;
273 | };
274 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
275 | // TODO: Consider calling
276 | // ActivityCompat#requestPermissions
277 | // here to request the missing permissions, and then overriding
278 | // public void onRequestPermissionsResult(int requestCode, String[] permissions,
279 | // int[] grantResults)
280 | // to handle the case where the user grants the permission. See the documentation
281 | // for ActivityCompat#requestPermissions for more details.
282 | Toast.makeText(getApplicationContext(),"location permission required !!",Toast.LENGTH_SHORT).show();
283 | return;
284 | }
285 | mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,
286 | mLocationCallback,
287 | null /* Looper */);
288 | button.setTag("f");
289 | button.setText("STOP FOREGROUND TRACKING");
290 | // Toast.makeText(getApplicationContext(),"Location update started",Toast.LENGTH_SHORT).show();
291 | }
292 | private void stopLocationUpdates() {
293 | if (button.getTag().equals("s")) {
294 | Log.d("TRACK", "stopLocationUpdates: updates never requested, no-op.");
295 | return;
296 | }
297 |
298 | // It is a good practice to remove location requests when the activity is in a paused or
299 | // stopped state. Doing so helps battery performance and is especially
300 | // recommended in applications that request frequent location updates.
301 | mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback);
302 | button.setTag("s");
303 | button.setText("START FOREGROUND TRACKING");
304 | bService.setVisibility(View.VISIBLE);
305 | // Toast.makeText(getApplicationContext(),"Location update stopped.",Toast.LENGTH_SHORT).show();
306 | }
307 |
308 | @Override
309 | protected void onDestroy() {
310 | try {
311 | if (registered) {
312 | unregisterReceiver(jobStateChanged);
313 | }
314 | }catch (Exception e){
315 | e.printStackTrace();
316 | }
317 | super.onDestroy();
318 | }
319 |
320 | @Override
321 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
322 | if( requestCode == REQUEST_CHECK_SETTINGS) {
323 | switch (resultCode) {
324 | case Activity.RESULT_OK:
325 | Log.i("Dash", "User agreed to make required location settings changes.");
326 | createLocationRequest();
327 | break;
328 | case Activity.RESULT_CANCELED:
329 | // showTimeoutDialog("Without location access, GreenPool Enterprise can't be used !!", true);
330 | Log.i("Dash", "User choose not to make required location settings changes.");
331 | break;
332 | }
333 | }else{
334 | super.onActivityResult(requestCode, resultCode, data);
335 | }
336 | }
337 |
338 | static void animateMarkerToICS(Marker marker, LatLng finalPosition) {
339 | TypeEvaluator typeEvaluator = new TypeEvaluator() {
340 | @Override
341 | public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
342 | return interpolate(fraction, startValue, endValue);
343 | }
344 | };
345 | Property property = Property.of(Marker.class, LatLng.class, "position");
346 | ObjectAnimator animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition);
347 | animator.setDuration(3000);
348 | animator.addListener(new Animator.AnimatorListener() {
349 | @Override
350 | public void onAnimationStart(Animator animator) {
351 |
352 | }
353 |
354 | @Override
355 | public void onAnimationEnd(Animator animator) {
356 | handler.post(moveThread);
357 | }
358 |
359 | @Override
360 | public void onAnimationCancel(Animator animator) {
361 |
362 | }
363 |
364 | @Override
365 | public void onAnimationRepeat(Animator animator) {
366 |
367 | }
368 | });
369 | animator.start();
370 | }
371 |
372 | public static LatLng interpolate(float fraction, LatLng a, LatLng b) {
373 | // function to calculate the in between values of old latlng and new latlng.
374 | // To get more accurate tracking(Car will always be in the road even when the latlng falls away from road), use roads api from Google apis.
375 | // As it has quota limits I didn't have used that method.
376 | double lat = (b.latitude - a.latitude) * fraction + a.latitude;
377 | double lngDelta = b.longitude - a.longitude;
378 |
379 | // Take the shortest path across the 180th meridian.
380 | if (Math.abs(lngDelta) > 180) {
381 | lngDelta -= Math.signum(lngDelta) * 360;
382 | }
383 | double lng = lngDelta * fraction + a.longitude;
384 | return new LatLng(lat, lng);
385 | }
386 |
387 | private class MoveThread implements Runnable {
388 | LatLng newPoint;
389 | float zoom = 16;
390 |
391 | void setNewPoint(LatLng latLng, float zoom){
392 | this.newPoint = latLng;
393 | this.zoom = zoom;
394 | }
395 |
396 | @Override
397 | public void run() {
398 | final CameraUpdate point = CameraUpdateFactory.newLatLngZoom(newPoint,zoom);
399 | runOnUiThread(new Runnable() {
400 | @Override
401 | public void run() {
402 | mMap.animateCamera(point);
403 | }
404 | });
405 | }
406 | }
407 |
408 | private void updateMarker(Location location) {
409 | if(location == null){
410 | return;
411 | }
412 | if(mMap!=null && mapLoaded){
413 | if(carMarker==null) {
414 | oldLocation = location;
415 | MarkerOptions markerOptions = new MarkerOptions();
416 | BitmapDescriptor car = BitmapDescriptorFactory.fromResource(R.mipmap.ic_car);
417 | markerOptions.icon(car);
418 | markerOptions.anchor(0.5f, 0.5f); // set the car image to center of the point instead of anchoring to above or below the location
419 | markerOptions.flat(true); // set as true, so that when user rotates the map car icon will remain in the same direction
420 | markerOptions.position(new LatLng(location.getLatitude(),location.getLongitude()));
421 | carMarker = mMap.addMarker(markerOptions);
422 | if(location.hasBearing()){ // if location has bearing set the same bearing to marker(if location is acquired using GPS bearing will be available)
423 | bearing = location.getBearing();
424 | }else{
425 | bearing = 0; // no need to calculate bearing as it will be the first point
426 | }
427 | carMarker.setRotation(bearing);
428 | moveThread = new MoveThread();
429 | moveThread.setNewPoint(new LatLng(location.getLatitude(),location.getLongitude()),16);
430 | handler.post(moveThread);
431 |
432 | }else{
433 | if(location.hasBearing()){// if location has bearing set the same bearing to marker(if location is acquired using GPS bearing will be available)
434 | bearing = location.getBearing();
435 | }else { // if not, calculate bearing between old location and new location point
436 | bearing = oldLocation.bearingTo(location);
437 | }
438 | carMarker.setRotation(bearing);
439 | moveThread.setNewPoint(new LatLng(location.getLatitude(),location.getLongitude()),mMap.getCameraPosition().zoom); // set the map zoom to current map's zoom level as user may zoom the map while tracking.
440 | animateMarkerToICS(carMarker,new LatLng(location.getLatitude(),location.getLongitude())); // animate the marker smoothly
441 | }
442 | }else{
443 | Log.e("map null or not loaded","");
444 | }
445 | }
446 | }
447 |
--------------------------------------------------------------------------------