android蓝牙与下位机交互

来源:互联网 发布:淘宝宁美国度 编辑:程序博客网 时间:2024/05/01 06:13

最近在做一个项目,是蓝牙与下位机进行交互,只是简单的数据交互,使用蓝牙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
  1. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <LinearLayout  
  7.         android:layout_width="match_parent"  
  8.         android:layout_height="wrap_content"  
  9.         android:orientation="vertical" >  
  10.   
  11.         <ImageButton  
  12.             android:id="@+id/btnOpenBT"  
  13.             android:layout_width="60dp"  
  14.             android:layout_height="60dp"  
  15.             android:background="@drawable/bluetooth_off" />  
  16.   
  17.         <LinearLayout  
  18.             android:layout_width="wrap_content"  
  19.             android:layout_height="wrap_content"  
  20.             android:orientation="horizontal" >  
  21.   
  22.             <TextView  
  23.                 android:id="@+id/tvDeviceName"  
  24.                 android:layout_width="0dp"  
  25.                 android:layout_height="wrap_content"  
  26.                 android:layout_weight="1"  
  27.                 android:gravity="right"  
  28.                 android:text="Bluetooth"  
  29.                 android:textSize="14sp" />  
  30.         </LinearLayout>  
  31.   
  32.         <TextView  
  33.             android:layout_width="fill_parent"  
  34.             android:layout_height="wrap_content"  
  35.             android:layout_marginTop="30dp"  
  36.             android:text="写入测试" />  
  37.   
  38.         <EditText  
  39.             android:id="@+id/output_test"  
  40.             android:layout_width="fill_parent"  
  41.             android:layout_height="wrap_content" />  
  42.   
  43.         <TextView  
  44.             android:layout_width="fill_parent"  
  45.             android:layout_height="wrap_content"  
  46.             android:text="数据回显测试" />  
  47.   
  48.         <TextView  
  49.             android:id="@+id/input_test"  
  50.             android:layout_width="fill_parent"  
  51.             android:textSize="14sp"  
  52.             android:layout_height="30dp" />  
  53.   
  54.         <Button  
  55.             android:id="@+id/start_test"  
  56.             android:layout_width="fill_parent"  
  57.             android:layout_height="wrap_content"  
  58.             android:text="开始测试" />  
  59.   
  60.         <Button  
  61.             android:id="@+id/btn1"  
  62.             android:layout_width="fill_parent"  
  63.             android:layout_height="wrap_content"  
  64.             android:text="pump on" />  
  65.   
  66.         <Button  
  67.             android:id="@+id/btn2"  
  68.             android:layout_width="fill_parent"  
  69.             android:layout_height="wrap_content"  
  70.             android:text="pump off" />  
  71.   
  72.         <Button  
  73.             android:id="@+id/btn3"  
  74.             android:layout_width="fill_parent"  
  75.             android:layout_height="wrap_content"  
  76.             android:text="detector pid_fid" />  
  77.   
  78.         <Button  
  79.             android:id="@+id/btn4"  
  80.             android:layout_width="fill_parent"  
  81.             android:layout_height="wrap_content"  
  82.             android:text="ignite" />  
  83.     </LinearLayout>  
  84.   
  85. </ScrollView>  
搜索蓝牙布局界面:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <TextView  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="@string/newdevice" />  
  11.   
  12.     <ListView  
  13.         android:id="@+id/lvNewDevices"  
  14.         android:layout_width="match_parent"  
  15.         android:layout_height="wrap_content"  
  16.         android:layout_weight="2"  
  17.         android:stackFromBottom="true" >  
  18.     </ListView>  
  19.   
  20.     <TextView  
  21.         android:layout_width="match_parent"  
  22.         android:layout_height="wrap_content"  
  23.         android:text="@string/paireddevice" />  
  24.   
  25.     <ListView  
  26.         android:id="@+id/lvPairedDevices"  
  27.         android:layout_width="match_parent"  
  28.         android:layout_height="wrap_content"  
  29.         android:layout_weight="2"  
  30.         android:stackFromBottom="true" >  
  31.     </ListView>  
  32.   
  33.     <Button  
  34.         android:id="@+id/btnScan"  
  35.         android:layout_width="match_parent"  
  36.         android:layout_height="wrap_content"  
  37.         android:text="@string/scan" />  
  38.   
  39. </LinearLayout>  

开始代码:

[java] view plaincopy
  1. package com.simpledraw.bluetoothservice;  
  2.   
  3. import java.text.DecimalFormat;  
  4.   
  5. import android.annotation.SuppressLint;  
  6. import android.app.Activity;  
  7. import android.bluetooth.BluetoothAdapter;  
  8. import android.bluetooth.BluetoothDevice;  
  9. import android.content.Intent;  
  10. import android.os.Bundle;  
  11. import android.os.Handler;  
  12. import android.util.Log;  
  13. import android.view.KeyEvent;  
  14. import android.view.Menu;  
  15. import android.view.MenuItem;  
  16. import android.view.View;  
  17. import android.view.View.OnClickListener;  
  18. import android.view.animation.Animation;  
  19. import android.view.animation.RotateAnimation;  
  20. import android.view.animation.ScaleAnimation;  
  21. import android.widget.Button;  
  22. import android.widget.EditText;  
  23. import android.widget.ImageButton;  
  24. import android.widget.TextView;  
  25. import android.widget.Toast;  
  26.   
  27. import com.simpledraw.bluetooth.BluetoothCommService;  
  28. import com.simpledraw.bluetooth.BluetoothEnvironment;  
  29. import com.simpledraw.bluetooth.ConstantsBluetooth;  
  30. import com.simpledraw.bluetooth.ScanBTDeviceActivity;  
  31. import com.simpledraw.bluetooth.data.Datagram;  
  32.   
  33. public class MainActivity extends Activity {  
  34.   
  35.     private TextView tvDirection1, tvDirection2;  
  36.     private ScaleAnimation animTemperature, animHumidity;  
  37.     private RotateAnimation animPressure;  
  38.     private float currentDirection1 = 0, currentDirection2 = 0, currentTemperature = ConstantsEwins.MIN_TEMPERATURE_Y,  
  39.             currentHumidity = 0.0f, currentPressure = 0;  
  40.     DecimalFormat df = new DecimalFormat("0.00");  
  41.   
  42.     private ImageButton btnOpenBT = null;  
  43.     private TextView tvDeviceName = null;  
  44.   
  45.     private Datagram datagram = new Datagram();  
  46.     private BluetoothAdapter btAdapter;  
  47.     private BluetoothDevice mDevice;  
  48.   
  49.     private int[] checked = new int[11];  
  50.   
  51.     private long exitTime = 0;// 用于再按一次退出  
  52.       
  53.     private String executStr = "";  
  54.       
  55.     @SuppressLint("NewApi")  
  56.     @Override  
  57.     protected void onCreate(Bundle savedInstanceState) {  
  58.         super.onCreate(savedInstanceState);  
  59.         setContentView(R.layout.activity_main);  
  60.   
  61.         getBluetoothAdapter();  
  62.   
  63.         findAllControls();  
  64.   
  65.     }  
  66.       
  67.     private EditText output_edit;  
  68.     private TextView input_edit;  
  69.       
  70.     private Button startTest;  
  71.       
  72.     private void findAllControls() {  
  73.           
  74.           
  75.         output_edit = (EditText) findViewById(R.id.output_test);  
  76.         input_edit = (TextView) findViewById(R.id.input_test);  
  77.           
  78.         startTest = (Button) findViewById(R.id.start_test);  
  79.           
  80.         ((Button)findViewById(R.id.btn1)).setOnClickListener(new OnClickListener() {  
  81.             @Override  
  82.             public void onClick(View v) {  
  83.                 executStr = ((Button)v).getText().toString();  
  84.                 output_edit.setText("");  
  85.                 executStr+="\r\n";  
  86.                 BluetoothEnvironment.service.write(executStr.getBytes());  
  87.                 output_edit.setText(executStr);  
  88.             }  
  89.         });  
  90.         ((Button)findViewById(R.id.btn2)).setOnClickListener(new OnClickListener() {  
  91.             @Override  
  92.             public void onClick(View v) {  
  93.                 executStr = ((Button)v).getText().toString();  
  94.                 output_edit.setText(executStr);  
  95.                 output_edit.setText("");  
  96.                 executStr+="\r\n";  
  97.                 BluetoothEnvironment.service.write(executStr.getBytes());  
  98.             }  
  99.         });  
  100.         ((Button)findViewById(R.id.btn3)).setOnClickListener(new OnClickListener() {  
  101.             @Override  
  102.             public void onClick(View v) {  
  103.                 executStr = ((Button)v).getText().toString();  
  104.                 output_edit.setText(executStr);  
  105.                 output_edit.setText("");  
  106.                 executStr="log start\r\n";  
  107.                 BluetoothEnvironment.service.write(executStr.getBytes());  
  108.                 executStr="detector pid_fid\r\n";  
  109.                 BluetoothEnvironment.service.write(executStr.getBytes());  
  110.             }  
  111.         });  
  112.         ((Button)findViewById(R.id.btn4)).setOnClickListener(new OnClickListener() {  
  113.             @Override  
  114.             public void onClick(View v) {  
  115.                 executStr = ((Button)v).getText().toString();  
  116.                 output_edit.setText(executStr);  
  117.                 output_edit.setText("");  
  118.                 executStr+="\r\n";  
  119.                 BluetoothEnvironment.service.write(executStr.getBytes());  
  120.                   
  121.             }  
  122.         });  
  123.           
  124.         startTest.setOnClickListener(new OnClickListener() {  
  125.             @Override  
  126.             public void onClick(View arg0) {  
  127.                 if(BluetoothEnvironment.service!=null){  
  128.                     output_edit.setText("");  
  129. //                  String outputData = output_edit.getText().toString();  
  130.                     executStr+="\r\n";  
  131. //                  byte[] bytes = outputData.getBytes();  
  132. //                  byte[] bytes2 = new byte[bytes.length+2];  
  133. //                  for(int i = 0;i<bytes.length;i++){  
  134. //                      bytes2[i] = bytes[i];  
  135. //                  }  
  136. //                  bytes2[bytes2.length-2] = 13;  
  137. //                  bytes2[bytes2.length-1] = 10;  
  138.                     BluetoothEnvironment.service.write(executStr.getBytes());  
  139.                 }  
  140.             }  
  141.         });  
  142.           
  143.           
  144.   
  145.         btnOpenBT = (ImageButton) findViewById(R.id.btnOpenBT);  
  146.         btnOpenBT.setOnClickListener(new OnClickListener() {  
  147.             @Override  
  148.             public void onClick(View arg0) {  
  149.                 Intent intent = new Intent(MainActivity.this, ScanBTDeviceActivity.class);  
  150.                 startActivityForResult(intent, ConstantsBluetooth.REQUEST_CONNECT_DEVICE);  
  151.             }  
  152.         });  
  153.         tvDeviceName = (TextView) findViewById(R.id.tvDeviceName);  
  154.   
  155.         for (int i = 0; i < 11; i++)  
  156.             checked[i] = View.VISIBLE;  
  157.     }  
  158.   
  159.   
  160.     private void getBluetoothAdapter() {  
  161.         btAdapter = BluetoothAdapter.getDefaultAdapter();  
  162.         if (btAdapter == null) {  
  163.             Toast.makeText(MainActivity.this"本设备不支持蓝牙", Toast.LENGTH_SHORT).show();  
  164.             finish();  
  165.             return;  
  166.         }  
  167.         while (!btAdapter.isEnabled()) {  
  168.             if (btAdapter.enable()) {  
  169.                 Toast.makeText(MainActivity.this"蓝牙已经启动", Toast.LENGTH_SHORT).show();  
  170.                 break;  
  171.             } else {  
  172.                 Toast.makeText(MainActivity.this"蓝牙启动失败", Toast.LENGTH_SHORT).show();  
  173.                 return;  
  174.             }  
  175.         }  
  176.         if (btAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {  
  177.             Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);  
  178.             intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);  
  179.             startActivity(intent);  
  180.         }  
  181.     }  
  182.   
  183.     @Override  
  184.     public boolean onCreateOptionsMenu(Menu menu) {  
  185.         menu.add(010, R.string.tianjiachuanganqi);  
  186.         return true;  
  187.     }  
  188.   
  189.     @Override  
  190.     public boolean onOptionsItemSelected(MenuItem item) {  
  191.         if (item.getOrder() == 0) {  
  192.             Intent intent = new Intent(MainActivity.this, AddDeleteSensorsActivity.class);  
  193.             intent.putExtra("checked", checked);  
  194.             startActivityForResult(intent, ConstantsEwins.REQUEST_ADDDELETE_SENSORS);  
  195.         }  
  196.         return super.onOptionsItemSelected(item);  
  197.     }  
  198.   
  199.     @Override  
  200.     protected void onResume() {  
  201.         System.out.println("------- ON RESUME ---------");  
  202.         super.onResume();  
  203.         if (BluetoothEnvironment.service != null) {  
  204.             if (btAdapter.isEnabled() && BluetoothEnvironment.service.getState() == ConstantsBluetooth.STATE_NONE) {  
  205.                 BluetoothEnvironment.service.start();  
  206.             }  
  207.             BluetoothEnvironment.service.setHandler(mHandler, null);  
  208.         } else {  
  209.             BluetoothEnvironment.service = new BluetoothCommService(this, mHandler, null);  
  210.         }  
  211.     }  
  212.   
  213.     @Override  
  214.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  215.         super.onActivityResult(requestCode, resultCode, data);  
  216.         switch (requestCode) {  
  217.         case ConstantsBluetooth.REQUEST_CONNECT_DEVICE:  
  218.             if (resultCode == RESULT_OK) {  
  219.                 String address = data.getExtras().getString(ConstantsBluetooth.DEVICE_ADDRESS);  
  220.                 mDevice = btAdapter.getRemoteDevice(address);  
  221.                 if (mDevice == null)  
  222.                     return;  
  223.                 if (BluetoothEnvironment.service != null)  
  224.                     BluetoothEnvironment.service.connect(mDevice);  
  225.             }  
  226.             break;  
  227.         case ConstantsEwins.REQUEST_ADDDELETE_SENSORS:  
  228.             if (resultCode == RESULT_OK) {  
  229.             }  
  230.             break;  
  231.         default:  
  232.             break;  
  233.         }  
  234.     }  
  235.   
  236.     @SuppressLint("HandlerLeak")  
  237.     private final Handler mHandler = new Handler() {  
  238.         int length = 0;  
  239.         boolean firstReceived = true;  
  240.         long lastReadTime = System.currentTimeMillis();  
  241.         StringBuffer sb = new StringBuffer(ConstantsEwins.DATA_LENGTH);  
  242.   
  243.         @Override  
  244.         public void handleMessage(android.os.Message msg) {  
  245.             switch (msg.what) {  
  246.             case ConstantsBluetooth.MESSAGE_STATE_CHANGE:  
  247.                 switch (msg.arg1) {  
  248.                 case ConstantsBluetooth.STATE_CONNECTED:  
  249.                     Toast.makeText(MainActivity.this"已连接至" + msg.obj + "!!fdasfds", Toast.LENGTH_SHORT).show();  
  250.                     tvDeviceName.setText((String) msg.obj);  
  251.                     btnOpenBT.setBackgroundResource(R.drawable.bluetooth_on);  
  252.                     break;  
  253.                 case ConstantsBluetooth.STATE_CONNECTING:  
  254.                     Toast.makeText(MainActivity.this"正在连接,请稍候", Toast.LENGTH_LONG).show();  
  255.                     break;  
  256.                 case ConstantsBluetooth.STATE_LISTEN:  
  257.                     if (ConstantsBluetooth.CONNECTION_FAILED.equals(msg.obj)) {  
  258.                         Toast.makeText(MainActivity.this"连接不成功", Toast.LENGTH_SHORT).show();  
  259.                         btnOpenBT.setBackgroundResource(R.drawable.bluetooth_off);  
  260.                     } else if (ConstantsBluetooth.CONNECTION_LOST.equals(msg.obj)) {  
  261.                         Toast.makeText(MainActivity.this"连接丢失", Toast.LENGTH_SHORT).show();  
  262.                         btnOpenBT.setBackgroundResource(R.drawable.bluetooth_off);  
  263.                     }  
  264.                     break;  
  265.                 case ConstantsBluetooth.STATE_NONE:  
  266.                     btnOpenBT.setBackgroundResource(R.drawable.bluetooth_off);  
  267.                     break;  
  268.                 }  
  269.                 break;  
  270.             case ConstantsBluetooth.MESSAGE_WRITE:  
  271.                 break;  
  272.             case ConstantsBluetooth.MESSAGE_READ:  
  273.                 if (firstReceived)  
  274.                     lastReadTime = System.currentTimeMillis();  
  275.                 firstReceived = false;  
  276.   
  277.                 if (System.currentTimeMillis() - lastReadTime > ConstantsEwins.DATAGRAM_INTERVAL) {  
  278.                     if (length == ConstantsEwins.DATAGRAM_BYTES_LENGTH) {  
  279.                         datagram.parseDatagram(sb.toString());  
  280.                         modifyViews();  
  281.                     }  
  282.                     sb = new StringBuffer(ConstantsEwins.DATA_LENGTH);  
  283.                     length = 0;  
  284.                 }  
  285.   
  286.                 String data = (String) msg.obj;  
  287.                 System.out.println("接收到的数据:" + data);  
  288.                 Log.e("texts",data);  
  289.                 length += msg.arg1;  
  290.                 sb.append(data);  
  291.                 lastReadTime = System.currentTimeMillis();  
  292.                 input_edit.setText(data);//sb.toString()  
  293.                 break;  
  294.             }  
  295.         }  
  296.     };  
  297.   
  298.     @SuppressLint("NewApi")  
  299.     private void modifyViews() {  
  300.         tvDirection1.setText("风向1: " + (datagram.getDirection1() - (datagram.getDirection1() / 360) * 360) + "°");  
  301.         tvDirection2.setText("风向2: " + (datagram.getDirection2() - (datagram.getDirection2() / 360) * 360) + "°");  
  302.   
  303.         // 风速改变  
  304.         long newDuration;  
  305.         newDuration = calcSpeedDuration(datagram.getSpeed1());  
  306.         newDuration = calcSpeedDuration(datagram.getSpeed2());  
  307.         newDuration = calcSpeedDuration(datagram.getSpeed3());  
  308.         newDuration = calcSpeedDuration(datagram.getSpeed4());  
  309.         newDuration = calcSpeedDuration(datagram.getSpeed5());  
  310.         newDuration = calcSpeedDuration(datagram.getSpeed6());  
  311.           
  312.         currentDirection1 = datagram.getDirection1();  
  313.         currentDirection2 = datagram.getDirection2();  
  314.   
  315.         // 温度、湿度和气压  
  316.         float newTemperature = (datagram.getTemperature() - ConstantsEwins.MIN_TEMPERATURE_VALUE)  
  317.                 * ConstantsEwins.TEMPERATURE_STEP + ConstantsEwins.MIN_TEMPERATURE_Y;  
  318.         float newHumidity = datagram.getHumidity() * ConstantsEwins.HUMIDITY_STEP + ConstantsEwins.MIN_HUMIDITY_Y;  
  319.         float newPressure = (datagram.getPressure() - ConstantsEwins.MIN_PRESSURE_VALUE) * ConstantsEwins.PRESSURE_STEP;  
  320.   
  321.         animTemperature = new ScaleAnimation(1.0f, 1.0f, currentTemperature, newTemperature,  
  322.                 Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.8f);  
  323.         animTemperature.setDuration(500);  
  324.         animTemperature.setFillAfter(true);  
  325.   
  326.         animHumidity = new ScaleAnimation(1.0f, 1.0f, currentHumidity, newHumidity, Animation.RELATIVE_TO_SELF, 0,  
  327.                 Animation.RELATIVE_TO_SELF, 0.8f);  
  328.         animHumidity.setDuration(500);  
  329.         animHumidity.setFillAfter(true);  
  330.   
  331.         animPressure = new RotateAnimation(currentPressure, newPressure, Animation.RELATIVE_TO_SELF, 0.5f,  
  332.                 Animation.RELATIVE_TO_SELF, 0.5f);  
  333.         animPressure.setDuration(500);  
  334.         animPressure.setFillAfter(true);  
  335.           
  336.         currentTemperature = newTemperature;  
  337.         currentHumidity = newHumidity;  
  338.         currentPressure = newPressure;  
  339.   
  340.     }  
  341.   
  342.     private long calcSpeedDuration(float speed) {  
  343.         int level;  
  344.         if (speed < 1.5f)  
  345.             level = 1;  
  346.         else if (speed > 1.6 && speed < 5.4)  
  347.             level = 2;  
  348.         else if (speed > 5.5 && speed < 7.9)  
  349.             level = 3;  
  350.         else if (speed > 8.0 && speed < 10.7)  
  351.             level = 4;  
  352.         else if (speed > 10.8 && speed < 13.8)  
  353.             level = 5;  
  354.         else if (speed > 13.9 && speed < 17.1)  
  355.             level = 6;  
  356.         else if (speed > 17.2 && speed < 20.7)  
  357.             level = 7;  
  358.         else if (speed > 20.8 && speed < 24.4)  
  359.             level = 8;  
  360.         else if (speed > 24.5 && speed < 28.4)  
  361.             level = 9;  
  362.         else if (speed > 28.5 && speed < 32.6)  
  363.             level = 10;  
  364.         else  
  365.             level = 11;  
  366.   
  367.         long duration;  
  368.         duration = (11 - level) * ConstantsEwins.SPEED_DURATION_STEP + ConstantsEwins.MIN_SPEED_DURATION;  
  369.         return duration;  
  370.     }  
  371.   
  372.     @Override  
  373.     public boolean onKeyDown(int keyCode, KeyEvent event) {  
  374.         if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {  
  375.             if ((System.currentTimeMillis() - exitTime) > 2000) {  
  376.                 Toast.makeText(this"再按一次退出程序", Toast.LENGTH_SHORT).show();  
  377.                 exitTime = System.currentTimeMillis();  
  378.             } else {  
  379.                 finish();  
  380.                 System.exit(0);  
  381.             }  
  382.             return true;  
  383.         }  
  384.         return super.onKeyDown(keyCode, event);  
  385.     }  
  386.   
  387. }  

[java] view plaincopy
  1. package com.simpledraw.bluetoothservice;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.drawable.Drawable;  
  6. import android.util.AttributeSet;  
  7. import android.widget.ImageView;  
  8.   
  9. public class DirectionPointerView extends ImageView {  
  10.   
  11.     private float mDirection;  
  12.     private Drawable compass;  
  13.   
  14.     public DirectionPointerView(Context context) {  
  15.         super(context);  
  16.         mDirection = 0.0f;  
  17.         compass = null;  
  18.     }  
  19.   
  20.     public DirectionPointerView(Context context, AttributeSet attrs) {  
  21.         super(context, attrs);  
  22.         mDirection = 0.0f;  
  23.         compass = null;  
  24.     }  
  25.   
  26.     public DirectionPointerView(Context context, AttributeSet attrs, int defStyle) {  
  27.         super(context, attrs, defStyle);  
  28.         mDirection = 0.0f;  
  29.         compass = null;  
  30.     }  
  31.   
  32.     @Override  
  33.     protected void onDraw(Canvas canvas) {  
  34.         if (compass == null) {  
  35.             compass = getDrawable();  
  36.             compass.setBounds(00, getWidth(), getHeight());  
  37.         }  
  38.   
  39.         canvas.save();  
  40.         canvas.rotate(mDirection, getWidth() / 2, getHeight() / 2);  
  41.         compass.draw(canvas);  
  42.         canvas.restore();  
  43.     }  
  44.   
  45.     public void updateDirection(float direction) {  
  46.         mDirection = direction;  
  47.         invalidate();  
  48.     }  
  49.   
  50. }  

[java] view plaincopy
  1. package com.simpledraw.bluetoothservice;  
  2.   
  3. public class ConstantsEwins {  
  4.   
  5.     public static final int REQUEST_ADDDELETE_SENSORS = 2;  
  6.   
  7.     public static final float MAX_SPEED_VALUE = 100;  
  8.     public static final float MIN_SPEED_VALUE = 0;  
  9.     public static final int MIN_SPEED_DURATION = 500;  
  10.     public static final int SPEED_DURATION_STEP = 500;  
  11.   
  12.     public static final float MAX_TEMPERATURE_VALUE = 53;  
  13.     public static final float MIN_TEMPERATURE_VALUE = -40;  
  14.     public static final float MIN_TEMPERATURE_Y = 0.02f;  
  15.     public static final float TEMPERATURE_STEP = 0.01185f;  
  16.   
  17.     public static final float MIN_HUMIDITY_Y = 0.0f;  
  18.     public static final float HUMIDITY_STEP = 0.01118f;  
  19.     public static final float MAX_PRESSURE_VALUE = 120;  
  20.     public static final float MIN_PRESSURE_VALUE = 10;  
  21.     public static final float PRESSURE_STEP = 2.38f;  
  22.       
  23.     public static final int DATAGRAM_INTERVAL = 500;  
  24.     // 报文的字节数  
  25.     public static final int DATAGRAM_BYTES_LENGTH = 20;  
  26.     // 需要使用的数据长度,例如将字节变成16进制字符串的长度,0x80变成80  
  27.     public static final int DATA_LENGTH = 40;  
  28.   
  29. }  

[java] view plaincopy
  1. package com.simpledraw.bluetooth.data;  
  2.   
  3. import android.annotation.SuppressLint;  
  4.   
  5. @SuppressLint("DefaultLocale")  
  6. public class DataTypeConverter {  
  7.   
  8.     public static String double2Str(double d) {  
  9.         return String.format("%.1f", d);  
  10.     }  
  11.   
  12.     public static double str2Double(String str) {  
  13.         return Double.parseDouble(str);  
  14.     }  
  15.   
  16.     public static String getMacAddress(String pStr) {  
  17.         return pStr.substring(pStr.length() - 17);  
  18.     }  
  19.   
  20.     public static double hexStr2Double(String pStr) {  
  21.         int i = Integer.parseInt(pStr, 16);  
  22.         double d;  
  23.         if (pStr.startsWith("F")) {  
  24.             d = (double) (i - 65536) / 100;  
  25.         } else {  
  26.             d = (double) i / 100;  
  27.         }  
  28.         d = ((double) Math.round(d * 10)) / 10;  
  29.         return d;  
  30.     }  
  31.   
  32.     public static float hexStr2Float(String pStr) {  
  33.         return (float) (hexStr2Double(pStr));  
  34.     }  
  35.   
  36.     public static int hexStr2Int(String pStr) {  
  37.         return Integer.parseInt(pStr, 16);  
  38.     }  
  39. }  


[java] view plaincopy
  1. package com.simpledraw.bluetooth.data;  
  2.   
  3. import java.text.DecimalFormat;  
  4.   
  5. import com.simpledraw.bluetoothservice.ConstantsEwins;  
  6.   
  7.   
  8. public class Datagram {  
  9.     private float speed1;  
  10.     private float speed2;  
  11.     private float speed3;  
  12.     private float speed4;  
  13.     private float speed5;  
  14.     private float speed6;  
  15.   
  16.     private int direction1;  
  17.     private int direction2;  
  18.   
  19.     private float temperature;  
  20.     private int humidity;  
  21.     private float pressure;  
  22.     DecimalFormat df = new DecimalFormat(".00");  
  23.   
  24.     public float getSpeed1() {  
  25.         return speed1;  
  26.     }  
  27.   
  28.     public void setSpeed1(float speed1) {  
  29.         this.speed1 = speed1 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE  
  30.                 : (speed1 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed1);  
  31.     }  
  32.   
  33.     public float getSpeed2() {  
  34.         return speed2;  
  35.     }  
  36.   
  37.     public void setSpeed2(float speed2) {  
  38.         this.speed2 = speed2 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE  
  39.                 : (speed2 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed2);  
  40.     }  
  41.   
  42.     public float getSpeed3() {  
  43.         return speed3;  
  44.     }  
  45.   
  46.     public void setSpeed3(float speed3) {  
  47.         this.speed3 = speed3 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE  
  48.                 : (speed3 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed3);  
  49.     }  
  50.   
  51.     public float getSpeed4() {  
  52.         return speed4;  
  53.     }  
  54.   
  55.     public void setSpeed4(float speed4) {  
  56.         this.speed4 = speed4 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE  
  57.                 : (speed4 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed4);  
  58.     }  
  59.   
  60.     public float getSpeed5() {  
  61.         return speed5;  
  62.     }  
  63.   
  64.     public void setSpeed5(float speed5) {  
  65.         this.speed5 = speed5 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE  
  66.                 : (speed5 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed5);  
  67.     }  
  68.   
  69.     public float getSpeed6() {  
  70.         return speed6;  
  71.     }  
  72.   
  73.     public void setSpeed6(float speed6) {  
  74.         this.speed6 = speed6 > ConstantsEwins.MAX_SPEED_VALUE ? ConstantsEwins.MAX_SPEED_VALUE  
  75.                 : (speed6 < ConstantsEwins.MIN_SPEED_VALUE ? ConstantsEwins.MIN_SPEED_VALUE : speed6);  
  76.     }  
  77.   
  78.     public int getDirection1() {  
  79.         return direction1;  
  80.     }  
  81.   
  82.     public void setDirection1(int direction1) {  
  83.         this.direction1 = direction1;  
  84.     }  
  85.   
  86.     public int getDirection2() {  
  87.         return direction2;  
  88.     }  
  89.   
  90.     public void setDirection2(int direction2) {  
  91.         this.direction2 = direction2;  
  92.     }  
  93.   
  94.     public float getTemperature() {  
  95.         return temperature;  
  96.     }  
  97.   
  98.     public void setTemperature(float temperature) {  
  99.         this.temperature = temperature > ConstantsEwins.MAX_TEMPERATURE_VALUE ? ConstantsEwins.MAX_TEMPERATURE_VALUE  
  100.                 : (temperature < ConstantsEwins.MIN_TEMPERATURE_VALUE ? ConstantsEwins.MIN_TEMPERATURE_VALUE  
  101.                         : temperature);  
  102.     }  
  103.   
  104.     public int getHumidity() {  
  105.         return humidity;  
  106.     }  
  107.   
  108.     public void setHumidity(int humidity) {  
  109.         this.humidity = humidity > 100 ? 100 : (humidity < 0 ? 0 : humidity);  
  110.     }  
  111.   
  112.     public float getPressure() {  
  113.         return pressure;  
  114.     }  
  115.   
  116.     public void setPressure(float pressure) {  
  117.         this.pressure = pressure > ConstantsEwins.MAX_PRESSURE_VALUE ? ConstantsEwins.MAX_PRESSURE_VALUE  
  118.                 : (pressure < ConstantsEwins.MIN_PRESSURE_VALUE ? ConstantsEwins.MIN_PRESSURE_VALUE : pressure);  
  119.     }  
  120.   
  121.     public void parseDatagram(String datagram) {  
  122.         // datagram = "01076954204231804B0A08072102C3046307F209";  
  123.         if (datagram == null || datagram == "") {  
  124.             System.out.println("kong");  
  125.             return;  
  126.         }  
  127.         setSpeed1(calcSpeed(datagram.substring(46)));  
  128.         setSpeed2(calcSpeed(datagram.substring(68)));  
  129.         setSpeed3(calcSpeed(datagram.substring(810)));  
  130.         setSpeed4(calcSpeed(datagram.substring(1012)));  
  131.         setSpeed5(calcSpeed(datagram.substring(1214)));  
  132.         setSpeed6(calcSpeed(datagram.substring(1416)));  
  133.   
  134.         setDirection1(calcDirection(datagram.substring(2224) + datagram.substring(2022)));  
  135.         setDirection2(calcDirection(datagram.substring(2628) + datagram.substring(2426)));  
  136.   
  137.         setTemperature(calcTemperature(datagram.substring(3032) + datagram.substring(2830)));  
  138.         setHumidity(calcHumidity(datagram.substring(3436) + datagram.substring(3234)));  
  139.         setPressure(calcPressure(datagram.substring(3840) + datagram.substring(3638)));  
  140.     }  
  141.   
  142.     private float calcSpeed(String pStrSpeedHex) {  
  143.         float speed = DataTypeConverter.hexStr2Int(pStrSpeedHex);  
  144.         return speed * 0.765f + 0.35f;  
  145.     }  
  146.   
  147.     private int calcDirection(String pStrDirectionHex) {  
  148.         int direction = DataTypeConverter.hexStr2Int(pStrDirectionHex);  
  149.         return (int) (direction * 0.094230277);  
  150.     }  
  151.   
  152.     private float calcTemperature(String pStrTempHex) {  
  153.         float temperature = DataTypeConverter.hexStr2Int(pStrTempHex);  
  154.         return (float) (temperature * 0.088695557 - 86.38);  
  155.     }  
  156.   
  157.     private int calcHumidity(String pStrHumidityHex) {  
  158.         int humidity = DataTypeConverter.hexStr2Int(pStrHumidityHex);  
  159.         return (int) (humidity * 0.031933594);  
  160.     }  
  161.   
  162.     private float calcPressure(String pStrPressureHex) {  
  163.         float pressure = DataTypeConverter.hexStr2Int(pStrPressureHex);  
  164.         return (float) (pressure * 0.03479165 + 10.55);  
  165.     }  
  166. }  

[html] view plaincopy
  1. package com.simpledraw.bluetooth;  
  2.   
  3. import java.util.Set;  
  4.   
  5. import android.app.Activity;  
  6. import android.bluetooth.BluetoothAdapter;  
  7. import android.bluetooth.BluetoothDevice;  
  8. import android.content.BroadcastReceiver;  
  9. import android.content.Context;  
  10. import android.content.Intent;  
  11. import android.content.IntentFilter;  
  12. import android.os.Bundle;  
  13. import android.view.View;  
  14. import android.view.View.OnClickListener;  
  15. import android.view.Window;  
  16. import android.widget.AdapterView;  
  17. import android.widget.AdapterView.OnItemClickListener;  
  18. import android.widget.ArrayAdapter;  
  19. import android.widget.Button;  
  20. import android.widget.ListView;  
  21. import android.widget.TextView;  
  22.   
  23. import com.simpledraw.bluetooth.data.DataTypeConverter;  
  24. import com.simpledraw.bluetoothservice.R;  
  25.   
  26.   
  27. public class ScanBTDeviceActivity extends Activity {  
  28.   
  29.     private Button btnScan = null;  
  30.     private ListView lvNewDevices, lvPairedDevices;  
  31.     private ArrayAdapter<String> adapterNewDevices, adapterPairedDevice;  
  32.   
  33.     private BluetoothAdapter btAdapter;  
  34.   
  35.     @Override  
  36.     protected void onCreate(Bundle savedInstanceState) {  
  37.         super.onCreate(savedInstanceState);  
  38.         // Setup the window  
  39.         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);  
  40.         setContentView(R.layout.device_list);  
  41.   
  42.         findAllViews();  
  43.   
  44.         btAdapter = BluetoothAdapter.getDefaultAdapter();  
  45.         if (btAdapter == null) {  
  46.             finish();  
  47.             return;  
  48.         }  
  49.         Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();  
  50.         for (BluetoothDevice device : pairedDevices) {  
  51.             adapterPairedDevice.add(device.getName() + "\n" + device.getAddress());  
  52.         }  
  53.   
  54.         IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);  
  55.         registerReceiver(mReceiver, filter);  
  56.         filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);  
  57.         registerReceiver(mReceiver, filter);  
  58.     }  
  59.   
  60.     private void findAllViews() {  
  61.         btnScan = (Button) findViewById(R.id.btnScan);  
  62.   
  63.         lvNewDevices = (ListView) findViewById(R.id.lvNewDevices);  
  64.         adapterNewDevices = new ArrayAdapter<String>(ScanBTDeviceActivity.this, android.R.layout.simple_list_item_1);  
  65.         lvNewDevices.setAdapter(adapterNewDevices);  
  66.         lvNewDevices.setOnItemClickListener(DeviceListClickListener);  
  67.   
  68.         lvPairedDevices = (ListView) findViewById(R.id.lvPairedDevices);  
  69.         adapterPairedDevice = new ArrayAdapter<String>(ScanBTDeviceActivity.this, android.R.layout.simple_list_item_1);  
  70.         lvPairedDevices.setAdapter(adapterPairedDevice);  
  71.         lvPairedDevices.setOnItemClickListener(DeviceListClickListener);  
  72.   
  73.         btnScan.setOnClickListener(new OnClickListener() {  
  74.             @Override  
  75.             public void onClick(View arg0) {  
  76.                 discoverDevices();  
  77.             }  
  78.         });  
  79.     }  
  80.   
  81.     private void discoverDevices() {  
  82.         btnScan.setEnabled(false);  
  83.         setTitle(R.string.scanning);  
  84.         if (btAdapter.isDiscovering()) {  
  85.             btAdapter.cancelDiscovery();  
  86.         }  
  87.         btAdapter.startDiscovery();  
  88.     }  
  89.   
  90.     private OnItemClickListener DeviceListClickListener = new OnItemClickListener() {  
  91.         @Override  
  92.         public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {  
  93.             btAdapter.cancelDiscovery();  
  94.             String address = DataTypeConverter.getMacAddress(((TextView) arg1).getText().toString());  
  95.             Intent intent = new Intent();  
  96.             intent.putExtra(ConstantsBluetooth.DEVICE_ADDRESS, address);  
  97.             setResult(RESULT_OK, intent);  
  98.             finish();  
  99.         }  
  100.     };  
  101.   
  102.     @Override  
  103.     protected void onDestroy() {  
  104.         super.onDestroy();  
  105.         if (btAdapter != null) {  
  106.             btAdapter.cancelDiscovery();  
  107.         }  
  108.         unregisterReceiver(mReceiver);  
  109.     };  
  110.   
  111.     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {  
  112.         @Override  
  113.         public void onReceive(Context context, Intent intent) {  
  114.             String action = intent.getAction();  
  115.             if (BluetoothDevice.ACTION_FOUND.equals(action)) {  
  116.                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  
  117.                 if (device.getBondState() != BluetoothDevice.BOND_BONDED)  
  118.                     adapterNewDevices.add(device.getName() + "\n" + device.getAddress());  
  119.             } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {  
  120.                 btnScan.setEnabled(true);  
  121.                 setTitle(R.string.select_device);  
  122.             }  
  123.         }  
  124.     };  
  125. }  

[java] view plaincopy
  1. package com.simpledraw.bluetooth;  
  2.   
  3. import java.util.UUID;  
  4.   
  5. public class ConstantsBluetooth {  
  6.     public static final int REQUEST_CONNECT_DEVICE = 1;  
  7.       
  8.     public static final String DEVICE_ADDRESS = "deviceaddress";  
  9.     public static final String CONNECTED_DEVICE_NAME = "connecteddevicename";  
  10.   
  11.     public static final String SERVER_NAME = "BluetoothComm";  
  12.     public static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  
  13.   
  14.     public static final int MESSAGE_STATE_CHANGE = 1;  
  15.     public static final int MESSAGE_READ = 2;  
  16.     public static final int MESSAGE_WRITE = 3;  
  17.     public static final int MESSAGE_DEVICE_NAME = 4;  
  18.   
  19.     public static final int STATE_NONE = 0// do nothing  
  20.     public static final int STATE_LISTEN = 1// 监听连接  
  21.     public static final int STATE_CONNECTING = 2// now initiating an outgoing  
  22.     public static final int STATE_CONNECTED = 3// 已连接上远程设备  
  23.   
  24.     public static final String CONNECTION_FAILED = "fail";  
  25.     public static final String CONNECTION_LOST = "lost";  
  26.     public static final String CONNECTION_CONNECTED = "connected";  
  27.   
  28.     public static final String COMMAND_1 = "uLPCC_0000CD?";  
  29.     public static final byte[] COMMAND_ACK = new byte[] { (byte0x06 };  
  30. }  

[java] view plaincopy
  1. package com.simpledraw.bluetooth;  
  2.   
  3.   
  4. public class BluetoothEnvironment {  
  5.   
  6.     public static BluetoothCommService service;  
  7. }  

[java] view plaincopy
  1. package com.simpledraw.bluetooth;  
  2.   
  3. import java.io.BufferedInputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.OutputStream;  
  7. import java.io.Serializable;  
  8. import java.util.UUID;  
  9.   
  10. import android.annotation.SuppressLint;  
  11. import android.bluetooth.BluetoothAdapter;  
  12. import android.bluetooth.BluetoothDevice;  
  13. import android.bluetooth.BluetoothServerSocket;  
  14. import android.bluetooth.BluetoothSocket;  
  15. import android.content.Context;  
  16. import android.os.Handler;  
  17. import android.os.Message;  
  18. import android.util.Log;  
  19. import android.widget.Toast;  
  20.   
  21. public class BluetoothCommService implements Serializable {  
  22.   
  23.     private static final long serialVersionUID = 1L;  
  24.     private static final String NAME = "BluetoothComm";  
  25.     // SPP协议UUID  
  26.     private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  
  27.     // Member fields  
  28.     private final BluetoothAdapter mAdapter;  
  29.     private Handler mHandler, receiveHandler;  
  30.     private int mState;  
  31.     private AcceptThread mAcceptThread;  
  32.     private ConnectThread mConnectThread;  
  33.     private ConnectedThread mConnectedThread;  
  34.   
  35.     public BluetoothCommService(Context context, Handler handler, Handler p_receiveHandler) {  
  36.         mAdapter = BluetoothAdapter.getDefaultAdapter();  
  37.         mHandler = handler;  
  38.         receiveHandler = p_receiveHandler;  
  39.         mState = ConstantsBluetooth.STATE_NONE;  
  40.     }  
  41.   
  42.     public void setHandler(Handler pHandler, Handler p_receiveHandler) {  
  43.         mHandler = pHandler;  
  44.         receiveHandler = p_receiveHandler;  
  45.     }  
  46.   
  47.     /** 
  48.      * Set the current state of the chat connection 
  49.      *  
  50.      * @param state 
  51.      *            An integer defining the current connection state 
  52.      */  
  53.     private synchronized void setState(int state) {  
  54.         mState = state;  
  55.         mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();  
  56.     }  
  57.   
  58.     /** 
  59.      * Return the current connection state. 
  60.      */  
  61.     public synchronized int getState() {  
  62.         return mState;  
  63.     }  
  64.   
  65.     /** 
  66.      * 开始服务,主要是开始AcceptThread线程,打开一个监听回话由BaowenActivity的onResume方法调用, 
  67.      * ***开启监听线程**** 
  68.      */  
  69.     public synchronized void start() {  
  70.         // 取消所有正在尝试连接的线程  
  71.         if (mConnectThread != null) {  
  72.             mConnectThread.cancel();  
  73.             mConnectThread = null;  
  74.         }  
  75.   
  76.         // 取消所有已经连接上的线程  
  77.         if (mConnectedThread != null) {  
  78.             mConnectedThread.cancel();  
  79.             mConnectedThread = null;  
  80.         }  
  81.   
  82.         // 打开一个监听BluetoothServerSocket的线程  
  83.         if (mAcceptThread == null) {  
  84.             mAcceptThread = new AcceptThread();  
  85.             mAcceptThread.start();// 开启监听线程  
  86.         }  
  87.         setState(ConstantsBluetooth.STATE_LISTEN);  
  88.     }  
  89.   
  90.     /** 
  91.      * Start the ConnectThread to initiate a connection to a remote device. 
  92.      *  
  93.      * @param device 
  94.      *            The BluetoothDevice to connect 
  95.      */  
  96.     public synchronized void connect(BluetoothDevice device) {  
  97.         // Cancel any thread attempting to make a connection  
  98.         if (mState == ConstantsBluetooth.STATE_CONNECTING) {// 正在连接状态״̬  
  99.             if (mConnectThread != null) {// 有ConnectThread,结束  
  100.                 mConnectThread.cancel();  
  101.                 mConnectThread = null;  
  102.             }  
  103.         }  
  104.   
  105.         // Cancel any thread currently running a connection  
  106.         if (mConnectedThread != null) {// 有处于连接中的线程,结束  
  107.             mConnectedThread.cancel();  
  108.             mConnectedThread = null;  
  109.         }  
  110.   
  111.         // Start the thread to connect with the given device  
  112.         mConnectThread = new ConnectThread(device);  
  113.         mConnectThread.start();// 开启新的连接请求线程  
  114.         setState(ConstantsBluetooth.STATE_CONNECTING);  
  115.     }  
  116.   
  117.     /** 
  118.      * Start the ConnectedThread to begin managing a Bluetooth connection 
  119.      *  
  120.      * @param socket 
  121.      *            The BluetoothSocket on which the connection was made 
  122.      * @param device 
  123.      *            The BluetoothDevice that has been connected 
  124.      */  
  125.     public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {  
  126.         // Cancel the thread that completed the connection  
  127.         if (mConnectThread != null) {  
  128.             mConnectThread.cancel();  
  129.             mConnectThread = null;  
  130.         }  
  131.   
  132.         // Cancel any thread currently running a connection  
  133.         if (mConnectedThread != null) {  
  134.             mConnectedThread.cancel();  
  135.             mConnectedThread = null;  
  136.         }  
  137.   
  138.         // Cancel the accept thread because we only want to connect to one  
  139.         // device  
  140.         if (mAcceptThread != null) {  
  141.             mAcceptThread.cancel();  
  142.             mAcceptThread = null;  
  143.         }  
  144.   
  145.         // Start the thread to manage the connection and perform transmissions  
  146.         mConnectedThread = new ConnectedThread(socket);  
  147.         mConnectedThread.start();// 和客户端开始通信  
  148.   
  149.         // 把已连接的设备的名称发给UI线程  
  150.         Message msg = mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_STATE_CHANGE);  
  151.         msg.arg1 = ConstantsBluetooth.STATE_CONNECTED;  
  152.         msg.obj = device.getName();  
  153.         mHandler.sendMessage(msg);  
  154.   
  155.         mState = ConstantsBluetooth.STATE_CONNECTED;  
  156.     }  
  157.   
  158.     /** 
  159.      * Stop all threads 
  160.      */  
  161.     public synchronized void stop() {  
  162.         if (mConnectThread != null) {  
  163.             mConnectThread.cancel();  
  164.             mConnectThread = null;  
  165.         }  
  166.         if (mConnectedThread != null) {  
  167.             mConnectedThread.cancel();  
  168.             mConnectedThread = null;  
  169.         }  
  170.         if (mAcceptThread != null) {  
  171.             mAcceptThread.cancel();  
  172.             mAcceptThread = null;  
  173.         }  
  174.         setState(ConstantsBluetooth.STATE_NONE);  
  175.     }  
  176.   
  177.     /** 
  178.      * Write to the ConnectedThread in an unsynchronized manner 
  179.      *  
  180.      * @param out 
  181.      *            The bytes to write 
  182.      * @see ConnectedThread#write(byte[]) 
  183.      */  
  184.     public void write(byte[] out) {  
  185.         // Create temporary object  
  186.         ConnectedThread r;  
  187.         // Synchronize a copy of the ConnectedThread  
  188.         synchronized (this) {  
  189.             if (mState != ConstantsBluetooth.STATE_CONNECTED)  
  190.                 return;  
  191.             r = mConnectedThread;// 得到连接线程  
  192.         }  
  193.         // Perform the write unsynchronized  
  194.         r.write(out);  
  195.     }  
  196.   
  197.     /** 
  198.      * Indicate that the connection attempt failed and notify the UI Activity. 
  199.      */  
  200.     private void connectionFailed() {  
  201.         setState(ConstantsBluetooth.STATE_LISTEN);  
  202.   
  203.         // // Send a failure message back to the Activity  
  204.         Message msg = mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_STATE_CHANGE);  
  205.         msg.obj = "fail";  
  206.         mHandler.sendMessage(msg);  
  207.     }  
  208.   
  209.     /** 
  210.      * Indicate that the connection was lost and notify the UI Activity. 
  211.      */  
  212.     @SuppressWarnings("unused")  
  213.     private void connectionLost() {  
  214.         setState(ConstantsBluetooth.STATE_LISTEN);  
  215.   
  216.         // Send a failure message back to the Activity  
  217.         Message msg = mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_STATE_CHANGE);  
  218.         msg.obj = "lost";  
  219.         mHandler.sendMessage(msg);  
  220.     }  
  221.   
  222.     /** 
  223.      * This thread runs while listening for incoming connections. It behaves 
  224.      * like a server-side client. It runs until a connection is accepted (or 
  225.      * until cancelled). 监听准备进入的连接,类似于服务端, 
  226.      */  
  227.     private class AcceptThread extends Thread {  
  228.         // 本地的socket  
  229.         private final BluetoothServerSocket mmServerSocket;  
  230.   
  231.         public AcceptThread() {  
  232.             BluetoothServerSocket tmp = null;  
  233.             // 创建一个新的监听服务器socket  
  234.             try {  
  235.                 // 根据名称,UUID创建并返回BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步  
  236.                 tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, SPP_UUID);  
  237.             } catch (IOException e) {  
  238.             }  
  239.             // 得到BluetoothServerSocket对象  
  240.             mmServerSocket = tmp;  
  241.         }  
  242.   
  243.         public void run() {  
  244.             setName("AcceptThread");// set the name of thread  
  245.             BluetoothSocket socket = null;  
  246.   
  247.             // Listen to the server socket if we're not connected  
  248.             while (mState != ConstantsBluetooth.STATE_CONNECTED) {// 若没有连接,一直执行  
  249.                 try {  
  250.                     // 注意:BluetoothServerSocket的accept是一个阻塞性线程,一直到用户成功的配对,因此不要放在Activity中,  
  251.                     // 远程蓝牙设备请求跟本设备建立连接请求时,  
  252.                     // BluetoothServerSocket会在连接被接收时返回一个被连接的BluetoothSocket对象。  
  253.                     socket = mmServerSocket.accept();  
  254.                 } catch (IOException e) {  
  255.                     break;  
  256.                 }  
  257.   
  258.                 // 连接建立成功  
  259.                 if (socket != null) {  
  260.                     synchronized (BluetoothCommService.this) {  
  261.                         switch (mState) {  
  262.                         case ConstantsBluetooth.STATE_LISTEN:  
  263.                         case ConstantsBluetooth.STATE_CONNECTING:  
  264.                             // 已经连接上,开始ConnectedThread线程  
  265.                             connected(socket, socket.getRemoteDevice());  
  266.                             break;  
  267.                         case ConstantsBluetooth.STATE_NONE:  
  268.                         case ConstantsBluetooth.STATE_CONNECTED:  
  269.                             // 或者设备没有准备好,或者已经连接,都将这个新的BluetoothSocket关掉  
  270.                             // 释放服务套接字,但不会关闭accept()返回的BluetoothSocket  
  271.                             try {  
  272.                                 socket.close();  
  273.                             } catch (IOException e) {  
  274.                             }  
  275.                             break;  
  276.                         }  
  277.                     }  
  278.                 }  
  279.             }  
  280.         }  
  281.   
  282.         public void cancel() {  
  283.             try {  
  284.                 mmServerSocket.close();  
  285.             } catch (IOException e) {  
  286.             }  
  287.         }  
  288.     }  
  289.   
  290.     /** 
  291.      * This thread runs while attempting to make an outgoing connection with a 
  292.      * device. It runs straight through; the connection either succeeds or 
  293.      * fails. 监听准备出去的连接 
  294.      */  
  295.     private class ConnectThread extends Thread {  
  296.         private final BluetoothSocket mmSocket;  
  297.         private final BluetoothDevice mmDevice;// 远程设备  
  298.   
  299.         public ConnectThread(BluetoothDevice device) {  
  300.             mmDevice = device;  
  301.             BluetoothSocket tmp = null;  
  302.   
  303.             // Get a BluetoothSocket for a connection with the  
  304.             // given BluetoothDevice  
  305.             try {  
  306.                 // 通过远程设备直接创建一个BluetoothSocket,要求该设备已经打开了BluetoothServerSocket获得一个BluetoothSocket对象  
  307.                 tmp = device.createRfcommSocketToServiceRecord(SPP_UUID);  
  308.             } catch (IOException e) {  
  309.             }  
  310.             mmSocket = tmp;  
  311.         }  
  312.   
  313.         public void run() {  
  314.             setName("ConnectThread");  
  315.   
  316.             // 取消搜索  
  317.             mAdapter.cancelDiscovery();  
  318.   
  319.             // Make a connection to the BluetoothSocket  
  320.             try {  
  321.                 // This is a blocking call and will only return on a  
  322.                 // successful connection or an exception  
  323.                 mmSocket.connect();  
  324.             } catch (IOException e) {  
  325.                 connectionFailed();  
  326.                 // Close the socket  
  327.                 try {  
  328.                     mmSocket.close();  
  329.                 } catch (IOException e2) {  
  330.                 }  
  331.                 // Start the service over to restart listening mode  
  332.                 BluetoothCommService.this.start();  
  333.                 return;  
  334.             }  
  335.   
  336.             // Reset the ConnectThread because we're done  
  337.             synchronized (BluetoothCommService.this) {  
  338.                 mConnectThread = null;  
  339.             }  
  340.   
  341.             // Start the connected thread,已连接上,管理连接  
  342.             connected(mmSocket, mmDevice);  
  343.         }  
  344.   
  345.         public void cancel() {  
  346.             try {  
  347.                 mmSocket.close();  
  348.             } catch (IOException e) {  
  349.             }  
  350.         }  
  351.     }  
  352.   
  353.     /** 
  354.      * This thread runs during a connection with a remote device. It handles all 
  355.      * incoming and outgoing transmissions. 监听 
  356.      */  
  357.     private class ConnectedThread extends Thread {  
  358.         private final BluetoothSocket mmSocket;  
  359.         private final OutputStream mmOutStream;  
  360.         private final BufferedInputStream reader;  
  361.   
  362.         public ConnectedThread(BluetoothSocket socket) {  
  363.             mmSocket = socket;  
  364.             InputStream tmpIn = null;  
  365.             OutputStream tmpOut = null;  
  366.   
  367.             // Get the BluetoothSocket input and output streams  
  368.             try {  
  369.                 tmpIn = socket.getInputStream();  
  370.                 tmpOut = socket.getOutputStream();  
  371.             } catch (IOException e) {  
  372.             }  
  373.   
  374.             reader = new BufferedInputStream(tmpIn);  
  375.             mmOutStream = tmpOut;  
  376.         }  
  377.         private String dataStr = "";  
  378.         @SuppressLint("NewApi")  
  379.         public void run() {  
  380.             byte[] buffer = new byte[44], temp = new byte[127];  
  381.             StringBuffer sb;  
  382.             String b;  
  383.             int numReadedBytes;  
  384.             boolean cleaning = true;  
  385.             long startTime = System.currentTimeMillis();  
  386.   
  387.             // 保持对InputStream的监听  
  388.             while (true) {  
  389.                 try {  
  390. //                  if (cleaning) {  
  391. ////                        if (System.currentTimeMillis() - startTime < 2000) {  
  392. //                        
  393. //                        
  394. //                        
  395. //                          numReadedBytes = reader.read(temp);  
  396. //                          // System.out.println("cleaning:" + numReadedBytes);  
  397. //                          continue;  
  398. ////                        } else  
  399. ////                            cleaning = false;  
  400. //                  }  
  401.                       
  402.                     numReadedBytes = reader.read(buffer);//temp  
  403.                     String tempStr = new String(buffer);//temp write to log  
  404.                     tempStr.replace("\r\n""***");  
  405.                     String[] strs = tempStr.split("\r\n");  
  406.                     // System.out.println("numReaded0:" + numReadedBytes);  
  407.                     Log.d("texts",tempStr);  
  408.                     sb = new StringBuffer();  
  409. //                  for (int i = 0; i < numReadedBytes; i++) {  
  410. //                      b = Integer.toHexString(buffer[i] & 0xFF);  
  411. //                      if (b.length() < 2)  
  412. //                          sb.append("0");  
  413. //                      sb.append(b);  
  414. //                  }  
  415.                     mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_READ, numReadedBytes, 0new String(buffer))  
  416.                             .sendToTarget();  
  417.                     buffer = new byte[44];  
  418.                 } catch (Exception e) {  
  419.                     e.printStackTrace();  
  420.                 }  
  421.             }  
  422.         }  
  423.   
  424.         /** 
  425.          * Write to the connected OutStream. 
  426.          *  
  427.          * @param buffer 
  428.          *            The bytes to write 
  429.          */  
  430.         public void write(byte[] buffer) {  
  431.             try {  
  432.                 mmOutStream.write(buffer);  
  433.                 mHandler.obtainMessage(ConstantsBluetooth.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();  
  434.             } catch (IOException e) {  
  435.                 e.printStackTrace();  
  436.                 Log.i("texts""数据流写入失败");  
  437.             }  
  438.         }  
  439.   
  440.         public void cancel() {  
  441.             try {  
  442.                 mmSocket.close();  
  443.             } catch (IOException e) {  
  444.             }  
  445.         }  
  446.     }  
  447. }  

OK,,,这样我所以项目都贴到上面了,,因为个人原因,不能贴项目源码,,但是改了一个项目,,亲测可用,,

我们要重点注意这里

MainActivity.java:

[java] view plaincopy
  1. ((Button)findViewById(R.id.btn1)).setOnClickListener(new OnClickListener() {  
  2.             @Override  
  3.             public void onClick(View v) {  
  4.                 executStr = ((Button)v).getText().toString();  
  5.                 output_edit.setText("");  
  6.                 executStr+="\r\n";  
  7.                 BluetoothEnvironment.service.write(executStr.getBytes());  
  8.                 output_edit.setText(executStr);  
  9.             }  
  10.         });  


这段是真实向下位机写数据,,如果你项目非常紧急,建议直接找到此处,修改这里,还有类似位置,然后我们在看看S端Return的值:

MainActivity.java:

[java] view plaincopy
  1. case ConstantsBluetooth.MESSAGE_READ:  
  2.                 if (firstReceived)  
  3.                     lastReadTime = System.currentTimeMillis();  
  4.                 firstReceived = false;  
  5.   
  6.                 if (System.currentTimeMillis() - lastReadTime > ConstantsEwins.DATAGRAM_INTERVAL) {  
  7.                     if (length == ConstantsEwins.DATAGRAM_BYTES_LENGTH) {  
  8.                         datagram.parseDatagram(sb.toString());  
  9.                         modifyViews();  
  10.                     }  
  11.                     sb = new StringBuffer(ConstantsEwins.DATA_LENGTH);  
  12.                     length = 0;  
  13.                 }  
  14.   
  15.                 String data = (String) msg.obj;  
  16.                 System.out.println("接收到的数据:" + data);  
  17.                 Log.e("texts",data);  
  18.                 length += msg.arg1;  
  19.                 sb.append(data);  
  20.                 lastReadTime = System.currentTimeMillis();  
  21.                 input_edit.setText(data);//sb.toString()  
  22.                 break;  

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

0 0
原创粉丝点击