Source code for enamlnative.android.android_sensors
"""
Copyright (c) 2017-2022, CodeLV.
Distributed under the terms of the MIT License.
The full license is in the file LICENSE, distributed with this software.
Created on Jan 28, 2018
"""
from typing import Optional
from atom.api import ForwardInstance, Int, Bool
from .android_content import Context, SystemService
from .bridge import JavaBridgeObject, JavaCallback, JavaMethod
[docs]class Sensor(JavaBridgeObject):
"""A wrapper for an Android sensor. This should be retrieved using
the `Sensor.get(sensor_type)` method.
Examples
--------
# In a function with an @inlineCallbacks or @coroutine decorator
def on_data(data):
# Handle data here...
# data is a dict with keys
# {'acc': <accuracy>, 'data': [v1, v2, ...], 'sensor': id, 'time': t}
def on_ready(sensor):
if sensor is not None:
sensor.start(callback=on_data)
# ...
sensor.stop()
"""
__nativeclass__ = "android.hardware.Sensor"
#: Reference to the sensor manager
manager = ForwardInstance(lambda: SensorManager)
#: Sensor type
type = Int()
TYPE_ACCELEROMETER = 1
TYPE_MAGNETIC_FIELD = 2
TYPE_ORIENTATION = 3 # Depreciated
TYPE_GYROSCOPE = 4
TYPE_LIGHT = 5
TYPE_PRESSURE = 6
TYPE_TEMPERATURE = 7 # Depreciated Use ambient temp instead
TYPE_PROXIMITY = 8
TYPE_GRAVITY = 9
TYPE_LINEAR_ACCELERATION = 10
TYPE_ROTATION_VECTOR = 11
TYPE_RELATIVE_HUMIDITY = 12
TYPE_AMBIENT_TEMPERATURE = 13
TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14
TYPE_GAME_ROTATION_VECTOR = 15
TYPE_GYROSCOPE_UNCALIBRATED = 16
TYPE_SIGNIFICANT_MOTION = 17
TYPE_STEP_DETECTOR = 18
TYPE_STEP_COUNTER = 19
TYPE_GEOMAGNETIC_ROTATION_VECTOR = 20
TYPE_HEART_RATE = 21
TYPE_POSE_6DOF = 28 # Requires API 24+
TYPE_STATIONARY_DETECT = 29 # Requires API 24+
TYPE_MOTION_DETECT = 30 # Requires API 24+
TYPE_HEART_BEAT = 31 # Requires API 24+
TYPE_LOW_LATENCY_OFFBODY_DETECT = 34 # Requires API 26+
SENSOR_DELAY_NORMAL = 3
SENSOR_DELAY_UI = 2
SENSOR_DELAY_GAME = 1
SENSOR_DELAY_FASTEST = 0
getFifoMaxEventCount = JavaMethod(returns=int)
getFifoReservedEventCount = JavaMethod(returns=int)
getMaximumRange = JavaMethod(returns=float)
getMaxDelay = JavaMethod(returns=int)
getMinDelay = JavaMethod(returns=int)
getName = JavaMethod(returns=str)
getPower = JavaMethod(returns=float)
getReportingMode = JavaMethod(returns=int)
getResolution = JavaMethod(returns=float)
getVendor = JavaMethod(returns=str)
getVersion = JavaMethod(returns=int)
getType = JavaMethod(returns=int)
getStringType = JavaMethod(returns=str)
isWakeUpSensor = JavaMethod(returns=bool)
# -------------------------------------------------------------------------
# SensorEventListener API
# -------------------------------------------------------------------------
onSensorChanged = JavaCallback("android.hardware.SensorEvent")
onAccuracyChanged = JavaCallback("android.hardware.Sensor", int)
#: Sensor state
started = Bool()
[docs] @classmethod
async def get(cls, sensor_type: int) -> Optional["Sensor"]:
"""Shortcut that acquires the default Sensor of a given type.
Parameters
----------
sensor_type: int
Type of sensor to get.
Returns
-------
result: Future
A future that resolves to an instance of the Sensor or None
if the sensor is not present or access is not allowed.
"""
mgr = await SensorManager.get()
sensor = await mgr.getDefaultSensor(sensor_type)
if sensor is None:
return None
sensor.manager = mgr
sensor.type = sensor_type
return sensor
[docs] def start(self, callback, rate=SENSOR_DELAY_NORMAL):
"""Start listening to sensor events. Sensor event data depends
on the type of sensor that was given to
Parameters
----------
callback: Callable
A callback that takes one argument that will be passed
the sensor data. Sensor data is a dict with data based on
the type of sensor.
rate: Integer
How fast to update. One of the Sensor.SENSOR_DELAY values
Returns
-------
result: Future
A future that resolves to whether the register call
completed.
"""
if not self.manager:
raise RuntimeError("Cannot start a sensor without a SensorManager!")
self.onSensorChanged.connect(callback)
self.started = True
return self.manager.registerListener(self.getId(), self, rate)
[docs] def stop(self):
"""Stop listening to sensor events. This should be done in
on resume.
"""
self.started = False
self.manager.unregisterListener(self.getId(), self)
[docs] def __del__(self):
if self.started:
self.stop()
super().__del__()
[docs]class SensorManager(SystemService):
SERVICE_TYPE = Context.SENSOR_SERVICE
__nativeclass__ = "android.hardware.SensorManager"
registerListener = JavaMethod(
"android.hardware.SensorEventListener",
Sensor,
int,
returns=bool,
)
unregisterListener = JavaMethod("android.hardware.SensorEventListener", Sensor)
getDefaultSensor = JavaMethod(int, returns=Sensor)
getSensorList = JavaMethod(int, returns="java.util.List")