Service to send GPS coordinates to server - android

I'm new in android and I am trying to send gps coordinates to a web server. I already get the GPS coord and request updates of them every X seconds.
What I want is to send those coords to a web server using a Service and running the service in different time intervals (user will decide how ofter he wants to update his position).
I have already searched and I want to do it the more efficient possible, that's why I think using a Service would be the best approach.
I'm having trouble knowing where to start the service and how to make it run in time intervals, also if I should use AsyncTask inside the service to POST the coords to the webserver.
Any hint would be appreciated.
Thanks!

Use an AlarmManager that starts a service every X sec.
The service should include a class that implements a location listener.
Refer this tutorial link that will helps you to know about the service and time intervals.
And you simply get the coordinates within an activity from the service and send it to the server using Async task.
Hope it will helps you.

You can do it without using AlarmManager.
I used onLocationChanged() from LocationManager
LocServ.java
import android.app.IntentService;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by BrijD on 14-12-22.
*/
public class LocServ extends Service implements LocationListener {
private static String url_insert_location = "http://172.20.10.4/testing/insert.php";
public static String LOG = "Log";
JSONParser jsonParser = new JSONParser();
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 0 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 ; // 1 second
// Declaring a Location Manager
protected LocationManager locationManager;
public LocServ(Context context){
this.mContext = context;
}
public LocServ(){
super();
mContext = LocServ.this;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
Log.i(LOG, "Service started");
Log.i("asd", "This is sparta");
new SendToServer().execute(Double.toString(getLocation().getLongitude()),Double.toString(getLocation().getLatitude()));
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
Log.i(LOG, "Service created");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG, "Service destroyed");
}
class SendToServer extends AsyncTask<String,String,String> {
#Override
protected String doInBackground(String... la ) {
try {
Log.i("string" , la[0]);
String longi = la[0];
String lati = la[1];
// Building Parameters
Log.d("value", lati);
Log.d("value", longi);
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("longitude", longi));
params.add(new BasicNameValuePair("latitude", lati));
// getting JSON Object
// Note that create product url accepts POST method
JSONObject json = jsonParser.makeHttpRequest(url_insert_location, "POST", params);
Log.d("Create Response", json.toString());
} catch (Exception e) {
Log.i("error", e.toString());
}
return "call";
}
}
public Location getLocation () {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
//updates will be send according to these arguments
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
#Override
public void onLocationChanged(Location location) {
//this will be called every second
new SendToServer().execute(Double.toString(getLocation().getLongitude()),Double.toString(getLocation().getLatitude()));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}

Use below service related code to achieve your requirement
where in onTick() method you can write your code to send data(GPS cordinate) from your device to web server even you can write your GPS related code here in this service(getting gps cordinate )
TimerService.java
package com.android.yourpackagename;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
public class TimerService extends Service {
// variables
MyCounter timer;
#Override
public void onCreate() {
timer = new MyCounter(30 * 60 * 1000, 1000);//counter of 30minutes and tick interval is //1 second(i.e.1000) you can increase its limit whatever you want as per your requirement
super.onCreate();
timer.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
private class MyCounter extends CountDownTimer {
public MyCounter(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#SuppressWarnings("static-access")
#Override
public void onFinish() {
//timer finished 30 minutes
stopSelf()//to stop service after counter stop
}
#Override
public void onTick(long millisUntilFinished) {
//timer clock tick event after each 1 second
}
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
timer.cancel();
super.onDestroy();
// call start servce here for lifetime running of service
// startService(new Intent(this, TimerService.class));
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
register your TimerService.java into manifest using below code
<service
android:name="com.android.yourpackagename.TimerService"
android:process=":TimerService" >
</service>
start service from your activity using startService() method like
startService(new Intent(getApplicationContext(), TimerService.class));
stop service using stopService() method like
stopService(new Intent(getApplicationContext(),
TimerService.class));
Hope this will help you cause it worked for me with same requirement :)

i think you should use the volley library instead of asynchronous task
this link explain the difference
and this's a method that can help you understand how to use it :
public static void postLatAndLongAndId(final Context context,String id,String imei,String latitude,String longitude) {
// Tag used to cancel the request
String tag_string_req = "req_login";
// progress bar showing
pDialog.setMessage("votre reservation est en cours de traitement ...");
showDialog();
//create jsonObject to post it
final JSONObject body = new JSONObject();
try {
body.put("id_client",id );
body.put("imei",imei);
body.put("lat",latitude);
body.put("long",longitude);
body.put("type","b2c");
// Log.e(TAG, "jsonObj body: " + body );
} catch (JSONException e) {
e.printStackTrace();
}
StringRequest strReq = new StringRequest(Method.POST,
AppConfig.URL_POSTING_USER_COORDINATES, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Log.e(TAG, "WebS Response: " + response.toString());
try {
JSONObject jObj = new JSONObject(response);
// Log.e(TAG, "affichage de jobj =: " + jObj );
String status = jObj.getString("status");
// Log.e(TAG, "status = ok ?? " + status.equals("OK") );
// Check for error node in json
if (status.equals("OK")){
//data send successfully
hideDialog();
} else {
// Error . Get the error message
String errorMsg = jObj.getString("message");
// Log.e(TAG, "webS Error: "+errorMsg);
Toast.makeText(context,
errorMsg, Toast.LENGTH_LONG).show();
hideDialog();
alert.showAlertDialog(context, "Désolé", " Une erreur est survenue, veuillez essayer ultérieurement",true);
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Log.e(TAG, "webS Error: " + error.getMessage());
Toast.makeText(context,
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
alert.showAlertDialog(context, "Désolé", " Une erreur est survenue, veuillez essayer ultérieurement",true);
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
// Log.e(TAG, "j'ai executé la methode getBody!! ");
return body.toString().getBytes();
}
#Override
public String getBodyContentType()
{
return "application/json";
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
hope it help :)

Alaram service or timer is good approach to perform time dependant tasks, but its best to use handler with post dalyed of your choice to perform any task you want, if you are using alarm manager than you are requesting OS to perform your task after some time, same with timer but for handlers you are using/managing in your own code

Related

Getting GPS in service in android

My problem is not new, but none of answers in Stackoverflow was helpful for me.
Situation: I have a service which works with an Alarm. it repeats every 1 minutes and run a service for me. in that service I need to send GPS data to a web server.
the codes are as below:
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.AsyncTask;
import android.os.IBinder;
import bliksund.taxitracking.tools.Cachepref;
import bliksund.taxitracking.tools.PostData;
public class SendData extends Service {
Cachepref cachepref;
GET_GPS gps;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
cachepref = new Cachepref(this);
gps = new GET_GPS(this);
new getloc().execute();
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private class getloc extends AsyncTask<Void, Void, Void> {
String username;
Double lt;
Double lg;
Location location;
#Override
protected Void doInBackground(Void... params) {
username = cachepref.getUsername();
location = gps.getLocation();
lt = location.getLatitude();
lg = location.getLongitude();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
PostData postData = new PostData(username, 1, lt, lg);
super.onPostExecute(aVoid);
}
}
}
this is my service.
+ PostData will Post the parameters to a web page.
+ Cachepref saves username for user Session.
Problem: When the codes go to get GPS Location. it will make an error that says:
location = gps.getLocation(); // will cause to below line error
Can't create handler inside thread that has not called Looper.prepare()
I used AsynTask to solve this problem, but it is still there.
GET_GPS code are as below:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class GET_GPS extends Service implements LocationListener {
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
protected LocationManager locationManager;
public GET_GPS(Context mContext) {
this.mContext = mContext;
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GET_GPS.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
with the help of ρяσѕρєя K . he said to move these codes to PostExecute and it was running, the problem with PostData happened. and I I solved in the way below. I hope it helps others.
private class getloc extends AsyncTask<Void, Void, Void> {
String username;
Double lt;
Double lg;
Location location;
#Override
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
username = cachepref.getUsername();
location = gps.getLocation();
lt = location.getLatitude();
lg = location.getLongitude();
new Thread(new Runnable() {
#Override
public void run() {
PostData postData = new PostData(username, 1, lt, lg);
}
}).start();
super.onPostExecute(aVoid);
}
}

android null pointer exceptions in AsyncTask [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I'm just starting to write under the android and ran into the problem that I do not know how to solve
PostData.java
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
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.Activity;
import android.os.AsyncTask;
import android.text.format.Time;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
class PostData extends AsyncTask<Void, Void, Void> {
// GPSTracker class
GPSTracker gps;
//определяем переменную главного активити
MainActivity ma;
Teleport_user_profile_activity UP;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
// do stuff before posting data
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
postData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
// do stuff after posting data
super.onPostExecute(result);
}
public void postData() {
// TODO Auto-generated method stub
// Create a new HttpClient and Post Header
//переводим значение double в стринг
double latitudep = gps.getLatitude();
double longitudep = gps.getLongitude();
double totalLatitude = latitudep;
String stotalLatitude = String.valueOf(totalLatitude);
double totalLongitude = longitudep;
String stotalLongitude = String.valueOf(totalLongitude);
// временная переменная для определения времени устройства
Time nowTime = new Time();
nowTime.setToNow();
String snowTime = String.valueOf(nowTime);
//берем информацию о юзере
UP.LoadUserInfoFromFile();
UP.LoadUserInfopassFromFile();
String UserInfo = Teleport_user_profile_activity.UserLoginFile;
String UserPass = Teleport_user_profile_activity.UserPassFile;
//посылка данных на сервер
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://myheart.pp.ua/Android_in.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
// nameValuePairs.add(new BasicNameValuePair("latitude", stotalLatitude));
// nameValuePairs.add(new BasicNameValuePair("longitude", stotalLongitude));
nameValuePairs.add(new BasicNameValuePair("Android_device_time", snowTime));
// nameValuePairs.add(new BasicNameValuePair("user_info", UserInfo));
// nameValuePairs.add(new BasicNameValuePair("user_pass", UserPass));
nameValuePairs.add(new BasicNameValuePair("separator", "______________________________________"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httpclient.execute(httppost);
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
MainActivity.java
R.id.menu_send_location_manual: {
GPSdetermination();
new PostData().execute();
// postData(); - вызывает ошибку на реальном устройстве
Toast.makeText(getApplicationContext(), R.string.location_send_manuall_toast, Toast.LENGTH_LONG).show();
break;
}
public void GPSdetermination() {
// create class object
gps = new GPSTracker(MainActivity.this);
// check if GPS enabled
if(gps.canGetLocation()){
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
// \n is for new line
Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
}else{
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
}
GPSTracker.java
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
//определяем переменную главного активити
MainActivity ma;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
// Функция для определения местоположения
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GPSTracker.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
* On pressing Settings button will lauch Settings Options
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
//события которые происходят если позиция поменялась
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
When I try to call PostData I get an error java.lang.NullPointerException in this code
double latitudep = gps.getLatitude();
double longitudep = gps.getLongitude();
can not seem to figure out how to fix it.
You have declared GPSTracker gps; inside your AsyncTask, it never seems to get initialised. In other words, it's null. Thus, NullPointerException.
I guess you need a constructor for your AsyncTask to set it:
public PostData (GPSTracker gps) {
this.gps = gps;
}
Then in MainActivity
new PostData(gps).execute();
AsyncTask is just a class like any other, with member variables, that need setting, if you want to use them.
gps is null because it isn't instantiated. In doInBackground() you can instantiate it
gps = new GPSTracker();
But since your GPSTracker constructor needs a Context you will have to add a constructor to your AsyncTas that accepts a Context
Async
pubic class PostData extends AsyncTask<Void, Void, Void> {
Context mContext;
MainActivity ma;
Teleport_user_profile_activity UP;
public PostData(Context c)
{
mContext = c;
}
Then in doInBackground()
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
gps = new GPSTracker(mContext);
postData();
return null;
}
And call your AsyncTask like this in MainActivity
R.id.menu_send_location_manual: {
GPSdetermination();
PostData task = new PostData(MainActivity.this);
task.execute();
new PostData().execute();
Your problem is that GPS can only be listened to within a regular thread, like the UI thread and not the doInBackground() method of an AsyncTask. This has to do with the fact that it requires a Looper to function properly. Here's a good post that's very similar to your problem.
Get your GPS data first in onCreate then you can transfer that data to your AsyncTask as varargs and use it in doInBackground that way.

getting "java.lang.RuntimeException" when sending latitude and longitude to remote mysql database within service in android"

i've created an android application which there are two buttons start stop. when start button is clicked then on every 1 seconds current latitude and longitude values are send to the usl as post to insert into a remote mysl database.
within start button i wrote a service MyService for sending latitude and longitude.
within the onStartCommand(..) method of MyService i have wrote a timer for sending latitude and longitude at 1 second.
But i'm getting the following exception
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Can anyone please tell me some solution for this
My Code is as given below
iLoadPage.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class iLoadPage extends Activity {
Button start,stop;
boolean flag=true;
double latin,longin,longitude,latitude;
Activity activity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.iloadpage);
start = (Button) findViewById(R.id.startapp);
stop = (Button) findViewById(R.id.stop);
stop.setEnabled(false);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
start.setEnabled(false);
stop.setEnabled(true);
String trackid= getIntent().getExtras().getString("trackid");
MyService.setTrackid(trackid);
startService(new Intent(getBaseContext(),MyService.class));
}
});
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
start.setEnabled(true);
stop.setEnabled(false);
stopService(new Intent(getBaseContext(),MyService.class));
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
}
public double getLatin() {
return latin;
}
public void setLatin(double latin) {
this.latin = latin;
}
public double getLongin() {
return longin;
}
public void setLongin(double longin) {
this.longin = longin;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
}
MyService .java
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
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 org.apache.http.util.EntityUtils;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.text.Html;
import android.widget.Toast;
public class MyService extends Service {
public static String trackid;
ScheduledExecutorService scheduler ;
GPSTracker gps;
boolean flag=false;
DownloadFile ss;
Handler handler = new Handler();
double latin,longin,longitude,latitude;
private final int TEN_SECONDS = 3000;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
String errors="notnull";
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
try
{
Toast.makeText(this, "Application Service Started!!!...", Toast.LENGTH_LONG).show();
try {
TimerTask myTimerTask = new TimerTask() {
#Override
public void run() {
flag=true;
DownloadFile sd=new DownloadFile();
sd.execute("");
} };
Timer timer = new Timer();
timer.schedule(myTimerTask, 1000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
Toast.makeText(this, "Service Error->"+e, Toast.LENGTH_LONG).show();}
return START_STICKY;
}
#Override
public void onDestroy()
{
flag=false;
super.onDestroy();
Toast.makeText(this, "Application Service Stopped!!!...", Toast.LENGTH_LONG).show();
}
public double getLatin() {
return latin;
}
public void setLatin(double latin) {
this.latin = latin;
}
public double getLongin() {
return longin;
}
public void setLongin(double longin) {
this.longin = longin;
}
public static String getTrackid() {
return trackid;
}
public static void setTrackid(String trackid) {
CopyOfMyService.trackid = trackid;
}
String pass;
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
try {
gps = new GPSTracker(CopyOfMyService.this);
latin = gps.getLatitude();
longin = gps.getLongitude();
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://iloadlogistics.com.au/insert1.jsp");
String trackid= CopyOfMyService.getTrackid();
List<NameValuePair> namevaluepairs = new ArrayList<NameValuePair>(2);
namevaluepairs.add(new BasicNameValuePair("trackid",trackid));
namevaluepairs.add(new BasicNameValuePair("lat",""+latin));
namevaluepairs.add(new BasicNameValuePair("lon",""+longin));
httppost.setEntity(new UrlEncodedFormEntity(namevaluepairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity rp = response.getEntity();
String origresponseText = EntityUtils.toString(rp);
String htmlTextStr = Html.fromHtml(origresponseText).toString();
pass=htmlTextStr.trim();
if(htmlTextStr.trim().equals("success"))
{
}else if(htmlTextStr.trim().equals("failure")){
}
} catch (Exception e) {
pass=""+e;
// TODO Auto-generated catch block
System.out.println("ERRRRRRRRRRRRRRRRRROR:"+e);
e.printStackTrace();
}
return pass;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(flag)
{
Toast.makeText(getApplicationContext(), "Inserted!!!...", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(), "Asyntask is Destroying!!!...", Toast.LENGTH_LONG).show();
onDestroy();
}
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
}
}
}
GPSTracker.java
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 10 meters
private static final long MIN_TIME_BW_UPDATES = 1000; // 1 minute
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GPSTracker.this);
}
}
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
return longitude;
}
public boolean canGetLocation() {
return this.canGetLocation;
}
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("GPS is settings");
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
public void onLocationChanged(Location location) {
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public IBinder onBind(Intent arg0) {
return null;
}
}
UPDATION 2
Instead of Timer i used to call the method scheduleSendLocation() which has the following definition given below
Runnable r=new Runnable() {
public void run() {
flag=true;
DownloadFile sd=new DownloadFile();
sd.execute("");
handler.postDelayed(this, TEN_SECONDS);
}
};
public void scheduleSendLocation() {
handler.postDelayed(r, TEN_SECONDS);
}
I don't really see what you need this handler for, but I see at least 2 problems:
you call new Handler() in the UI thread which has no prepared looper
you create a handler without overriding handleMessage() (what does this handler do then?)
When you create a new Handler with the constructor that has no parameter, the handler is associated with the message queue of the current thread (calling new Handler()). It means the thread needs a looper. You can do it by calling Looper.prepare() before creating the handler.
However, you can't do it yet because new Handler() is called as a field initialization. You should move this call somewhere else, such as in onCreate() and then add Looper.prepare() before it.

Force close when test my gps location getting and calculate total distance I travelled in android

Recently I am learning about using gps and marker to pinpoint my current location. And now I try to modify so that the code will be able to keep track my current location and calculate my total distance travelled when there is updated in my location. At the beginning, it works find. But after 2-3 minutes, my app start hang and prompt me force close as no response from my application.
Below is my code:
public class WhereAmINowActivity extends Activity {
//declaration of variables
public void getPrevActivityValue(){
Intent intent = getIntent();
// get the value from prev activity
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_distance);
getPrevActivityValue();
btnStart = (Button)findViewById(R.id.btnStart);
btnStop = (Button)findViewById(R.id.btnStop);
distance = (TextView)findViewById(R.id.distance);
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
provider = locationManager.getBestProvider(criteria, true);
location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
locationManager.requestLocationUpdates(provider, TWO_MIN, HUNDRED_METERS ,locationListener);
addListenerOnBtnStart();
addListenerOnBtnStop();
}
public void addListenerOnBtnStart(){
btnStart.setOnClickListener(new View.OnClickListener(){
public void onClick(View paramAnonymousView){
if(!startPressed){
// Initialize the variables of current and old location coordinates
}
catch (Exception e){
e.printStackTrace();
}
}
else{
// Do nothing
}
}
});
}
public void addListenerOnBtnStop(){
btnStop.setOnClickListener(new View.OnClickListener(){
public void onClick(View paramAnonymousView){
try{
if(connected to internet is true)
// Do something here
}
else{
// prompt message to notify user connectivity is not available
}
}
catch (Exception e){
e.printStackTrace();
}
}
});
}
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider){
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider){ }
public void onStatusChanged(String provider, int status,
Bundle extras){ }
};
private void updateWithNewLocation(Location location) {
// Update the current location, old coordinates and get the address
}
}
Some of the value is passed from previous activity by using getIntent().
can anyone help me figure out which part I done it wrongly?
Addition:
I removed the overlay and tested on merely the location listener.
I found that when it run about 2-3minutes, the interface of my app will not response on what I pressed (as I declare two button- start and stop). When I pressed the stop button, there is nothing happened, then a force close message is prompt to me. Is this the part I did wrong? How should I correct it so that it can work as like a normal distance calculation when I walk by using GPS?
I have solved this exact problem in my open source Gps Tracker. The full working android project is here:
https://github.com/nickfox/GpsTracker/tree/master/phoneClients/android
and the class that does the tracking is below. You want to take a look at the variable called totalDistanceInMeters.
package com.websmithing.gpstracker;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
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;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class LocationService extends Service implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG = "LocationService";
// use the websmithing defaultUploadWebsite for testing and then check your
// location with your browser here: https://www.websmithing.com/gpstracker/displaymap.php
private String defaultUploadWebsite;
private boolean currentlyProcessingLocation = false;
private LocationRequest locationRequest;
private LocationClient locationClient;
#Override
public void onCreate() {
super.onCreate();
defaultUploadWebsite = getString(R.string.default_upload_website);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// if we are currently trying to get a location and the alarm manager has called this again,
// no need to start processing a new location.
if (!currentlyProcessingLocation) {
currentlyProcessingLocation = true;
startTracking();
}
return START_NOT_STICKY;
}
private void startTracking() {
Log.d(TAG, "startTracking");
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
locationClient = new LocationClient(this,this,this);
if (!locationClient.isConnected() || !locationClient.isConnecting()) {
locationClient.connect();
}
} else {
Log.e(TAG, "unable to connect to google play services.");
}
}
protected void sendLocationDataToWebsite(Location location) {
// formatted for mysql datetime format
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getDefault());
Date date = new Date(location.getTime());
SharedPreferences sharedPreferences = this.getSharedPreferences("com.websmithing.gpstracker.prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
float totalDistanceInMeters = sharedPreferences.getFloat("totalDistanceInMeters", 0f);
boolean firstTimeGettingPosition = sharedPreferences.getBoolean("firstTimeGettingPosition", true);
if (firstTimeGettingPosition) {
editor.putBoolean("firstTimeGettingPosition", false);
} else {
Location previousLocation = new Location("");
previousLocation.setLatitude(sharedPreferences.getFloat("previousLatitude", 0f));
previousLocation.setLongitude(sharedPreferences.getFloat("previousLongitude", 0f));
float distance = location.distanceTo(previousLocation);
totalDistanceInMeters += distance;
editor.putFloat("totalDistanceInMeters", totalDistanceInMeters);
}
editor.putFloat("previousLatitude", (float)location.getLatitude());
editor.putFloat("previousLongitude", (float)location.getLongitude());
editor.apply();
final RequestParams requestParams = new RequestParams();
requestParams.put("latitude", Double.toString(location.getLatitude()));
requestParams.put("longitude", Double.toString(location.getLongitude()));
Double speedInMilesPerHour = location.getSpeed()* 2.2369;
requestParams.put("speed", Integer.toString(speedInMilesPerHour.intValue()));
try {
requestParams.put("date", URLEncoder.encode(dateFormat.format(date), "UTF-8"));
} catch (UnsupportedEncodingException e) {}
requestParams.put("locationmethod", location.getProvider());
if (totalDistanceInMeters > 0) {
requestParams.put("distance", String.format("%.1f", totalDistanceInMeters / 1609)); // in miles,
} else {
requestParams.put("distance", "0.0"); // in miles
}
requestParams.put("username", sharedPreferences.getString("userName", ""));
requestParams.put("phonenumber", sharedPreferences.getString("appID", "")); // uuid
requestParams.put("sessionid", sharedPreferences.getString("sessionID", "")); // uuid
Double accuracyInFeet = location.getAccuracy()* 3.28;
requestParams.put("accuracy", Integer.toString(accuracyInFeet.intValue()));
Double altitudeInFeet = location.getAltitude() * 3.28;
requestParams.put("extrainfo", Integer.toString(altitudeInFeet.intValue()));
requestParams.put("eventtype", "android");
Float direction = location.getBearing();
requestParams.put("direction", Integer.toString(direction.intValue()));
final String uploadWebsite = sharedPreferences.getString("defaultUploadWebsite", defaultUploadWebsite);
LoopjHttpClient.get(uploadWebsite, requestParams, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, org.apache.http.Header[] headers, byte[] responseBody) {
LoopjHttpClient.debugLoopJ(TAG, "sendLocationDataToWebsite - success", uploadWebsite, requestParams, responseBody, headers, statusCode, null);
stopSelf();
}
#Override
public void onFailure(int statusCode, org.apache.http.Header[] headers, byte[] errorResponse, Throwable e) {
LoopjHttpClient.debugLoopJ(TAG, "sendLocationDataToWebsite - failure", uploadWebsite, requestParams, errorResponse, headers, statusCode, e);
stopSelf();
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
Log.e(TAG, "position: " + location.getLatitude() + ", " + location.getLongitude() + " accuracy: " + location.getAccuracy());
// we have our desired accuracy of 500 meters so lets quit this service,
// onDestroy will be called and stop our location uodates
if (location.getAccuracy() < 500.0f) {
stopLocationUpdates();
sendLocationDataToWebsite(location);
}
}
}
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) {
Log.d(TAG, "onConnected");
locationRequest = LocationRequest.create();
locationRequest.setInterval(1000); // milliseconds
locationRequest.setFastestInterval(1000); // the fastest rate in milliseconds at which your app can handle location updates
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() {
Log.e(TAG, "onDisconnected");
stopLocationUpdates();
stopSelf();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed");
stopLocationUpdates();
stopSelf();
}
}

How to Calculate Total Miles Travel from the Curent loaction to some another location Location Listener?

Hi Can anybody tell me how can i calculate Total Miles Travel from the Curent location to another location? e.g. like i start walking from point A and reached at point B. how can i find the total distance travel from point A to B. Please help me!!!
Criteria c=new Criteria()
c.setAccuracy(Criteria.ACCURACY_FINE);
String providerName=locMgr.getBestProvider(c,true);
Location startLocation = new Location(providerName);
startLocation.setLatitude(PrevLatitude);
startLocation.setLongitude(PrevLongitude);
startLocation.set(startLocation);
Location _myLoc = new Location(providerName);
_myLoc.setLatitude(Double.valueOf(nf.format(location.getLatitude())));
_myLoc.setLongitude(Double.valueOf(nf.format(location.getLongitude())));
_myLoc.set(_myLoc);
double meters = _myLoc.distanceTo(startLocation);
double miles = (meters*0.000621371192237334);
Assume, you have Location start_location and finish_location.
So you can use start_location.distanceTo(finish_location)
Please See , Location in Android
I have solved this exact problem in my open source Gps Tracker. The full working android project is here:
https://github.com/nickfox/GpsTracker/tree/master/phoneClients/android
and the class that does the tracking is below. You want to take a look at the variable called totalDistanceInMeters.
package com.websmithing.gpstracker;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
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;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class LocationService extends Service implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG = "LocationService";
// use the websmithing defaultUploadWebsite for testing and then check your
// location with your browser here: https://www.websmithing.com/gpstracker/displaymap.php
private String defaultUploadWebsite;
private boolean currentlyProcessingLocation = false;
private LocationRequest locationRequest;
private LocationClient locationClient;
#Override
public void onCreate() {
super.onCreate();
defaultUploadWebsite = getString(R.string.default_upload_website);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// if we are currently trying to get a location and the alarm manager has called this again,
// no need to start processing a new location.
if (!currentlyProcessingLocation) {
currentlyProcessingLocation = true;
startTracking();
}
return START_NOT_STICKY;
}
private void startTracking() {
Log.d(TAG, "startTracking");
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
locationClient = new LocationClient(this,this,this);
if (!locationClient.isConnected() || !locationClient.isConnecting()) {
locationClient.connect();
}
} else {
Log.e(TAG, "unable to connect to google play services.");
}
}
protected void sendLocationDataToWebsite(Location location) {
// formatted for mysql datetime format
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getDefault());
Date date = new Date(location.getTime());
SharedPreferences sharedPreferences = this.getSharedPreferences("com.websmithing.gpstracker.prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
float totalDistanceInMeters = sharedPreferences.getFloat("totalDistanceInMeters", 0f);
boolean firstTimeGettingPosition = sharedPreferences.getBoolean("firstTimeGettingPosition", true);
if (firstTimeGettingPosition) {
editor.putBoolean("firstTimeGettingPosition", false);
} else {
Location previousLocation = new Location("");
previousLocation.setLatitude(sharedPreferences.getFloat("previousLatitude", 0f));
previousLocation.setLongitude(sharedPreferences.getFloat("previousLongitude", 0f));
float distance = location.distanceTo(previousLocation);
totalDistanceInMeters += distance;
editor.putFloat("totalDistanceInMeters", totalDistanceInMeters);
}
editor.putFloat("previousLatitude", (float)location.getLatitude());
editor.putFloat("previousLongitude", (float)location.getLongitude());
editor.apply();
final RequestParams requestParams = new RequestParams();
requestParams.put("latitude", Double.toString(location.getLatitude()));
requestParams.put("longitude", Double.toString(location.getLongitude()));
Double speedInMilesPerHour = location.getSpeed()* 2.2369;
requestParams.put("speed", Integer.toString(speedInMilesPerHour.intValue()));
try {
requestParams.put("date", URLEncoder.encode(dateFormat.format(date), "UTF-8"));
} catch (UnsupportedEncodingException e) {}
requestParams.put("locationmethod", location.getProvider());
if (totalDistanceInMeters > 0) {
requestParams.put("distance", String.format("%.1f", totalDistanceInMeters / 1609)); // in miles,
} else {
requestParams.put("distance", "0.0"); // in miles
}
requestParams.put("username", sharedPreferences.getString("userName", ""));
requestParams.put("phonenumber", sharedPreferences.getString("appID", "")); // uuid
requestParams.put("sessionid", sharedPreferences.getString("sessionID", "")); // uuid
Double accuracyInFeet = location.getAccuracy()* 3.28;
requestParams.put("accuracy", Integer.toString(accuracyInFeet.intValue()));
Double altitudeInFeet = location.getAltitude() * 3.28;
requestParams.put("extrainfo", Integer.toString(altitudeInFeet.intValue()));
requestParams.put("eventtype", "android");
Float direction = location.getBearing();
requestParams.put("direction", Integer.toString(direction.intValue()));
final String uploadWebsite = sharedPreferences.getString("defaultUploadWebsite", defaultUploadWebsite);
LoopjHttpClient.get(uploadWebsite, requestParams, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, org.apache.http.Header[] headers, byte[] responseBody) {
LoopjHttpClient.debugLoopJ(TAG, "sendLocationDataToWebsite - success", uploadWebsite, requestParams, responseBody, headers, statusCode, null);
stopSelf();
}
#Override
public void onFailure(int statusCode, org.apache.http.Header[] headers, byte[] errorResponse, Throwable e) {
LoopjHttpClient.debugLoopJ(TAG, "sendLocationDataToWebsite - failure", uploadWebsite, requestParams, errorResponse, headers, statusCode, e);
stopSelf();
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
Log.e(TAG, "position: " + location.getLatitude() + ", " + location.getLongitude() + " accuracy: " + location.getAccuracy());
// we have our desired accuracy of 500 meters so lets quit this service,
// onDestroy will be called and stop our location uodates
if (location.getAccuracy() < 500.0f) {
stopLocationUpdates();
sendLocationDataToWebsite(location);
}
}
}
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) {
Log.d(TAG, "onConnected");
locationRequest = LocationRequest.create();
locationRequest.setInterval(1000); // milliseconds
locationRequest.setFastestInterval(1000); // the fastest rate in milliseconds at which your app can handle location updates
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() {
Log.e(TAG, "onDisconnected");
stopLocationUpdates();
stopSelf();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed");
stopLocationUpdates();
stopSelf();
}
}

Categories

Resources