【问题标题】:Android Google Map + Pusher (real time) ListenerAndroid Google Map + Pusher(实时)监听器
【发布时间】:2015-08-13 00:12:04
【问题描述】:

我有一个片段,我正在使用来自 Google Maps API 的 getMapAsync 方法,它工作正常。

同时,我想将我的应用程序连接到 Pusher,并且在我收到的每个事件中,我想在地图中放置一个标记(我想实时显示每个用户的位置,当他们连接到应用程序)。

一切正常,但我无法访问 Pusher 侦听器(onEvent 方法)内的 googleMap var。为什么??

我是 Java 编程新手,我认为我做错了什么,:/

public class HomeFragment extends Fragment implements OnMapReadyCallback,PresenceChannelEventListener{

private me.agiliza.agilizame.models.User _user;
private View _view;
private MapView _map;
private GoogleMap _googleMap;
private Pusher _pusher;
private PresenceChannel _presenceChannel;
private boolean _isSubscribedToPresence;

public HomeFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    _view = inflater.inflate(R.layout.fragment_home, container, false);

    _user = UserManager.getInstance(getActivity().getApplicationContext());

    _map = (MapView) _view.findViewById(R.id.vMap);

    _map.onCreate(savedInstanceState);
    _map.onResume(); // needed to get the map to display immediately

    MapsInitializer.initialize(getActivity().getApplicationContext());

    _map.getMapAsync(this);

    return _view;
}

@Override
public void onResume() {
    super.onResume();
    _map.onResume();
}

@Override
public void onPause() {
    super.onPause();
    _map.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    _map.onDestroy();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    _map.onLowMemory();
}


@Override
public void onMapReady(GoogleMap googleMap) {
    Log.i("Carregou", "Mapa");
    _googleMap = googleMap;
    _googleMap.setMyLocationEnabled(true);
    _googleMap.getUiSettings().setMyLocationButtonEnabled(false);

    loadConnectedProviders();

    _googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
        @Override
        public void onMyLocationChange(Location location) {
            if (_isSubscribedToPresence) {
                LatLng coordinates = new LatLng(location.getLatitude(), location.getLongitude());
                _googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(coordinates, 15));
                Log.d(Utils.TAG, "Atualizou localização");
                _googleMap.setMyLocationEnabled(false);
                _googleMap.addMarker(new MarkerOptions().position(coordinates)).setTitle("Minha localização");

                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("id", _user.getId());
                    jsonObject.put("latitude", coordinates.latitude);
                    jsonObject.put("longitude", coordinates.longitude);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                _presenceChannel.trigger("client-locup", jsonObject.toString());
            }
        }
    });

}

public void loadConnectedProviders(){
    _pusher = PusherManager.getInstance(getActivity());
    _pusher.unsubscribe("presence-providers");
    _presenceChannel = _pusher.subscribePresence("presence-providers", this, "client-locup");

}

@Override
public void onUsersInformationReceived(String channelName, Set<User> users) {}

@Override
public void userSubscribed(String channelName, User user) {
}

@Override
public void userUnsubscribed(String channelName, User user) {}

@Override
public void onAuthenticationFailure(String message, Exception e) {
    _isSubscribedToPresence = false;
}

@Override
public void onSubscriptionSucceeded(String channelName) {
    _isSubscribedToPresence = true;
}

@Override
public void onEvent(String channelName, String eventName, String data) {
            try {
                JSONObject jsonObject = new JSONObject(data);
                int userId = jsonObject.getInt("id");
                LatLng latLng = new LatLng(jsonObject.getDouble("latitude"),jsonObject.getDouble("longitude"));

                // I cant get this to work
                //_googleMap.addMarker(new MarkerOptions().position(latLng));

                Log.d(Utils.TAG, "Id is " + userId + " Value of lat is " + latLng.latitude + " and long is " + latLng.longitude);
            } catch (JSONException e) {
                e.printStackTrace();
            }

}

}

【问题讨论】:

  • 提示 1:始终检查您的地图是否在 onMapReady() 之外为空,提示 2:使用队列来处理您的标记。一次添加太多标记会阻塞地图的 UI
  • 谢谢,我认为问题不在于 NullPointerException。

标签: java android google-maps pusher


【解决方案1】:

您必须得到 NullPointerException,因为_googleMap 无法准备好。试试这样的。

private final Stack<JSONObject> mPending = new Stack<>();

@Override
public void onMapReady(GoogleMap googleMap) {
    Log.i("Carregou", "Mapa");
    _googleMap = googleMap;
    syncMarkers(); // <=== LOOK HERE
    _googleMap.setMyLocationEnabled(true);
    _googleMap.getUiSettings().setMyLocationButtonEnabled(false);

    loadConnectedProviders();

    _googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
        @Override
        public void onMyLocationChange(Location location) {
            if (_isSubscribedToPresence) {
                LatLng coordinates = new LatLng(location.getLatitude(), location.getLongitude());
                _googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(coordinates, 15));
                Log.d(Utils.TAG, "Atualizou localização");
                _googleMap.setMyLocationEnabled(false);
                _googleMap.addMarker(new MarkerOptions().position(coordinates)).setTitle("Minha localização");

                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("id", _user.getId());
                    jsonObject.put("latitude", coordinates.latitude);
                    jsonObject.put("longitude", coordinates.longitude);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                _presenceChannel.trigger("client-locup", jsonObject.toString());
            }
        }
    });

}

    @Override
    public void onEvent(String channelName, String eventName, String data) {
        try {
            JSONObject jsonObject = new JSONObject(data);
            mPending.add(jsonObject);
            syncMarkers(); // <=== LOOK HERE
            Log.d(Utils.TAG, "Id is " + userId + " Value of lat is " + latLng.latitude + " and long is " + latLng.longitude);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void syncMarkers() {
        if (_googleMap != null) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    while (!mPending.empty()) {
                        JSONObject jsonObject = mPending.pop();
                        int userId = jsonObject.getInt("id");
                        LatLng latLng = new LatLng(jsonObject.getDouble("latitude"), jsonObject.getDouble("longitude"));
                        _googleMap.addMarker(new MarkerOptions().position(latLng));
                    }
                }
            });
        }
    }

【讨论】:

  • :( 它不起作用,但感谢您的帮助。我认为问题不是 NullPointerException。这是问题的屏幕截图:prntscr.com/840h5a
  • 这个错误表明你的视图没有在UI线程(又名主线程)上更新,使用runOnUIThreadsyncMarkers();
  • 您能否发布一个示例,说明我应该如何在我的代码中实现 runOnUiThread?谢谢!
  • 嘿,你们太棒了!!它奏效了,我只是将 Nguyễn Hoài Nam 建议 (runOnUiThread) 放在我的 syncMarkers 内的“addMarker”中(由 betorcs 建议),一切都像一个魅力。难以置信......我试图解决这个问题将近两天。我还有很多东西要学,谢谢!我想将你们两个标记为“作为答案”,但我只能标记一个,并且只有 betorcs 发布为答案,但我很感谢你们!
猜你喜欢
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
  • 2012-05-17
  • 1970-01-01
相关资源
最近更新 更多