我很遗憾在哪里看到我已经看到有某些方法here,并且看着these old questions他们提到它很难但我想知道从那以后在新版本的android中是否有任何改进.
下面的图片是我希望手机移动方向的一个额外示例.
解决方法
>我们需要听手机传感器
>我们需要检查手机是否处于垂直位置
>我们需要制作一个时间计数器,用于垂直注册手机并计数
>我们需要在屏幕上显示时间
对于第一步,我将向我们的类实现SensorEventListener,这将允许我们使用onSensorChanged方法.
@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; } } }
对于第二步,我构建了一个名为isPhoneVertical的方法来检查我们的手机是否处于垂直方向,它主要是检查y轴.您可以通过更改maxVertical来更改陡度.
她的价值不那么陡,0意味着手机应该几乎100%垂直.对于我的测试,它设置为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; }
对于第3步,我做了一些方法来检查开始时间和停止时间,并更新一个跟踪时间的全局变量,以秒为单位.
private long getStartTime() { return System.currentTimeMillis() / 1000; } private long getDiffTime() { return getStartTime() - mStartTime; }
对于第4步,我已经定期运行RunUnThread来更新屏幕上的时间.
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()) + ""); } }); }
也就是说这个解决方案是为了说明如何达到这个目标,我相信它可以通过不同的方式完成.但我想展示解决方案背后的逻辑.
这里是应用程序的屏幕截图,它计算每次手机垂直的时间和垂直的总时间.
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>
我也会留下一些阅读链接.
> https://developer.android.com/reference/android/hardware/SensorManager.html
> http://www.livescience.com/40103-accelerometer-vs-gyroscope.html
> https://physics.stackexchange.com/questions/41653/how-do-i-get-the-total-acceleration-from-3-axes
> https://code.tutsplus.com/tutorials/how-to-recognize-user-activity-with-activity-recognition–cms-25851
> http://www.vogella.com/tutorials/AndroidSensor/article.html
> How to get Android phone orientation matching human orientation?
如果您认为我可能会添加更多可以帮助您解决问题的信息,请告诉我们.目前还不清楚你是否正在寻找行走检测/计数器,如果这是你感兴趣的一些事情,请看下面的答案/链接.
> Activity Recognition Api
> How to detect walking with Android accelerometer
> how to calculate exact foot step count using accelerometer in android?
> Detect Movement Accurately using Accelerometer in Android
和GitHub源代码
> https://github.com/bagilevi/android-pedometer
> https://github.com/tartakynov/robowalk