FusedLocationApi is not working while scheduling it with JobScheduler - android

Calling FusedLocationApi within jobscheduler doesn't work. I have tried in 2 ways but onConnected() are never called in both of them. How can I make it work? Thankyou
MainActivity.class
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStartJob = (Button)findViewById(R.id.startjob);
jobScheduler = (JobScheduler)getSystemService(JOB_SCHEDULER_SERVICE);
btnStartJob.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
ComponentName jobService =
new ComponentName(getPackageName(), MyJobService.class.getName());
PersistableBundle bundle = new PersistableBundle();
bundle.putString("lat", latitude+"");
bundle.putString("lon", longitude+"");
JobInfo jobInfo =
new JobInfo.Builder(MYJOBID, jobService).setPeriodic(10000).
setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY).
setRequiresCharging(false).
setRequiresDeviceIdle(false).
setPersisted(true).
setExtras(bundle).
build();
int jobId = jobScheduler.schedule(jobInfo);
if(jobScheduler.schedule(jobInfo)>0){
}else{
}
}
});
}
}
Try 1:
Here I have implemented ConnectionCallbacks, OnConnectionFailedListener in JobService but its onConnected() method is never called...
public class MyJobService extends JobService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
protected JobParameters mJobParameters;
private GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
public MyJobService() {
}
#Override
public boolean onStartJob(JobParameters jobParameters) {
Log.e("token", "Start Job Called");
setUpLocationClientIfNeeded();
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
return true;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
Toast.makeText(this,
"MyJobService.onStopJob()",
Toast.LENGTH_SHORT).show();
return false;
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(this.mGoogleApiClient,
mLocationRequest, this); // This is the changed line.
Log.e("onConnected", "onConnected");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
private void setUpLocationClientIfNeeded()
{
if(mGoogleApiClient == null)
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
this.mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
this.mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
Log.e("token",location.getLatitude()+""+location.getLongitude());
}
}
Try 2:
Called innerClass that implements ConnectionCallbacks, OnConnectionFailedListener in onStartJob of JobService but still onConnected method is never called
public class MyJobService extends JobService {
private Location mLastLocation;
String latitude = null;
String longitude = null;
protected JobParameters mJobParameters;
private class GetLocation extends AsyncTask<Integer, Void, Integer> implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
protected Integer doInBackground(Integer... jobID) {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(getBaseContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
return jobID[0];
}
protected void onPostExecute(Integer jobID) {
//h2 = new Handler();
//Runnable run = new Runnable() {
// #Override
// public void run() {
// long millis = System.currentTimeMillis() - 0;
// int seconds = (int) (millis / 1000);
// int minutes = seconds / 60;
// seconds = seconds % 60;
// Log.i("JobSchedulerTest","Job Finished!");
// h2.postDelayed(this, 1500);
jobFinished(mJobParameters, true);
}
};
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.e("onConnected " , "onConnected" );
createLocationRequest();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ActivityCompat.checkSelfPermission(MyJobService.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MyJobService.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationCallback() {
#Override
public void onLocationResult(final LocationResult locationResult) {
latitude = locationResult.getLastLocation().getLatitude() + "";
longitude = locationResult.getLastLocation().getLongitude() + "";
Log.e("onLocationResult lat", latitude);
Log.e("onLocationResult Lon", longitude);
}
#Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
}
}, null);
}
}
public MyJobService() {
}
#Override
public boolean onStartJob(JobParameters jobParameters) {
Log.d("onstart", "onStartJob() :: ");
mJobParameters=jobParameters;
Integer i=new Integer(jobParameters.getJobId());
new GetLocation().execute(i);
return false;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
Toast.makeText(this,
"MyJobService.onStopJob()",
Toast.LENGTH_SHORT).show();
return false;
}
}

Related

How to use locationListener in android fragment

I want to use locationListener in my android fragment. But I am getting an error. My code is in below.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
}
};
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, locationListener);
}
else {
}
}
I am getting this error.
Can't resolve method requestLocationUpdates
Implement all the methods of LocationListener
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setText(R.string.hello_blank_fragment);
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
if (new Utility().checkAndGrantPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 101, "your custom message"))
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, locationListener);
}
return textView;
}
Outside from onCreate
LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//Todo your code
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
//Todo your code
}
#Override
public void onProviderEnabled(String provider) {
//Todo your code
}
#Override
public void onProviderDisabled(String provider) {
//Todo your code
}
};
And the checkAndGrantPermission method is
public boolean checkAndGrantPermission(final Context context, final String permissionString, final int requestCode, String permissoinTypeMessage)
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, permissionString) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permissionString)) {
// your custom dialog screen when user deny permission
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{permissionString}, requestCode);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
In Activity override onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 101) {
yourFragmentInstance.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
}
In Your Framgent override onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 101) {
if (requestCode == AppConstants.runtimePermissionCode) {
if (permissions[0].equals(Manifest.permission.ACCESS_FINE_LOCATION) && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, locationListener);
}
}
}
}
Got your issue.
You have used Location listener from
com.google.android.gms.location.LocationListener;
You have to import LocationListener from
android.location.Location;
Try this one:
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, new android.location.LocationListener() {
#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) {
}
});
Hope it helps:)
Create this class:
public class GetCurrentLocation implements
ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
private static final String TAG = "location-updates-sample";
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 0;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
private final String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
private final String LOCATION_KEY = "location-key";
private final String LAST_UPDATED_TIME_STRING_KEY = "last-updated-time-string-key";
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Context mContext;
private getLocation mGetCurrentLocation;
public GetCurrentLocation(Context context) {
mContext = context;
buildGoogleApiClient();
}
private synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
public interface getLocation{
public void onLocationChanged(Location location);
}
public void startGettingLocation(getLocation location) {
mGetCurrentLocation = location;
connect();
}
public void stopGettingLocation() {
stopLocationUpdates();
disconnect();
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void startLocationUpdates() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
private void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
private void connect() {
mGoogleApiClient.connect();
}
private void disconnect() {
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "Connected to GoogleApiClient");
startLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
mGetCurrentLocation.onLocationChanged(location);
}
#Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
}
In your fragment class:
private GetCurrentLocation mListen;
mListen = new GetCurrentLocation(this);
mListen.startGettingLocation(new GetCurrentLocation.getLocation() {
#Override
public void onLocationChanged(Location location) {
// Here is my working with location object
}
});
make sure you have added latest googleplayservice library in your gradle file.

using Location Services fusedlocationapi in Android service -- Receiving only one location update

I'm trying my hand at making a background service that I'd like to run when the app is closed and terminate when the app is open.
as you can see in the code below, I have a Toast message that is supposed that is supposed to display in onLocationChanged(). I am only seeing that message appear once.
Here is what the permission looks like in the manifest:
<application
...
<activity android:name=".activities.ChatUsersActivity" />
<activity android:name=".activities.RequestsActivity"></activity>
<service android:name=".pops.PopService"
android:exported="false"
android:icon="#drawable/usericonmdpi"/>
</application>
And also, here is my Service extended class:
public class PopService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
ScheduledThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(2);
Runnable backgroundCollector = new BackgroundPopCollector();
private GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
Location mLastLocation;
private PopCityCollection cities;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
// Code to execute when the service is first created
super.onCreate();
buildGoogleApiClient();
}
#Override
public void onDestroy() {
super.onDestroy();
threadPoolExecutor.shutdownNow();
}
#Override
public void onLocationChanged(Location location) {
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
UserLocation.setLatitude(location.getLatitude());
UserLocation.setLongitude(location.getLongitude());
Toast.makeText(getBaseContext(), "Latitude is " + location.getLatitude(), Toast.LENGTH_SHORT).show();
System.out.println(UserLocation.getLatitude()+", "+UserLocation.getLongitude()+" --->BACKGROUND!!");
if(cities==null) {
cities = new PopCityCollection(new LatLng(location.getLatitude(), location.getLongitude()));
cities.findMyCity(this);
}
DatabaseReference db = FirebaseDatabase.getInstance().getReference().child("pops");
db.push().setValue("test");
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(100);
mLocationRequest.setFastestInterval(100);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
threadPoolExecutor.scheduleAtFixedRate(backgroundCollector, 0, 10, TimeUnit.SECONDS);
return START_NOT_STICKY;
}
}
Thank you for any insights you can provide!
-T
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
the above condition will remove the location updates , after first time so remove this code
removeLocationUpdates
Removes all location updates for the given location listener.

make GMS location tracking work in background

My Activity is like this:
public class MainMap extends FragmentActivity implements OnMarkerClickListener, OnMapReadyCallback,
ConnectionCallbacks, OnConnectionFailedListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
private static final int REQUEST_ACCESS_FINE_LOCATION = 0;
protected GoogleApiClient mGoogleApiClient;
protected Location mCurrentLocation;
protected LocationRequest mLocationRequest;
// ...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(NativeLib.get_location_update_interval_in_mil());
mLocationRequest.setFastestInterval(NativeLib.get_location_fastest_update_interval_in_mil());
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
protected void onStart() {
if (debug_mode) { Log.i(TAG, "onStart");}
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
if (debug_mode) { Log.i(TAG, "onStop");}
super.onStop();
mGoogleApiClient.disconnect();
}
#Override
public void onConnected(Bundle connectionHint) {
if (debug_mode) { Log.i(TAG, "onConnected");}
// permissions
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
request_fine_location_permission();
}
// location
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onLocationChanged(Location location) {
// CALL either do_background or do_foreground
}
private void do_background() {
// DO WORK
}
private void do_foreground() {
// DO WORK
}
}
The code works just fine in the foreground - what I want to do is to make sure that location is constantly tracked (even when the app is in the background or the phone is in sleep mode) and launch the appropriate function in my Activity.

Android studio get distance in every 5s

No bug, but the distance keeps changing when i click test button(not every 5s), so i dunno if my code really works well or not. It would be appreciated if you can tell whether there is some logical error or not.
here is my code.
The logic here is, when i have clicked start button, it will get the location, and then in every 5s, it will get a new location and calculate the distance and store it in an array. When i press test button, the total distance will be shown
public class MapsActivity extends BaseActivity /*implements LocationListener*/{
double totalDis=0;
double l;
int oxy =0;
TimeAnimator anim = new TimeAnimator();
private int isReset = 1;
private TextView textTimer;
private Button startButton;
private Button pauseButton;
private Button resetButton;
private long startTime = 0L;
private Handler myHandler = new Handler();
long timeInMillies = 0L;
long timeSwap = 0L;
long finalTime = 0L;
private String[] navMenuTitles;
private TypedArray navMenuIcons;
private GoogleMap mMap;
private Button testbtn;
double x;
double y;
double j;
double k;
float [] dis = new float[6];
TextView txt;
Location locationA;
Location locationB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items); // load
// titles
// from
// strings.xml
navMenuIcons = getResources()
.obtainTypedArray(R.array.nav_drawer_icons);// load icons from
// strings.xml
set(navMenuTitles, navMenuIcons);
textTimer = (TextView) findViewById(R.id.textTimer);
testbtn = (Button) findViewById(R.id.testbtn);
txt = (TextView) findViewById(R.id.textTest);
testbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for(int i=0;i<dis.length;i++){
totalDis+=dis[i];
}
txt.setText("dis = "+totalDis);
}
});
startButton = (Button) findViewById(R.id.btnStart);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startTime = SystemClock.uptimeMillis();
myHandler.postDelayed(updateTimerMethod, 0);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Location locationA = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
x = locationA.getLatitude();
y = locationA.getLongitude();
anim.start();
anim.setTimeListener(new TimeAnimator.TimeListener() {
long time = 0;
#Override
public void onTimeUpdate(TimeAnimator timeAnimator, long t, long dt) {
time += dt;
if (time >= 5000) { // >= needed because this also might be not totally accurate...
time -= 5000; // keep the remainder (if there is) to correct the accuracy of next loop
// do stuff here (in every 5 seconds)
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Location locationB = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
j = locationB.getLatitude();
k = locationB.getLongitude();
Location.distanceBetween(x,y,j,k,dis);
x=j;
y=k;
}
}
});
}
});
pauseButton = (Button) findViewById(R.id.btnPause);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
timeSwap += timeInMillies;
myHandler.removeCallbacks(updateTimerMethod);
}
});
resetButton = (Button) findViewById(R.id.btnReset);
resetButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
textTimer.setText("0:00:00");
timeSwap=0;
}
});
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.setMyLocationEnabled(true);
}
private Runnable updateTimerMethod = new Runnable() {
public void run() {
timeInMillies = SystemClock.uptimeMillis() - startTime;
finalTime = timeSwap + timeInMillies;
int seconds = (int) (finalTime / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
int milliseconds = (int) (finalTime % 1000);
textTimer.setText("" + minutes + ":"
+ String.format("%02d", seconds) + ":"
+ String.format("%03d", milliseconds));
myHandler.postDelayed(this, 0);
}
};
}
put these codes into yours as directed .
declair these veriables
LocationManager manager;
Button start_calculating, show;
boolean startcount_now = false;
double total_dist = 0;
Location last_loc = null;
import
import android.location.LocationListener;
and implement
LocationListener
then implement these methods
#Override
public void onLocationChanged(Location location) {
if (startcount_now == true) {
if (last_loc == null) {
last_loc = location;
} else {
total_dist += location.distanceTo(last_loc);
}
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
protected void onResume() {
super.onResume();
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(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
return;
}
if (manager != null) {
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, this);
}
}
#Override
protected void onPause() {
super.onPause();
super.onResume();
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(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
return;
}
if (manager != null) {
manager.removeUpdates(MainActivity.this);
}
}
in oncreate()
manager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
the listeners for the button (you add these into your own button used for this purpose)
start_calculating.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startcount_now = true;
}
});
show.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "total distancetravelled is " + total_dist, Toast.LENGTH_LONG).show();
}
});
add permission in menifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
the show button will show you the total distance in toast . you can use as you want it. the location fetching will be stopped when your app is in background. for the location fetching mechanism please read this.
let me know if this is what you want.
Your code is very very wrong.
Refer to Receiving Location updates page. That page leaves some stuff for you to implement, so I'll give you working example. You'll need to adapt it for your needs yourself.
#Override
public void onConnected(#Nullable final Bundle bundle) {
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
public void onConnectionSuspended(final int i) {
}
#Override
public void onLocationChanged(final Location location) {
EventBus.getDefault().post(new LocationChangedEvent(location));
}
#Override
public void onConnectionFailed(#NonNull final ConnectionResult connectionResult) {
}
protected synchronized void buildGoogleApiClient() {
Logger.e(this, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void startLocationUpdates() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
Utils.showPermissionRationaleDialog(MainActivity.this, R.string.permission_rationale_location,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
}
});
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
}
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
mRequestingLocationUpdates = savedInstanceState.getBoolean(
"request_location_updates");
}
buildGoogleApiClient();
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
}
}
#Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}

Start a service when activity is paused

i'm creating an app that show user's location into a map, now i want to update the user location when the app is in background,especially i want to start the Service when the Activity's method onPause() is called.
my activity:
public class MapsActivity extends Activity implements OnClickListener, GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener, OnInfoWindowClickListener {
private static final long UPDATE_INTERVAL = 5000;
private static final long FASTEST_INTERVAL = 1000;
private GoogleMap map = null;
private LocationClient locationClient;
private Location myLocation;
private LocationRequest locationRequest;
private LatLng newPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
locationClient = new LocationClient(this, this, this);
locationRequest = LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL).setSmallestDisplacement(10);
if (locationClient != null)
// connect the client to the Google Play services
locationClient.connect();
}
#Override
public void onLocationChanged(Location location) {
newPosition = new LatLng(location.getLatitude(), location.getLongitude());
myLocation = location;
if (myLocation != null)
button.setClickable(true);
else
button.setClickable(false);
map.animateCamera(CameraUpdateFactory.newLatLngZoom(newPosition, 20));
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
}
#Override
public void onConnected(Bundle arg0) {
Toast.makeText(this, "I'm bringing you to your area.", Toast.LENGTH_SHORT).show();
// start periodic updates
locationClient.requestLocationUpdates(locationRequest, this);
}
#Override
public void onDisconnected() {
Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}
public ProgressDialog getProgress() {
return progress;
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onRestart() {
super.onRestart();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onStop() {
super.onStop();
}
#Override
protected void onDestroy() {
if (locationClient.isConnected() && locationClient != null) {
locationClient.removeLocationUpdates(this);
locationClient.disconnect();
}
super.onDestroy();
}
}
my Service Class:
public class locationBackgroundService extends Service implements LocationListener, GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
private LocationRequest mLocationRequest;
private LocationClient mLocationClient;
public locationBackgroundService() {
}
#Override
public void onCreate() {
mLocationRequest = LocationRequest.create();
// mLocationRequest.setInterval(CommonUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// mLocationRequest.setFastestInterval(CommonUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
mLocationClient = new LocationClient(getApplicationContext(), this, this);
mLocationClient.connect();
}
#Override
public void onStart(Intent intent, int startId) {
int start = Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onConnected(Bundle arg0) {
Log.i("info", "Location Client is Connected");
mLocationClient.requestLocationUpdates(mLocationRequest, this);
Log.i("info", "Service Connect status :: " + isServicesConnected());
}
#Override
public void onDisconnected() {
Log.i("info", "Location Client is Disconnected");
}
#Override
public void onLocationChanged(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
}
private boolean isServicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(locationBackgroundService.this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
return true;
} else {
return false;
}
}
#Override
public void onDestroy() {
mLocationClient.removeLocationUpdates(this);
super.onDestroy();
}
}
is it possible to do that?
thanks in advance.
example of LocationService.class
package com.example.myapp;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.example.myapp.activities.MainActivity;
public class LocationService extends Service implements
LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
public static final String LOCATION_SERVICE = "LocationService";
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
float minDist = 100f;
int minTime = 10000;
PendingIntent contentIntent;
public static String USER_LATITUDE = "user_latitude";
public static String USER_LONGITUDE = "user_longitude";
#Override
public void onCreate() {
Log.d("onCreate", "");
super.onCreate();
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
mLocationClient = new LocationClient(this, this, this);
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(minTime);
//mLocationRequest.setSmallestDisplacement(minDist);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mLocationClient.connect();
return Service.START_NOT_STICKY;
}
#Override
public void onLocationChanged(Location location) {
float latitude = (float) location.getLatitude();
float longitude = (float) location.getLongitude();
Log.d("onLocationChanged. latLng", latitude + ", " + longitude);
Intent intent = new Intent(LOCATION_SERVICE);
intent.putExtra(USER_LATITUDE, latitude);
intent.putExtra(USER_LONGITUDE, longitude);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
if (mLocationClient.isConnected() ) {
stopPeriodicUpdates();
}
}
#Override
public void onConnected(Bundle bundle) {
Log.d(LOCATION_SERVICE, "onConnected");
startPeriodicUpdates();
}
#Override
public void onDisconnected() {
Log.d(LOCATION_SERVICE, "onDisconnected");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(LOCATION_SERVICE, "onConnectionFailed");
}
public void startPeriodicUpdates() {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
Log.d(LOCATION_SERVICE, "startPeriodicUpdates");
}
private void stopPeriodicUpdates() {
mLocationClient.removeLocationUpdates(this);
Log.d(LOCATION_SERVICE, "stopPeriodicUpdates");
}
}
add in MainActivity.class
private boolean servicesConnected() {
int resultCode =
GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == resultCode) {
Log.d("servicesConnected", "Google play services isConnected");
return true;
} else {
return false;
}
}
private BroadcastReceiver mLocationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
float latitude = intent.getFloatExtra(LocationService.USER_LATITUDE, 0);
float longitude = intent.getFloatExtra(LocationService.USER_LONGITUDE, 0);
//do something
}
};
#Override
public void onPause() {
super.onPause();
Intent service = new Intent(this, LocationService.class);
IntentFilter intentLocationServiceFilter = new IntentFilter(LocationService
.LOCATION_SERVICE);
LocalBroadcastManager.getInstance(this)
.registerReceiver(mLocationReceiver, intentLocationServiceFilter);
if (servicesConnected()) {
startService(service);
}
}
And do not forget add to AndroidManifest file your LocationService

Categories

Resources