/** * Copyright (C) 2015 Monitordroid Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @author Tyler Butler **/ package com.monitordroid.app; import static com.monitordroid.app.CommonUtilities.LOCATION_URL; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import android.app.Service; import android.content.Intent; import android.location.Location; import android.os.AsyncTask; import android.os.Bundle; import android.os.IBinder; import com.google.android.gcm.GCMRegistrar; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesClient; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.location.LocationClient; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; public class LocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener { String regId = ""; String mTime = ""; String mAccuracy = ""; int minutesTillRefresh; private boolean currentlyProcessingLocation = false; private LocationRequest locationRequest; private LocationClient locationClient; @Override public void onCreate() { super.onCreate(); } /** * When the service is initially started, extract the desired minutes * between location refreshes from the intent */ @Override public int onStartCommand(Intent intent, int flags, int startId) { minutesTillRefresh = (Integer) intent.getExtras().get( "minutesTillRefresh"); if (!currentlyProcessingLocation) { currentlyProcessingLocation = true; startTracking(); } return START_NOT_STICKY; } /** * Connect to Google Play Services */ private void startTracking() { if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) { locationClient = new LocationClient(this, this, this); if (!locationClient.isConnected() || !locationClient.isConnecting()) { locationClient.connect(); } } else { } } /** * Stop location updates and kill the service */ @Override public void onDestroy() { stopLocationUpdates(); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return null; } /** * Called when a new location has been acquired * * Extracts the latitude, longitude, time, and accuracy from the location * object then executes an Asynctask to post them to the web server. */ @Override public void onLocationChanged(Location loc) { if (loc != null) { loc.getLatitude(); loc.getLongitude(); loc.getTime(); // Returns accuracy of location lock in meters loc.getAccuracy(); String newLat = String.valueOf(loc.getLatitude()); String newLong = String.valueOf(loc.getLongitude()); String time = String.valueOf(loc.getTime()); String formattedDate = millisToDate(Long.parseLong(time)); String accuracy = String.valueOf(loc.getAccuracy()); mTime = formattedDate; mAccuracy = accuracy; regId = GCMRegistrar.getRegistrationId(LocationService.this); new MyAsyncTask().execute(newLat, newLong); if (minutesTillRefresh == 0) { stopSelf(); } } } /** * Takes in a measured amount of milliseconds since January 1st, 1970 and * converts it into a calendar date and time * * @param currentTime * in milliseconds since January 1st, 1970 * @return The formatted calendar date of that time */ private String millisToDate(long currentTime) { String finalDate; Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(currentTime); Date date = calendar.getTime(); finalDate = date.toString(); return finalDate; } /** * Stop requesting location updates and disconnect from Google Play Services */ private void stopLocationUpdates() { if (locationClient != null && locationClient.isConnected()) { locationClient.removeLocationUpdates(this); locationClient.disconnect(); } } /** * Called by Location Services when the request to connect the client * finishes successfully. At this point, you can request the current * location or start periodic updates */ @Override public void onConnected(Bundle bundle) { locationRequest = LocationRequest.create(); if (minutesTillRefresh != 0) { locationRequest.setInterval(1000 * 60 * minutesTillRefresh); locationRequest.setFastestInterval(1000 * 60 * minutesTillRefresh); } else { locationRequest.setInterval(1); // Single update, set interval to // 1ms locationRequest.setFastestInterval(1); } locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationClient.requestLocationUpdates(locationRequest, this); } /** * Called by Location Services if the connection to the location client * drops because of an error. */ @Override public void onDisconnected() { stopLocationUpdates(); stopSelf(); } /** * Called when connection to Google Play Services failed Stops the * requesting of location updates and kill the service */ @Override public void onConnectionFailed(ConnectionResult connectionResult) { stopLocationUpdates(); stopSelf(); } private class MyAsyncTask extends AsyncTask<String, String, Double> { @Override protected Double doInBackground(String... params) { postData(params[0], params[1]); return null; } protected void onPostExecute(Double result) { } private void postData(String value1, String value2) { HttpClient httpclient = new DefaultHttpClient(); String url = LOCATION_URL; HttpPost httppost = new HttpPost(url); try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("Latitude", value1)); nameValuePairs.add(new BasicNameValuePair("Longitude", value2)); nameValuePairs.add(new BasicNameValuePair("Time", mTime)); nameValuePairs .add(new BasicNameValuePair("Accuracy", mAccuracy)); nameValuePairs.add(new BasicNameValuePair("regName", regId)); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); // Execute HTTP Post Request httpclient.execute(httppost); } catch (ClientProtocolException e) { } catch (IOException e) { } } } }