如何通过 Handler 更新地图图标

Posted

技术标签:

【中文标题】如何通过 Handler 更新地图图标【英文标题】:how to update map icon via Handler 【发布时间】:2020-02-02 00:59:21 【问题描述】:

我是一个非常新手的程序员。 我正在使用处理程序将我的位置数据从服务获取到我的主要活动,但我想使用服务中的代码更新地图。

GPS 坐标是通过处理程序正确发送的,但我似乎对如何使用处理程序通过更新地图上的地图/图标来实际呈现数据感到困惑。

地图始终将标记置于 0.0,也不会将地图定位在通过处理程序发送的新位置。

   //get GPS latitude and Longitude from service here
    private void displayLatLong() 
        final TextView latitudeView = (TextView) findViewById(R.id.latitude);
        final TextView longitudeView = (TextView) findViewById(R.id.longitude);
        final TextView latitudeCoordsView = (TextView) findViewById(R.id.latitudecoordsView);
        final TextView longitudeCoordsView = (TextView) findViewById(R.id.latitudecoordsView);

        final Handler handler = new Handler();
        handler.post(new Runnable() 
            @Override
            public void run() 
                double latitude = 0.0;
                double longitude = 0.0;

                //latitudeCoords = "not empty"; //debug
                //longitudeCoords = "not empty"; //debug

                if(bound && locationService != null) 
                    latitude = locationService.getLastLatitude();
                    longitude = locationService.getlastLongitude();
                
                String latitudeStr = String.format(Locale.getDefault(), "%1$, .5f lat", latitude);
                String longitutdeStr = String.format(Locale.getDefault(), "%1$, .5f long", longitude);
                latitudeView.setText(latitudeStr);
                longitudeView.setText(longitutdeStr);

                latCoords = latitude;
                longCoords = longitude;

               // longitudeCoordsView.setText(longitudeCoords); //debug
               // latitudeCoordsView.setText(longitudeCoords); //debug

                handler.postDelayed(this, 1000);
            
        );
    

@Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get the SupportMapFragment and request notification
        // when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);


        //Bind location service here so it keeps running even if activity is stopped.
        Intent intent = new Intent(this, LocationService.class);
        bindService(intent, connection, Context.BIND_AUTO_CREATE);

        displayDistance();
        displayLatLong();
    

@Override
    public void onMapReady(GoogleMap map) 
        mMap = map;
        LatLng player= new LatLng(latCoords, longCoords);
        mMap.addMarker(new MarkerOptions().position(player).title("current player position"));//set marker with player position and description
        mMap.moveCamera(CameraUpdateFactory.newLatLng(player)); //move Camera to player position
    locat

【问题讨论】:

您没有分配 locationService 引用,因此它始终为空。不过,总的来说,您在这里采用的方法并不好。您不应该直接引用服务。此外,您正在尝试轮询值,而您应该等待服务一旦获得位置的回调。您可以使用绑定服务,或使用广播接收器,请参见此处:***.com/questions/10179470/… 但我正在从服务获取位置数据,因为我有这个 ` String latitudeStr = String.format(Locale.getDefault(), "%1$, .5f lat", latitude); String longitutdeStr = String.format(Locale.getDefault(), "%1$, .5f long", longitude); latitudeView.setText(latitudeStr); longitudeView.setText(longitutdeStr); ` 准确显示当前 GPS 坐标,为什么我不能在地图上使用这些坐标?我已经在这段代码中使用了绑定服务。我只是没有发布完整的代码。 【参考方案1】:

您只需要在获得位置后更新地图。

添加将更新地图的方法:

private void updateMapLocation() 
  LatLng player= new LatLng(latCoords, longCoords);
  mMap.addMarker(new MarkerOptions().position(player).title("current player position"));//set marker with player position and description
  mMap.moveCamera(CameraUpdateFactory.newLatLng(player)); //move Camera to player position

然后在填充了latCoordslongCoords 成员变量后调用此方法:

//get GPS latitude and Longitude from service here
private void displayLatLong() 
    final TextView latitudeView = (TextView) findViewById(R.id.latitude);
    final TextView longitudeView = (TextView) findViewById(R.id.longitude);
    final TextView latitudeCoordsView = (TextView) findViewById(R.id.latitudecoordsView);
    final TextView longitudeCoordsView = (TextView) findViewById(R.id.latitudecoordsView);

    final Handler handler = new Handler();
    handler.post(new Runnable() 
        @Override
        public void run() 
            double latitude = 0.0;
            double longitude = 0.0;

            if(bound && locationService != null) 
                latitude = locationService.getLastLatitude();
                longitude = locationService.getlastLongitude();
            
            String latitudeStr = String.format(Locale.getDefault(), "%1$, .5f lat", latitude);
            String longitutdeStr = String.format(Locale.getDefault(), "%1$, .5f long", longitude);
            latitudeView.setText(latitudeStr);
            longitudeView.setText(longitutdeStr);


            latCoords = latitude;
            longCoords = longitude;

            // Add call to update map with location:
            if (latCoords > 0 && longCoords > 0) 
              updateMapLocation()
            

            handler.postDelayed(this, 1000);
        
    );

【讨论】:

这似乎有效,因为它确实将标记放置在虚拟设备设置的位置,但是如果我随后进入 AVM 中的扩展控件并设置一个新位置,它会立即把它放回第一个坐标?如果我想保持标记移动,我不应该继续轮询新的更新吗?意思是我也应该把 handler.postdelayed 放在 IF 中?因为我想一直跟踪当前用户的位置。 当然,我没有意识到你想继续投票。刚刚更新了答案。 您的解决方案运行良好,我唯一想做的基本上就是在新位置“刷新”图标。当前的解决方案在保持原样不变的同时添加了另一个标记。我怎么能做到这一点? 只保留一个引用当前位置标记的成员变量。看看这里的答案,以及如何保持成员变量mCurrLocationMarker:***.com/a/34582595/4409409

以上是关于如何通过 Handler 更新地图图标的主要内容,如果未能解决你的问题,请参考以下文章

qt中handler的定义

Handle的原理(LooperHandlerMessage三者关系)

Handle详解

Handler系列之使用

Handle的原理代码实现

Android中的Handle(句柄)