最近在做一个项目,是蓝牙与下位机进行交互,只是简单的数据交互,使用蓝牙4.0.。。。
先看看项目的简易通信协议:
协议内容,是一个44位字节的通信命令式协议:
协议格式:
输出格式:pump on + (char)13 + (char)10
返回格式 10PID 9PStatus 10FID 9FStatus <CF><LR>,去掉结尾符共42位,结尾以char[10]char[13];
解释下:
char[13]char[10]就是“\r\n”;
看懂了这些,开始找思路,其实蓝牙无非就是socket通信,下位机当做S端,终端设备是C端,请求连接S端,然后用socket向S端写数据,写过C的都知道,C中没有String的概
念,只有char*[],这样就有个问题,我们java的命令行是拼接的String字符串,如何去转化成char*[]呢,我们知道C接受数据时候的没有byte,但是要理解byte其实就是无属的char
即(C没有这个类型,byte表示一个字节,对应C的unsigned char),java是没有指针概念的,,其实这里非常简单,,char*[]无非就是一个char型的数组,那么有了这条思路,我
们用String.getByteArray()
即可。转化成字节数组,那么对应的就是C中unsigned char[ ],既然数据类型匹配完成,那么就开始从java入手书写代码:
主界面:
- <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
- <ImageButton
- android:id="@+id/btnOpenBT"
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:background="@drawable/bluetooth_off" />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
- <TextView
- android:id="@+id/tvDeviceName"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="right"
- android:text="Bluetooth"
- android:textSize="14sp" />
- </LinearLayout>
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="30dp"
- android:text="写入测试" />
- <EditText
- android:id="@+id/output_test"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="数据回显测试" />
- <TextView
- android:id="@+id/input_test"
- android:layout_width="fill_parent"
- android:textSize="14sp"
- android:layout_height="30dp" />
- <Button
- android:id="@+id/start_test"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="开始测试" />
- <Button
- android:id="@+id/btn1"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="pump on" />
- <Button
- android:id="@+id/btn2"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="pump off" />
- <Button
- android:id="@+id/btn3"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="detector pid_fid" />
- <Button
- android:id="@+id/btn4"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="ignite" />
- </LinearLayout>
- </ScrollView>
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/newdevice" />
- <ListView
- android:id="@+id/lvNewDevices"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="2"
- android:stackFromBottom="true" >
- </ListView>
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/paireddevice" />
- <ListView
- android:id="@+id/lvPairedDevices"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="2"
- android:stackFromBottom="true" >
- </ListView>
- <Button
- android:id="@+id/btnScan"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/scan" />
- </LinearLayout>
开始代码:
- package com.simpledraw.bluetoothservice;
- import java.text.DecimalFormat;
- import android.annotation.SuppressLint;
- import android.app.Activity;
- import android.bluetooth.BluetoothAdapter;
- import android.bluetooth.BluetoothDevice;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- import android.util.Log;
- import android.view.KeyEvent;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.animation.Animation;
- import android.view.animation.RotateAnimation;
- import android.view.animation.ScaleAnimation;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ImageButton;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.simpledraw.bluetooth.BluetoothCommService;
- import com.simpledraw.bluetooth.BluetoothEnvironment;
- import com.simpledraw.bluetooth.ConstantsBluetooth;
- import com.simpledraw.bluetooth.ScanBTDeviceActivity;
- import com.simpledraw.bluetooth.data.Datagram;
- public class MainActivity extends Activity {
- private TextView tvDirection1, tvDirection2;
- private ScaleAnimation animTemperature, animHumidity;
- private RotateAnimation animPressure;
- private float currentDirection1 = 0, currentDirection2 = 0, currentTemperature = ConstantsEwins.MIN_TEMPERATURE_Y,
- currentHumidity = 0.0f, currentPressure = 0;
- DecimalFormat df = new DecimalFormat("0.00");
- private ImageButton btnOpenBT = null;
- private TextView tvDeviceName = null;
- private Datagram datagram = new Datagram();
- private BluetoothAdapter btAdapter;
- private BluetoothDevice mDevice;
- private int[] checked = new int[11];
- private long exitTime = 0;// 用于再按一次退出
- private String executStr = "";
- @SuppressLint("NewApi")
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- getBluetoothAdapter();
- findAllControls();
- }
- private EditText output_edit;
- private TextView input_edit;
- private Button startTest;
- private void findAllControls() {
- output_edit = (EditText) findViewById(R.id.output_test);
- input_edit = (TextView) findViewById(R.id.input_test);
- startTest = (Button) findViewById(R.id.start_test);
- ((Button)findViewById(R.id.btn1)).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- executStr = ((Button)v).getText().toString();
- output_edit.setText("");
- executStr+="\r\n";
- BluetoothEnvironment.service.write(executStr.getBytes());
- output_edit.setText(executStr);
- }
- });
- ((Button)findViewById(R.id.btn2)).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- executStr = ((Button)v).getText().toString();
- output_edit.setText(executStr);
- output_edit.setText("");
- executStr+="\r\n";
- BluetoothEnvironment.service.write(executStr.getBytes());
- }
- });
- ((Button)findViewById(R.id.btn3)).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- executStr = ((Button)v).getText().toString();
- output_edit.setText(executStr);
- output_edit.setText("");
- executStr="log start\r\n";
- BluetoothEnvironment.service.write(executStr.getBytes());
- executStr="detector pid_fid\r\n";
- BluetoothEnvironment.service.write(executStr.getBytes());
- }
- });
- ((Button)findViewById(R.id.btn4)).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- executStr = ((Button)v).getText().toString();
- output_edit.setText(executStr);
- output_edit.setText("");
- executStr+="\r\n";
- BluetoothEnvironment.service.write(executStr.getBytes());
- }
- });
- startTest.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- if(BluetoothEnvironment.service!=null){
- output_edit.setText("");
- // String outputData = output_edit.getText().toString();
- executStr+="\r\n";
- // byte[] bytes = outputData.getBytes();
- // byte[] bytes2 = new byte[bytes.length+2];
- // for(int i = 0;i<bytes.length;i++){
- // bytes2[i] = bytes[i];
- // }
- // bytes2[bytes2.length-2] = 13;
- // bytes2[bytes2.length-1] = 10;
- BluetoothEnvironment.service.write(executStr.getBytes());
- }
- }
- });
- btnOpenBT = (ImageButton) findViewById(R.id.btnOpenBT);
- btnOpenBT.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- Intent intent = new Intent(MainActivity.this, ScanBTDeviceActivity.class);
- startActivityForResult(intent, ConstantsBluetooth.REQUEST_CONNECT_DEVICE);
- }
- });
- tvDeviceName = (TextView) findViewById(R.id.tvDeviceName);
- for (int i = 0; i < 11; i++)
- checked[i] = View.VISIBLE;
- }
- private void getBluetoothAdapter() {
- btAdapter = BluetoothAdapter.getDefaultAdapter();
- if (btAdapter == null) {
- Toast.makeText(MainActivity.this, "本设备不支持蓝牙", Toast.LENGTH_SHORT).show();
- finish();
- return;
- }
- while (!btAdapter.isEnabled()) {
- if (btAdapter.enable()) {
- Toast.makeText(MainActivity.this, "蓝牙已经启动", Toast.LENGTH_SHORT).show();
- break;
- } else {
- Toast.makeText(MainActivity.this, "蓝牙启动失败", Toast.LENGTH_SHORT).show();
- return;
- }
- }
- if (btAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
- Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
- intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
- startActivity(intent);
- }
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(0, 1, 0, R.string.tianjiachuanganqi);
- return true;
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getOrder() == 0) {
- Intent intent = new Intent(MainActivity.this, AddDeleteSensorsActivity.class);
- intent.putExtra("checked", checked);
- startActivityForResult(intent, ConstantsEwins.REQUEST_ADDDELETE_SENSORS);
- }
- return super.onOptionsItemSelected(item);
- }
- @Override
- protected void onResume() {
- System.out.println("------- ON RESUME ---------");
- super.onResume();
- if (BluetoothEnvironment.service != null) {
- if (btAdapter.isEnabled() && BluetoothEnvironment.service.getState() == ConstantsBluetooth.STATE_NONE) {
- BluetoothEnvironment.service.start();
- }
- BluetoothEnvironment.service.setHandler(mHandler, null);
- } else {
- BluetoothEnvironment.service = new BluetoothCommService(this, mHandler, null);
- }
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- switch (requestCode) {
- case ConstantsBluetooth.REQUEST_CONNECT_DEVICE:
- if (resultCode == RESULT_OK) {
- String address = data.getExtras().getString(ConstantsBluetooth.DEVICE_ADDRESS);
- mDevice = btAdapter.getRemoteDevice(address);
- if (mDevice == null)
- return;
- if (BluetoothEnvironment.service != null)
- BluetoothEnvironment.service.connect(mDevice);
- }
- break;
- case ConstantsEwins.REQUEST_ADDDELETE_SENSORS:
- if (resultCode == RESULT_OK) {
- }
- break;
- default:
- break;
- }
- }
- @SuppressLint("HandlerLeak")
- private final Handler mHandler = new Handler() {
- int length = 0;
- boolean firstReceived = true;
- long lastReadTime = System.currentTimeMillis();
- StringBuffer sb = new StringBuffer(ConstantsEwins.DATA_LENGTH);
- @Override
- public void handleMessage(android.os.Message msg) {
- switch (msg.what) {
- case ConstantsBluetooth.MESSAGE_STATE_CHANGE:
- switch (msg.arg1) {
- case ConstantsBluetooth.STATE_CONNECTED:
- Toast.makeText(MainActivity.this, "已连接至" + msg.obj + "!!fdasfds", Toast.LENGTH_SHORT).show();
- tvDeviceName.setText((String) msg.obj);
- btnOpenBT.setBackgroundResource(R.drawable.bluetooth_on);
- break;
- case ConstantsBluetooth.STATE_CONNECTING:
- Toast.makeText(MainActivity.this, "正在连接,请稍候", Toast.LENGTH_LONG).show();
- break;
- case ConstantsBluetooth.STATE_LISTEN:
- if (ConstantsBluetooth.CONNECTION_FAILED.equals(msg.obj)) {
- Toast.makeText(MainActivity.this, "连接不成功", Toast.LENGTH_SHORT).show();
- btnOpenBT.setBackgroundResource(R.drawable.bluetooth_off);
- } else if (ConstantsBluetooth.CONNECTION_LOST.equals(msg.obj)) {
- Toast.makeText(MainActivity.this, "连接丢失", Toast.LENGTH_SHORT).show();
- btnOpenBT.setBackgroundResource(R.drawable.bluetooth_off);
- }
- break;
- case ConstantsBluetooth.STATE_NONE:
- btnOpenBT.setBackgroundResource(R.drawable.bluetooth_off);
- break;
- }
- break;
- case ConstantsBluetooth.MESSAGE_WRITE:
- break;
- case ConstantsBluetooth.MESSAGE_READ:
- if (firstReceived)
- lastReadTime = System.currentTimeMillis();
- firstReceived = false;
- if (System.currentTimeMillis() - lastReadTime > ConstantsEwins.DATAGRAM_INTERVAL) {
- if (length == ConstantsEwins.DATAGRAM_BYTES_LENGTH) {
- datagram.parseDatagram(sb.toString());
- modifyViews();
- }
- sb = new StringBuffer(ConstantsEwins.DATA_LENGTH);
- length = 0;
- }
- String data = (String) msg.obj;
- System.out.println("接收到的数据:" + data);
- Log.e("texts",data);
- length += msg.arg1;
- sb.append(data);
- lastReadTime = System.currentTimeMillis();
- input_edit.setText(data);//sb.toString()
- break;
- }
- }
- };
- @SuppressLint("NewApi")
- private void modifyViews() {
- tvDirection1.setText("风向1: " + (datagram.getDirection1() - (datagram.getDirection1() / 360) * 360) + "°");
- tvDirection2.setText("风向2: " + (datagram.getDirection2() - (datagram.getDirection2() / 360) * 360) + "°");
- // 风速改变
- long newDuration;
- newDuration = calcSpeedDuration(datagram.getSpeed1());
- newDuration = calcSpeedDuration(datagram.getSpeed2());
- newDuration = calcSpeedDuration(datagram.getSpeed3());
- newDuration = calcSpeedDuration(datagram.getSpeed4());
- newDuration = calcSpeedDuration(datagram.getSpeed5());
- newDuration = calcSpeedDuration(datagram.getSpeed6());
- currentDirection1 = datagram.getDirection1();
- currentDirection2 = datagram.getDirection2();
- // 温度、湿度和气压
- float newTemperature = (datagram.getTemperature() - ConstantsEwins.MIN_TEMPERATURE_VALUE)
- * ConstantsEwins.TEMPERATURE_STEP + ConstantsEwins.MIN_TEMPERATURE_Y;
- float newHumidity = datagram.getHumidity() * ConstantsEwins.HUMIDITY_STEP + ConstantsEwins.MIN_HUMIDITY_Y;
- float newPressure = (datagram.getPressure() - ConstantsEwins.MIN_PRESSURE_VALUE) * ConstantsEwins.PRESSURE_STEP;
- animTemperature = new ScaleAnimation(1.0f, 1.0f, currentTemperature, newTemperature,
- Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.8f);
- animTemperature.setDuration(500);
- animTemperature.setFillAfter(true);
- animHumidity = new ScaleAnimation(1.0f, 1.0f, currentHumidity, newHumidity, Animation.RELATIVE_TO_SELF, 0,
- Animation.RELATIVE_TO_SELF, 0.8f);
- animHumidity.setDuration(500);
- animHumidity.setFillAfter(true);
- animPressure = new RotateAnimation(currentPressure, newPressure, Animation.RELATIVE_TO_SELF, 0.5f,
- Animation.RELATIVE_TO_SELF, 0.5f);
- animPressure.setDuration(500);
- animPressure.setFillAfter(true);
- currentTemperature = newTemperature;
- currentHumidity = newHumidity;
- currentPressure = newPressure;
- }
- private long calcSpeedDuration(float speed) {
- int level;
- if (speed < 1.5f)
- level = 1;
- else if (speed > 1.6 && speed < 5.4)
- level = 2;
- else if (speed > 5.5 && speed < 7.9)
- level = 3;
- else if (speed > 8.0 && speed < 10.7)
- level = 4;
- else if (speed > 10.8 && speed < 13.8)
- level = 5;
- else if (speed > 13.9 && speed < 17.1)
- level = 6;
- else if (speed > 17.2 && speed < 20.7)
- level = 7;
- else if (speed > 20.8 && speed < 24.4)
- level = 8;
- else if (speed > 24.5 && speed < 28.4)
- level = 9;
- else if (speed > 28.5 && speed < 32.6)
- level = 10;
- else
- level = 11;
- long duration;
- duration = (11 - level) * ConstantsEwins.SPEED_DURATION_STEP + ConstantsEwins.MIN_SPEED_DURATION;
- return duration;
- }
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
- if ((System.currentTimeMillis() - exitTime) > 2000) {
- Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
- exitTime = System.currentTimeMillis();
- } else {
- finish();
- System.exit(0);
- }
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
- }
- package com.simpledraw.bluetoothservice;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.drawable.Drawable;
- import android.util.AttributeSet;
- import android.widget.ImageView;
- public class DirectionPointerView extends ImageView {
- private float mDirection;
- private Drawable compass;
- public DirectionPointerView(Context context) {
- super(context);
- mDirection = 0.0f;
- compass = null;
- }
- public DirectionPointerView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mDirection = 0.0f;
- compass = null;
- }
- public DirectionPointerView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mDirection = 0.0f;
- compass = null;
- }
- @Override
- protected void onDraw(Canvas canvas) {
- if (compass == null) {
- compass = getDrawable();
- compass.setBounds(0, 0, getWidth(), getHeight());
- }
- canvas.save();
- canvas.rotate(mDirection, getWidth() / 2, getHeight() / 2);
- compass.draw(canvas);
- canvas.restore();
- }
- public void updateDirection(float direction) {
- mDirection = direction;
- invalidate();
- }
- }
- package com.simpledraw.bluetoothservice;
- public class ConstantsEwins {
- public static final int REQUEST_ADDDELETE_SENSORS = 2;
- public static final float MAX_SPEED_VALUE = 100;
- public static final float MIN_SPEED_VALUE = 0;
- public static final int MIN_SPEED_DURATION = 500;
- public static final int SPEED_DURATION_STEP = 500;
- public static final float MAX_TEMPERATURE_VALUE = 53;
- public static final float MIN_TEMPERATURE_VALUE = -40;
- public static final float MIN_TEMPERATURE_Y = 0.02f;
- public static final float TEMPERATURE_STEP = 0.01185f;
- public static final float MIN_HUMIDITY_Y = 0.0f;
- public static final float HUMIDITY_STEP = 0.01118f;
- public static final float MAX_PRESSURE_VALUE = 120;
- public static final float MIN_PRESSURE_VALUE = 10;
- public static final float PRESSURE_STEP = 2.38f;
- public static final int DATAGRAM_INTERVAL = 500;
- // 报文的字节数
- public static final int DATAGRAM_BYTES_LENGTH = 20;
- // 需要使用的数据长度,例如将字节变成16进制字符串的长度,0x80变成80
- public static final int DATA_LENGTH = 40;
- }
- package com.simpledraw.bluetooth.data;
- import android.annotation.SuppressLint;
- @SuppressLint("DefaultLocale")
- public class DataTypeConverter {
- public static String double2Str(double d) {
- return String.format("%.1f", d);
- }
- public static double str2Double(String str) {
- return Double.parseDouble(str);
- }
- public static String getMacAddress(String pStr) {
- return pStr.substring(pStr.length() - 17);
- }
- public static double hexStr2Double(String pStr) {
- int i = Integer.parseInt(pStr, 16);
- double d;
- if (pStr.startsWith("F")) {
- d = (double) (i - 65536) / 100;
- } else {
- d = (double) i / 100;
- }
- d = ((double) Math.round(d * 10)) / 10;
- return d;
- }
- public static float hexStr2Float(String pStr) {
- return (float) (hexStr2Double(pStr));
- }
- public static int hexStr2Int(String pStr) {
- return Integer.parseInt(pStr, 16);
- }
- }
- package com.simpledraw.bluetooth.data;
- import java.text.DecimalFormat;
- import com.simpledraw.bluetoothservice.ConstantsEwins;
- public class Datagram {
- private float speed1;
- private float speed2;
- private float speed3;
- private float speed4;
- private float speed5;
- private float speed6;
- private int direction1;
- private int direction2;
- private float temperature;
- private int humidity;
- private float pressure;
- DecimalFormat df = new DecimalFormat(".00");
- public float getSpeed1() {
- return speed1;
- }
- public void setSpeed1(float speed1) {
- this.speed1 = speed1 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE
- : (speed1 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed1);
- }
- public float getSpeed2() {
- return speed2;
- }
- public void setSpeed2(float speed2) {
- this.speed2 = speed2 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE
- : (speed2 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed2);
- }
- public float getSpeed3() {
- return speed3;
- }
- public void setSpeed3(float speed3) {
- this.speed3 = speed3 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE
- : (speed3 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed3);
- }
- public float getSpeed4() {
- return speed4;
- }
- public void setSpeed4(float speed4) {
- this.speed4 = speed4 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE
- : (speed4 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed4);
- }
- public float getSpeed5() {
- return speed5;
- }
- public void setSpeed5(float speed5) {
- this.speed5 = speed5 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE
- : (speed5 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed5);
- }
- public float getSpeed6() {
- return speed6;
- }
- public void setSpeed6(float speed6) {
- this.speed6 = speed6 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE
- : (speed6 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed6);
- }
- public int getDirection1() {
- return direction1;
- }
- public void setDirection1(int direction1) {
- this.direction1 = direction1;
- }
- public int getDirection2() {
- return direction2;
- }
- public void setDirection2(int direction2) {
- this.direction2 = direction2;
- }
- public float getTemperature() {
- return temperature;
- }
- public void setTemperature(float temperature) {
- this.temperature = temperature > ConstantsEwins.MAX_TEMPERATURE_VALUE ? ConstantsEwins.MAX_TEMPERATURE_VALUE
- : (temperature < ConstantsEwins.MIN_TEMPERATURE_VALUE ? ConstantsEwins.MIN_TEMPERATURE_VALUE
- : temperature);
- }
- public int getHumidity() {
- return humidity;
- }
- public void setHumidity(int humidity) {
- this.humidity = humidity > 100 ? 100 : (humidity < 0 ? 0 : humidity);
- }
- public float getPressure() {
- return pressure;
- }
- public void setPressure(float pressure) {
- this.pressure = pressure > ConstantsEwins.MAX_PRESSURE_VALUE ? ConstantsEwins.MAX_PRESSURE_VALUE
- : (pressure < ConstantsEwins.MIN_PRESSURE_VALUE ? ConstantsEwins.MIN_PRESSURE_VALUE : pressure);
- }
- public void parseDatagram(String datagram) {
- // datagram = "01076954204231804B0A08072102C3046307F209";
- if (datagram == null || datagram == "") {
- System.out.println("kong");
- return;
- }
- setSpeed1(calcSpeed(datagram.substring(4, 6)));
- setSpeed2(calcSpeed(datagram.substring(6, 8)));
- setSpeed3(calcSpeed(datagram.substring(8, 10)));
- setSpeed4(calcSpeed(datagram.substring(10, 12)));
- setSpeed5(calcSpeed(datagram.substring(12, 14)));
- setSpeed6(calcSpeed(datagram.substring(14, 16)));
- setDirection1(calcDirection(datagram.substring(22, 24) + datagram.substring(20, 22)));
- setDirection2(calcDirection(datagram.substring(26, 28) + datagram.substring(24, 26)));
- setTemperature(calcTemperature(datagram.substring(30, 32) + datagram.substring(28, 30)));
- setHumidity(calcHumidity(datagram.substring(34, 36) + datagram.substring(32, 34)));
- setPressure(calcPressure(datagram.substring(38, 40) + datagram.substring(36, 38)));
- }
- private float calcSpeed(String pStrSpeedHex) {
- float speed = DataTypeConverter.hexStr2Int(pStrSpeedHex);
- return speed * 0.765f + 0.35f;
- }
- private int calcDirection(String pStrDirectionHex) {
- int direction = DataTypeConverter.hexStr2Int(pStrDirectionHex);
- return (int) (direction * 0.094230277);
- }
- private float calcTemperature(String pStrTempHex) {
- float temperature = DataTypeConverter.hexStr2Int(pStrTempHex);
- return (float) (temperature * 0.088695557 - 86.38);
- }
- private int calcHumidity(String pStrHumidityHex) {
- int humidity = DataTypeConverter.hexStr2Int(pStrHumidityHex);
- return (int) (humidity * 0.031933594);
- }
- private float calcPressure(String pStrPressureHex) {
- float pressure = DataTypeConverter.hexStr2Int(pStrPressureHex);
- return (float) (pressure * 0.03479165 + 10.55);
- }
- }
- package com.simpledraw.bluetooth;
- import java.util.Set;
- import android.app.Activity;
- import android.bluetooth.BluetoothAdapter;
- import android.bluetooth.BluetoothDevice;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.Window;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.ArrayAdapter;
- import android.widget.Button;
- import android.widget.ListView;
- import android.widget.TextView;
- import com.simpledraw.bluetooth.data.DataTypeConverter;
- import com.simpledraw.bluetoothservice.R;
- public class ScanBTDeviceActivity extends Activity {
- private Button btnScan = null;
- private ListView lvNewDevices, lvPairedDevices;
- private ArrayAdapter<String> adapterNewDevices, adapterPairedDevice;
- private BluetoothAdapter btAdapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // Setup the window
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
- setContentView(R.layout.device_list);
- findAllViews();
- btAdapter = BluetoothAdapter.getDefaultAdapter();
- if (btAdapter == null) {
- finish();
- return;
- }
- Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
- for (BluetoothDevice device : pairedDevices) {
- adapterPairedDevice.add(device.getName() + "\n" + device.getAddress());
- }
- IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
- registerReceiver(mReceiver, filter);
- filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- registerReceiver(mReceiver, filter);
- }
- private void findAllViews() {
- btnScan = (Button) findViewById(R.id.btnScan);
- lvNewDevices = (ListView) findViewById(R.id.lvNewDevices);
- adapterNewDevices = new ArrayAdapter<String>(ScanBTDeviceActivity.this, android.R.layout.simple_list_item_1);
- lvNewDevices.setAdapter(adapterNewDevices);
- lvNewDevices.setOnItemClickListener(DeviceListClickListener);
- lvPairedDevices = (ListView) findViewById(R.id.lvPairedDevices);
- adapterPairedDevice = new ArrayAdapter<String>(ScanBTDeviceActivity.this, android.R.layout.simple_list_item_1);
- lvPairedDevices.setAdapter(adapterPairedDevice);
- lvPairedDevices.setOnItemClickListener(DeviceListClickListener);
- btnScan.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- discoverDevices();
- }
- });
- }
- private void discoverDevices() {
- btnScan.setEnabled(false);
- setTitle(R.string.scanning);
- if (btAdapter.isDiscovering()) {
- btAdapter.cancelDiscovery();
- }
- btAdapter.startDiscovery();
- }
- private OnItemClickListener DeviceListClickListener = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
- btAdapter.cancelDiscovery();
- String address = DataTypeConverter.getMacAddress(((TextView) arg1).getText().toString());
- Intent intent = new Intent();
- intent.putExtra(ConstantsBluetooth.DEVICE_ADDRESS, address);
- setResult(RESULT_OK, intent);
- finish();
- }
- };
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (btAdapter != null) {
- btAdapter.cancelDiscovery();
- }
- unregisterReceiver(mReceiver);
- };
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (BluetoothDevice.ACTION_FOUND.equals(action)) {
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- if (device.getBondState() != BluetoothDevice.BOND_BONDED)
- adapterNewDevices.add(device.getName() + "\n" + device.getAddress());
- } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
- btnScan.setEnabled(true);
- setTitle(R.string.select_device);
- }
- }
- };
- }
- package com.simpledraw.bluetooth;
- import java.util.UUID;
- public class ConstantsBluetooth {
- public static final int REQUEST_CONNECT_DEVICE = 1;
- public static final String DEVICE_ADDRESS = "deviceaddress";
- public static final String CONNECTED_DEVICE_NAME = "connecteddevicename";
- public static final String SERVER_NAME = "BluetoothComm";
- public static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
- public static final int MESSAGE_STATE_CHANGE = 1;
- public static final int MESSAGE_READ = 2;
- public static final int MESSAGE_WRITE = 3;
- public static final int MESSAGE_DEVICE_NAME = 4;
- public static final int STATE_NONE = 0; // do nothing
- public static final int STATE_LISTEN = 1; // 监听连接
- public static final int STATE_CONNECTING = 2; // now initiating an outgoing
- public static final int STATE_CONNECTED = 3; // 已连接上远程设备
- public static final String CONNECTION_FAILED = "fail";
- public static final String CONNECTION_LOST = "lost";
- public static final String CONNECTION_CONNECTED = "connected";
- public static final String COMMAND_1 = "uLPCC_0000CD?";
- public static final byte[] COMMAND_ACK = new byte[] { (byte) 0x06 };
- }
- package com.simpledraw.bluetooth;
- public class BluetoothEnvironment {
- public static BluetoothCommService service;
- }
- package com.simpledraw.bluetooth;
- import java.io.BufferedInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.Serializable;
- import java.util.UUID;
- import android.annotation.SuppressLint;
- import android.bluetooth.BluetoothAdapter;
- import android.bluetooth.BluetoothDevice;
- import android.bluetooth.BluetoothServerSocket;
- import android.bluetooth.BluetoothSocket;
- import android.content.Context;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.widget.Toast;
- public class BluetoothCommService implements Serializable {
- private static final long serialVersionUID = 1L;
- private static final String NAME = "BluetoothComm";
- // SPP协议UUID
- private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
- // Member fields
- private final BluetoothAdapter mAdapter;
- private Handler mHandler, receiveHandler;
- private int mState;
- private AcceptThread mAcceptThread;
- private ConnectThread mConnectThread;
- private ConnectedThread mConnectedThread;
- public BluetoothCommService(Context context, Handler handler, Handler p_receiveHandler) {
- mAdapter = BluetoothAdapter.getDefaultAdapter();
- mHandler = handler;
- receiveHandler = p_receiveHandler;
- mState = ConstantsBluetooth.STATE_NONE;
- }
- public void setHandler(Handler pHandler, Handler p_receiveHandler) {
- mHandler = pHandler;
- receiveHandler = p_receiveHandler;
- }
- /**
- * Set the current state of the chat connection
- *
- * @param state
- * An integer defining the current connection state
- */
- private synchronized void setState(int state) {
- mState = state;
- mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
- }
- /**
- * Return the current connection state.
- */
- public synchronized int getState() {
- return mState;
- }
- /**
- * 开始服务,主要是开始AcceptThread线程,打开一个监听回话由BaowenActivity的onResume方法调用,
- * ***开启监听线程****
- */
- public synchronized void start() {
- // 取消所有正在尝试连接的线程
- if (mConnectThread != null) {
- mConnectThread.cancel();
- mConnectThread = null;
- }
- // 取消所有已经连接上的线程
- if (mConnectedThread != null) {
- mConnectedThread.cancel();
- mConnectedThread = null;
- }
- // 打开一个监听BluetoothServerSocket的线程
- if (mAcceptThread == null) {
- mAcceptThread = new AcceptThread();
- mAcceptThread.start();// 开启监听线程
- }
- setState(ConstantsBluetooth.STATE_LISTEN);
- }
- /**
- * Start the ConnectThread to initiate a connection to a remote device.
- *
- * @param device
- * The BluetoothDevice to connect
- */
- public synchronized void connect(BluetoothDevice device) {
- // Cancel any thread attempting to make a connection
- if (mState == ConstantsBluetooth.STATE_CONNECTING) {// 正在连接状态״̬
- if (mConnectThread != null) {// 有ConnectThread,结束
- mConnectThread.cancel();
- mConnectThread = null;
- }
- }
- // Cancel any thread currently running a connection
- if (mConnectedThread != null) {// 有处于连接中的线程,结束
- mConnectedThread.cancel();
- mConnectedThread = null;
- }
- // Start the thread to connect with the given device
- mConnectThread = new ConnectThread(device);
- mConnectThread.start();// 开启新的连接请求线程
- setState(ConstantsBluetooth.STATE_CONNECTING);
- }
- /**
- * Start the ConnectedThread to begin managing a Bluetooth connection
- *
- * @param socket
- * The BluetoothSocket on which the connection was made
- * @param device
- * The BluetoothDevice that has been connected
- */
- public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
- // Cancel the thread that completed the connection
- if (mConnectThread != null) {
- mConnectThread.cancel();
- mConnectThread = null;
- }
- // Cancel any thread currently running a connection
- if (mConnectedThread != null) {
- mConnectedThread.cancel();
- mConnectedThread = null;
- }
- // Cancel the accept thread because we only want to connect to one
- // device
- if (mAcceptThread != null) {
- mAcceptThread.cancel();
- mAcceptThread = null;
- }
- // Start the thread to manage the connection and perform transmissions
- mConnectedThread = new ConnectedThread(socket);
- mConnectedThread.start();// 和客户端开始通信
- // 把已连接的设备的名称发给UI线程
- Message msg = mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_STATE_CHANGE);
- msg.arg1 = ConstantsBluetooth.STATE_CONNECTED;
- msg.obj = device.getName();
- mHandler.sendMessage(msg);
- mState = ConstantsBluetooth.STATE_CONNECTED;
- }
- /**
- * Stop all threads
- */
- public synchronized void stop() {
- if (mConnectThread != null) {
- mConnectThread.cancel();
- mConnectThread = null;
- }
- if (mConnectedThread != null) {
- mConnectedThread.cancel();
- mConnectedThread = null;
- }
- if (mAcceptThread != null) {
- mAcceptThread.cancel();
- mAcceptThread = null;
- }
- setState(ConstantsBluetooth.STATE_NONE);
- }
- /**
- * Write to the ConnectedThread in an unsynchronized manner
- *
- * @param out
- * The bytes to write
- * @see ConnectedThread#write(byte[])
- */
- public void write(byte[] out) {
- // Create temporary object
- ConnectedThread r;
- // Synchronize a copy of the ConnectedThread
- synchronized (this) {
- if (mState != ConstantsBluetooth.STATE_CONNECTED)
- return;
- r = mConnectedThread;// 得到连接线程
- }
- // Perform the write unsynchronized
- r.write(out);
- }
- /**
- * Indicate that the connection attempt failed and notify the UI Activity.
- */
- private void connectionFailed() {
- setState(ConstantsBluetooth.STATE_LISTEN);
- // // Send a failure message back to the Activity
- Message msg = mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_STATE_CHANGE);
- msg.obj = "fail";
- mHandler.sendMessage(msg);
- }
- /**
- * Indicate that the connection was lost and notify the UI Activity.
- */
- @SuppressWarnings("unused")
- private void connectionLost() {
- setState(ConstantsBluetooth.STATE_LISTEN);
- // Send a failure message back to the Activity
- Message msg = mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_STATE_CHANGE);
- msg.obj = "lost";
- mHandler.sendMessage(msg);
- }
- /**
- * This thread runs while listening for incoming connections. It behaves
- * like a server-side client. It runs until a connection is accepted (or
- * until cancelled). 监听准备进入的连接,类似于服务端,
- */
- private class AcceptThread extends Thread {
- // 本地的socket
- private final BluetoothServerSocket mmServerSocket;
- public AcceptThread() {
- BluetoothServerSocket tmp = null;
- // 创建一个新的监听服务器socket
- try {
- // 根据名称,UUID创建并返回BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步
- tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, SPP_UUID);
- } catch (IOException e) {
- }
- // 得到BluetoothServerSocket对象
- mmServerSocket = tmp;
- }
- public void run() {
- setName("AcceptThread");// set the name of thread
- BluetoothSocket socket = null;
- // Listen to the server socket if we're not connected
- while (mState != ConstantsBluetooth.STATE_CONNECTED) {// 若没有连接,一直执行
- try {
- // 注意:BluetoothServerSocket的accept是一个阻塞性线程,一直到用户成功的配对,因此不要放在Activity中,
- // 远程蓝牙设备请求跟本设备建立连接请求时,
- // BluetoothServerSocket会在连接被接收时返回一个被连接的BluetoothSocket对象。
- socket = mmServerSocket.accept();
- } catch (IOException e) {
- break;
- }
- // 连接建立成功
- if (socket != null) {
- synchronized (BluetoothCommService.this) {
- switch (mState) {
- case ConstantsBluetooth.STATE_LISTEN:
- case ConstantsBluetooth.STATE_CONNECTING:
- // 已经连接上,开始ConnectedThread线程
- connected(socket, socket.getRemoteDevice());
- break;
- case ConstantsBluetooth.STATE_NONE:
- case ConstantsBluetooth.STATE_CONNECTED:
- // 或者设备没有准备好,或者已经连接,都将这个新的BluetoothSocket关掉
- // 释放服务套接字,但不会关闭accept()返回的BluetoothSocket
- try {
- socket.close();
- } catch (IOException e) {
- }
- break;
- }
- }
- }
- }
- }
- public void cancel() {
- try {
- mmServerSocket.close();
- } catch (IOException e) {
- }
- }
- }
- /**
- * This thread runs while attempting to make an outgoing connection with a
- * device. It runs straight through; the connection either succeeds or
- * fails. 监听准备出去的连接
- */
- private class ConnectThread extends Thread {
- private final BluetoothSocket mmSocket;
- private final BluetoothDevice mmDevice;// 远程设备
- public ConnectThread(BluetoothDevice device) {
- mmDevice = device;
- BluetoothSocket tmp = null;
- // Get a BluetoothSocket for a connection with the
- // given BluetoothDevice
- try {
- // 通过远程设备直接创建一个BluetoothSocket,要求该设备已经打开了BluetoothServerSocket获得一个BluetoothSocket对象
- tmp = device.createRfcommSocketToServiceRecord(SPP_UUID);
- } catch (IOException e) {
- }
- mmSocket = tmp;
- }
- public void run() {
- setName("ConnectThread");
- // 取消搜索
- mAdapter.cancelDiscovery();
- // Make a connection to the BluetoothSocket
- try {
- // This is a blocking call and will only return on a
- // successful connection or an exception
- mmSocket.connect();
- } catch (IOException e) {
- connectionFailed();
- // Close the socket
- try {
- mmSocket.close();
- } catch (IOException e2) {
- }
- // Start the service over to restart listening mode
- BluetoothCommService.this.start();
- return;
- }
- // Reset the ConnectThread because we're done
- synchronized (BluetoothCommService.this) {
- mConnectThread = null;
- }
- // Start the connected thread,已连接上,管理连接
- connected(mmSocket, mmDevice);
- }
- public void cancel() {
- try {
- mmSocket.close();
- } catch (IOException e) {
- }
- }
- }
- /**
- * This thread runs during a connection with a remote device. It handles all
- * incoming and outgoing transmissions. 监听
- */
- private class ConnectedThread extends Thread {
- private final BluetoothSocket mmSocket;
- private final OutputStream mmOutStream;
- private final BufferedInputStream reader;
- public ConnectedThread(BluetoothSocket socket) {
- mmSocket = socket;
- InputStream tmpIn = null;
- OutputStream tmpOut = null;
- // Get the BluetoothSocket input and output streams
- try {
- tmpIn = socket.getInputStream();
- tmpOut = socket.getOutputStream();
- } catch (IOException e) {
- }
- reader = new BufferedInputStream(tmpIn);
- mmOutStream = tmpOut;
- }
- private String dataStr = "";
- @SuppressLint("NewApi")
- public void run() {
- byte[] buffer = new byte[44], temp = new byte[127];
- StringBuffer sb;
- String b;
- int numReadedBytes;
- boolean cleaning = true;
- long startTime = System.currentTimeMillis();
- // 保持对InputStream的监听
- while (true) {
- try {
- // if (cleaning) {
- if (System.currentTimeMillis() - startTime < 2000) {
- //
- //
- //
- // numReadedBytes = reader.read(temp);
- // // System.out.println("cleaning:" + numReadedBytes);
- // continue;
- } else
- cleaning = false;
- // }
- numReadedBytes = reader.read(buffer);//temp
- String tempStr = new String(buffer);//temp write to log
- tempStr.replace("\r\n", "***");
- String[] strs = tempStr.split("\r\n");
- // System.out.println("numReaded0:" + numReadedBytes);
- Log.d("texts",tempStr);
- sb = new StringBuffer();
- // for (int i = 0; i < numReadedBytes; i++) {
- // b = Integer.toHexString(buffer[i] & 0xFF);
- // if (b.length() < 2)
- // sb.append("0");
- // sb.append(b);
- // }
- mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_READ, numReadedBytes, 0, new String(buffer))
- .sendToTarget();
- buffer = new byte[44];
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * Write to the connected OutStream.
- *
- * @param buffer
- * The bytes to write
- */
- public void write(byte[] buffer) {
- try {
- mmOutStream.write(buffer);
- mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
- } catch (IOException e) {
- e.printStackTrace();
- Log.i("texts", "数据流写入失败");
- }
- }
- public void cancel() {
- try {
- mmSocket.close();
- } catch (IOException e) {
- }
- }
- }
- }
OK,,,这样我所以项目都贴到上面了,,因为个人原因,不能贴项目源码,,但是改了一个项目,,亲测可用,,
我们要重点注意这里
MainActivity.java:
- ((Button)findViewById(R.id.btn1)).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- executStr = ((Button)v).getText().toString();
- output_edit.setText("");
- executStr+="\r\n";
- BluetoothEnvironment.service.write(executStr.getBytes());
- output_edit.setText(executStr);
- }
- });
这段是真实向下位机写数据,,如果你项目非常紧急,建议直接找到此处,修改这里,还有类似位置,然后我们在看看S端Return的值:
MainActivity.java:
- case ConstantsBluetooth.MESSAGE_READ:
- if (firstReceived)
- lastReadTime = System.currentTimeMillis();
- firstReceived = false;
- if (System.currentTimeMillis() - lastReadTime > ConstantsEwins.DATAGRAM_INTERVAL) {
- if (length == ConstantsEwins.DATAGRAM_BYTES_LENGTH) {
- datagram.parseDatagram(sb.toString());
- modifyViews();
- }
- sb = new StringBuffer(ConstantsEwins.DATA_LENGTH);
- length = 0;
- }
- String data = (String) msg.obj;
- System.out.println("接收到的数据:" + data);
- Log.e("texts",data);
- length += msg.arg1;
- sb.append(data);
- lastReadTime = System.currentTimeMillis();
- input_edit.setText(data);//sb.toString()
- break;
以上即可与下位机交互,,,图片资源请自行寻找,,懒得贴了,,不做伸手党!!!