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

相關問題