Amrita Stha
Amrita Stha

Reputation: 3347

Re- JobScheduler combined with FusedLocationProvider Api oftens gives null location value

I have a jobScheduler with fusedLocationApi provider. It works alright but once a while it gives null value for a no. of time (6-7 times in a sequence). I tried onLocationChanged() and LocationServices.FusedLocationApi.requestLocationUpdates(), both gives null values at same time. How can I improve it? I have set high accuracy or Gps,wifi and mobile networks as locating method in device setting. thanks in advance.

One more thing, 80% of the null value are received when there is no wifi. I think Fused Api should have worked well without wifi as well Since there is gps available, isn't it?

Main class

public class LiveTrack extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_live_track);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        jobScheduler = (JobScheduler)getSystemService(JOB_SCHEDULER_SERVICE);
        ComponentName jobService =
                        new ComponentName(getPackageName(), MyJobService.class.getName());
        JobInfo jobInfo =
                        new JobInfo.Builder(MYJOBID, jobService).setPeriodic(15 * 60 * 1000L)
                                .setExtras(bundle)
                                .build();
        int jobId = jobScheduler.schedule(jobInfo);

        if(jobScheduler.schedule(jobInfo)>0){
            Log.e("status","running");
        }else{
            Log.e("status","failed");
        }
    }
}

JobService class with fused Api Provider

public class MyJobService extends JobService
        implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener
        , LocationListener {

    private GoogleApiClient mGoogleApiClient;
    LocationRequest mLocationRequest;
    private Location mLastLocation;



    public static String latitude;
    public static String latitudeIfNull;
    public static String longitude;
    public static String longitudeIfNull;

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        setUpLocationClientIfNeeded();

        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        mLocationRequest.setInterval(30000);
        mLocationRequest.setFastestInterval(30000);
        return false;
    }


    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        Toast.makeText(this,
                "App has stopped working. Please open the app again. Thankyou",
                Toast.LENGTH_LONG).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); 
        createLocationRequest();

        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

    }

    @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) {
        latitudeIfNull = location.getLatitude() + "";
        longitudeIfNull = location.getLongitude() + "";
        Log.e("gps longitude",longitudeIfNull);
    }

    protected void createLocationRequest() {

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(60000);
        mLocationRequest.setFastestInterval(50000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        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(mGoogleApiClient, mLocationRequest, new LocationCallback() {
            @Override
            public void onLocationResult(final LocationResult locationResult) {
                latitude = locationResult.getLastLocation().getLatitude() + "";
                longitude = locationResult.getLastLocation().getLongitude() + "";
                Log.i("latitude ", latitude + "");
                Log.i("longitude ", longitude + "");
            }

            @Override
            public void onLocationAvailability(LocationAvailability locationAvailability) {
                Log.i("onLocationAvailability", "onLocationAvailability: isLocationAvailable =  " + locationAvailability.isLocationAvailable());
            }
        }, null);
    }
}
                                                     .

Upvotes: 2

Views: 550

Answers (1)

AbhayBohra
AbhayBohra

Reputation: 2117

Try this

Create a background service class like this

public class LocationBackGroundService extends Service implements LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "LocationBackGroundService";
    private static final long INTERVAL = 100;
    private static final long FASTEST_INTERVAL = 100;

    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location mCurrentLocation;
    Context mCOntext;

    public void LocationBackGroundService(Context mContext) {
        this.mCOntext = mContext;
    }

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        mGoogleApiClient.connect();
    }

    @Override
    public void onCreate() {
        super.onCreate();

        if (!isGooglePlayServicesAvailable()) {
            // finish();
        }
        createLocationRequest();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        if (mGoogleApiClient.isConnected()) {
            startLocationUpdates();
        }
    }

    private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            return false;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onConnected(Bundle bundle) {
        startLocationUpdates();
    }


    protected void startLocationUpdates() {
        PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);

        Log.d(TAG, "Location update started ..............: ");
    }

    @Override
    public void onConnectionSuspended(int i) {

        Toast.makeText(this, "OnConnection Suspended", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Toast.makeText(this, "OnConnection Failed", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLocationChanged(Location location) {

        if (null != mCurrentLocation) {
            mCurrentLocation = location;
            String lat = String.valueOf(mCurrentLocation.getLatitude());
            String lng = String.valueOf(mCurrentLocation.getLongitude());

        }
    }
}

And call when activity starts like this

startService(new Intent(this, yourBackgroundServiceName.class));

and in menifest

<service android:name=".yourBackgroundServiceName"></service>

and don;t forget to add run time permissions before stating a service

Upvotes: 1

Related Questions