是否可以测量手机垂直移动的距离 [英] Is it possible to measure the how far the phone travels vertically

查看:74
本文介绍了是否可以测量手机垂直移动的距离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道是否有可能/从哪里开始测量Android设备的向上和向下运动.我需要尽可能准确.

我完全不知道在哪里看,我已经看到了某些方法

解决方案

在寻求解决方案之前,我将解决方案分为小资产,并提出解决方案的难题

  1. 我们需要听电话感应器
  2. 我们需要检查手机是否处于垂直位置
  3. 我们需要建立一个可以垂直注册手机并向上计数的计时器
  4. 我们需要在屏幕上显示时间

对于第一步,我将对我们的类实现 SensorEventListener ,这将使我们能够使用 onSensorChanged 方法.

  @Override公共无效onSensorChanged(SensorEvent事件){如果(event.sensor.getType()== Sensor.TYPE_ACCELEROMETER){listenToSensors(event);}}私人无效的listenToSensors(SensorEvent事件){如果(isPhoneVertical(event)){timeCounter();如果(mStatus){mStartTime = getStartTime();mStatus = false;}} 别的 {如果(!mStatus){mTotalTime = getDiffTime()+ mTotalTime;mStatus = true;}}} 

对于第二步,我建立了一个名为 isPhoneVertical 的方法来检查我们的手机是否处于垂直状态,主要是检查y轴.您可以通过更改 maxVertical 来更改陡峭度.值越小,她的陡度就越小,0表示手机应几乎是100%垂直的.对于我的测试,它设置为3.

 私有布尔isPhoneVertical(SensorEvent事件){float [] values = event.values;双重y =值[1];//请勿更改此值yAxisInitValue的两倍= 10.0;double verMargin = yAxisInitValue-maxVertical;返回y> = verMargin;} 

对于第3步,我几乎没有方法检查开始时间和结束时间以及更新以秒为单位跟踪时间的全局变量.

  private long getStartTime(){返回System.currentTimeMillis()/1000;}私人长getDiffTime(){返回getStartTime()-mStartTime;} 

对于第4步,我制作了一个常规的 runOnUiThread 来更新屏幕上的时间.

  private void timeCounter(){runOnUiThread(new Runnable(){@Override公共无效run(){mView1.setText(电话已垂直放置:" + getDiffTime()+秒");mView2.setText(总时间:" +(mTotalTime + getDiffTime())+");}});} 

那是说这个解决方案是为了说明如何实现这个目标,我相信可以用不同的方式来实现.但是我想展示解决方案背后的逻辑.

这是该应用程序的屏幕截图,其中统计了手机每次垂直移动的时间和垂直移动的总时间.

解决方案包括一些解释:

MainActivity.java

 公共类MainActivity扩展Activity实现SensorEventListener {私有SensorManager mSensorManager;专用传感器加速度计;私人TextView mView1,mView2;私人长mStartTime;私人长mTotalTime;私有布尔值mStatus = true;//值越小,她的陡度就越小,0表示电话应该几乎是100%垂直//试试看私人double maxVertical = 3.0;@Override公共无效onCreate(捆绑保存的InstanceState){requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mView1 =(TextView)findViewById(R.id.textView1);mView2 =(TextView)findViewById(R.id.textView2);mSensorManager =(SensorManager)getSystemService(SENSOR_SERVICE);加速度计= mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);}@Override公共无效onSensorChanged(SensorEvent事件){如果(event.sensor.getType()== Sensor.TYPE_ACCELEROMETER){listenToSensors(event);}}私人无效的listenToSensors(SensorEvent事件){如果(isPhoneVertical(event)){timeCounter();如果(mStatus){mStartTime = getStartTime();mStatus = false;}} 别的 {如果(!mStatus){mTotalTime = getDiffTime()+ mTotalTime;mStatus = true;}}}//此方法仅针对特定的手机方向返回true//垂直方向的y轴私人布尔isPhoneVertical(SensorEvent事件){float [] values = event.values;双重y =值[1];//请勿更改此值yAxisInitValue的两倍= 10.0;double verMargin = yAxisInitValue-maxVertical;返回y> = verMargin;}私人长getStartTime(){返回System.currentTimeMillis()/1000;}私人长getDiffTime(){返回getStartTime()-mStartTime;}//更新用户界面中的步骤私人void timeCounter(){runOnUiThread(new Runnable(){@Override公共无效run(){mView1.setText(电话已垂直放置:" + getDiffTime()+秒");mView2.setText(总时间:" +(mTotalTime + getDiffTime())+");}});}@Overridepublic void onAccuracyChanged(Sensor sensor,int precision){}@Override受保护的void onResume(){super.onResume();mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);}@Override受保护的void onPause(){super.onPause();//如果您要在手机屏幕关闭时收集数据,只需禁用//在以下一行中,该应用仍将收集传感器数据mSensorManager.unregisterListener(this);}} 

Activity_main.xml

 <?xml version ="1.0" encoding ="utf-8"?>< RelativeLayout xmlns:android ="http://schemas.android.com/apk/res/android"xmlns:tools ="http://schemas.android.com/tools"android:id ="@ + id/activity_main"android:layout_width ="match_parent"android:layout_height ="match_parent"android:paddingBottom ="@ dimen/activity_vertical_margin"android:paddingLeft ="@ dimen/activity_horizo​​ntal_margin"android:paddingRight ="@ dimen/activity_horizo​​ntal_margin"android:paddingTop ="@ dimen/activity_vertical_margin"工具:context ="com.example.maytham.verticaltravels.MainActivity">< TextViewandroid:id ="@ + id/textView1"android:layout_width ="match_parent"android:layout_height ="wrap_content"android:layout_alignParentLeft ="true"android:layout_alignParentStart ="true"android:layout_alignParentTop ="true"android:textSize ="20sp"android:text ="TextView1"/>< TextViewandroid:id ="@ + id/textView2"android:layout_width ="match_parent"android:layout_height ="wrap_content"android:layout_alignParentLeft ="true"android:layout_alignParentStart ="true"android:layout_below ="@ + id/textView1"android:layout_marginTop ="57dp"android:textSize ="20sp"android:text ="TextView2"/></RelativeLayout> 

我也会留下一些阅读链接.

如果您认为我可能会添加更多可以帮助您进一步解决问题的信息,请告诉我.还不清楚您是否正在寻找步行检测/计数器,如果这是您感兴趣的事情,请查看以下答案/链接.

和GitHub源代码

I'm just wondering if it is possible / where would I get started in measuring the upwards and downwards movement of an Android device. I'd need it to be as accurate as possible.

I'm quite lost of where to look I've seen there are certain methods here, and looking at these old questions they mention it's quite difficult but I wanted to know if there had been any improvements since then in newer versions of android.

The image below is an extra example of the the direction I would like the phone to move in.

解决方案

Before going to solution, I would split the solution in small assets and put the puzzle for solution

  1. We need to listen to phone sensors
  2. We need to check phone is in vertical position or not
  3. We need to make a time counter that register the phone vertically and count up
  4. We need to display the time on screen

For step one, I would implement SensorEventListener to our class, this will allow us to use onSensorChanged method.

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        listenToSensors(event);
    }
}

private void listenToSensors(SensorEvent event) {
    if (isPhoneVertical(event)) {
        timeCounter();
        if (mStatus) {
            mStartTime = getStartTime();
            mStatus = false;
        }
    } else {
        if (!mStatus) {
            mTotalTime = getDiffTime() + mTotalTime;
            mStatus = true;
        }
    }
}

For step two, I have built a method called isPhoneVertical to check if our phone is in vertical way or not, it is primarily checking the y axis. You can change the steep degree by changing maxVertical. Less value her less steep, 0 means the phone should almost be 100% vertical. For my test it is set to 3.

private boolean isPhoneVertical(SensorEvent event) {
    float[] values = event.values;
    double y = values[1];
    // do not change this value
    double yAxisInitValue = 10.0;
    double verMargin = yAxisInitValue - maxVertical;

    return y >= verMargin;
}

For step 3 I have made few method to check start time and stop time and update a global variable that keep track of time in seconds.

private long getStartTime() {
    return System.currentTimeMillis() / 1000;
}

private long getDiffTime() {
    return getStartTime() - mStartTime;
}

For step 4 I have made a regular runOnUiThread to update the time on screen.

private void timeCounter() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mView1.setText("Phone has been vertical for: " + getDiffTime() + " seconds");
            mView2.setText("The total time: " + (mTotalTime + getDiffTime()) + "");
        }
    });
}

That said this solution is to illustrate how this goal can be reached, I am sure it can be done different ways. But I wanted to show the logic behind the solution.

And here is a screen shot of the app that counts the time for each time the phone is vertical and total time it has been vertical.

The solution including some explanations:

MainActivity.java

public class MainActivity extends Activity implements SensorEventListener {
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private TextView mView1, mView2;
    private long mStartTime;
    private long mTotalTime;
    private boolean mStatus = true;
    // less value her less steep, 0 means the phone should almost be 100% vertical
    // try it out
    private double maxVertical = 3.0;

    @Override
    public 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);
        mView1 = (TextView) findViewById(R.id.textView1);
        mView2 = (TextView) findViewById(R.id.textView2);

        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            listenToSensors(event);
        }
    }

    private void listenToSensors(SensorEvent event) {
        if (isPhoneVertical(event)) {
            timeCounter();
            if (mStatus) {
                mStartTime = getStartTime();
                mStatus = false;
            }
        } else {
            if (!mStatus) {
                mTotalTime = getDiffTime() + mTotalTime;
                mStatus = true;
            }
        }
    }

    // This method return true only for specific phone orientation
    // y axis for vertical orientation
    private boolean isPhoneVertical(SensorEvent event) {
        float[] values = event.values;
        double y = values[1];
        // do not change this value
        double yAxisInitValue = 10.0;
        double verMargin = yAxisInitValue - maxVertical;

        return y >= verMargin;
    }

    private long getStartTime() {
        return System.currentTimeMillis() / 1000;
    }

    private long getDiffTime() {
        return getStartTime() - mStartTime;
    }

    // update steps in user interface
    private void timeCounter() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mView1.setText("Phone has been vertical for: " + getDiffTime() + " seconds");
                mView2.setText("The total time: " + (mTotalTime + getDiffTime()) + "");
            }
        });
    }

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

    }

    @Override
    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // if you want to collect data while mobile screen off, just disable the
        // following line, the app will still collecting sensor data
        mSensorManager.unregisterListener(this);
    }
}

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.maytham.verticaltravels.MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:textSize="20sp"
        android:text="TextView1" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="57dp"
        android:textSize="20sp"
        android:text="TextView2" />
</RelativeLayout>

I will leave some link for reading as well.

If you think I might add more information that can help you further with your question please let me know. It is also unclear if you was looking for walking detection/counter, if that is some thing you are interesting in, look at following answers/links.

and GitHub source codes

这篇关于是否可以测量手机垂直移动的距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆