我有一个片段,我想在其中显示用户(设备)的当前位置。我使用Google Map Android API v2。如何获得当前设备的经纬度?
下面你可以看到我使用过的代码。不幸的是,app工作错误,不像我预期的那样。它只显示地图,但没有我设置的标记,也没有当前位置。任何人都可以检查并修复它吗?怎么了?谢谢你的帮助!
编辑:
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>
答案 0 :(得分:1)
此信息以及更多内容可在您的应用可从融合位置提供商处检索的位置对象中提供:https://developer.android.com/training/location/retrieve-current.html。
答案 1 :(得分:1)
请注意,如果最近获得的位置不可用,getLastKnownLocation
可以返回null。在尝试提取纬度/经度之前,您应该检查此方法调用的结果。显然,如果结果 为null,则请求纬度或经度将导致NullPointerException。
答案 2 :(得分:1)
这是我当前的工作代码,它是一种用于通过广播发送位置的服务。
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)
{
}
}
}
您需要通过以下代码
开始服务Intent locationservice= new Intent(this,LocationService.class);
startService(locationservice);
接收广播
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"));
}
}
注册广播接收器。
IntentFilter filter = new IntentFilter();
filter.addAction(LocationService.BROADCAST_ACTION);
registerReceiver(receiver, filter);
使用服务在不使用时会消耗停电服务。
更新您的代码
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);
}
}
}
答案 3 :(得分:1)
你可以从我目前的项目中试试这个 -
使用位置管理器获取上一个已知位置:
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);
}
我正在调用此方法从手机中获取最后一个位置。