Working on a Location App.. I want to Get user location from fusedlocation provider when location is changed in a background service.
My service give me location on every interval but i want location when location changed not every interval
My service started on reboot. and get location on every interval set by me. But I want location when location change(User move to new location), not every time interval,
public class BacLocSerUme extends Service implements ConnectionCallbacks,
OnConnectionFailedListener, LocationListener {
protected static final String TAG = "sanu location services";
// parameters for the GoogleApiClient Location Request
private static final long INTERVAL = 1000 * 60;
private static final long FASTEST_INTERVAL = 1000 * 5;
private static final long ONE_MIN = 1000 * 60;
private static final long REFRESH_TIME = ONE_MIN * 5;
private static final float MINIMUM_ACCURACY = 50.0f;
// in it for Api params
private LocationRequest locationRequest;
private GoogleApiClient googleApiClient;
private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
private Location mlocation;
// Flag that indicates if a request is underway.
private boolean mInProgress;
private Boolean servicesAvailable = false;
IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public BacLocSerUme getServerInstance() {
return BacLocSerUme.this;
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mBinder;
}
// On create Method to init all the value of request of playservices
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.i(TAG, "on create of service");
mInProgress = false;
buildGoogleApiClient();
servicesAvailable = servicesConnected();
}
private Boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
return true;
} else {
return false;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.i(TAG, "on start of services");
super.onStartCommand(intent, flags, startId);
if (!servicesAvailable || googleApiClient.isConnected() || mInProgress)
return START_STICKY;
setUpLocationClientIfNeeded();
if (googleApiClient.isConnected() || !googleApiClient.isConnecting()
&& !mInProgress) {
Log.i(TAG, "Services Started from service class");
mInProgress = true;
googleApiClient.connect();
}
return START_STICKY;
}
private void setUpLocationClientIfNeeded() {
if (mlocation == null) {
buildGoogleApiClient();
}
}
// Building GoogleApiClient
private void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
createLocationRequest();
}
// Building Request for googleApiClient
private void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
Log.i(TAG, "location request created");
}
// This Followins two mathod is generated by implements of
// connectioncallback
// on connected and on connection suspend
// this is used for connection call back//// check connected or not
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "Connected to GoogleApiClient");
mlocation = fusedLocationProviderApi.getLastLocation(googleApiClient);
if (mlocation == null) {
fusedLocationProviderApi.requestLocationUpdates(googleApiClient,
locationRequest, this);
}
Intent intent = new Intent(this, LocationReceiver.class);
PendingIntent locationIntent = PendingIntent.getBroadcast(
getApplicationContext(), 14872, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
fusedLocationProviderApi.removeLocationUpdates(googleApiClient,
locationIntent);
}
#Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "Connection suspended");
googleApiClient.connect();
}
// generated from inplementation from OnConnectionFailedListener
#Override
public void onConnectionFailed(ConnectionResult result) {
mInProgress = false;
Log.i(TAG, "Location Services fails. ");
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
// method generated from requestlocation listener
#Override
public void onLocationChanged(Location location) {
mlocation = location;
Log.i(TAG, "Location Changed");
appendLog(DateFormat.getDateTimeInstance().format(new Date())
+ ": location changed" + mlocation.getLatitude(),
Constants.LOG_FILE);
Toast.makeText(this, "Locatiopn Changed", Toast.LENGTH_LONG).show();
}
// ondestroid method of services
#Override
public void onDestroy() {
// TODO Auto-generated method stub
mInProgress = false;
if (servicesAvailable && googleApiClient != null) {
fusedLocationProviderApi.removeLocationUpdates(googleApiClient,
this);
// Destroy the current location client
googleApiClient = null;
}
super.onDestroy();
}
// extra methods for utill
public String getTime() {
SimpleDateFormat mDateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
return mDateFormat.format(new Date());
}
public void appendLog(String text, String filename) {
File logFile = new File(filename);
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
// BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile,
true));
buf.append(text);
buf.newLine();
buf.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}// End of main services
You can do this using ResultReceiver .
Ref Link : how to send message from service to activity
Simply send some message when location is changed using
resRec.send(object,null);
Related
I am Using Fused Location Provider Google api client to get the location for every 5 minutes . It is updating both in background and also when the application is killed . But it is Stopped updating after some 2 to 3 days . i have tested in most of the android devices.
I am calling this Service from an Activity and i am Killing the application, it is sending location updates for every 5 minutes for almost 3 days after that it is getting stopped .I tried So many times.
public class GPSTracker extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
com.google.android.gms.location.LocationListener {
protected static final String TAG = "Location...";
private Context mContext = this;
/**
* Tracks the status of the location updates request.
*/
public static Boolean mRequestingLocationUpdates;
/**
* Time when the location was updated represented as a String.
*/
protected String mLastUpdateTime;
/**
* Provides the entry point to Google Play services.
*/
protected GoogleApiClient mGoogleApiClient;
/**
* Stores parameters for requests to the FusedLocationProviderApi.
*/
protected LocationRequest mLocationRequest;
/**
* Represents a geographical location.
*/
protected Location mCurrentLocation;
public static boolean isEnded = false;
#Override
public void onCreate() {
super.onCreate();
buildGoogleApiClient();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("LOC", "Service init...");
isEnded = false;
mRequestingLocationUpdates = false;
mLastUpdateTime = "";
// buildGoogleApiClient();
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
return START_STICKY;
}
#Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended==");
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
double latitude = location.getLatitude();
double longitude = location.getLongitude();
StringBuilder stringBuilder = new StringBuilder();
StringBuilder latlong = stringBuilder.append(latitude + "," + longitude);
Calendar cal = Calendar.getInstance();
String zone = TimeZone.getDefault().getDisplayName(false, android.icu.util.TimeZone.SHORT);
SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM 'at' h:mm a");
Date date = new Date();
String localtime = (formatter.format(date)).toString();
Date myDate = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTime(myDate);
date = calendar.getTime();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss zz");
dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String utc = dateFormatter.format(date);
// DateFormat df = DateFormat.getTimeInstance();
// df.setTimeZone(TimeZone.getTimeZone("gmt"));
// String gmtTime = df.format(new Date());
String model = Build.MODEL;
String reqString = Build.VERSION.RELEASE
+ " " + Build.VERSION_CODES.class.getFields()[android.os.Build.VERSION.SDK_INT].getName();
// Date currentTime = Calendar.getInstance().getTime();
// String localtime = currentTime.toString();
PreferencesClass preferencesClass = new PreferencesClass(mContext);
String id = preferencesClass.getFingerPrint();
Data data = null;
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("userId", id);
jsonObject.put("latLon", latlong);
jsonObject.put("timeZone", zone);
jsonObject.put("localTime", localtime);
jsonObject.put("osVersion",reqString);
jsonObject.put("phoneModel",model);
jsonObject.put("utcTime",utc);
data = new Data();
data.setData(jsonObject.toString());
if (data != null) {
if (Utility.isConnectingToInternet(mContext)) {
// boolean isChecked = preferencesClass.getIsChecked();
// if (isChecked){
LocationWebServiceMgr locationWebServiceMgr = new LocationWebServiceMgr();
locationWebServiceMgr.Location(data, new CallBackInterface() {
#Override
public void onResponse(ArrayList<Object> objects, ResponseMetaData responseMetaData) {
Log.d(TAG, "onResponse: Succesfully added the location to server");
// Toast.makeText(getApplicationContext(), "added to server", Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(ResponseMetaData t) {
}
});
// } else {
// Log.d("serverCall", "Location Permission not available ");
// }
} else {
Log.e("serverCall", "Network not available");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
/**
* Builds a GoogleApiClient. Uses the {#code #addApi} method to request the
* LocationServices API.
*/
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient===");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
/**
* Sets up the location request. Android has two location request settings:
* {#code ACCESS_COARSE_LOCATION} and {#code ACCESS_FINE_LOCATION}. These settings control
* the accuracy of the current location. This sample uses ACCESS_FINE_LOCATION, as defined in
* the AndroidManifest.xml.
* <p/>
* When the ACCESS_FINE_LOCATION setting is specified, combined with a fast update
* interval (5 seconds), the Fused Location Provider API returns location updates that are
* accurate to within a few feet.
* <p/>
* These settings are appropriate for mapping applications that show real-time location
* updates.
*/
protected void createLocationRequest() {
mGoogleApiClient.connect();
mLocationRequest = new LocationRequest();
// Sets the desired interval for active location updates. This interval is
// inexact. You may not receive updates at all if no location sources are available, or
// you may receive them slower than requested. You may also receive updates faster than
// requested if other applications are requesting location at a faster interval.
mLocationRequest.setInterval(Constants.UPDATE_INTERVAL_IN_MILLISECONDS);
// Sets the fastest rate for active location updates. This interval is exact, and your
// application will never receive updates faster than this value.
mLocationRequest.setFastestInterval(Constants.FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
// mLocationRequest.setSmallestDisplacement(Constants.DISPLACEMENT);
//mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
/**
* Requests location updates from the FusedLocationApi.
*/
protected void startLocationUpdates() {
if (!mRequestingLocationUpdates) {
mRequestingLocationUpdates = true;
// The final argument to {#code requestLocationUpdates()} is a LocationListener
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.i(TAG, " startLocationUpdates===");
isEnded = true;
}
}
}
you can create service for do this
public class TimeService extends Service {
// constant
public static final long NOTIFY_INTERVAL = 10 * 1000; // 10 seconds
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
// cancel if already existed
if(mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
startService(new Intent(this, MyService.class));
}
});
}
private String getDateTime() {
// get date time in custom format
SimpleDateFormat sdf = new SimpleDateFormat("[yyyy/MM/dd - HH:mm:ss]");
return sdf.format(new Date());
}
}
and service for location
public class MyService extends Service
{
private static final String TAG = "BOOMBOOMTESTGPS";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 10f;
private class LocationListener implements android.location.LocationListener
{
Location mLastLocation;
public LocationListener(String provider)
{
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location)
{
Log.e(TAG, "onLocationChanged: " + location);
mLastLocation.set(location);
}
#Override
public void onProviderDisabled(String provider)
{
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider)
{
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.e(TAG, "onStatusChanged: " + provider);
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate()
{
Log.e(TAG, "onCreate");
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
#Override
public void onDestroy()
{
Log.e(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
}
Use workmanager to reschedule your location service. Check if location service not running then start from scheduler.
To read more regarding workmanager click here
Create a class for location get.
private class LocationListener implements android.location.LocationListener
{
Location mLastLocation;
public LocationListener(String provider)
{
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location)
{
Log.e(TAG, "onLocationChanged: " + location);
mLastLocation.set(location);
}
#Override
public void onProviderDisabled(String provider)
{
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider)
{
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.e(TAG, "onStatusChanged: " + provider);
}
}
in onLocation(Location location) change method you will get current let,long
For that, you can use AlarmManager or firebase jobdispatcher or job scheduler to trigger any event after specific intervals. I suggest you to use AlarmManager which are easiest.
Refer this code to set alarm:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int notificationID = 2018;
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notificationID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),5*1000, pendingIntent);
And you can cancel alarm like this way:
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notificationID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.cancel(pendingIntent);
pendingIntent.cancel();
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
I am using Google API to get location from GPS in Android. i got accurate location if i moving. but if i am in same location above 15 mins it give more locations.
My code is:
public class LocationServiceTesting extends Service
implements LocationListener, ConnectionCallbacks, OnConnectionFailedListener {
// Location updates intervals in sec
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FATEST_INTERVAL = 5000; // 5 sec
private static int DISPLACEMENT = 10; // 10 meters
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation,mLastLocation,Test3LastLocation,Test2LastLocation;
String mLastUpdateTime;
String DeviceCode = "", ImeiNumber = "";
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
private boolean isGooglePlayServicesAvailable(Context context) {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, (Activity) context, 0).show();
return false;
}
}
public LocationServiceTesting() {
// TODO Auto-generated constructor stub
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d(TAG, "onCreate ...............................");
// show error dialog if GoolglePlayServices not available
Log.d(TAG, "on play service "+checkPlayServices());
if (checkPlayServices()) {
Log.e("oogleplay service found", "service");
buildGoogleApiClient();
createLocationRequest();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
super.onStartCommand(intent, flags, startId);
if(!mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
return START_STICKY;
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if(mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// TODO Auto-generated method stub
Log.d(TAG, "Connection failed: in service " + connectionResult.toString());
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
Log.e(TAG, "onConnected - isConnected inservice " + mGoogleApiClient.isConnected());
startLocationUpdates1();
}
protected void startLocationUpdates() {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
Log.d(TAG, "Location update started ..............: ");
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
mGoogleApiClient.connect();
}
// get distance between two latlong
public double getDistance(Location Lastlocation, Location Currentlocation) {
double distance = 0;
distance = Lastlocation.distanceTo(Currentlocation);
return distance;
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Sync synctoServer = new Sync();
Log.e("With out API Location ", "location "+location);
if (location.getAccuracy() < 20) {
Location Curloc;
double Distance=0.0;
Curloc= LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(Test3LastLocation!=null)
{
Distance=getDistance(Test3LastLocation, Curloc);
Log.e("Distance", "Distance "+Distance);
}
if(Distance>20)
{
dbo.InsertGPS(dbo, DeviceCode, ImeiNumber, "" + location.getLongitude(), "" + location.getLatitude(),
_contrl.getCurrentTimeStamp());
}
Test3LastLocation=Curloc;
}
mLastLocation = location;
displayLocation();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
//GooglePlayServicesUtil.getErrorDialog(resultCode, this,PLAY_SERVICES_RESOLUTION_REQUEST).show();
Toast.makeText(getBaseContext(), "play service not", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"This device is not supported.", Toast.LENGTH_LONG)
.show();
//finish();
}
return false;
}
return true;
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
//lblLocation.setText(latitude + ", " + longitude);
Log.e("Location chnage ", ""+mLastLocation+" "+mLastLocation.getTime()+" "+mLastLocation.getElapsedRealtimeNanos());
} else {
Log.e("Location chnage ", "null values");
//lblLocation.setText("(Couldn't get the location. Make sure location is enabled on the device)");
}
}
protected void startLocationUpdates1() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
}
please help me. thanks in advance.....
I refereed this link http://www.androidhive.info/2015/02/android-location-api-using-google-play-services/
please help me to over come this problem....
I am getting this like location if i am in a same location
I had same issue before few days ago.I have changed the setPriority() to PRIORITY_BALANCED_POWER_ACCURACY. It might resolve your problem.
You have used PRIORITY_HIGH_ACCURACY in your createLocationRequest() method.
Instead of this line mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
Add this line
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
This issue is occurred because of onLocationChanged method called with PRIORITY_HIGH_ACCURACY and It gives us new location which is different.
My suggestion is to use PRIORITY_BALANCED_POWER_ACCURACY.
I have a service that when it creates and starts, initiates prerequisites of using FusedLocationAPI . buildGoogleApiClient() and createLocationRequest() with parameters that initiated by my getConfig() method from database.
This solution works great and accurate with parameters like:
UPDATE_INTERVAL= 10000 (10 sec) , FASTEST_INTERVAL= 5000 (5 sec) , DISPLACEMENT= 10 ( m )
But I need to set interval up to 5 minutes. So when i set prameters like :
UPDATE_INTERVAL= 300000 (5 min) , FASTEST_INTERVAL= 180000 (3 min) , DISPLACEMENT= 10 ( m )
GPS behaves differently and after 30 seconds stops searching GPS and location notification that blinks, disappears.
And starts searching again after device locked and unlocked or this Service stops and starts again.
Here is my service. Please tell me why searching GPS stops right after 30 seconds.
Thanks in advanece.
public class MainService extends Service implements ConnectionCallbacks,
OnConnectionFailedListener, LocationListener {
private final static String TAG = MainActivity.class.getSimpleName();
private static int UPDATE_INTERVAL;
private static int FASTEST_INTERVAL;
private static int DISPLACEMENT;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Location mLastLocation;
public String deviceIMEI;
public boolean isGpsEnabled = false;
DatabaseHelper mDBHelper;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
getDeviceIMEI();
getConfig();
startForeGroundService();
if (checkPlayServices() && checkLocationServices()) {
buildGoogleApiClient();
createLocationRequest();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mGoogleApiClient != null)
mGoogleApiClient.connect();
else {
stopForeground(true);
stopSelf();
}
return (START_NOT_STICKY);
}
#Override
public void onDestroy() {
stopForeground(true);
if (mGoogleApiClient != null)
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
#SuppressWarnings("deprecation")
public void startForeGroundService() {
Notification note = new Notification(
R.drawable.track_notification_alert,
"GPS tracking started ...", System.currentTimeMillis());
Intent i = new Intent();
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
note.setLatestEventInfo(this, "GPS is active.",
"Now this tablet is under tracking. ", pi);
note.flags |= Notification.FLAG_NO_CLEAR;
startForeground(1337, note);
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private boolean checkLocationServices() {
LocationManager lm = (LocationManager) getApplicationContext()
.getSystemService(LOCATION_SERVICE);
isGpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
return isGpsEnabled;
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
return false;
}
return true;
}
#Override
public void onConnected(Bundle arg0) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
if (Globals.isSatelliteFix && Globals.isGPSEnable)
setPoint();
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (Globals.isSatelliteFix && Globals.isGPSEnable)
setPoint();
}
private void setPoint() {
mDBHelper = new DatabaseHelper(getApplicationContext());
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
try {
Point p = new Point();
p.setId(UUID.randomUUID().toString());
p.setIMEI(deviceIMEI);
p.setLatitude(String.valueOf(latitude));
p.setLongitude(String.valueOf(longitude));
p.setTimeStamp(createTimeStamp());
long result = mDBHelper.addPoint(p);
if (result != -1) {
Log.i(TAG, "Insertion Successfull With RowId: " + result);
} else
Log.e(TAG, "Insertion Error");
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Insertion Error: " + e.getMessage());
}
}
}
public String createTimeStamp() {
String strTimeStamp = new SimpleDateFormat("yyyy-MM-dd_kk:mm:ss")
.format(new Date());
return strTimeStamp;
}
public void getDeviceIMEI() {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
deviceIMEI = telephonyManager.getDeviceId();
}
public long getTimeInMiliSeconds() {
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
return date.getTime();
}
public void getConfig() {
Config config = new Config();
mDBHelper = new DatabaseHelper(getApplicationContext());
config = mDBHelper.getConfig();
UPDATE_INTERVAL = config.getUpdateInterval();
FASTEST_INTERVAL = config.getFastestInterval();
DISPLACEMENT = config.getSmallestDisplacement();
}
}
I am fetching latitude and longitude of current location but onLocationChanged returns same location on mobile data I am using PRIORITY_BALANCED_POWER_ACCURACY mode.
Please tell me where is it misbehaving here's my code
public class Latlng_Service extends Service implements
com.google.android.gms.location.LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
public static String STOP_USER_SERVICE = "STOP_USER_SERVICE";
private static final long INTERVAL = 3000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
private WakeLock wl;
int distance = 0;
List<Address> address_list;
String add_String,cat_id,module_id = "3";
LocationRequest locationRequest;
GoogleApiClient googleApiClient;
Location mloLocation, lastlocation;
String lat, lng, accuracy, name;
String battery_level;
String signal_strength;
Handler fivemiuntesHandler,thirtysecHandler;
Start_latlng_service start_latlng_service;
String login_id, gcm_id, url, response,responseArray[];
boolean flag = false;
List<LatLng> lisLatLngs = new ArrayList<LatLng>();
// public static final String BROADCAST_ACTION =
// "com.xsinfosol.smart_crm.attndance.location";
Intent intent;
String count;
#SuppressWarnings("deprecation")
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
createLocationRequest();
flag = false;
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
googleApiClient.connect();
start_latlng_service = new Start_latlng_service();
this.registerReceiver(this.broadcastReceiver, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED));
this.registerReceiver(this.stop_service_at_time, new IntentFilter(
STOP_USER_SERVICE));
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "whatever");
wl.acquire();
return START_STICKY;
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
mloLocation = location;
lat = String.valueOf(location.getLatitude());
lng = String.valueOf(location.getLongitude());
accuracy = String.valueOf(location.getAccuracy());
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
myConnection.logs_onlocation_insert(currentDateTimeString, String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
AtendenceAutoManualFunction(location);
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
System.out.println("Connection Falied " + arg0.getErrorCode());
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
startLocationUpdates();
this.registerReceiver(this.broadcastReceiver, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED));
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
protected void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
locationRequest.setInterval(INTERVAL).setFastestInterval(
FASTEST_INTERVAL);
// .setSmallestDisplacement(10);
// .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
protected void startLocationUpdates() {
#SuppressWarnings("unused")
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi
.requestLocationUpdates(googleApiClient, locationRequest, this);
Log.d(TAG, "Location update started ..............: ");
if (fivemiuntesHandler == null) {
Log.d(TAG, "Location update started five minutes ..............: ");
fivemiuntesHandler = new Handler();
fivemiuntesHandler.postDelayed(fiveminutes, 300000);
}
if (thirtysecHandler == null) {
Log.d(TAG, "Location update started five minutes ..............: ");
thirtysecHandler = new Handler();
thirtysecHandler.postDelayed(thirtySec, 0);
}
}
protected void stopLocationUpdates() {
if (googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(
googleApiClient, this);
}
Log.d(TAG, "Location update stopped .......................");
}
#SuppressWarnings("deprecation")
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
stopLocationUpdates();
googleApiClient.disconnect();
unregisterReceiver(broadcastReceiver);
unregisterReceiver(stop_service_at_time);
sharedPreferences = getSharedPreferences("user_detail",
MODE_WORLD_WRITEABLE);
login_id = sharedPreferences.getString("login_id", "");
gcm_id = sharedPreferences.getString("reg_id", "");
if (!login_id.contentEquals("") && !gcm_id.contentEquals("")
&& flag == false) {
sendBroadcast(new Intent("CantKillMe"));
} else {
wl.release();
stopSelf();
}
}
}
Hi I have a service in which I find the user location co-ordinates. This service is started in onCreate in my MainActivity. however until it finds the values as I know GPS can take some time to find the co-ordinates the screen is black. I have created a splash screen which I would like to show but I am not sure on how to implement. My code will explain more:
My service:
public class LocationService extends Service implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
LocationListener {
public static double curlat;
public static double curlong;
IBinder mBinder = new LocalBinder();
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
// Flag that indicates if a request is underway.
private boolean mInProgress;
public static final String BROADCAST_ACTION = "com.example.fusedlocation.displayevent";
Intent intent;
private Boolean servicesAvailable = false;
public class LocalBinder extends Binder {
public LocationService getServerInstance() {
return LocationService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
mInProgress = false;
// Create the LocationRequest object
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
// Set the update interval to 5 seconds
mLocationRequest.setInterval(Constants.UPDATE_INTERVAL);
// Set the fastest update interval to 1 second
mLocationRequest.setFastestInterval(Constants.FASTEST_INTERVAL);
servicesAvailable = servicesConnected();
/*
* Create a new location client, using the enclosing class to
* handle callbacks.
*/
mLocationClient = new LocationClient(this, this, this);
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
return true;
} else {
return false;
}
}
public int onStartCommand (Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);
if(!servicesAvailable || mLocationClient.isConnected() || mInProgress)
return START_STICKY;
setUpLocationClientIfNeeded();
if(!mLocationClient.isConnected() || !mLocationClient.isConnecting() && !mInProgress)
{
appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Started", Constants.LOG_FILE);
mInProgress = true;
mLocationClient.connect();
}
return START_STICKY;
}
/*
* Create a new location client, using the enclosing class to
* handle callbacks.
*/
private void setUpLocationClientIfNeeded()
{
if(mLocationClient == null)
mLocationClient = new LocationClient(this, this, this);
}
// Define the callback method that receives location updates
#Override
public void onLocationChanged(android.location.Location location) {
// Report to the UI that the location was updated
String msg = Double.toString(location.getLatitude()) + "," +
Double.toString(location.getLongitude());
Log.d("debug", msg);
curlat = location.getLatitude();
curlong = location.getLongitude();
// Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
appendLog(msg, Constants.LOCATION_FILE);
intent.putExtra("Latitude", location.getLatitude());
intent.putExtra("Longitude", location.getLongitude());
sendBroadcast(intent, null);
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public String getTime() {
SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return mDateFormat.format(new Date());
}
public void appendLog(String text, String filename)
{
File logFile = new File(filename);
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onDestroy(){
// Turn off the request flag
mInProgress = false;
if(servicesAvailable && mLocationClient != null) {
mLocationClient.removeLocationUpdates(this);
// Destroy the current location client
mLocationClient = null;
}
// Display the connection status
// Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Stopped", Constants.LOG_FILE);
super.onDestroy();
}
/*
* 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) {
// Request location updates using static settings
mLocationClient.requestLocationUpdates(mLocationRequest, this);
appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Connected", Constants.LOG_FILE);
}
/*
* Called by Location Services if the connection to the
* location client drops because of an error.
*/
#Override
public void onDisconnected() {
// Turn off the request flag
mInProgress = false;
// Destroy the current location client
mLocationClient = null;
// Display the connection status
// Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected", Constants.LOG_FILE);
}
/*
* Called by Location Services if the attempt to
* Location Services fails.
*/
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
mInProgress = false;
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
// If no resolution is available, display an error dialog
} else {
}
}
}
MainActivity ( Only the relevant parts):
public class MainActivity extends Activity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener{
// Google Map & markers
private GoogleMap googleMap;
private Circle mCircle;
private Marker mMarker;
double radiusInMeters;
long start_time, countUp, timeDialogShown = 0;
double latitude, longitude, startLongitude, startLatitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting the layout
setContentView(R.layout.activity_main);
try {
// Loading map
initilizeMap();
} catch (Exception e) {
e.printStackTrace();
}
startService(new Intent(this, LocationService.class));
} // end onCreate
//Checking the latest location updates
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
latitude = extras.getDouble("Latitude");
longitude = extras.getDouble("Longitude");
LatLng latLng = new LatLng(latitude, longitude);
if (mCircle == null || mMarker == null) {
drawMarkerWithCircle(latLng);
} else {
updateMarkerWithCircle(latLng);
}
getDistance();
//Getting the current weather conditions
//if (condDescr.getText().equals(" ")){
// getWeatherConditions();
//}
//Check if the user has breached the Geofence boundaries
checkBoundaries();
}
};
Check my answer here:
Android SplashScreen
Basically creating a theme background will deal with the black screen till you set the content.
Create a splash_screen activity. Set it as start-up activity.
In this splash_screen activity's onCreate() u can start a service to get location update.
Once u r done with location update, start ur MainAcitivity.class.
protected void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen_layout);
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
// start the service to get location update
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
// start the main activity
}
});
t1.start();
}