【发布时间】:2018-03-20 03:14:03
【问题描述】:
我是使用 Android Studio 的新手,目前正在编写一个应用,该应用利用手机中的传感器来控制另一台设备。我搜索并没有找到太多可以帮助我解决问题的东西。最终我需要通过网络传输从传感器获得的数据,但我离那个点还很远,所以改天再说吧。
现在,该应用可以访问传感器并将其显示在手机屏幕上。每次按下屏幕按钮都会更新读数。我想要它做的是,一旦我按下按钮一次,随着手机的移动不断实时更新值。如果再次按下按钮,我希望它停止。以下是我在主要活动中的当前代码。我试图做的是使用一个整数,每次按下按钮时我都会切换它并在其中一个值上运行一个 do while 循环。当 do while 循环在那里时,它不会做任何事情。如果我把它拿出来,它会像每次按下按钮时更新值一样运行。我还在传感器值旁边显示“切换”的值,并且当 do while 循环不存在时它正在切换。我不明白为什么 do while 循环根本不会运行。我也尝试使用布尔值并在真假之间切换,但我得到了相同的结果。我也意识到 do while 循环的设置方式可能无法停止,但我认为它至少会进入循环并继续运行,这至少会让我开始.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.TextView;
import android.widget.Button;
import android.view.View;
public class MainActivity extends AppCompatActivity
{
MySensorUpdateThread mySensorUpdateThread = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySensorUpdateThread = new MySensorUpdateThread(this);
SensorManager sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
final float[] mValuesMagnet = new float[3];
final float[] mValuesAccel = new float[3];
final float[] mValuesOrientation = new float[3];
final float[] mRotationMatrix = new float[9];
final Button btn_valider = (Button) findViewById(R.id.btn1);
final TextView txt1 = (TextView) findViewById(R.id.textView1);
final SensorEventListener mEventListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
System.arraycopy(event.values, 0, mValuesAccel, 0, 3);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
System.arraycopy(event.values, 0, mValuesMagnet, 0, 3);
break;
}
}
;
};
setListners(sensorManager, mEventListener);
btn_valider.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
mySensorUpdateThread.toggleThread();
if (mySensorUpdateThread.isRunning())
{
mySensorUpdateThread.start();
}
}
});
}
public void setListners(SensorManager sensorManager, SensorEventListener mEventListener)
{
sensorManager.registerListener(mEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(mEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_NORMAL);
}
public class MySensorUpdateThread extends Thread
{
private boolean keepRunning = false;
private String sensorResults = "";
private MainActivity mActivity;
public MySensorUpdateThread(MainActivity activity)
{
this.mActivity = activity;
}
public void toggleThread()
{
this.keepRunning = !this.keepRunning;
}
public boolean isRunning()
{
return this.keepRunning;
}
public String getSensorResults()
{
return this.sensorResults;
}
@Override
public void run()
{
int i = 0;
int maxIterations = 100;
try{
while(this.keepRunning)
{
// This keeps the thread from going on too long in case
if(i > maxIterations)
{
this.keepRunning = false;
break;
}
// This causes the thread to rest for 50ms to
// slow things down
try
{
Thread.sleep(50);
}
catch(InterruptedException e)
{
}
SensorManager.getRotationMatrix(mRotationMatrix, null, mValuesAccel, mValuesMagnet);
SensorManager.getOrientation(mRotationMatrix, mValuesOrientation);
sensorResults = "Roll/Pitch (degrees): " + /*mValuesOrientation[0]*(180/Math.PI) + " "+ "," + " " +*/
mValuesOrientation[1] * (180 / Math.PI) + " " + "/" + " " +
mValuesOrientation[2] * (-180 / Math.PI);
// Now post the results to the UI Thread
runOnUiThread(new Runnable(){
@Override
public void run(){
txt1.setText(getSensorResults());
}
});
}
}
catch()
{
Log.e(TAG, ex.getMessage());
}
}
}
}
【问题讨论】:
-
您是否遇到任何错误?
-
我认为您的问题不在于 while 循环本身,而在于您如何使用它。我猜你在等待结果的同时不停地做,对吗?并且您是否在运行 for 循环时遇到 UI 中的冻结时刻,并且真的感觉什么都没有发生?
-
杰斯是对的。您在循环期间阻塞了您的 ui。您需要在后台线程中运行循环。
-
我已经编辑了我的答案以简化代码的工作方式。现在我只是跟踪迭代次数并将该信息发布到 txt1 TextView。这应该让您更好地了解正在发生的事情以及如何中断线程。
-
我认为您的问题更多地与设备
Sensor和SensorManager的有效实现有关,而不是线程。我建议您就该主题提出一个新问题 - 我认为您会得到更好的回应和更明智的答案。