I have defined a service (i.e. LocationService ) which gives me users's current latitude and longitude as an intent extras to my_activity. Now , I want to use them to show current location on map (using Google maps) . I passed these latlng in mMap.animateCamera and mMap.moveCamera methods but they are not showing any Marker or zoom in to the current location . Please tell me if I am doing anything wrong .

Code for the LocationService and my MainActivity is pasted below :

LocationServices.java

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

private static final String TAG = LocationServicesForLocationUpdates.class.getSimpleName();

public static final String ACTION_LOCATION_BROADCAST
        = LocationServicesForLocationUpdates.class.getName() + "LocationBroadcast";

public static final String EXTRA_LATITUDE = "extra_latitude";
public static final String EXTRA_LONGITUDE = "extra_longitude";

private GoogleApiClient mLocationClient;
private LocationRequest mLocationRequest = new LocationRequest();

@Override
public int onStartCommand(Intent intent, int flags, int startId) {


    mLocationClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    mLocationRequest.setInterval(5000);
    mLocationRequest.setFastestInterval(3000);

    mLocationClient.connect();

   // return super.onStartCommand(intent, flags, startId);

    return START_STICKY;
}

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

/*
 * LOCATION CALLBACKS
 */
@Override
public void onConnected(Bundle dataBundle) {
    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED

            && ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        // 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.

        Log.d(TAG, "== Error On onConnected() Permission not granted");
        //Permission not granted by user so cancel the further execution.


        return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest ,this);

    Log.d(TAG, "Connected to Google API");
}



//to get the location change
@Override
public void onLocationChanged(Location location) {
    Log.d(TAG, "Location changed");


    if (location != null) {
        Log.d(TAG, "== location != null");

        //Send result to activities
        sendMessageToUI(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));

    }
}

private void sendMessageToUI(String lat, String lng) {

    Log.d(TAG, "Sending info...");

    Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
    intent.putExtra(EXTRA_LATITUDE, lat);
    intent.putExtra(EXTRA_LONGITUDE, lng);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}


@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}
}

New MainActivity.java

 public class MainActivity extends AppCompatActivity implements OnMapReadyCallback{

private TextView mLatlngTxtVu , mAddressTxtVu;


private boolean mAlreadyStartedService;

private static final String TAG = ParentHomeActivity.class.getSimpleName();

private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;


private GoogleMap mGoogleMap;

Double mlattitude , mlongitude;

Marker mCurrentMarker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_parent_home);


    Log.d(TAG, "onCreate: Called");
    mLatlngTxtVu = (TextView) findViewById(R.id.latlng_txtview);
    mAddressTxtVu = (TextView) findViewById(R.id.address_txtvu);

    LocalBroadcastManager.getInstance(this).registerReceiver(
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
                    mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));


                    Log.d("latlng", "onReceive: " + mlongitude + mlattitude);



                    if (mlattitude != null && mlongitude != null) {
                        mLatlngTxtVu.setText("Latitude : " + mlattitude + "Longitude: " + mlongitude);
                    }
                }
            }, new IntentFilter(LocationServicesForLocationUpdates.ACTION_LOCATION_BROADCAST)
    );

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.main_map);
    mapFragment.getMapAsync(MainActivity.this);

}

@Override
protected void onResume() {
    super.onResume();

    checkGooglePlayServices();

}


@Override
public void onMapReady(GoogleMap googleMap) {

    mGoogleMap = googleMap ;

    Log.d(TAG, "onMapReady: called");

    Log.d("coord", mlattitude + "   " + mlongitude);

    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;
    }


    mGoogleMap.setMyLocationEnabled(true);
    mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
    mGoogleMap.getUiSettings().setMapToolbarEnabled(false);


    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(mlattitude, mlongitude))      // Sets the center of the map to location user
            .zoom(14)                   // Sets the zoom
            .bearing(0)                // Sets the orientation of the camera to east
            .tilt(90)                   // Sets the tilt of the camera to 30 degrees
            .build();                   // Creates a CameraPosition from the builder
    mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));


    LatLng latLng = new LatLng(mlattitude  , mlongitude);

    mGoogleMap.addMarker(new MarkerOptions().position(latLng).title("YOU"));

   // mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

   /* CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(mlattitude, mlongitude))      // Sets the center of the map to location user
            .zoom(17)                   // Sets the zoom
            .bearing(90)                // Sets the orientation of the camera to east
            .tilt(40)                   // Sets the tilt of the camera to 30 degrees
            .build();                   // Creates a CameraPosition from the builder
    mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));*/

}



private void checkGooglePlayServices() {

    //Check whether this user has installed Google play service which is being used by Location updates.
    if (isGooglePlayServicesAvailable()) {

        //Passing null to indicate that it is executing for the first time.
        checkAndPromptForInternetConnection(null);

    } else {
        Toast.makeText(getApplicationContext(), "Play services Not Available", Toast.LENGTH_LONG).show();
    }

}

private boolean checkAndPromptForInternetConnection(DialogInterface dialog) {

    ConnectivityManager connectivityManager
            = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();

    if (activeNetworkInfo == null || !activeNetworkInfo.isConnected()) {
        promptInternetConnect();
        return false;
    }


    if (dialog != null) {
        dialog.dismiss();
    }

    //Yes there is active internet connection. Next check Location is granted by user or not.

    if (checkPermissions()) { //Yes permissions are granted by the user. Go to the next step.
        startedLocationServices();
    } else {  //No user has not granted the permissions yet. Request now.
        requestPermissions();
    }
    return true;
}

/**
 * Step 3: Start the Location Monitor Service
 */
private void startedLocationServices() {

    //And it will be keep running until you close the entire application from task manager.
    //This method will executed only once.

    if (!mAlreadyStartedService && mLatlngTxtVu != null) {

        mLatlngTxtVu.setText("Running ");

        //Start location sharing service to app server.........
        Intent intent = new Intent(this, LocationServicesForLocationUpdates.class);
        startService(intent);

        mAlreadyStartedService = true;
        //Ends................................................
    }
}
/**
 * Show A Dialog with button to refresh the internet state.
 */
private void promptInternetConnect() {
    AlertDialog.Builder builder = new AlertDialog.Builder(ParentHomeActivity.this);
    builder.setTitle("No internet connection");
    builder.setMessage("Please Check your internet connection");

    String positiveText = "Refresh";
    builder.setPositiveButton(positiveText,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {


                    //Block the Application Execution until user grants the permissions
                    if (checkAndPromptForInternetConnection(dialog)) {

                        //Now make sure about location permission.
                        if (checkPermissions()) {

                            //Step 2: Start the Location Monitor Service
                            //Everything is there to start the service.
                            startedLocationServices();
                        } else if (!checkPermissions()) {
                            requestPermissions();
                        }

                    }
                }
            });

    AlertDialog dialog = builder.create();
    dialog.show();
}


/**
 * Return the availability of GooglePlayServices
 */
public boolean isGooglePlayServicesAvailable() {
    GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
    int status = googleApiAvailability.isGooglePlayServicesAvailable(this);
    if (status != ConnectionResult.SUCCESS) {
        if (googleApiAvailability.isUserResolvableError(status)) {
            googleApiAvailability.getErrorDialog(this, status, 2404).show();
        }
        return false;
    }
    return true;
}


/**
 * Return the current state of the permissions needed.
 */
private boolean checkPermissions() {
    int permissionState1 = ActivityCompat.checkSelfPermission(this,
            android.Manifest.permission.ACCESS_FINE_LOCATION);

    int permissionState2 = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION);

    return permissionState1 == PackageManager.PERMISSION_GRANTED && permissionState2 == PackageManager.PERMISSION_GRANTED;

}

/**
 * Start permissions requests.
 */
private void requestPermissions() {

    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    android.Manifest.permission.ACCESS_FINE_LOCATION);

    boolean shouldProvideRationale2 =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION);


    // Provide an additional rationale to the img_user. This would happen if the img_user denied the
    // request previously, but didn't check the "Don't ask again" checkbox.
    if (shouldProvideRationale || shouldProvideRationale2) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");
        showSnackbar(R.string.grantPermission,
                android.R.string.ok, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Request permission
                        ActivityCompat.requestPermissions(ParentHomeActivity.this,
                                new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                                REQUEST_PERMISSIONS_REQUEST_CODE);
                    }
                });
    } else {
        Log.i(TAG, "Requesting permission");
        // Request permission. It's possible this can be auto answered if device policy
        // sets the permission in a given state or the img_user denied the permission
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(ParentHomeActivity.this,
                new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

/**
 * Shows a {@link Snackbar}.
 *
 * @param mainTextStringId The id for the string resource for the Snackbar text.
 * @param actionStringId   The text of the action item.
 * @param listener         The listener associated with the Snackbar action.
 */
private void showSnackbar(final int mainTextStringId, final int actionStringId,
                          View.OnClickListener listener) {
    Snackbar.make(
            findViewById(android.R.id.content),
            getString(mainTextStringId),
            Snackbar.LENGTH_INDEFINITE)
            .setAction(getString(actionStringId), listener).show();
}


/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length <= 0) {
            // If img_user interaction was interrupted, the permission request is cancelled and you
            // receive empty arrays.
            Log.i(TAG, "User interaction was cancelled.");
        } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            Log.i(TAG, "Permission granted, updates requested, starting location updates");
            startedLocationServices();

        } else {
            // Permission denied.

            // Notify the img_user via a SnackBar that they have rejected a core permission for the
            // app, which makes the Activity useless. In a real app, core permissions would
            // typically be best requested during a welcome-screen flow.

            // Additionally, it is important to remember that a permission might have been
            // rejected without asking the img_user for permission (device policy or "Never ask
            // again" prompts). Therefore, a img_user interface affordance is typically implemented
            // when permissions are denied. Otherwise, your app could appear unresponsive to
            // touches or interactions which have required permissions.
            showSnackbar(R.string.permissionDenied,
                R.string.settings, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Build intent that displays the App settings screen.
                        Intent intent = new Intent();
                        intent.setAction(
                                Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package",
                                BuildConfig.APPLICATION_ID, null);
                        intent.setData(uri);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                    }
                });
        }
    }
}

@Override
public void onDestroy() {


    //Stop location sharing service to app server.........

    stopService(new Intent(this, LocationServicesForLocationUpdates.class));
    mAlreadyStartedService = false;
    //Ends................................................

    super.onDestroy();
}

}

Feel free to ask any queries in case you don't understand my problem and tell me the correct approach to solve my problem . I am new to android app development.

2 Answers

1
ismail alaoui On Best Solutions

in onMapReady() please create a new LatLng position and add it in as MarkerOption

   @Override
   public void onMapReady(GoogleMap googleMap) {
       .......
       .......
    // make sure you  are getting your latitude and longitude string value
    mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
    mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));

 CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(mLattitude,mlongitude)) // My position
            .zoom(14)           // Zoom Level
            .bearing(0)         // camera position, (0 north , 180 south )
            .tilt(90)           // Inclinaison de la camera
            .build();

    googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

LatLng position = new LatLng(mlattitude,mlongitude);
googleMap.addMarker(new MarkerOptions().position(position)
            .title("my marker"));
   }

edit

Do not forget to call getMapAsync in your onReceive() method

    LocalBroadcastManager.getInstance(this).registerReceiver(
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
                mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
        .findFragmentById(R.id.main_map);
mapFragment.getMapAsync(MainActivity.this);

                Log.d("latlng", "onReceive: " + mlongitude + mlattitude);
                if (mlattitude != null && mlongitude != null) {
                    mLatlngTxtVu.setText("Latitude : " + mlattitude + "Longitude: " + mlongitude);
                }
            }
        }, new IntentFilter(LocationServicesForLocationUpdates.ACTION_LOCATION_BROADCAST)
);

);
0
user2132115 On

You can do like that :

public class MapsMarkerActivity extends AppCompatActivity
    implements OnMapReadyCallback {
   // Include the OnCreate() method here too, as described above.
   @Override
   public void onMapReady(GoogleMap googleMap) {
       // Add a marker in Sydney, Australia,
       // and move the map's camera to the same location.
       LatLng sydney = new LatLng(-33.852, 151.211);
       googleMap.addMarker(new MarkerOptions().position(sydney)
            .title("Marker in Sydney"));
       googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
   }
}

The code is from the Google documentation page