Problem of devices showing in traccar manager 1.3

DBNman 9 years ago

Hi,
i have traccar server 3.0 and traccar manager 1.3 and i think they are not compatible because when i use "demo.traccar.com" in manager it work good but when i use my own server i can't show the devices.
i think because of compatibility between server 3.0 and manager 1.3 in database.
there is a solutions to that or no ? and thanks in advance.

Anton Tananaev 9 years ago

Yes, they are not compatible. You need latest server version to be able to use Manager app.

DBNman 9 years ago

Is there a way to use it with server 3.0 without update it ? because i need the 3.0 version.
like changing something in codes

Anton Tananaev 9 years ago

There is no way to use it with version 3.0 without modifying the code of the app.

DBNman 9 years ago

If possible, can you tell me the classes that i should change? and sorry for disturbing.

Anton Tananaev 9 years ago

I guess you need to change API-related classes. Are you talking about iOS or Android or both?

DBNman 9 years ago

Only android.

Anton Tananaev 9 years ago

Check "WebService" interface. That's a good place to start, but there might be some other changes required as well. As far as I remember, version 3.0 doesn't even use REST API, so I'm not sure if you can use Retrofit at all.

DBNman 9 years ago

I will try it.
Thank you for help and sorry for disturbing.

DBNman 9 years ago

Sorry i don't know what i should change.
Here is the WebService Interface:

public interface WebService {

    @FormUrlEncoded
    @POST("/api/session")
    Call<User> addSession(@Field("email") String email, @Field("password") String password);

    @GET("/api/devices")
    Call<List<Device>> getDevices();

}

In DevicesFragment class:

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        final MainApplication application = (MainApplication) getActivity().getApplication();
        application.getServiceAsync(new MainApplication.GetServiceCallback() {
            @Override
            public void onServiceReady(OkHttpClient client, Retrofit retrofit, WebService service) {
                service.getDevices().enqueue(new WebServiceCallback<List<Device>>(getContext()) {
                    @Override
                    public void onSuccess(Response<List<Device>> response) {
                        setListAdapter(new ArrayAdapter<>(application, R.layout.list_item, android.R.id.text1, response.body()));
                    }
                });
            }
        });
    }

In MainFragment:

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_DEVICE && resultCode == RESULT_SUCCESS) {
            long deviceId = data.getLongExtra(DevicesFragment.EXTRA_DEVICE_ID, 0);
            Position position = positions.get(deviceId);
            if (position != null) {
                map.moveCamera(CameraUpdateFactory.newLatLng(
                        new LatLng(position.getLatitude(), position.getLongitude())));
                markers.get(deviceId).showInfoWindow();
            }
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        map = googleMap;

        map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
            @Override
            public View getInfoWindow(Marker marker) {
                return null;
            }

            @Override
            public View getInfoContents(Marker marker) {
                View view = getLayoutInflater(null).inflate(R.layout.view_info, null);
                ((TextView) view.findViewById(R.id.title)).setText(marker.getTitle());
                ((TextView) view.findViewById(R.id.details)).setText(marker.getSnippet());
                return view;
            }
        });

        createWebSocket();
    }

    private String formatDetails(Position position) {
        return new StringBuilder()
                .append(getString(R.string.position_latitude)).append(": ")
                .append(String.format("%.5f", position.getLatitude())).append('\n')
                .append(getString(R.string.position_longitude)).append(": ")
                .append(String.format("%.5f", position.getLongitude())).append('\n')
                .append(getString(R.string.position_speed)).append(": ")
                .append(String.format("%.1f", position.getSpeed())).append('\n')
                .append(getString(R.string.position_course)).append(": ")
                .append(String.format("%.1f", position.getCourse()))
                .toString();
    }

    private void handleMessage(String message) throws IOException {
        Update update = objectMapper.readValue(message, Update.class);
        if (update != null && update.positions != null) {
            for (Position position : update.positions) {
                long deviceId = position.getDeviceId();
                LatLng location = new LatLng(position.getLatitude(), position.getLongitude());
                Marker marker = markers.get(deviceId);
                if (marker == null) {
                    marker = map.addMarker(new MarkerOptions()
                            .title(devices.get(deviceId).getName()).position(location));
                    markers.put(deviceId, marker);
                } else {
                    marker.setPosition(location);
                }
                marker.setSnippet(formatDetails(position));
                positions.put(deviceId, position);
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (webSocket != null) {
            webSocket.cancel();
        }
    }

    private void reconnectWebSocket() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (getActivity() != null) {
                    createWebSocket();
                }
            }
        });
    }

    private void createWebSocket() {
        final MainApplication application = (MainApplication) getActivity().getApplication();
        application.getServiceAsync(new MainApplication.GetServiceCallback() {
            @Override
            public void onServiceReady(final OkHttpClient client, final Retrofit retrofit, WebService service) {
                service.getDevices().enqueue(new WebServiceCallback<List<Device>>(getContext()) {
                    @Override
                    public void onSuccess(retrofit2.Response<List<Device>> response) {
                        for (Device device : response.body()) {
                            devices.put(device.getId(), device);
                        }

                        Request request = new Request.Builder().url(retrofit.baseUrl().url().toString() + "api/socket").build();
                        webSocket = WebSocketCall.create(client, request);
                        webSocket.enqueue(new WebSocketListener() {
                            @Override
                            public void onOpen(WebSocket webSocket, Response response) {
                            }

                            @Override
                            public void onFailure(IOException e, Response response) {
                                reconnectWebSocket();
                            }

                            @Override
                            public void onMessage(ResponseBody message) throws IOException {
                                final String data = message.string();
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            handleMessage(data);
                                        } catch (IOException e) {
                                            Log.w(MainFragment.class.getSimpleName(), e);
                                        }
                                    }
                                });
                            }

                            @Override
                            public void onPong(Buffer payload) {
                            }

                            @Override
                            public void onClose(int code, String reason) {
                                reconnectWebSocket();
                            }
                        });
                    }
                });
            }
        });

Can you help me please.

Anton Tananaev 9 years ago

I don't think you can use Retrofit because it's not REST API. You need to implement API calls yourself or using some other library.

DBNman 9 years ago

Ok, thanks.