您的位置:首页 > 移动开发 > Android开发

android蓝牙与下位机交互

2015-06-03 10:47 423 查看
最近在做一个项目,是蓝牙与下位机进行交互,只是简单的数据交互,使用蓝牙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入手书写代码:

主界面:

[html] view
plaincopy

<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>

搜索蓝牙布局界面:

[html] view
plaincopy

<?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>

开始代码:

[java] view
plaincopy

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);

}

}

[java] view
plaincopy

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();

}

}

[java] view
plaincopy

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;

}

[java] view
plaincopy

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);

}

}

[java] view
plaincopy

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);

}

}

[html] view
plaincopy

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);

}

}

};

}

[java] view
plaincopy

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 };

}

[java] view
plaincopy

package com.simpledraw.bluetooth;

public class BluetoothEnvironment {

public static BluetoothCommService service;

}

[java] view
plaincopy

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:

[java] view
plaincopy

((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:

[java] view
plaincopy

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;

以上即可与下位机交互,,,图片资源请自行寻找,,懒得贴了,,不做伸手党!!!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: