android - 如何以编程方式在 Android 设备中设置模拟传感器(加速度计)

标签 android accelerometer android-sensors

如何在 Android 设备上设置模拟传感器?

是否可以使用 Android API 设置模拟传感器,或者我们是否需要使用 NDK 和 JNI 或使用第三方库?

谁能告诉我如何实现这个?

最佳答案

我需要模拟陀螺仪传感器,但找不到方法,所以我决定自己做。如果它对任何人有帮助,我会把它留在这里。唯一的要求是:您的设备中必须有加速计传感器。如果这样做,您可以使用如下方法模拟加速度计或陀螺仪:

  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;
    }
}
  • 创建一个SensorDataListener。这相当于 android.hardware.SensorEventListener
  • import android.hardware.Sensor;
    
    public interface SensorDataListener {
        void onSensorChanged(SensorData data);
    
        void onAccuracyChanged(Sensor sensor, int accuracy);
    }
    
  • 创建一个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);
        }
    
        // ...
    }
    
  • 已经完成了。您可以像这样使用 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) {}
    }
    

    关于android - 如何以编程方式在 Android 设备中设置模拟传感器(加速度计),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22610098/

    相关文章:

    Android 子类的数据绑定(bind)

    swift - 我正在尝试设置 coreMotion,但我的加速处理程序中出现此错误?

    安卓实时绘图

    android - 如何将外部传感器连接到 Android 设备?

    android - 检测智能手机在 table 上的水平和垂直运动

    java - 创建对象时出现 NullPointerException

    android - 设置导航项文本颜色白色android

    ios - Core Motion 加速度计显示奇怪的数据

    java - 仅在用户移动时运行服务以收集传感器数据

    java - AppCompat 相当于 "Theme.Wallpaper.NoTitleBar.Fullscreen"