Как исправить проблемы нестабильности Android Wear MessageClient - PullRequest
0 голосов
/ 03 января 2019

Я разрабатываю приложение, которое отправляет данные о частоте сердечных сокращений с часов Android Wear (TicWatch Pro) на подключенный телефон.Это работает хорошо, пока часы не перейдут в режим Ambient.Сообщения больше не поступают, пока не дотронутся до экрана часов и часы не выйдут из режима Ambient.

Я использую TicWatch Pro под управлением Android Wear 2. Я пытался внедрить службу какочень похоже на Руководство разработчика .Я провел некоторые исследования в Интернете и не смог найти похожие проблемы.Я делаю что-то не так или часы могут работать не так, как другие часы?

MeasuringService.java

...

public class MeasuringService extends Service implements MessageClient.OnMessageReceivedListener, SensorEventListener {

    ...

    private String nodeId = null;
    private CapabilityClient.OnCapabilityChangedListener capabilityListener = null;

    ...

    private CapabilityClient.OnCapabilityChangedListener capabilityListener = null;

    @Override
    public void onCreate() {
        super.onCreate();

        Wearable.getMessageClient(this).addListener(this);

        openNotification();

        ...
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        Log.d(TAG, "onStartCommand()");

        findNodeId();

        startMeasurement();

        return Service.START_STICKY;
    }

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

        Wearable.getMessageClient(this).removeListener(this);

        stopMeasurement();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onMessageReceived(@NonNull MessageEvent messageEvent) {
        Log.d(
                TAG,
                "onMessageReceived() A message from phone was received:"
                        + messageEvent.getRequestId()
                        + " "
                        + messageEvent.getPath());
    }

    private void sendHeartRate(HeartRateModel heartRateModel) {
        Log.d(TAG, "sendHeartRate(): timestamp: " + Long.toString(heartRateModel.getTimestamp()));

        sendMessageToPhone(ClientPaths.HR_UPDATE, heartRateModel.toByteArray());
    }

    private void sendMessageToPhone(String path, byte[] payload) {
        Context context = this.getApplicationContext();
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (nodeId != null) {
                    Task<Integer> sendMessageTask =
                            Wearable.getMessageClient(context).sendMessage(nodeId, path, payload);

                    try {
                        // Block on a task and get the result synchronously (because this is on a background
                        // thread).
                        Integer result = Tasks.await(sendMessageTask);
                        Log.d(TAG, "Message sent: " + result);
                    } catch (ExecutionException exception) {
                        Log.e(TAG, "Task failed: " + exception);
                    } catch (InterruptedException exception) {
                        Log.e(TAG, "Interrupt occurred: " + exception);
                    }
                } else {
                    Log.e(TAG, "No node to send message to");
                }
            }
        }).start();
    }

    private void findNodeId() {
        Context context = this.getApplicationContext();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    CapabilityInfo capabilityInfo = Tasks.await(
                            Wearable.getCapabilityClient(context).getCapability(
                                    Constants.CAPABILITY_PHONE_APP, CapabilityClient.FILTER_REACHABLE));
                    updateNodeId(capabilityInfo);
                } catch (ExecutionException | InterruptedException e) {
                    Log.d(TAG, "Could not find node: " + e);
                }

                capabilityListener =
                        capabilityInfo -> {
                            updateNodeId(capabilityInfo);
                        };
                Wearable.getCapabilityClient(context).addListener(
                        capabilityListener,
                        Constants.CAPABILITY_PHONE_APP);
            }
        }).start();
    }

    private void updateNodeId(CapabilityInfo capabilityInfo) {
        nodeId = pickBestNodeId(capabilityInfo.getNodes());
    }

    private String pickBestNodeId(Set<Node> nodes) {
        String bestNodeId = null;
        // Find a nearby node or pick one arbitrarily
        for (Node node : nodes) {
            if (node.isNearby()) {
                return node.getId();
            }
            bestNodeId = node.getId();
        }
        return bestNodeId;
    }

    private void openNotification() {
        String title = "";
        String text = "";

        showNotification(RUNNING_NOTIFICATION_CHANNEL, RUNNING_NOTIFICATION_ID, title, text, true);
    }

    ...

    private void startMeasurement() {
        Log.w(TAG, "startMeasurement()");
        mSensorManager = ((SensorManager) getSystemService(SENSOR_SERVICE));

        if (mSensorManager != null) {
            Sensor mHeartrateSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
            if (mHeartrateSensor != null) {
                mSensorManager.registerListener(this, mHeartrateSensor, SensorManager.SENSOR_DELAY_FASTEST);
            }
        }

        ...
    }

    private void stopMeasurement() {
        if (mSensorManager != null)
            mSensorManager.unregisterListener(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        // send heartrate data and create new intent
        if (event.sensor.getType() == Sensor.TYPE_HEART_RATE && event.values.length > 0 && event.accuracy > 0) {
            int newValue = Math.round(event.values[0]);
            if(newValue!=0) {
                // HeartRateModel is a data class cointaining the time of measurement, heart-rate and sensor accuracy
                HeartRateModel heartRateModel = new HeartRateModel(System.currentTimeMillis(), event.values[0], event.accuracy);

                sendHeartRate(heartRateModel);
            }
        }
    }


    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}

Я ожидаю, что сообщения будут отправлены, даже когда часыпереходит в режим Ambient.

Если потребуется дополнительная информация, я был бы рад сделать это.

...