简体   繁体   English

Android加速度计和磁力计同时读取

[英]Android Accelerometer and Magnetometer readings simultaneously

I am writing an app which collects android sensor data and sends it to a server. 我正在编写一个收集android传感器数据并将其发送到服务器的应用程序。 I have started with Accelerometer and Magnetometer and following the tutorials online, I have written a little code. 我从加速计和磁力计开始,并按照在线教程学习了一些代码。 The problem is that accelerometer works but the magnetometer does not. 问题是加速度计可以工作,而磁力计不能工作。 Please look at the code below. 请查看下面的代码。

MainActivity.java MainActivity.java

package com.example.aliraza.wirelesshints;

import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.hardware.SensorManager;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import com.example.aliraza.wirelesshints.MyAccelerometer;

public class MainActivity extends AppCompatActivity{

    static TextView textView2, textView4;
    MyAccelerometer myAccel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView2 = (TextView) findViewById(R.id.textView2);
        textView4 = (TextView) findViewById(R.id.textView4);

        myAccel = new MyAccelerometer(this);
    }


    @Override
    protected void onResume() {
        super.onResume();

        myAccel.sensorManager.registerListener((SensorEventListener) myAccel, myAccel.accelerometer,SensorManager.SENSOR_DELAY_UI);
        myAccel.sensorManager.registerListener((SensorEventListener) myAccel, myAccel.magnetometer, SensorManager.SENSOR_DELAY_UI);
           }

    @Override
    protected void onPause() {
        // unregister listener
        super.onPause();
        myAccel.sensorManager.unregisterListener((SensorEventListener) myAccel);
    }
}

MyAccelerometer.java (contains magnetometer code as well) MyAccelerometer.java(也包含磁力计代码)

package com.example.aliraza.wirelesshints;

import android.content.Context;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.Toast;

public class MyAccelerometer implements SensorEventListener {
    Context mContext;
    SensorManager sensorManager;
    Sensor accelerometer;
    Sensor magnetometer;

    float[] mGravity;
    float[] mGeomagnetic;
    StringBuilder sb1, sb2;


    public MyAccelerometer(Context context){
        this.mContext = context;
        sensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        magnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        sb1 = new StringBuilder();
        sb2 = new StringBuilder();
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            if (mGravity != null) {
                mGravity = event.values;
                sb1.append("x = ");
                sb1.append(mGravity[0]);
                sb1.append(", y = ");
                sb1.append(mGravity[1]);
                sb1.append(", z = ");
                sb1.append(mGravity[2]);
                MainActivity.textView2.setText(sb1.toString());
            }
        }
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            if (event.sensor == magnetometer) {
                mGeomagnetic = event.values;
                if (mGravity != null && mGeomagnetic != null) {
                    float R[] = new float[9];
                    float I[] = new float[9];
                    boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
                    if (success) {
                        float orientation[] = new float[3];
                        SensorManager.getOrientation(R, orientation);
                        sb2.append("azimuth = ");
                        sb2.append(orientation[0]);
                        sb2.append(", pitch = ");
                        sb2.append(orientation[1]);
                        sb2.append(", roll = ");
                        sb2.append(orientation[2]);
                        MainActivity.textView4.setText(sb2.toString());
                    }
                }
            }

        }
    }


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

    }
}

If I run the above code the emulator and my actual phone show no output as shown below 如果运行上面的代码,模拟器和我的实际电话将不显示任何输出,如下所示

没用

If I comment out the following if condition statement without the internal code from MyAccelerometer.java, the accelerometer readings become visible 如果我注释了以下if条件语句,但没有MyAccelerometer.java的内部代码,则加速度计读数将变为可见

if (mGravity != null) {

As shown below 如下所示

加速度计的工作

But if I do the same with Magnetometer part ie the following if condition statement 但是如果我对磁力计部分做同样的操作,即以下if条件语句

if (mGravity != null && mGeomagnetic != null) {

nothing happens, in fact if I do anything, magnetometer readings just wont show in emulator and phone. 什么也没发生,实际上,如果我做任何事情,磁力计的读数将不会显示在模拟器和电话中。

I think the code does not go into the following condition 我认为代码没有进入以下条件

if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {

I will really appreciate some help. 我将非常感谢您的帮助。 Sorry for the incredibly long post. 很抱歉,发布了如此长的帖子。

Thanks 谢谢

You might have a problem with the getDefaultSensor()-method. 您可能对getDefaultSensor()方法有疑问。 Basically that should be a description of the sensor, but not necessarily a reference to the sensor itself. 基本上,这应该是对传感器的描述,但不一定是对传感器本身的引用。 You are probably better off not checking for the sensor itself, but for the sensor type (like you ALSO do). 您最好不要检查传感器本身,而是检查传感器类型(也可以像这样检查)。

Also your gravity!=null condition will always be false, because gravity is only set IF gravity is not null. 同样,您的引力!= null条件将始终为假,因为只有当引力不为null时才设置引力。 So it will never be set, if you start with it being null. 因此,如果您将其设置为null,则永远不会设置它。 Unless you want to control logging the input by setting it to null, you should not check for this. 除非您希望通过将输入设置为null来控制对输入进行日志记录,否则不应该对此进行检查。 Also note, that setting your "gravity" variable to something does not set the values of that variable, it sets the pointer. 还要注意,将“ gravity”变量设置为某种值不会设置该变量的值,而是设置指针。 So you set your pointer to the sensor values given by android. 因此,您将指针设置为android给定的传感器值。 It might work, but it's probably a better idea to either set the components individually on a pre-created array, or simply clone() the incoming data. 它可能会起作用,但是最好是将组件分别设置在预先创建的数组上,或者只是对输入的数据进行clone(),这可能是一个更好的主意。

Removing both conditions, this code should work. 除去这两个条件,此代码应该起作用。 Try Log.d("", ""+event.sensor.getType()) in your sensor event handler outside of any if-structures, and check if it shows 2 different values. 在任何if结构之外的传感器事件处理程序中尝试Log.d(“”,“” + event.sensor.getType()),并检查它是否显示2个不同的值。 Then you can be sure that you registered the sensors correctly, and your problem is processing. 然后,可以确保正确注册了传感器,并且问题正在处理中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM