Gloegg
Gloegg

Reputation: 380

WearOS Off Body Event is not always triggered

I'm developing a simple app for WearOS. This app consists of the app itself, which just shows an image and two services. One is a service, does NFC card emulation and the other simply listens for the off body event, and resets some values, whenever the watch is taken off. This works well while I'm debugging and also for a some time when started normally.

However, after a few hours, the watch can be taken off, without my app getting the event. I suspect, that the OS is killing the service and not restarting it, despite the START_STICKY flag. The watch is not coupled with a phone and is not running other apps.

This is the code of my service:

public class MySensorService extends Service
{
    private static final String TAG = "MySensorService";

    private SensorManager sensorManager;
    private Sensor mOffBody;

    public MySensorService()
    {
        Log.i(TAG, "Sensor service was created.");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        Log.i(TAG, "Sensor service starting.");

        sensorManager = (SensorManager) getApplicationContext().getSystemService(SENSOR_SERVICE);
        mOffBody = sensorManager.getDefaultSensor(TYPE_LOW_LATENCY_OFFBODY_DETECT, true);
        if (mOffBody != null) {
            sensorManager.registerListener(mOffbodySensorListener, mOffBody,
                    SensorManager.SENSOR_DELAY_NORMAL);
        }
        Log.i(TAG, "Sensor service was started.");
        return START_STICKY;
    }

    private void onWatchRemoved()
    {
        Log.i(TAG, "Watch is not worn anymore");
        Intent intent = new Intent(this, MyAPDUService.class);
        intent.putExtra("UserID", 0);
        Log.d(TAG,"starting service");
        startService(intent);
    }

    private void onWatchAttached()
    {
        Log.i(TAG, "Watch is now worn");
    }

    private final SensorEventListener mOffbodySensorListener = new SensorEventListener()
    {
        @Override
        public void onSensorChanged(SensorEvent event)
        {
            if (event.values.length > 0)
            {
                if (event.values[0] == 0) // 0 = Watch is not worn; 1 = Watch is worn
                {
                    onWatchRemoved();
                }
                else
                {
                    onWatchAttached();
                }
            }
        }

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

        }
    };

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        Log.i(TAG, "Sensor Service destroyed");
    }
}

Upvotes: 1

Views: 275

Answers (1)

arango_86
arango_86

Reputation: 4435

Looks like your wrist detection logic is correct. May be issue with service.

Refer the below reference for off body event details https://developer.samsung.com/sdp/blog/en/2023/06/14/detect-when-a-galaxy-watch-is-being-worn

Try setting your service as a foreground service with a notification. Background services are not guaranteed to run endless. If you want to use this service running for hours I think u need to use this as a Foreground service.

val intent = Intent(...) // Build the intent for the service
context.startForegroundService(intent)

Please refer the following more info. https://developer.android.com/develop/background-work/services/foreground-services

Upvotes: 0

Related Questions