简体   繁体   中英

How to get latitude and longitude of current location in Android?

I have a Fragment in which I want to show current location of user(device). I use Google Map Android API v2. How get current latitude and longitude of device?

Here below you can see code that I used. Unfortunately app works wrong, not as i expected. It just show map but there is no marker that i set and no current location. Can anyone check it and fix it? Whats wrong? Thanks for any help!

EDIT:

MainFragment.java

public class MainFragment extends Fragment{

    private SupportMapFragment mSupportMapFragment;
    private GoogleMap mGoogleMap;

    public BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        Bundle extras = intent.getExtras();
        LatLng temp = new LatLng(extras.getDouble("Latitude"),extras.getDouble("Longitude"));
    }
    };

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        FragmentManager mFragmentManager = getChildFragmentManager();
        mSupportMapFragment = (SupportMapFragment) mFragmentManager.findFragmentById(R.id.map_container);
        if (mSupportMapFragment == null) {
            mSupportMapFragment = SupportMapFragment.newInstance();
            mFragmentManager.beginTransaction().replace(R.id.map_container, mSupportMapFragment).commit();
        }

        //Broadcast/ Filter
        IntentFilter filter = new IntentFilter();
        filter.addAction(LocationService.BROADCAST_ACTION);
        getActivity().registerReceiver(receiver, filter);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
           //Start service
           getActivity().startService(new Intent(getActivity(),LocationService.class));
    }

    @Override
    public void onResume(){
         receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            Log.d(TAG, "BroadcastReceiver works!");

            Bundle extras = intent.getExtras();
            final LatLng temp = new LatLng(extras.getDouble("Latitude"),extras.getDouble("Longitude"));

            if (mGoogleMap != null) {
                mGoogleMap = mSupportMapFragment.getMap();
                mGoogleMap.addMarker(new MarkerOptions().position(temp).title("Marker").snippet("Location"));
            }
            try {
                CameraUpdate center = CameraUpdateFactory.newLatLng(temp);
                CameraUpdate zoom = CameraUpdateFactory.zoomTo(15f);
                mGoogleMap.moveCamera(center);
                mGoogleMap.animateCamera(zoom);
            }catch (NumberFormatException e) {
                //Some code here for exception
            }
        }
    };
    }

    @Override
    public void onDetach() {
        super.onDetach();
        try {
            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}

fragment_main.xml

<RelativeLayout
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:id="@+id/map_container">

       <!-- The map fragments will go here -->
</RelativeLayout>

您可以从融合位置提供程序检索的位置对象中提供此信息等信息: https//developer.android.com/training/location/retrieve-current.html

Note that getLastKnownLocation can return null if no recently-acquired location is available. You should check the result from this method call before attempting to extract the latitude/longitude. Obviously, if the result is null, requesting either the latitude or longitude will result in a NullPointerException.

This my current working code which is a service used to send location via Broadcast.

package maps.custom.com.googlemapsapi;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.hardware.GeomagneticField;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
import android.app.Service;

import com.google.android.gms.maps.model.LatLng;

import java.util.ArrayList;
import java.util.List;
import maps.custom.com.googlemapsapi.support.CNotificationBuilder;

/**
 * Created by hackers on 7/12/14.
 */
public class LocationService extends Service
{
    public static final String BROADCAST_ACTION = "com.location.service.location";
    public static final long DEFAULT_DELAY=1000;
    private static final int TWO_MINUTES = 1000 * 60 * 2;
    public LocationManager locationManager;
    public MyLocationListener listener;
    public Location previousBestLocation = null;

    Intent intent;
    int counter = 0;

    @Override
    public void onCreate()
    {
        super.onCreate();
        Log.i("Service","create");
        intent = new Intent(BROADCAST_ACTION);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("Service","started");
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        listener = new MyLocationListener();
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3*DEFAULT_DELAY, 0, listener); //get updates in every 3 seconds
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3*DEFAULT_DELAY, 0, listener); //get updates in every 3 seconds
        return super.onStartCommand(intent, flags, startId);
    }



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

    protected boolean isBetterLocation(Location location, Location currentBestLocation) {
        if (currentBestLocation == null) {
            // A new location is always better than no location
            return true;
        }

        // Check whether the new location fix is newer or older
        long timeDelta = location.getTime() - currentBestLocation.getTime();
        boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
        boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
        boolean isNewer = timeDelta > 0;

        // If it's been more than two minutes since the current location, use the new location
        // because the user has likely moved
        if (isSignificantlyNewer) {
            return true;
            // If the new location is more than two minutes older, it must be worse
        } else if (isSignificantlyOlder) {
            return false;
        }

        // Check whether the new location fix is more or less accurate
        int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
        boolean isLessAccurate = accuracyDelta > 0;
        boolean isMoreAccurate = accuracyDelta < 0;
        boolean isSignificantlyLessAccurate = accuracyDelta > 200;

        // Check if the old and new location are from the same provider
        boolean isFromSameProvider = isSameProvider(location.getProvider(),
                currentBestLocation.getProvider());

        // Determine location quality using a combination of timeliness and accuracy
        if (isMoreAccurate) {
            return true;
        } else if (isNewer && !isLessAccurate) {
            return true;
        } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
            return true;
        }
        return false;
    }



    /** Checks whether two providers are the same */
    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
            return provider2 == null;
        }
        return provider1.equals(provider2);
    }



    @Override
    public void onDestroy() {
        // handler.removeCallbacks(sendUpdatesToUI);
        super.onDestroy();
        Log.v("STOP_SERVICE", "DONE");
        locationManager.removeUpdates(listener);
    }

    public static Thread performOnBackgroundThread(final Runnable runnable) {
        final Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    runnable.run();
                } finally {

                }
            }
        };
        t.start();
        return t;
    }


    GeomagneticField geoField;
    float heading;

    public class MyLocationListener implements LocationListener
    {


        public void onLocationChanged(final Location loc)
        {
            Log.i("**************************************", "Location changed");
            if(isBetterLocation(loc, previousBestLocation)) {
                loc.getLatitude();
                loc.getLongitude();

                intent.putExtra("Latitude", loc.getLatitude());
                intent.putExtra("Longitude", loc.getLongitude());
                intent.putExtra("Provider", loc.getProvider());
                intent.putExtra("Accuracy",  loc.getAccuracy());
                intent.putExtra("Speed",loc.getSpeed());
                sendBroadcast(intent);
        }

        public void onProviderDisabled(String provider)
        {
            Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show();
        }


        public void onProviderEnabled(String provider)
        {
            Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
        }


        public void onStatusChanged(String provider, int status, Bundle extras)
        {

        }

    }
}

You need to start service by following code

Intent locationservice= new Intent(this,LocationService.class);
startService(locationservice);

to receive Broadcast

  BroadcastReceiver receiver = new BroadcastReceiver() {

                @Override
                public void onReceive(Context context, Intent intent) {

                    Bundle extras = intent.getExtras();
                    LatLng temp = new LatLng(extras.getDouble("Latitude"),extras.getDouble("Longitude"));
    }
    }

to Register Broadcast Recever.

IntentFilter filter = new IntentFilter();
    filter.addAction(LocationService.BROADCAST_ACTION);
    registerReceiver(receiver, filter); 

Using service consumes power stop service when not in use.

Update on your Code

public class MainFragment extends Fragment{

    private SupportMapFragment mSupportMapFragment;
    private GoogleMap mGoogleMap;

    public BroadcastReceiver receiver=null;
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);


    receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

        Bundle extras = intent.getExtras();
        final LatLng temp = new LatLng(extras.getDouble("Latitude"),extras.getDouble("Longitude"));
           if (mGoogleMap != null) {
      mGoogleMap.addMarker(new MarkerOptions().position(temp).title("Marker").snippet("Location"));

        try {
            CameraUpdate center = CameraUpdateFactory.newLatLng(temp);
            CameraUpdate zoom = CameraUpdateFactory.zoomTo(15f);
            mGoogleMap.moveCamera(center);
            mGoogleMap.animateCamera(zoom);
        }catch (NumberFormatException e) {
            //Some code here for exception
        }
           }
    }
    };
        FragmentManager mFragmentManager = getChildFragmentManager();
        mSupportMapFragment = (SupportMapFragment) mFragmentManager.findFragmentById(R.id.map_container);
        if (mSupportMapFragment == null) {
            mSupportMapFragment = SupportMapFragment.newInstance();
            mFragmentManager.beginTransaction().replace(R.id.map_container, mSupportMapFragment).commit();
        }


    }

    @Override
    public void onResume(){
         if (mGoogleMap == null) {
        mGoogleMap = mSupportMapFragment.getMap();
        mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
        mGoogleMap.setMyLocationEnabled(true);

    }

        //Broadcast/ Filter
        IntentFilter filter = new IntentFilter();
        filter.addAction(LocationService.BROADCAST_ACTION);
        getActivity().registerReceiver(receiver, filter);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        try {
            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}

You can try this out from my current project -

Using location manager to get last known location:

public void onLocationChanged(Location location) {
    TextView locationTv = (TextView) findViewById(R.id.latlongLocation);
    double latitude = location.getLatitude();
    double longitude = location.getLongitude();
    LatLng latLng = new LatLng(latitude, longitude);
    googleMap.addMarker(new MarkerOptions().position(latLng));
    googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    googleMap.animateCamera(CameraUpdateFactory.zoomTo(21));
    locationTv.setText("Latitude:" + latitude + ", Longitude:" + longitude);
}

I'm calling this method to get the last location from my phone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM