task) {
+ if (task.isSuccessful() && task.getResult() != null) {
+ mLocation = task.getResult();
+ Log.i(TAG, "getLastLocation " + mLocation);
+// Toast.makeText(getApplicationContext(), "" + mLocation, Toast.LENGTH_SHORT).show();
+ onNewLocation(mLocation);
+ } else {
+ Log.w(TAG, "Failed to get location.");
+ }
+ }
+ });
+ } catch (SecurityException unlikely) {
+ Log.e(TAG, "Lost location permission." + unlikely);
+ }
+ }
+
+ private void onNewLocation(Location location) {
+ Log.i(TAG, "New location: " + location);
+// Toast.makeText(getApplicationContext(), "onNewLocation " + location, Toast.LENGTH_LONG).show();
+
+ mLocation = location;
+ if (this.iLocationProvider != null) {
+ this.iLocationProvider.onLocationUpdate(mLocation);
+ }
+ }
+
+ /**
+ * Sets the location request parameters.
+ */
+ private void createLocationRequest() {
+ mLocationRequest = new LocationRequest();
+ mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
+ mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
+ mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+
+ /**
+ * implements this interface to get call back of location changes
+ */
+ public interface ILocationProvider {
+ void onLocationUpdate(Location location);
+ }
+}
\ No newline at end of file
diff --git a/locationTrack/src/main/java/app/prior/tracker/MainActivity.java b/locationTrack/src/main/java/app/prior/tracker/MainActivity.java
new file mode 100644
index 0000000..d695594
--- /dev/null
+++ b/locationTrack/src/main/java/app/prior/tracker/MainActivity.java
@@ -0,0 +1,130 @@
+package app.prior.tracker;
+
+import android.Manifest;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.location.Location;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.support.annotation.NonNull;
+import android.support.v4.app.ActivityCompat;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+public class MainActivity extends AppCompatActivity {
+
+ private static final String TAG = MainActivity.class.getSimpleName();
+
+ private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
+ public static final String MESSENGER_INTENT_KEY = "msg-intent-key";
+
+ // as google doc says
+ // Handler for incoming messages from the service.
+ private IncomingMessageHandler mHandler;
+ private TextView locationMsg;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ locationMsg = findViewById(R.id.location);
+
+ findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ requestPermissions();
+
+ }
+ });
+
+ findViewById(R.id.stop).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ stopService(new Intent(MainActivity.this, MyIntentService.class));
+ }
+ });
+
+ mHandler = new IncomingMessageHandler();
+
+ }
+
+ private void requestPermissions() {
+ boolean shouldProvideRationale =
+ ActivityCompat.shouldShowRequestPermissionRationale(this,
+ Manifest.permission.ACCESS_FINE_LOCATION);
+
+ // Provide an additional rationale to the user. This would happen if the user denied the
+ // request previously, but didn't check the "Don't ask again" checkbox.
+ if (shouldProvideRationale) {
+ Log.i(TAG, "Displaying permission rationale to provide additional context.");
+ // Request permission
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
+ REQUEST_PERMISSIONS_REQUEST_CODE);
+ } else {
+ Log.i(TAG, "Requesting permission");
+ // Request permission. It's possible this can be auto answered if device policy
+ // sets the permission in a given state or the user denied the permission
+ // previously and checked "Never ask again".
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
+ REQUEST_PERMISSIONS_REQUEST_CODE);
+ }
+ }
+
+ /**
+ * Callback received when a permissions request has been completed.
+ */
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
+ Log.i(TAG, "onRequestPermissionResult grantResults " + grantResults);
+ if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
+ if (grantResults.length <= 0) {
+ // If user interaction was interrupted, the permission request is cancelled and you
+ // receive empty arrays.
+ Log.i(TAG, "User interaction was cancelled.");
+ finish();
+ } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ // can be schedule in this way also
+ // Utils.scheduleJob(this, LocationUpdatesService.class);
+ //doing this way to communicate via messenger
+ // Start service and provide it a way to communicate with this class.
+ Intent startServiceIntent = new Intent(this, MyIntentService.class);
+ Messenger messengerIncoming = new Messenger(mHandler);
+ startServiceIntent.putExtra(MESSENGER_INTENT_KEY, messengerIncoming);
+ startService(startServiceIntent);
+ } else {
+ // Permission denied.
+ finish();
+ }
+ }
+ }
+
+ class IncomingMessageHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ Log.i(TAG, "handleMessage..." + msg.toString());
+
+ super.handleMessage(msg);
+
+ switch (msg.what) {
+ case MyIntentService.LOCATION_MESSAGE:
+ Location obj = (Location) msg.obj;
+ String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
+ locationMsg.setText("LAT : " + obj.getLatitude() + "\nLNG : " + obj.getLongitude() + "\n\n" + obj.toString() + " \n\n\nLast updated- " + currentDateTimeString);
+ break;
+ }
+ }
+ }
+
+
+}
diff --git a/locationTrack/src/main/java/app/prior/tracker/MyIntentService.java b/locationTrack/src/main/java/app/prior/tracker/MyIntentService.java
new file mode 100644
index 0000000..7875aea
--- /dev/null
+++ b/locationTrack/src/main/java/app/prior/tracker/MyIntentService.java
@@ -0,0 +1,94 @@
+package app.prior.tracker;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.location.Location;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+import static app.prior.tracker.MainActivity.MESSENGER_INTENT_KEY;
+
+/**
+ * An {@link IntentService} subclass for handling asynchronous task requests in
+ * a service on a separate handler thread.
+ *
+ * helper methods.
+ */
+public class MyIntentService extends IntentService implements LocationUpdatesComponent.ILocationProvider {
+ private static final String TAG = MyIntentService.class.getSimpleName();
+ public static final int LOCATION_MESSAGE = 999;
+
+ private LocationUpdatesComponent locationUpdatesComponent;
+ private Messenger mActivityMessenger;
+
+ public MyIntentService() {
+ super("MyIntentService");
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Log.i(TAG, "onCreate ");
+
+ locationUpdatesComponent = new LocationUpdatesComponent(this);
+ locationUpdatesComponent.onCreate(this);
+ }
+
+ // this makes service running continuously,,commenting this start command method service runs only once
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Log.i(TAG, "onStartCommand Service started....");
+ if (intent != null) {
+ mActivityMessenger = intent.getParcelableExtra(MESSENGER_INTENT_KEY);
+ }
+
+ //hey request for location updates
+ locationUpdatesComponent.onStart();
+ return START_STICKY;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ Log.i(TAG, "onDestroy...");
+
+ locationUpdatesComponent.onStop();
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ Log.i(TAG, "onHandleIntent" + intent);
+ if (intent != null) {
+ final String action = intent.getAction();
+ }
+ }
+
+ /**
+ * send message by using messenger
+ *
+ * @param messageID
+ */
+ private void sendMessage(int messageID, Location location) {
+ // If this service is launched by the JobScheduler, there's no callback Messenger. It
+ // only exists when the MainActivity calls startService() with the callback in the Intent.
+ if (mActivityMessenger == null) {
+ Log.d(TAG, "Service is bound, not started. There's no callback to send a message to.");
+ return;
+ }
+ Message m = Message.obtain();
+ m.what = messageID;
+ m.obj = location;
+ try {
+ mActivityMessenger.send(m);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error passing service object back to activity.");
+ }
+ }
+
+ @Override
+ public void onLocationUpdate(Location location) {
+ sendMessage(LOCATION_MESSAGE, location);
+ }
+}
diff --git a/locationTrack/src/main/res/drawable-v24/ic_launcher_foreground.xml b/locationTrack/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..c7bd21d
--- /dev/null
+++ b/locationTrack/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/locationTrack/src/main/res/drawable/ic_launcher_background.xml b/locationTrack/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..d5fccc5
--- /dev/null
+++ b/locationTrack/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/locationTrack/src/main/res/layout/activity_main.xml b/locationTrack/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..bea2047
--- /dev/null
+++ b/locationTrack/src/main/res/layout/activity_main.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/locationTrack/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/locationTrack/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/locationTrack/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/locationTrack/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/locationTrack/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/locationTrack/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/locationTrack/src/main/res/mipmap-hdpi/ic_launcher.png b/locationTrack/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a2f5908
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/locationTrack/src/main/res/mipmap-hdpi/ic_launcher_round.png b/locationTrack/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..1b52399
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/locationTrack/src/main/res/mipmap-mdpi/ic_launcher.png b/locationTrack/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..ff10afd
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/locationTrack/src/main/res/mipmap-mdpi/ic_launcher_round.png b/locationTrack/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..115a4c7
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/locationTrack/src/main/res/mipmap-xhdpi/ic_launcher.png b/locationTrack/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..dcd3cd8
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/locationTrack/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/locationTrack/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..459ca60
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/locationTrack/src/main/res/mipmap-xxhdpi/ic_launcher.png b/locationTrack/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..8ca12fe
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/locationTrack/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/locationTrack/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8e19b41
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/locationTrack/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/locationTrack/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b824ebd
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/locationTrack/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/locationTrack/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4c19a13
Binary files /dev/null and b/locationTrack/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/locationTrack/src/main/res/values/colors.xml b/locationTrack/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/locationTrack/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/locationTrack/src/main/res/values/strings.xml b/locationTrack/src/main/res/values/strings.xml
new file mode 100644
index 0000000..36994f3
--- /dev/null
+++ b/locationTrack/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Location Track
+
diff --git a/locationTrack/src/main/res/values/styles.xml b/locationTrack/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/locationTrack/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/locationTrack/src/test/java/app/prior/tracker/ExampleUnitTest.java b/locationTrack/src/test/java/app/prior/tracker/ExampleUnitTest.java
new file mode 100644
index 0000000..f8f25e7
--- /dev/null
+++ b/locationTrack/src/test/java/app/prior/tracker/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package app.prior.tracker;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file