我刚才使用Android Studio,目前正在编写一款应用程序,该应用程序利用手机中的传感器来控制其他设备。我搜索过并找不到太多可以帮助我解决问题的方法。最终,我需要通过网络传输从传感器获得的数据,但我还没有接近那一点,以至于还有一天。
目前,该应用可以访问传感器并在手机屏幕上显示。每次按下屏幕按钮,它都会更新读数。我想要它做的是,一旦我按下按钮一次,在手机移动时不断地实时更新值。如果再次按下该按钮,我希望它停止。以下是我在主要活动中的当前代码。我试图做的是使用一个整数,我会在每次按下按钮时切换,并在其中一个值上运行do while循环。当do while循环在那里时它不会做任何事情。如果我把它拿出来,就会像每次按下按钮时更新值一样运行。我也正在展示"切换"的价值。在传感器值旁边,当do while循环不在那里时切换。我不明白为什么while循环根本不会运行。我也尝试使用布尔值并在true和false之间切换,但我得到了相同的结果。我也意识到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());
}
}
}
}
答案 0 :(得分:0)
将传感器读数放在后台线程中。这只是一个例子。根据需要进行修改!
在Activity
课程中,您需要设置后台线程对象:
MySensorUpdateThread mySensorUpdateThread = null;
在您的活动onCreate()
方法中,通过添加:
mySensorUpdateThread = new MySensorUpdateThread();
在onClick()
方法中启动并停止后台线程:
public void onClick(View view){
mySensorUpdateThread.toggleThread();
if(mySensorUpdateThread.isRunning()){
mySensorUpdateThread.start();
}
});
现在这里是后台线程的代码:
public class MySensorUpdateThread extends Thread{
SensorManager sensorManager = null;
private boolean keepRunning = false;
private String sensorResults = "";
public void toggleThread(){
this.keepRunning = !this.keepRunning;
}
public void isRunning(){
return this.keepRunning;
}
public String getSensorResults(){
return this.sensorResults;
}
@Override
public void run(){
if(sensorManager == null){
sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
}
int i = 0;
int maxIterations = 100;
String mess = "";
try{
while(this.keepRunning){
mess = "Number of iterations: " + i;
Log.e(TAG, mess);
// This keeps the thread from going on too long in case
if(i > maxIterations){
this.keepRunning = false;
break;
}
// This causes your thread to rest for 500ms it might be a
// good idea to slow things down a bit -- just a suggestion
Thread.sleep(500);
// Get your sensor data here and set it to the
// local variable to be posted to the UI Thread
//this.sensorResults = sensorString;
// Now post the results to the UI Thread
runOnUiThread(new Runnable(){
@Override
public void run(){
txt1.setText(getSensorResults());
}
}
}
}
catch(){
Log.e(TAG, ex.getMessage());
}
}
}
您可能希望停止活动onPause()
方法的后台主题,并可能在onResume()
上重新启动它。
答案 1 :(得分:0)
当我使用处理程序线程进行长时间任务时,我发现它很有用,处理程序线程是机器人处理长时间运行任务的官方方式。这是官方链接 有关如何使用处理程序线程的更多信息。
https://developer.android.com/reference/android/os/HandlerThread.html