I am using Fused Location API to get latitude & longitude. My question is how can i set these value to other variables so that i can do some calculation or show them on my application. I have tried below code so far.
public class FusedLocationDetector implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private Activity context;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private double temp;
private String mib;
public LocationAddress locationAddress=new LocationAddress();
public FusedLocationDetector(Activity context) {
mGoogleApiClient=new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
this.context=context;
// locationAddress=new LocationAddress();
}
public void startConnection(){
if(mGoogleApiClient!=null){
mGoogleApiClient.connect();
}
}
public void stopConnection(){
if(mGoogleApiClient!=null){
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnected(Bundle bundle) {
fusedOperation();
}
#Override
public void onConnectionSuspended(int i) {
// mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public void fusedOperation(){
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
mib= String.valueOf(mLastLocation.getLatitude());
locationAddress.setLatitude(mLastLocation.getLatitude());
locationAddress.setLongitude(mLastLocation.getLongitude());
Log.d("Longitude",String.valueOf(locationAddress.getLongitude()));
Log.d("Longitude",mib);
}
}
}
Related
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;
}
}
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.
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.
I'm trying to implement abstract Activity, whose inheritants would be able to get Location data. I'm strictly following this guide, that seems pretty straightforward.
But after all I have a few problems. Google API should pass location data even if GPS is off, getting this from network data or even passive data from other apps. But in my case it works only with GPS enabled.
Another question is what happens when I turn GPS off/on. In my case after that I can't het any data at all.
Here's the class that makes everything done.
public abstract class LocationProviderActivity extends BaseDrawerActivity
implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private final String TAG = "LOCATION";
GoogleApiClient client;
protected Location location;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (client == null) {
client = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
#Override
protected void onStart() {
client.connect();
Log.i(TAG, "Connected");
super.onStart();
}
#Override
protected void onStop() {
client.disconnect();
Log.i(TAG, "Disconnected");
super.onStop();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//TODO
return;
}
location = LocationServices.FusedLocationApi.getLastLocation(client);
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Location services connected.");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.i(TAG, "Location services suspended. Please reconnect.");
}
#Override
public void onLocationChanged(Location location) {
}
}
I have used Fused Location API to get location updates. I am getting updates while setting LocationRequest based on setTimeInterval. But I need only updates on 10m Movement. So i placed setSmallestDisplacement(10) .But when i put setSmallestDisplacement(10), i didnt get updates. Following is my LocationUpdate class
public class LocationManger implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
GoogleApiClient mLocationClient;
Location mCurrentLocation;
LocationRequest mLocationRequest;
Context mContext;
public LocationManger(Context context) {
super();
mLocationClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mContext = context;
}
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Helper.showToast("failed", mContext);
}
#Override
public void onConnected(Bundle arg0) {
if (mLocationRequest == null) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setSmallestDisplacement(10);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
mLocationClient.connect();
}
/**
* Function to start the location updates
*/
public void startLocationUpdates() {
if (!mLocationClient.isConnected())
mLocationClient.connect();
}
/**
* function to stop the location updates
*/
public void stopUpdatingLocation() {
if (mLocationClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mLocationClient, this);
}
mLocationClient.disconnect();
}
/**
* function to get the current latitude
*/
public double getCurrentLatitude() {
if (mCurrentLocation != null) {
return mCurrentLocation.getLatitude();
}
return 0;
}
/**
* function to get the current longitude
*/
public double getCurrentLongitude() {
if (mCurrentLocation != null) {
return mCurrentLocation.getLongitude();
}
return 0;
}
/**
* function to get the current location
*/
public Location getCurrentLocation() {
return LocationServices.FusedLocationApi.getLastLocation(mLocationClient);
}
}
Please give me a solution if anyone know the issue. Thanks in advance
Use setFastestInterval(0) to allow updates more frequently than called for by setInterval. Otherwise you will miss some updates from displacement