如何创建一个按钮,该按钮将在没有听众的情况下获取用户的位置

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()

这种方法会一直更新位置,并且根据您的设置可能会影响电池消耗。

但另一种选择是仅在按下按钮时请求更新,并在第一个结果后取消它们,这会在按下按钮和接收位置之间有延迟。