如何创建一个按钮,该按钮将在没有听众的情况下获取用户的位置
How do I create a button who will fetch the user's location without listeners
我正在尝试在我的应用中使用用户的 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;
}
}
}
有什么想法吗?
设备不会自行确定其位置,只有在某些应用程序请求位置时才会确定。因此,您的应用程序现在依赖于请求位置更新的其他应用程序。这就是为什么即使四处走动,你也会卡在同一个位置。
此外 "last known location" 这里的意思恰恰是:它可能不是最新的。位置确实带有时间戳,可用于评估位置是否仍然相关。
我在您的代码中没有看到对 requestLocationUpdates()
的调用。您可以将其添加到 onConnected()
。这将以您可以指定的时间间隔请求最新的位置更新。然后,您可以使用 getLastLocation()
访问这个最新的 "latest location",就像您已经这样做的那样。
然后您应该在不再需要跟踪用户时调用 removeLocationUpdates()
。
这种方法会一直更新位置,并且根据您的设置可能会影响电池消耗。
但另一种选择是仅在按下按钮时请求更新,并在第一个结果后取消它们,这会在按下按钮和接收位置之间有延迟。
我正在尝试在我的应用中使用用户的 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;
}
}
}
有什么想法吗?
设备不会自行确定其位置,只有在某些应用程序请求位置时才会确定。因此,您的应用程序现在依赖于请求位置更新的其他应用程序。这就是为什么即使四处走动,你也会卡在同一个位置。
此外 "last known location" 这里的意思恰恰是:它可能不是最新的。位置确实带有时间戳,可用于评估位置是否仍然相关。
我在您的代码中没有看到对 requestLocationUpdates()
的调用。您可以将其添加到 onConnected()
。这将以您可以指定的时间间隔请求最新的位置更新。然后,您可以使用 getLastLocation()
访问这个最新的 "latest location",就像您已经这样做的那样。
然后您应该在不再需要跟踪用户时调用 removeLocationUpdates()
。
这种方法会一直更新位置,并且根据您的设置可能会影响电池消耗。
但另一种选择是仅在按下按钮时请求更新,并在第一个结果后取消它们,这会在按下按钮和接收位置之间有延迟。