Sensors API é uma interface da plataforma Android para acessar sensores de hardware do dispositivo. A API fornece uma maneira unificada de obter dados do acelerômetro, giroscópio, magnetômetro, sensor de luz e outros sensores. De acordo com Google, 2026, mais de 95% dos dispositivos Android modernos possuem pelo menos três tipos de sensores, abrindo amplas oportunidades para o desenvolvimento de aplicativos sensíveis ao contexto.
Principais conclusões
Sensors API é uma interface de software do Android Framework que fornece aos desenvolvedores acesso aos sensores de hardware do dispositivo móvel. A API faz parte do Android SDK desde a versão 1.0 e está disponível através do pacote android.hardware. A interface abstrai as diferenças entre implementações de sensores de diferentes fabricantes — Qualcomm, MediaTek, Samsung Exynos — e fornece um modelo unificado para trabalhar com sensores.
A API permite três operações principais: obter uma lista de sensores disponíveis, registrar listeners para receber dados e gerenciar a taxa de atualização. SensorManager atua como o ponto central de acesso para todas as operações. O sistema notifica o aplicativo através do callback onSensorChanged, passando um objeto SensorEvent com uma matriz de valores float.
Ao longo da existência do Android, a API passou por vários estágios de desenvolvimento. A versão 2.3 (Gingerbread) introduziu suporte para Batch Processing — agrupamento de eventos de sensor para reduzir o consumo de energia. Android 4.0 (Ice Cream Sandwich) adicionou os sensores virtuais Gravity e Linear Acceleration. A partir do Android 8.0, o sistema restringiu o acesso em segundo plano aos sensores para melhorar a privacidade.
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensorList: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
sensorList.forEach { sensor ->
Log.d("Sensores", "${sensor.name} — ${sensor.type}")
}
Nem todos os dispositivos têm o mesmo conjunto de sensores. Um aplicativo deve verificar a disponibilidade de um sensor específico antes de registrar um listener. O Emulador Android suporta apenas um conjunto limitado de sensores — acelerômetro e magnetômetro. Testar outros sensores requer um dispositivo físico. A partir do Android 12, os aplicativos devem declarar o uso de sensores no manifesto.
O Android classifica todos os sensores em três categorias: Motion, Position e Environment. Sensores Motion incluem acelerômetro, giroscópio e pedômetro. Sensores Position incluem magnetômetro e orientação. Sensores Environment incluem luz, pressão, temperatura e umidade.
| Categoria | Sensores | Tipo (constante) | Físico/Virtual |
|---|---|---|---|
| Motion | Acelerômetro | TYPE_ACCELEROMETER | Físico |
| Motion | Giroscópio | TYPE_GYROSCOPE | Físico |
| Motion | Pedômetro | TYPE_STEP_COUNTER | Físico |
| Motion | Gravity | TYPE_GRAVITY | Virtual |
| Position | Magnetômetro | TYPE_MAGNETIC_FIELD | Físico |
| Position | Rotation Vector | TYPE_ROTATION_VECTOR | Virtual |
| Environment | Luz | TYPE_LIGHT | Físico |
| Environment | Pressão | TYPE_PRESSURE | Físico |
O acelerômetro mede a aceleração em m/s² ao longo de três eixos — X, Y e Z. Os valores incluem a gravidade (9,8 m/s² ao longo do eixo Z em repouso). O giroscópio mede a velocidade angular em rad/s — a velocidade de rotação do dispositivo em torno de cada eixo. A combinação desses dois sensores é usada em navegação, jogos e aplicativos de RA.
class SensorActivity : Activity(), SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
val x = event.values[0]
val y = event.values[1]
val z = event.values[2]
textView.text = "X: $x, Y: $y, Z: $z"
}
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}
O magnetômetro (TYPE_MAGNETIC_FIELD) mede o campo magnético em microteslas (µT) ao longo de três eixos. É usado como bússola digital — em combinação com o acelerômetro, determina o azimute do dispositivo. Rotation Vector é um sensor virtual que funde dados do giroscópio, acelerômetro e magnetômetro para determinação precisa da orientação.
O sensor de luz (TYPE_LIGHT) mede o nível de luz ambiente em lux (lx). É usado para ajuste automático de brilho da tela. O sensor de pressão (TYPE_PRESSURE) mede a pressão atmosférica em hectopascais (hPa) — usado em aplicativos de navegação para determinar a altitude acima do nível do mar.
Sensors API é construído em uma arquitetura cliente-servidor. O aplicativo atua como cliente e o SensorManager como serviço do sistema Android. Quando o aplicativo registra um listener através de registerListener, o SensorManager se comunica com a HAL (Hardware Abstraction Layer) — um driver de sensor de baixo nível executado no nível do kernel Linux.
O driver HAL recebe dados brutos do chip de hardware, filtra ruídos e os envia para cima na pilha — através do SensorService (processo do sistema) para o aplicativo. Os dados são passados como um objeto SensorEvent contendo uma matriz de valores float values e um timestamp em nanossegundos. A taxa de eventos depende do modo de entrega selecionado.
Ao registrar um listener, o desenvolvedor especifica o atraso desejado entre eventos usando as constantes SENSOR_DELAY_NORMAL (200 ms), SENSOR_DELAY_UI (60 ms), SENSOR_DELAY_GAME (20 ms) e SENSOR_DELAY_FASTEST (0 ms — taxa máxima). A taxa real pode diferir — o sistema otimiza o consumo de energia.
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(
this,
sensor,
SensorManager.SENSOR_DELAY_GAME
)
A partir do Android 2.3, os sensores suportam modo lote — os eventos são acumulados em um buffer FIFO e entregues em um único lote. Isso permite que o processador permaneça mais tempo em modo de suspensão, reduzindo o consumo de energia em até 60%. O tamanho do buffer depende do chip do sensor e é especificado no campo Sensor.fifoMaxEventCount.
SensorManager é um serviço de sistema disponível através de getSystemService(Context.SENSOR_SERVICE). Ele fornece métodos para obter uma lista de sensores, obter um sensor padrão específico e registrar/cancelar listeners. SensorManager é um singleton — uma única instância para todo o aplicativo.
Antes de usar um sensor, você deve verificar sua disponibilidade. O método getDefaultSensor(type) retorna null se o sensor não estiver presente no dispositivo. Obter null sem verificação resultará em NullPointerException ao registrar um listener. O método getSensorList(type) retorna uma lista de todos os sensores.
fun checkSensorAvailability(type: Int): Boolean {
val sensorManager =
getSystemService(Context.SENSOR_SERVICE) as SensorManager
return sensorManager.getDefaultSensor(type) != null
}
// Uso:
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
Log.d("Sensor", "Giroscópio disponível")
}
Um listener é registrado através de registerListener(listener, sensor, delay). Importante: você deve cancelar o listener no método onPause() através de unregisterListener(listener). Se não fizer isso, o aplicativo continuará recebendo eventos do sensor, drenando a bateria mesmo em segundo plano. Android 8+ mostra um aviso no logcat sobre listeners não cancelados.
O método onAccuracyChanged(sensor, accuracy) é chamado quando a precisão do sensor muda. Valores: SENSOR_STATUS_ACCURACY_HIGH, MEDIUM, LOW e UNRELIABLE. Ao receber UNRELIABLE, os dados do sensor devem ser ignorados até que a precisão seja restaurada. Por exemplo, o magnetômetro requer calibração — agitar o dispositivo em forma de oito.
Vamos ver exemplos práticos de uso do Sensors API em aplicativos Android com Kotlin. O primeiro exemplo — determinar a orientação da tela usando o acelerômetro. O segundo — ler dados do magnetômetro com calibração. O terceiro — um detector de passos usando o pedômetro.
Uma combinação de acelerômetro e magnetômetro é usada para determinar a orientação. O método SensorManager.getRotationMatrix() calcula a matriz de rotação, e getOrientation() extrai os ângulos pitch, roll e azimuth. Azimuth — o ângulo relativo ao norte magnético em radianos.
val gravity = FloatArray(3)
val geomagnetic = FloatArray(3)
val rotationMatrix = FloatArray(9)
val orientation = FloatArray(3)
SensorManager.getRotationMatrix(
rotationMatrix, null, gravity, geomagnetic
)
SensorManager.getOrientation(rotationMatrix, orientation)
// orientation[0] — azimuth, [1] — pitch, [2] — roll
val azimuthDeg = Math.toDegrees(orientation[0].toDouble())
O pedômetro (TYPE_STEP_COUNTER) retorna o número total de passos dados pelo usuário desde a última reinicialização do dispositivo. O sensor funciona em nível de hardware — está ativo mesmo quando o aplicativo não está em execução. Para obter passos por sessão, você precisa salvar o valor inicial e calcular a diferença.
var initialSteps = 0
var isInitialized = false
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor.type == Sensor.TYPE_STEP_COUNTER) {
if (!isInitialized) {
initialSteps = event.values[0].toInt()
isInitialized = true
}
val currentSteps = event.values[0].toInt()
val sessionSteps = currentSteps - initialSteps
Log.d("Passos", "Passos por sessão: $sessionSteps")
}
}
O sensor de luz permite adaptar a interface às condições ambientais. Com pouca luz (menos de 10 lx), você pode mudar para o modo escuro. Com luz solar intensa (mais de 10000 lx), você pode aumentar o contraste. Uma média móvel dos últimos 5 valores é usada para filtrar ruídos.
O Android fornece vários sensores virtuais que não possuem um equivalente direto de hardware. Um sensor virtual calcula suas leituras com base em uma combinação de sensores físicos. Isso reduz a carga para o desenvolvedor — o próprio sistema implementa algoritmos de fusão de dados.
O sensor Gravity (TYPE_GRAVITY) extrai o componente gravitacional das leituras do acelerômetro usando um filtro passa-baixa. Linear Acceleration (TYPE_LINEAR_ACCELERATION), ao contrário, remove a gravidade e deixa apenas a aceleração linear do dispositivo. A soma de Gravity e Linear Acceleration fornece as leituras brutas do acelerômetro.
Rotation Vector — o sensor virtual mais complexo. Ele combina dados do giroscópio (mudanças de alta frequência), acelerômetro (vetor de gravidade) e magnetômetro (orientação relativa ao norte). O resultado é um quatérnio que descreve a orientação absoluta do dispositivo no espaço. É usado em aplicativos de RA e headsets de RV.
Game Rotation Vector — uma versão simplificada do Rotation Vector sem usar o magnetômetro. Isso fornece menor precisão de azimute, mas maior taxa de atualização e estabilidade. É recomendado para jogos onde a baixa latência é importante, não a orientação absoluta relativa ao norte.
Os sensores estão entre os componentes do dispositivo que mais consomem energia. O acelerômetro e o giroscópio na taxa máxima de amostragem podem drenar a bateria em 3–4 horas de operação contínua. Otimizar o uso de sensores é uma tarefa crítica para qualquer aplicativo que use Sensors API.
Não use SENSOR_DELAY_FASTEST desnecessariamente. Para animações de UI, SENSOR_DELAY_UI (60 ms) é suficiente. Para detecção de orientação de tela — SENSOR_DELAY_NORMAL (200 ms). Quanto maior a taxa, mais tempo o processador passa no estado ativo. A diferença entre NORMAL e FASTEST é de até 10x no consumo de energia.
A partir do Android 8.0 (API 26), aplicativos em segundo plano recebem eventos de sensores com frequência reduzida. No Android 12+, o acesso em segundo plano a sensores Motion e Position requer a permissão BODY_SENSORS_BACKGROUND. Cancele o listener quando o aplicativo entrar em segundo plano — isso estende a vida útil da bateria do dispositivo.
Use o processamento em lote através do método registerListener(listener, sensor, delay, maxReportLatencyUs). O parâmetro maxReportLatencyUs define a latência máxima de entrega de eventos em microssegundos. Com um valor de 1000000 (1 segundo), os eventos se acumulam no buffer FIFO do sensor e são entregues uma vez por segundo — o processador acorda com menos frequência.
Perguntas frequentes
O conjunto mínimo é um acelerômetro e um magnetômetro. Esses dois sensores estão presentes em mais de 95% dos dispositivos. Giroscópio, sensor de luz e sensor de proximidade — em 70–80% dos modelos modernos. Outros sensores (pressão, temperatura, umidade, pedômetro) são menos comuns e dependem da categoria de preço do dispositivo.
TYPE_ACCELEROMETER retorna a aceleração total incluindo gravidade (9,8 m/s²). TYPE_LINEAR_ACCELERATION retorna aceleração excluindo gravidade — apenas a aceleração do movimento do dispositivo. Se o dispositivo estiver parado, o acelerômetro mostrará 9,8 m/s² ao longo do eixo Z, enquanto o Linear Acceleration mostrará 0 em todos os eixos.
Use getPackageManager().hasSystemFeature() com as constantes apropriadas: FEATURE_SENSOR_ACCELEROMETER, FEATURE_SENSOR_GYROSCOPE, FEATURE_SENSOR_PROXIMITY e outras. Uma maneira alternativa é chamar getDefaultSensor(type) e verificar se o resultado é null. O primeiro método é preferível para verificação durante a inicialização.
Os dados brutos do sensor contêm ruído. Para suavizar, use um filtro passa-baixa: newValue = alpha * rawValue + (1 — alpha) * previousValue. Um coeficiente alpha de 0,1–0,3 fornece um bom equilíbrio entre capacidade de resposta e suavidade. Para o giroscópio, também é aplicado um filtro passa-alta para remover a deriva do zero.
Sim, mas com limitações. A partir do Android 8.0, a taxa de eventos do sensor é reduzida para aplicativos em segundo plano. A partir do Android 12, a permissão BODY_SENSORS_BACKGROUND é necessária para acesso a sensores em segundo plano. Para trabalho em segundo plano, é recomendado usar um Foreground Service com uma notificação.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também