如何在android设备中使用编程方式设置模拟传感器(加速计)

k97glaaz  于 2022-12-21  发布在  Android
关注(0)|答案(2)|浏览(184)

如何在Android设备上设置模拟传感器?
是否可以使用Android API设置模拟传感器,或者我们是否需要使用NDK和JNI或使用第三方库?
有人能告诉我如何实现这个吗?

ghhaqwfi

ghhaqwfi1#

我需要模拟一个陀螺仪传感器,但是找不到方法,所以我决定自己来做,如果对大家有帮助的话,我就把它放在这里,唯一的要求是:您的设备中必须有加速度传感器。如果有,您可以使用类似下面的方法模拟加速度传感器或陀螺仪:
1.创建一个SensorData。这将等同于android.hardware.SensorEvent。您将从该类读取传感器事件。

import android.hardware.SensorEvent;

public class SensorData {
    public final long timestamp;
    public final int sensorType;
    public final float x;
    public final float y;
    public final float z;
    
    public static SensorData from(SensorEvent event) {
        final float[] values = event.values;
        return new SensorData(
            event.timestamp,
            event.sensor.getType(),
            values[0],
            values[1],
            values[2]
        );
    }
    
    public SensorData(long timestamp, int sensorType, float x, float y, float z) {
        this.timestamp = timestamp;
        this.sensorType = sensorType;
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

1.创建一个SensorDataListener。这将等效于android.hardware.SensorEventListener

import android.hardware.Sensor;

public interface SensorDataListener {
    void onSensorChanged(SensorData data);

    void onAccuracyChanged(Sensor sensor, int accuracy);
}

1.创建一个SensorProvider。它将等价于android.hardware.SensorManager。你必须子类化这个类来实现你的模拟。

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;

public abstract class SensorProvider implements SensorEventListener {
    protected final Context context;
    protected final SensorManager manager;
    protected SensorDataListener listener;
    
    public SensorProvider(Context context) {
        this.context = context;
        this.manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
    }
    
    public void register(SensorDataListener listener, int sensorType, int delay) {
        this.listener = listener;
        manager.registerListener(this, manager.getDefaultSensor(sensorType), delay);
    }
    
    public void unregister() {
        manager.unregisterListener(this);
    }
    
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {}
    
    public abstract bool contains(int sensorType);
}

4.1.创建您的模拟。在本例中,加速度计值将是原始加速度计值的平方根,陀螺仪值将是原始加速度计值的平方。

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;

public class MockSensorProvider extends SensorProvider {
    public MockSensorProvider(Context context) {
        super(context);
    }
    
    @Override
    public bool contains(int sensorType) {
        return sensorType == Sensor.TYPE_ACCELEROMETER ||
            sensorType == Sensor.TYPE_GYROSCOPE;
    }
    
    @Override
    public void onSensorChanged(SensorEvent event) {
        final SensorDataListener listener = this.listener;
        if (listener == null) return;
        
        final float[] values = event.values;
        final SensorData accData = SensorData(
            event.timestamp,
            Sensor.TYPE_ACCELEROMETER,
            Math.sqrt(values[0]),
            Math.sqrt(values[1]),
            Math.sqrt(values[2])
        );
        listener.onSensorChanged(accData);
        
        final SensorData gyrData = SensorData(
            event.timestamp + 10,
            Sensor.TYPE_GYROSCOPE,
            values[0] * values[0],
            values[1] * values[1],
            values[2] * values[2]
        );
        listener.onSensorChanged(gyrData);
    }
}

4.2.在SensorProvider中创建静态方法以获取当前提供程序。

public abstract class SensorProvider implements SensorEventListener {
    // ...

    public static SensorProvider get(Context context) {
        return new MockSensorProvider(context);
    }

    // ...
}

1.完成了。您可以像这样使用SensorProvider

public class MainActivity extends AppCompatActivity implements SensorDataListener {
    private SensorProvider provider;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        provider = SensorProvider.get(this);
        if (provider.contains(Sensor.TYPE_ACCELEROMETER)) {
            provider.register(this, Sensor.TYPE_ACCELEROMETER, 20000);
        }
        if (provider.contains(Sensor.TYPE_GYROSCOPE)) {
            provider.register(this, Sensor.TYPE_GYROSCOPE, 20000);
        }
    }

    @Override
    public void onDestroy() {
        provider.unregister();
        super.onDestroy();
    }

    @Override
    public void onSensorChanged(SensorData data) {
        Log.d("%d %.2f %.2f %.2f".format(data.timestamp, data.x, data.y, data.z));
    }

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

svmlkihl2#

前面的答案给了我一个很好的基础,但是我想我已经找到了一个更简单的方法来达到同样的结果,而不需要替换java类,只需要修改实际的SensorEvent(感谢java默认的可变属性)。
使用存储的originalListener创建CustomSensorEventListener接口并从SensorEventListener继承

interface CustomSensorEventListener : SensorEventListener {
    var originalListener: SensorEventListener?
}

onSensorChanged回调中根据需要修改传感器值。

override fun onSensorChanged(event: SensorEvent?) {
    Log.d("TAG", "onSensorChanged: original value: ${event?.values?.joinToString()}")
    event?.values?.forEachIndexed { index, value -> event.values[index] = value * value }

    originalListener?.onSensorChanged(event)
}

然后创建SystemSensorsManager接口和实现,如下所示:

interface SystemSensorsManager {

    fun getDefaultSensor(type: Int): Sensor?

    fun registerListener(
        systemSensorListener: SensorEventListener,
        sensor: Sensor?,
        sensorDelay: Int
    ): Boolean

   fun unregisterListener(systemSensorListener: SensorEventListener, sensor: Sensor?)
}

class SystemSensorsManagerImpl(context: Context) : SystemSensorsManager {
    private val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as? SensorManager

    private val customSystemSensorEventListener: CustomSensorEventListener =
    CustomSensorEventListenerImpl()

    override fun getDefaultSensor(type: Int): Sensor? {
       return sensorManager?.getDefaultSensor(type)
    }

    override fun registerListener(systemSensorListener: SensorEventListener, sensor: Sensor?, sensorDelay: Int): Boolean {
        customSystemSensorEventListener.originalListener = systemSensorListener
        return sensorManager?.registerListener(
            customSystemSensorEventListener,
            sensor,
            sensorDelay
        ) ?: false
    }

    override fun unregisterListener(systemSensorListener: SensorEventListener, sensor: Sensor?) {
        sensorManager?.unregisterListener(
            customSystemSensorEventListener, sensor)
    }
}

最后,在您感兴趣的传感器上注册侦听器并提供实际侦听器。例如,在MainActivity中,与前面的答案相同:

class MainActivity : AppCompatActivity(), SensorEventListener {
    private val systemSensorsManager: SystemSensorsManager by lazy {
        SystemSensorsManagerImpl(applicationContext)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onStart() {
        super.onStart()
        val sensor = systemSensorsManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
        systemSensorsManager.registerListener(
            systemSensorListener = this,
            sensor = sensor,
            sensorDelay = sensor!!.minDelay
        )
    }

    override fun onDestroy() {
        systemSensorsManager.unregisterListener(
            systemSensorListener = this,
            sensor =
systemSensorsManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    )
        super.onDestroy()
    }

    override fun onSensorChanged(event: SensorEvent?) {
        Log.d("TAG", "onSensorChanged: modified value: 
${event?.values?.joinToString()}")
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {

    }
}

相关问题