按钮功能的管理和蓝牙控制器方法的调用



向所有人致以亲切的问候。

我最近加入了这个社区,我在安卓编程方面不是很有经验,所以我向大家发表讲话,希望能解决一个问题。

我正在开发一个Android应用程序,它允许我通过蓝牙控制一个机器人,该机器人使用手机作为陀螺仪控制器,并添加通过按钮实现的命令。我希望方向命令的调度由ToggleButton管理;即:仅在压力和转换到就绪状态之后,并且在下一压力和转换为NOT READY状态时禁用发送。我的问题是能够在第一次按下后调用"onSensorChanged"陀螺仪传感器方法。

主要活动如下((:

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.widget.Toast;
import android.widget.ToggleButton;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import java.io.OutputStream;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor rotationVectorSensor;
private SensorEventListener mListener;
//variabili per misure giroscopio
private TextView assex;
private TextView assey;
private TextView assez;
//variabili per frecce
private ImageView arrowup;
private ImageView arrowdown;
private ImageView arrowleft;
private ImageView arrowright;
//variabili per i bottoni
private Button calibrate;
private Button auto;
private Button stop;
private ToggleButton toggleState;
//variabili per la compensazione della misura della posizione angolare rilevata dal giroscopio
float compensationy;
float compensationz;
float[] orientations = new float[3];
//variabile per associazione deispositivo bluetooth
public UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
//variabili gestione bluetooth
BluetoothSocket mmSocket=null;
BluetoothDevice mmDevice=null;
OutputStream outStream;
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//variabile visualizzazione stato sensore gioscopico
private TextView sensor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//per visualizzare le misure del giroscopio
assex = (TextView) findViewById(R.id.assexvalue);
assey = (TextView) findViewById(R.id.asseyvalue);
assez = (TextView) findViewById(R.id.assezvalue);
//per visualizzare le immagini delle frecce
arrowup = (ImageView) findViewById(R.id.imageViewUp);
arrowdown = (ImageView) findViewById(R.id.imageViewDown);
arrowleft = (ImageView) findViewById(R.id.imageViewLeft);
arrowright = (ImageView) findViewById(R.id.imageViewRight);
//per visualizzare le immagini del bottoni
calibrate = (Button) findViewById(R.id.calibrate);
auto = (Button) findViewById(R.id.Auto);
stop = (Button) findViewById(R.id.Stop);
toggleState = (ToggleButton) findViewById(R.id.ToggleState);
//per visualizzare lo stato del giroscopio
sensor = (TextView) findViewById(R.id.sensor);
//controllo presenza sensore giroscopio
mSensorManager = (SensorManager) this.getSystemService(Activity.SENSOR_SERVICE);
rotationVectorSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
if(rotationVectorSensor==null)
sensor.setText("Il sensore non è presente");
else
sensor.setText("Il sensore è attivo");

/***************    GESTIONE PULSANTI   ***********************/
//Pulsante CALIBRATE:
calibrate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
compensationy = -Math.round(orientations[1]);
compensationz = -Math.round(orientations[2]);
}
});
//Pulsante STOP!:
stop.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
sendMessageBluetooth("N"); //invio comando di STOP!
}
});
//Pulsante AUTO:
auto.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
sendMessageBluetooth("M"); //invio comando di FUNZIONAMENTO AUTOMATICO
}
});
//ToggleState READY!/NOT READY!:  //RIVEDI!!!!!!!
toggleState.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if(!toggleState.isChecked()){
//dopo la prima pressione del toggle button c'è la scritta NOT READ!
//alla seconda  pressione del del toggle button entro nella suddetta modalità e
// non invio alcun carattere
}
/*le frecce sono disabilitate*/
else {
//sul bottone inizialmente c'è la scritta READY!
//alla prima pressione del del toggle button entro nella suddetta modalità e
// chiamo la funzione 'onSensorChanged'
//invio comandi frecce
}
}
});
/***************************************************************/
/***************** Gestione e controllo connessione bluetooth **********************/
if (mBluetoothAdapter == null){
// IL BLUETOOTH NON E' SUPPORTATO
Toast.makeText(MainActivity.this, "BlueTooth non supportato", Toast.LENGTH_LONG).show();
}
else {
if (!mBluetoothAdapter.isEnabled())//controlla che sia abilitato il devices
//  NON E' ABILITATO IL BLUETOOTH
Toast.makeText(MainActivity.this, "BlueTooth non abilitato", Toast.LENGTH_LONG).show();
else {
mmDevice = mBluetoothAdapter.getRemoteDevice("00:12:12:24:17:08");
try {
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
}
catch (IOException e) {
;
}
try {
mmSocket.connect();
outStream = mmSocket.getOutputStream();
Toast.makeText(MainActivity.this, "ON", Toast.LENGTH_SHORT).show();
}
catch (IOException closeException) {
try {
mmSocket.close();
}
catch (IOException ceXC) {
;
}
}
}
}
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, rotationVectorSensor, SensorManager.SENSOR_DELAY_UI);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrixFromVector(
rotationMatrix, sensorEvent.values);
// Remap coordinate system
float[] remappedRotationMatrix = new float[9];
SensorManager.remapCoordinateSystem(rotationMatrix,
SensorManager.AXIS_Y,
SensorManager.AXIS_MINUS_X,
remappedRotationMatrix);
// Convert to orientations
SensorManager.getOrientation(remappedRotationMatrix, orientations);
for(int i = 0; i < 3; i++) {
orientations[i] = (float)(Math.toDegrees(orientations[i]));
}
float valuey = Math.round((orientations[1])  + compensationy);
float valuez = Math.round((orientations[2])  + compensationz);
assex.setText(Float.toString(Math.round(orientations[0])));
assey.setText(Float.toString( valuey ));
assez.setText(Float.toString( valuez ));;
if(valuey > 20 ) {
arrowup.setVisibility(View.VISIBLE);
arrowdown.setVisibility(View.INVISIBLE);
sendMessageBluetooth("W");
}
else if(valuey < -20 ) {
arrowdown.setVisibility(View.VISIBLE);
arrowup.setVisibility(View.INVISIBLE);
sendMessageBluetooth("S");
}
else if (valuez > 20) {
arrowright.setVisibility(View.VISIBLE);
arrowleft.setVisibility(View.INVISIBLE);
sendMessageBluetooth("D");
}
else if (valuez < -20) {
arrowleft.setVisibility(View.VISIBLE);
arrowright.setVisibility(View.INVISIBLE);
sendMessageBluetooth("A");
}
else if (valuez > -20 && valuez < -15 || valuey < 20 && valuey > 15|| valuey > -20 && valuey < -15|| valuez < 20 && valuez > 15 ){
sendMessageBluetooth("P");
}
else {
arrowup.setVisibility(View.INVISIBLE);
arrowdown.setVisibility(View.INVISIBLE);
arrowleft.setVisibility(View.INVISIBLE);
arrowright.setVisibility(View.INVISIBLE);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
;
}
public void sendMessageBluetooth(String message) {
if (outStream == null)
return;
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
}
catch (IOException e) {
;
}
}

}

这段代码是我的2.0版本,是从以前的1.0版本开始开发的,在之前的1.0版本中,ToggleButton不存在,方向命令是随着手机的倾斜而发送的。如果我需要,我会加载它。

你如何吃大象?。。。一块一块。因此,我建议首先将MainActivity中的代码分离为自己的可重用类。它将帮助您更好地调试,更好地开发,并且更容易获得帮助。

例如,以下是可以拆分代码的部分:

  • 实现SensorEventListener的传感器类
  • 负责蓝牙的蓝牙类
  • MainActivity应该只负责UI
  • 核心类应该在MainActivity和其他类之间。它应该包含您的"业务逻辑"并保持程序的"状态">

现在,回答您的评论:

我的问题是能够在第一次按下后调用"onSensorChanged"陀螺仪传感器方法。

查看此StackOverFlow帖子以获得可能的答案:onSensorChanged((未调用陀螺仪传感器

它没有启动的原因是,当传感器发生更改时,您没有为给定活动注册回调。请参阅此处http://developer.android.com/reference/android/hardware/SensorManager.html。

尝试一下,看看这是否对你有帮助。

最新更新