周期性任务(消息通过蓝牙发送)
问题描述:
在我的移动机器人项目,该项目有2个伺服电机在两个平面旋转的相机,我想通过旋转来控制他们在我的Android应用程序的智能手机(通过读数偏航/俯仰/从智能手机的加速度计滚动)。周期性任务(消息通过蓝牙发送)
为此,我必须通过蓝牙向Arduino发送关于这三个角度的数据。因此,例如,样本数据分组的样子:
“Y:100,P:20,R:45” 其中[Y-偏航,P-间距,R辊。 >
bl.sendData("A:"+String.format("%.0f",azimut) + ",P:" + String.format("%.0f",pitch) + ",R:" + String.format("%.0f",roll) + ".");
欲被在每200ms发送环状此消息(当我在此活动林) - - >(现在它是负责发送该命令/消息的Arduino
代码每次点击按钮“发送”:D时发送)。
我还必须提到的是,除了这个消息Arduino的应用程序发送另一个消息,当我触摸虚拟摇杆在这同样的活动来控制我的移动机器人的方向,我希望这是同时发送邮件)
之间没有冲突那我该如何得到它?一些示例代码?
这是从Android Studio中的代码(这个活动):
package com.samplecompass;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements SensorEventListener {
private cBluetooth bl = null;
private String address = "00:11:35:94:61:19";
private StringBuilder sb = new StringBuilder();
private Button send;
Float azimutF;
Float pitchF;
Float pitchMax=0.0f;
Float azimut; // View to draw a compass
Float pitch;
Float roll;
int zgoda=0;
int zgodaa=1;
int znak=1;
private TextView mPitch;
private SensorManager mSensorManager;
Sensor accelerometer;
Sensor magnetometer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bl = new cBluetooth(this, mHandler);
bl.checkBTState();
mPitch = (TextView) findViewById(R.id.Pitch);
send = (Button) findViewById(R.id.send);
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
zgodaa=0;
//bl.sendData("Hello");
}
});
}
private final Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case cBluetooth.BL_NOT_AVAILABLE:
Log.d(cBluetooth.TAG, "Bluetooth is not available. Exit");
Toast.makeText(getBaseContext(), "Bluetooth is not available", Toast.LENGTH_SHORT).show();
finish();
break;
case cBluetooth.BL_INCORRECT_ADDRESS:
Log.d(cBluetooth.TAG, "Incorrect MAC address");
Toast.makeText(getBaseContext(), "Incorrect Bluetooth address", Toast.LENGTH_SHORT).show();
break;
case cBluetooth.BL_REQUEST_ENABLE:
Log.d(cBluetooth.TAG, "Request Bluetooth Enable");
BluetoothAdapter.getDefaultAdapter();
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
break;
case cBluetooth.BL_SOCKET_FAILED:
Toast.makeText(getBaseContext(), "Socket failed", Toast.LENGTH_SHORT).show();
finish();
break;
case cBluetooth.RECIEVE_MESSAGE: // if message is recieved
byte[] readBuf = (byte[]) msg.obj;
String strIncom = new String(readBuf, 0, msg.arg1); // create string from bytes array
sb.append(strIncom); // append string
int endOfLineIndex = sb.indexOf("\r\n"); // determine the end-of-line
if (endOfLineIndex > 0) { // if end-of-line,
String sbprint = sb.substring(0, endOfLineIndex); // extract string
sb.delete(0, sb.length()); // and clear
//txtArduino.setText("Data from Arduino: " + sbprint); // update TextView
}
break;
}
};
};
protected void onResume() {
super.onResume();
bl.BT_Connect(address);
//bl.sendData("Hello World");
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
}
protected void onPause() {
super.onPause();
bl.BT_onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
float[] mGravity;
float[] mGeomagnetic;
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
if(zgoda==0) {
azimutF = -orientation[0] * 360/(2 * 3.14159f) - 90;
pitchF = orientation[1]*360/(2*3.14159f);
}
zgoda=1;
azimut = -orientation[0]*360/(2*3.14159f) - azimutF; // orientation contains: azimut, pitch and roll
pitch = -1*(orientation[1]*360/(2*3.14159f));
if(pitchMax<pitch){ pitchMax=pitch;}
/**if (Math.round(pitch) == 0) {
if(znak==1) znak=-1;
else if(znak==-1) znak=1;
}**/
roll = -orientation[2]*360/(2*3.14159f);
mPitch.setText(String.valueOf("Azimut: " + String.format("%.0f",azimut)) + String.valueOf("Znak:" + pitchMax) + String.valueOf("Pitch:" + String.format("%.0f",pitch)) + String.valueOf("Roll:" + String.format("%.0f",roll)));
if(zgodaa== 0) {bl.sendData("A:"+String.format("%.0f",azimut) + ",P:" + String.format("%.0f",pitch) + ",R:" + String.format("%.0f",roll) + ".");}
zgodaa=1;
}
}
}
}
答
@jdv谢谢大家的帮助,现在我知道如何做到这一点 - >
public class MainActivity extends Activity implements SensorEventListener {
private Handler handler
...
protected void onCreate(Bundle savedInstanceState) {
handler = new Handler();
...
}
Runnable mStatusChecker = new Runnable() {
@Override
public void run() {
try {
bl.sendData("A:"+i+String.format("%.0f",azimut) + ",P:" + String.format("%.0f",pitch) + ",R:" + String.format("%.0f",roll) + ".");; //this function can change value of mInterval.
} finally {
// 100% guarantee that this always happens, even if
// your update method throws an exception
handler.postDelayed(mStatusChecker, 1000);
}
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
private final Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case cBluetooth.BL_OK:
startRepeatingTask();
Toast.makeText(getBaseContext(), "BL_OK",
Toast.LENGTH_SHORT).show();
break;
}
}
}
因此,我调用函数当蓝牙连接时,因为在其他情况下弹出错误。
但现在我有一个问题,我不希望创建新的话题,所以你可以告诉我哪个功能调用,当我把我的智能手机home键和后退按钮?
onResume在这两种情况下或万一HOME另一个功能?
https://guides.codepath.com/android/Repeating-Periodic-Tasks – jdv
@jdv我不知道什么时候应该将这部分代码插入到MyActivity/code - > // //我们需要使用这个处理程序包 import android.os.Handler; //创建Handler对象(默认在主线程中) Handler handler = new Handler(); //定义代码块被执行 私人的Runnable runnableCode =新的Runnable(){ ' –
@jdv CD'@覆盖 公共无效的run(){// 这里做什么主线程 Log.d上(“处理程序”,“主线程调用”); //重复此同一可运行代码块再次2秒钟 //“这个”被引用Runnable对象 handler.postDelayed(这一点,2000); } }; //通过处理程序 handler.post(runnableCode)发布启动初始运行的任务;' –