如何创建一个按钮,该按钮将在没有侦听器的情况下获取用户的位置
Posted
技术标签:
【中文标题】如何创建一个按钮,该按钮将在没有侦听器的情况下获取用户的位置【英文标题】:How do I create a button who will fetch the user's location without listeners 【发布时间】:2017-08-24 17:26:54 【问题描述】:我正在尝试在我的应用中使用用户的 gps 位置。这个想法是有一个按钮来获取他的当前位置并将其显示在地图上。我不想实时更新他的位置。只有当他按下按钮时,他的位置才会更新。这是我的片段示例。
public class HomeFragment extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, View.OnClickListener
private static final int MY_PERMISSION_ACCESS_COARSE_LOCATION = 11;
private static final int MY_PERMISSION_ACCESS_FINE_LOCATION = 12;
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private LocationManager mLocationManager;
private String mLatitudeText;
private String mLongitudeText;
private View view;
private MarkerOptions mMarker = new MarkerOptions();
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
if (view != null)
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
try
Log.d("debug", "inside TRy");
view = inflater.inflate(R.layout.fragment_homepage, container, false);
catch (Exception e)
Log.d("debug", "error inside try:"+e.toString());
finally
SupportMapFragment mMap = (SupportMapFragment) this.getChildFragmentManager()
.findFragmentById(R.id.map);
ImageButton mGpsUpdate = (ImageButton) view.findViewById(R.id.update_gps);
Log.d("debug", "after inflater");
mGpsUpdate.setOnClickListener(this);
createGoogleMapClient(); // <- moi
mMap.getMapAsync(this);
return view;
public void onStart()
mGoogleApiClient.connect();
super.onStart();
public void onStop()
mGoogleApiClient.disconnect();
super.onStop();
private void createGoogleMapClient()
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
@Override
public void onMapReady(GoogleMap googleMap)
Log.d("debug", "in");
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng champlain = new LatLng(45.5164522,-73.52062409999996);
mMap.addMarker(new MarkerOptions().position(champlain).title("Champlain College"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(champlain));//Move camera to Champlain
CameraPosition oldPos = mMap.getCameraPosition();
CameraPosition pos = CameraPosition.builder(oldPos).bearing(-103).build(); //rotate map
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos));
//Debug
updateLocation();
mMap.setMinZoomPreference((float)17.3);
mMap.setMaxZoomPreference(20);
mMap.getUiSettings().setRotateGesturesEnabled(false);
mMap.getUiSettings().setCompassEnabled(false);
@Override
public void onConnected(@Nullable Bundle bundle)
updateLocation();
private void checkPermission()
if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions( getActivity(), new String[] android.Manifest.permission.ACCESS_COARSE_LOCATION ,
MY_PERMISSION_ACCESS_COARSE_LOCATION );
ActivityCompat.requestPermissions( getActivity(), new String[] android.Manifest.permission.ACCESS_FINE_LOCATION ,
MY_PERMISSION_ACCESS_FINE_LOCATION );
@Override
public void onConnectionSuspended(int i)
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult)
@Override
public void onDestroyView()
FragmentManager fm = getFragmentManager();
Fragment xmlFragment = fm.findFragmentById(R.id.map);
if (xmlFragment != null)
fm.beginTransaction().remove(xmlFragment).commit();
super.onDestroyView();
public void updateLocation()
checkPermission();
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null)
mLatitudeText = String.valueOf(mLastLocation.getLatitude());
mLongitudeText = String.valueOf(mLastLocation.getLongitude());
Log.d("Coordinates",(mLatitudeText + ", " + mLongitudeText));
LatLng me = new LatLng(Double.parseDouble(mLatitudeText), Double.parseDouble(mLongitudeText));
mMap.addMarker(mMarker.position(me).title("me"));
@Override
public void onClick(View v)
Log.d("debug", "inside Button Listener");
switch(v.getId())
case R.id.update_gps:
Log.d("debug", "inside good case");
mMap.clear();
updateLocation();
break;
有什么想法吗?
【问题讨论】:
顺便说一下,我在原帖中尝试的方法不起作用。即使我四处走动,它也总是给我相同的位置 【参考方案1】:设备不会自行确定其位置,而是仅在某些应用程序请求位置时确定。因此,您的应用程序现在依赖于请求位置更新的其他应用程序。这就是为什么即使四处走动也会卡在同一个位置的原因。
这里的“最后已知位置”也意味着:它可能不是最新的。位置确实带有时间戳,可用于评估该位置是否仍然相关。
我在您的代码中的任何地方都没有看到对requestLocationUpdates()
的调用。您可以将其添加到onConnected()
。这将按照您可以指定的时间间隔请求最新的位置更新。然后,您可以使用getLastLocation()
访问这个最新的“最新位置”,就像您已经做的那样。
当您不再需要跟踪用户时,您应该致电removeLocationUpdates()
。
这种方法会一直更新位置,并且根据您的设置可能会影响电池消耗。
但另一种选择是仅在按下按钮时请求更新,并在第一个结果后取消更新,这将在按钮按下和接收位置之间产生延迟。
【讨论】:
所以基本上我会创建 requestLocationUpdates(),只有在创建按钮时才会以极高的频率,一旦给出位置,我就会停止位置请求并显示结果? 类似的东西。它不必是“非常高的频率”,因为无论如何只要它可用,第一个位置就会出现。频率(更新时间间隔)仅影响之后的位置更新。位置更新触发onLocationChanged()
回调方法,其中位置可用作方法参数。您可以将位置存储到您自己的变量中,也可以继续使用getLastLocation()
。任何一个都可以。以上是关于如何创建一个按钮,该按钮将在没有侦听器的情况下获取用户的位置的主要内容,如果未能解决你的问题,请参考以下文章