4

我有一个片段,我想在其中显示用户(设备)的当前位置。我使用Google Map Android API v2。如何获得当前设备的经纬度?如何获取Android中当前位置的纬度和经度?

下面您可以看到我使用的代码。不幸的是,应用程序工作不正确,不像我预期的它只是显示地图,但没有我设置的标记,也没有当前位置。任何人都可以检查并修复它吗?怎么了?谢谢你的帮助!

编辑:

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

你可以添加错误日志吗? – Muthu 2015-02-08 18:07:53

+0

@Muthu我在真实的设备上测试过它。我测试了我刚刚编写的纬度和经度值,并在这种情况下运行。我也尝试在模拟器中测试,它们具有Google API,但内存出现错误。 – 2015-02-08 19:48:17

+0

你好@Muthu我编辑了我的帖子。现在我只看到地图,它没有显示标记和当前位置。请你可以再次检查帖子的代码并说出最新的错误?感谢,并有一个愉快的一天! – 2015-02-09 09:02:44

回答

1

此信息,更多的,是在Location对象提供您的应用程序可以从融合位置提供商处检索:https://developer.android.com/training/location/retrieve-current.html

+0

GoogleApiClient可以在片段中使用吗?事实上,我也试图使用它,但应用程序也崩溃了。 – 2015-02-08 19:03:00

+0

你好玛丽安Paździoch!我在你给我的那个资料的帮助下编辑了我的帖子。现在我只看到地图,它没有显示标记和当前位置。请你可以再次检查帖子的代码并说出最新的错误?感谢,并有一个愉快的一天! – 2015-02-09 09:00:46

1

请注意,如果没有最近获取的位置可用,getLastKnownLocation可以返回null。在尝试提取纬度/经度之前,您应该检查此方法调用的结果。显然,如果结果 null,则请求纬度或经度将导致NullPointerException。

+0

你好!我尝试创建单独的服务类并使用LocationListener实现它,并且我像你所说的那样思考。经度/纬度值为0/0。如果你愿意,我可以向你展示那堂课。你有没有可行的例子? – 2015-02-08 19:59:46

+0

你好@stkent我在你给我的信息帮助下编辑了我的帖子。现在我只看到地图,它没有显示标记和当前位置。请你可以再次检查帖子的代码并说出最新的错误?感谢,并有一个愉快的一天! – 2015-02-09 09:01:47

+0

此行有问题:'if(mLocation!= null&mGoogleMap == null){'。您不希望每次收到位置更新时都检查“mGoogleMap”是否为空。将其分解为两个单独的if语句(首先检查“mGoogleMap”)。那有意义吗? – stkent 2015-02-09 13:33:03

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

到注册广播Recever启动服务。

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); 
     } 
    } 
} 
+0

Ohhh它只显示没有任何内容的地图,所以很伤心=(我接下来也试过了:我认为最好是在onResume方法中调用receiver并将其移除到该方法, – 2015-02-10 09:42:14

+0

做一件事你可以在BradCast最后一页记录经纬度吗?如果你获得纬度和经度,我们可以找到其他方式,这意味着服务不运行你需要启动服务 – Muthu 2015-02-10 09:47:43

+0

你好,Muthu!我也考虑过这个问题。是否可以删除Intent mLocationService = new Intent(this,LocationService.class); startService(mLocationService);为了Fragment的原因,现在它在我的MainActivity中。 – 2015-02-10 13:36:24

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

我打电话这方法从我的手机获取最后的位置。

+0

你好!这个代码在我的情况下只显示地图,但你如何采取设备的当前经度/纬度? – 2015-02-09 14:23:26

相关问题