我目前正在开发一款Android应用,每分钟都必须从其他设备接收GPS位置,并将其显示在地图上。 我正在使用GoogleMaps Api V2,
我想做的是在收到新位置时刷新位置标记。 (我不想刷新整个地图)
目前,我在菜单中添加了一个按钮,可以刷新整个地图。
为了详细说明结构,我有一个运行MQTT的服务,每次收到一个位置时,我都会将它添加到代表我的地图数据源的Hashmap中。 这个HashMap是一个扩展Observable的Singleton。 而且,我的片段显示了我的工具Observer。
我的Fragment中实现Observer的代码
public void update(Observable observable, final Object object)
{
if (observable instanceof ListPositions && object != null)
{
Position p = (Position) object;
LatLng position = new LatLng(p.getLatitude(), p.getLongitude());
// Where i'd like to move the markers
}
else
{
// Where i'd like to remove the marker from the map
}
}
代码来自我的单身人士职位列表
public class ListPositions extends Observable{
private HashMap<String,Position> mapPosition;
private ListPositions()
{
mapPosition = new HashMap<String, Position>();
VehicleMapFragment mapFragmentObserver = new VehicleMapFragment();
this.addObserver(mapFragmentObserver);
}
private static ListPositions INSTANCE = null;
public static synchronized ListPositions getInstance()
{
if (INSTANCE == null)
{ INSTANCE = new ListPositions();
}
return INSTANCE;
}
public int getNumberOfPosition()
{
return mapPosition.size();
}
public void addPosition(String key, Position p){
mapPosition.put(key,p);
setChanged();
notifyObservers(p);
}
public void removePosition(String key){
mapPosition.remove(key);
setChanged();
notifyObservers();
}
代码来自运行MQTT的myService
public void onPositionMessageReceived(MqttMessage message, String source)
{
Gson gson = new Gson();
String s = gson.toJson(message.toString());
String jsonPosition = gson.toJson(message.toString());
jsonPosition = formatMessage(jsonPosition);
Position p = gson.fromJson(jsonPosition, Position.class);
ListPositions.getInstance().addPosition(source, p);
}
在观察者片段的更新功能中,有人可以知道如何单独移动每个标记而不刷新整个地图吗? 我可以使用Handler来更新Map,从另一个线程来修改主UI线程吗?
非常感谢
编辑:
因为AniV给出的第一个方法对我来说不起作用,所以我尝试使用当我的Observer从Observable List收到通知时运行的Asyntask。
观察者片段中的代码:
public void update(Observable observable, final Object object)
{
if (observable instanceof ListPositions && object != null)
{
Position p = (Position) object;
position = new LatLng(p.getLatitude(), p.getLongitude());
options = new MarkerOptions().position(position).title("TEST").snippet("TEST");
PositionUpdate positionUpdaterTask = new PositionUpdate(myGoogleMap, options, position);
positionUpdaterTask.execute();
}
}
来自AsyncTask的代码:
public class PositionUpdate extends AsyncTask<Void, Void, Void>{
private GoogleMap myGoogleMap;
private MarkerOptions options;
private LatLng positionToAdd;
public PositionUpdate(GoogleMap googleMap, MarkerOptions options, LatLng position)
{
this.myGoogleMap = googleMap;
this.options = options;
this.positionToAdd = position;
}
@Override
protected Void doInBackground(Void...voids)
{
return null;
}
@Override
protected void onPostExecute(Void aVoid)
{
if (myGoogleMap != null)
{
myGoogleMap.addMarker(options.position(positionToAdd));
Log.i(ConstElisa.LOG_ELISA, "MARKER ADDED");
}
else
{
Log.e(ConstElisa.LOG_ELISA, "ERROR ADDING THE MARKER");
}
super.onPostExecute(aVoid);
}
但是,在这种情况下,myGoogleMap变量始终为null,因此标记永远不会添加到Google地图中。
有人知道为什么这个变量是空的吗?
答案 0 :(得分:1)
我终于通过使用AsyncTask成功完成了这件事。
在我的编辑中,我说我的Google Maps对象的null实例遇到了一些问题。 这是由我的Singleton Observable引起的。实际上,在构造函数中,我使用了
VehicleMapFragment mapFragmentObserver = new VehicleMapFragment();
this.addObserver(mapFragmentObserver);
此代码示例重新创建了我的Fragment的另一个实例,以及ii具有Null对象的原因。
要解决此问题,我只使用:
ListPositions.getInstance().addObserver(this);
在我的片段观察者中。
因此,如果您想更新标记位置而不刷新整个地图, 您可以使用Observer / Observable Pattern,并使用Asynctask来更新标记位置。
答案 1 :(得分:0)
这里有两个选项:
使用setPosition()方法以编程方式更新标记位置。
Marker marker = googleMap.addMarker(new MarkerOptions().position(entry.getValue()).title(entry.getKey()));
使用此对象更改其位置:
marker.setPosition(new LatLng(5, 5));
或者如您所说,使用处理程序:
Handler locationHandler;
final static long REFRESH = 10 * 1000;
final static int SUBJECT = 0;
private GoogleMap mMap;
private Marker myMarker = null;
和onCreate()
locationHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == SUBJECT) {
updateMarker();
this.sendEmptyMessageDelayed(SUBJECT, REFRESH);
}
}
};
如果您必须以特定时间间隔更新位置,则处理程序选项会更好。
答案 2 :(得分:0)
我有类似的东西。我每5分钟收到一个设备列表来更新地图的位置。
您如何看待这个
private HashMap<String, Marker> mMarkers = new HashMap<>();
private void drawDevicesOnMap() {
if (isMapReady) {
for (Device device : mDeviceList) {
List<com.model.Location> locationList = device.getLocations();
if (locationList != null && !locationList.isEmpty()) {
if (mMarkers.containsKey(device.getId())) { //update
Marker m = mMarkers.get(device.getId());
m.setPosition(device.getLocations().get(0).getCoordinates().getLatLng());
mMarkers.put(device.getId(), m);
} else { //add
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(locationList.get(0).getCoordinates().getLatLng());
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(device.getHue()));
markerOptions.title(device.getNickname());
Marker marker = mMap.addMarker(markerOptions);
mMarkers.put(device.getId(), marker);
}
}
}
}
}
如果在HashMap中找到具有x id的设备的标记,则更新其位置。