How to return current location on flutter using native android code in java

Viewed 511

I am trying to get current location using native code for my flutter app.

It seemed more doable to implement something similar to Google Maps where the app asks the user whether they would like location turned on or not and if they say ok, then location is turned on automatically. I have been able to do this successfully but I also want to return the current location back to the flutter end. Now, I am obtaining the user action from onActivityResult() and then running the getLastLocation() method if resultCode == RESULT_OK. However, I want the flutter end to wait until the current location is obtained. I have tried using a lock mechanism but this causes the app to freeze. Currently, I have the naive implementation of just using Thread.sleep(long millis) until an affirmative result has been obtained at which point the result would be returned back to flutter.

This is the code to turn location on:

private void turnLocationOn(Context context) {
  GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
          .addApi(LocationServices.API).build();
  googleApiClient.connect();

  LocationRequest locationRequest = LocationRequest.create();
  locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
  locationRequest.setInterval(10000);
  locationRequest.setFastestInterval(10000 / 2);

  LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
          .addLocationRequest(locationRequest);
  builder.setAlwaysShow(true);

  Task<LocationSettingsResponse> result = LocationServices.getSettingsClient(this)
          .checkLocationSettings(builder.build());
    result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
        @Override
        public void onComplete(@NonNull Task<LocationSettingsResponse> task) {
            try {
                LocationSettingsResponse response =
                        task.getResult(ApiException.class);
            } catch (ApiException ex) {
                switch (ex.getStatusCode()) {
                    case LocationSettingsStatusCodes
                            .RESOLUTION_REQUIRED:
                        try {
                            ResolvableApiException resolvableApiException =
                                    (ResolvableApiException) ex;
                            resolvableApiException
                                    .startResolutionForResult(MainActivity.this,
                                            LOCATION_SETTINGS_REQUEST);
                        } catch (IntentSender.SendIntentException e) {
                              e.printStackTrace();
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        break;
                }
            }
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == LOCATION_SETTINGS_REQUEST) {
        if (resultCode == RESULT_OK)
        {
            Log.i(TAG, "User turned on location");
            callResult = true;
        } else if (resultCode == RESULT_CANCELED) {
            Log.i(TAG, "User declined location setting request");
            callResult = false;
           // setCallResult(false);
        }
    }
}

This is the method that sets the current location. It is an implementation of LocationListener:

@Override
public void onLocationChanged(Location location) {
    callResult = true;
    currLocation = location.getLatitude() + ", " + location.getLongitude();
}

This is the Method channel that returns a result back to flutter

new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
        new MethodChannel.MethodCallHandler() {
            @Override
            public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
                if (methodCall.method.equals("getCurrentLocation")) {
                    turnLocationOn(MainActivity.this);
                    while (!callResult) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    result.success(currLocation);
                } else {
                    result.notImplemented();
                }
            }
        });

...and this is from the flutter end

final String result = await platform.invokeMethod('getCurrentLocation');
resultFromCall = "SUCCESS: $result";
debugPrint(resultFromCall);
0 Answers
Related