如何修复Android Wear MessageClient不稳定问题

时间:2019-01-03 16:17:27

标签: java android wear-os android-wear-data-api

我正在开发一个应用程序,它将来自Android Wear手表(TicWatch Pro)的心率数据发送到已连接的手机。在手表进入“环境模式”之前,此方法效果良好。直到触摸手表的屏幕并​​且手表退出环境模式后,消息才继续通过。

我正在使用运行Android Wear 2的TicWatch Pro。我尝试按照Developer guide的方式来实现该服务。我已经在网上进行了一些研究,但找不到类似的问题。我是在做错什么,还是手表的表现与其他手表不同?

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) {

    }
}

我希望消息能够发送,即使手表进入环境模式。

如果需要更多信息,我很乐意为您服务。

0 个答案:

没有答案