0

I want to set up marker on Google Map when GPS is enabled.

I created a broadcast receiver to check if GPS is enabled or disabled. It works. However, i don't know how to get Location and set up marker on map with Google Play services.

Method connect() on a LocationClient is started on method onStart() and startUpdates() is started on onResume().

How can i setup map on my Broadcast receiver ?

If i use getLocation() (see below) it returns null because i'm not connected to GooglePlay services.

If i use LocationClient.connect() i have to wait the client be connected to get location.

How can i do that ?

PS : I use this sample of code to connect to Google play services : http://developer.android.com/training/location/receive-location-updates.html

My inner class GpsLocationReceiver :

public class GpsLocationReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            LocationManager lm = (LocationManager) context.getSystemService(Service.LOCATION_SERVICE);
            boolean isEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
            onGpsStatusChanged(isEnabled);
        }
    }

    private void onGpsStatusChanged(boolean b) {
        if (!servicesConnected() && b) {
            mLocationClient.connect();
        }
        /*currentLocation = getLocation();
        //setUpMapIfNeeded();
        if (currentLocation == null) {
            Toast.makeText(this, "GPS enabled - " + b + " Loc : null", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "GPS enabled - " + b + " Loc : " + currentLocation.toString(), Toast.LENGTH_LONG).show();

        }*/
    }

My method getLocation

public Location getLocation() {

        // If Google Play Services is available
        if (servicesConnected()) {

            // Get the current location
            return mLocationClient.getLastLocation();
        }
        return null;
    }

my method onConnected() :

 @Override
    public void onConnected(Bundle bundle) {

        //Set currentLocation
        currentLocation = getLocation();

        if (currentLocation == null) {
            Toast.makeText(HomeActivity.this, "location null", Toast.LENGTH_LONG).show();
        }
        else {
            Toast.makeText(HomeActivity.this, "Lat : "+ currentLocation.getLatitude() + " Long : "+currentLocation.getLongitude(), Toast.LENGTH_LONG).show();
            //Get map if needed
            setUpMapIfNeeded();
        }



        if (mUpdatesRequested) {
            startPeriodicUpdates();
        }
    }

Thx

EDIT : I had modify my code. It seems clearer for me. Now, my function getLocation() called after connect) finished succesfully return null. That means that google play service is not available.

How is it possible because connection to the service is finished successfully ?

Maxouille
  • 2,729
  • 2
  • 19
  • 42

2 Answers2

2

If I understand you well, the problem is that even though the GPS is enabled you have to wait until the GPS gets at least it's first fix to get the user's location. I don't understand why you are checking the GPS status in a BroadcastReceiver, but I think it is better if you check if the GPS is enabled before connecting your LocationClient (maybe you could check it even before launching the Actviity, if your requirements allow it) and then you can request the location.

Now, there's another issue: if you call mLocationClient.getLastLocation()there is the possibility that you retrieve a cached location (as it's called, it's the "last location" registered by the system) or if the system didn't have any, you could get a null location, so your marker will obviously be innaccurate. As I usually do, after checking if the GPS is enabled you can make a LocationRequest with PRIORITY_HIGH_ACCURACY and implement the LocationListener as the Android training does, then after the first locationChange is received you can removeLocationUpdates if you only want one marker and now you can be sure that the location you got is the user`s CURRENT location, but you have to INEVITABLY wait for the GPS to connect, it could be a couple of minutes or it may never happen, it depends on the weather and a couple of random variables out of your control.

EDIT: here is an example taken from the Google Play Services SDK's samples (sdk/extras/google/google_play_services/samples/maps)::

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.mapdemo;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener;
import com.google.android.gms.maps.SupportMapFragment;

import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

/**
 * This demo shows how GMS Location can be used to check for changes to the users location.  The
 * "My Location" button uses GMS Location to set the blue dot representing the users location. To
 * track changes to the users location on the map, we request updates from the
 * {@link LocationClient}.
 */
public class MyLocationDemoActivity extends FragmentActivity
        implements
        ConnectionCallbacks,
        OnConnectionFailedListener,
        LocationListener,
        OnMyLocationButtonClickListener {

    private GoogleMap mMap;

    private LocationClient mLocationClient;
    private TextView mMessageView;

    // These settings are the same as the settings for the map. They will in fact give you updates
    // at the maximal rates currently possible.
    private static final LocationRequest REQUEST = LocationRequest.create()
            .setInterval(5000)         // 5 seconds
            .setFastestInterval(16)    // 16ms = 60fps
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_location_demo);
        mMessageView = (TextView) findViewById(R.id.message_text);
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
        setUpLocationClientIfNeeded();
        mLocationClient.connect();
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mLocationClient != null) {
            mLocationClient.disconnect();
        }
    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        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) {
                mMap.setMyLocationEnabled(true);
                mMap.setOnMyLocationButtonClickListener(this);
            }
        }
    }

    private void setUpLocationClientIfNeeded() {
        if (mLocationClient == null) {
            mLocationClient = new LocationClient(
                    getApplicationContext(),
                    this,  // ConnectionCallbacks
                    this); // OnConnectionFailedListener
        }
    }

    /**
     * Button to get current Location. This demonstrates how to get the current Location as required
     * without needing to register a LocationListener.
     */
    public void showMyLocation(View view) {
        if (mLocationClient != null && mLocationClient.isConnected()) {
            String msg = "Location = " + mLocationClient.getLastLocation();
            Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * Implementation of {@link LocationListener}.
     */
    @Override
    public void onLocationChanged(Location location) {
        mMessageView.setText("Location = " + location);
    }

    /**
     * Callback called when connected to GCore. Implementation of {@link ConnectionCallbacks}.
     */
    @Override
    public void onConnected(Bundle connectionHint) {
        mLocationClient.requestLocationUpdates(
                REQUEST,
                this);  // LocationListener
    }

    /**
     * Callback called when disconnected from GCore. Implementation of {@link ConnectionCallbacks}.
     */
    @Override
    public void onDisconnected() {
        // Do nothing
    }

    /**
     * Implementation of {@link OnConnectionFailedListener}.
     */
    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // Do nothing
    }

    @Override
    public boolean onMyLocationButtonClick() {
        Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT).show();
        // Return false so that we don't consume the event and the default behavior still occurs
        // (the camera animates to the user's current position).
        return false;
    }
}
peguerosdc
  • 946
  • 11
  • 21
  • I set up the map even GPS is disable. Map has no marker. When GPS is enabled, i want to add a marker on my current location and animate the map. However, i can connect my locationClient when GPS is enabled. But how can i know when background connecting task is finished ? I can't write "while !locationclient.isconnected() do again" because Thread UI will be blocked. Can you send me an example of your second part with locationREquest, LocationListener etc please ? – Maxouille Jul 18 '14 at 10:00
  • There is an example in the [link you posted](http://developer.android.com/training/location/receive-location-updates.html) . As you can see, you need to implement your location interface callbacks, so Google Play Services will notify your activity's method onLocationChanged when the location is retrieved. See my edit in which I added and example from the GPS SDK. – peguerosdc Jul 18 '14 at 10:21
  • If i wanna do something like start updates. I have to do this after that : @Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); setUpLocationClientIfNeeded(); mLocationClient.connect(); //DO HERE } But if connection is not yet available, it will be return error. When can i start updates ? – Maxouille Jul 18 '14 at 12:01
  • I had modify my code. It seems clearer for me. Now, my function getLocation() called after connect) finished succesfully return null. That means that google play service is not available. How is it possible because connection to the service is finished successfully. – Maxouille Jul 18 '14 at 12:31
  • A successful connection to the services doesn't imply that the GPS is ready to provide you with the location, they are different things. The services are just a framework to access the GPS. You should retrieve the location in onLocationChange(Location location). onConnected you need to ask for location updates as the example does. – peguerosdc Jul 18 '14 at 19:18
-1

How about this answer? Use geo Location and give the fine location access to the maniefest

https://stackoverflow.com/a/8543819/2931489

Voggela Tutorial

http://www.vogella.com/tutorials/AndroidLocationAPI/article.html

Community
  • 1
  • 1
Harsh Patel
  • 1,056
  • 2
  • 10
  • 20
  • I can find current Location. It is not the problem. But imagine : i launch my app with GPS is disabled. I enable GPS. My app detect that GPS is enabled but it does not update my map to put marker on it. – Maxouille Jul 22 '14 at 08:28
  • Ohk Got your problem, So i found this GPS Change Listener try this http://stackoverflow.com/a/18259264/2931489 – Harsh Patel Jul 22 '14 at 08:39