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

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()。任何一个都可以。

以上是关于如何创建一个按钮,该按钮将在没有侦听器的情况下获取用户的位置的主要内容,如果未能解决你的问题,请参考以下文章

动态创建按钮的事件监听器

以编程方式创建按钮并使用侦听器从第一个按钮创建下一个按钮

JAVA:如何通过此命令来监听按钮按下?

如何将相同的事件侦听器分配给 Vue.js 中动态创建的按钮并将对象的值作为参数传递给它?

如何在没有导航控制器的情况下获取导航栏后退按钮

如何在没有侦听器的情况下获取 javafx 媒体元数据