16、蓝牙技术

蓝牙简介

        蓝牙(Bluetooth)是一种短距离的无线通信技术标准。这个名子来源于10世纪丹麦国王Harald Blatand,英文名子是Harold Bluetooth。在无线行业协会组织人员的讨论后,有人认为用Blatand国王的名字命名这种无线技术是再好不过了,这是因为Blatand国王将挪威、瑞典和丹麦统一起来,这就如同这项技术将统一无线通信领域一样。至此,蓝牙的名字也就这样定了下来。

       蓝牙协议分为4层,即核心协议层、电缆替代协议层、电话控制协议层和采纳的其它协议层。这4种协议中最重要的是核心协议。蓝牙的核心协议包括基带、链路管理、逻辑链路控制和适应协议四部分。其中链路管理(LMP)负责蓝牙组件间连接的建立。逻辑链路控制与适应协议(L2CAP)位于基带协议层上,属于数据链路层,是一个为高层传输和应用层协议屏蔽基带协议的适配协议。

打开和关闭蓝牙设备

第1种打开蓝牙的方式

Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableIntent, 1);

必须设置权限

<uses-permission android:name="android.permission.BLUETOOTH" />

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

 

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter()

adapter.enable();

adapter.disable();

搜索蓝牙设备

16、蓝牙技术

 

蓝牙数据传输

      通过蓝牙传输数据与Socket类似。在网络中使用Socket和ServerSocket控制客户端和服务端的数据读写。而蓝牙通讯也由客户端和服务端Socket来完成。蓝牙客户端Socket是BluetoothSocket,蓝牙服务端Socket是BluetoothServerSocket。这两个类都在android.bluetooth包中。

      无论是BluetoothSocket,还是BluetoothServerSocket,都需要一个UUID(全局唯一标识符,Universally Unique Identifier).格式如下:

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

UUID的格式被分成5段,其中中间3段的字符数相同,都是4,第1段是8个字符,最后一段是12个字符。所以UUID实际上是一个8-4-4-4-12的字符串。

UUID相当于Socket的端口,而蓝牙地址相当于Socket的IP。

蓝牙的UUID

      两个蓝牙设备进行连接时需要使用同一个UUID。但很多读者可能发现,有很多型号的手机(可能是非Android系统的手机)之间使用了不同的程序也可以使用蓝牙进行通讯。从表面上看,它们之间几乎不可能使用同一个UUID。 

       实际上,UUID和TCP的端口一样,也有一些默认的值。例如,将蓝牙模拟成串口的服务就使用了一个标准的UUID:

00001101-0000-1000-8000-00805F9B34FB。除此之外,还有很多标准的UUID,如下面就是两个标准的UUID。

信息同步服务:00001104-0000-1000-8000-00805F9B34FB
文件传输服务:00001106-0000-1000-8000-00805F9B34FB
 
DEMO:
 1 <?xml version="1.0" encoding="utf-8"?>

 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

 3     android:layout_width="fill_parent"

 4     android:layout_height="fill_parent"

 5     android:orientation="vertical" >

 6 

 7     <Button

 8         android:layout_width="fill_parent"

 9         android:layout_height="wrap_content"

10         android:onClick="onClick_Search"

11         android:text="搜索" />

12 

13     <ListView

14         android:id="@+id/lvDevices"

15         android:layout_width="fill_parent"

16         android:layout_height="wrap_content" />

17 

18 </LinearLayout>
  1 import java.io.InputStream;

  2 import java.io.OutputStream;

  3 import java.util.ArrayList;

  4 import java.util.List;

  5 import java.util.Set;

  6 import java.util.UUID;

  7 

  8 import android.app.Activity;

  9 import android.bluetooth.BluetoothAdapter;

 10 import android.bluetooth.BluetoothDevice;

 11 import android.bluetooth.BluetoothServerSocket;

 12 import android.bluetooth.BluetoothSocket;

 13 import android.content.BroadcastReceiver;

 14 import android.content.Context;

 15 import android.content.Intent;

 16 import android.content.IntentFilter;

 17 import android.os.Bundle;

 18 import android.os.Handler;

 19 import android.os.Message;

 20 import android.view.View;

 21 import android.view.Window;

 22 import android.widget.AdapterView;

 23 import android.widget.AdapterView.OnItemClickListener;

 24 import android.widget.ArrayAdapter;

 25 import android.widget.ListView;

 26 import android.widget.Toast;

 27 

 28 /**

 29  * 单击列表项蓝牙设备,去连接另外一个蓝牙设备,并且进行配对,

 30  * 配对完后,将一个文本信息,传递过去。

 31  * @author dr

 32  *

 33  */

 34 public class Main extends Activity implements OnItemClickListener {

 35 

 36     private ListView lvDevices;   // 蓝牙列表

 37     private BluetoothAdapter bluetoothAdapter;  // 蓝牙适配器

 38     // 用于储存所有搜索到的蓝牙名称和地址。

 39     private List<String> bluetoothDevices = new ArrayList<String>();

 40     // 数组适配器,显示列表

 41     private ArrayAdapter<String> arrayAdapter;

 42     // 

 43     private final UUID MY_UUID = UUID

 44             .fromString("db764ac8-4b08-7f25-aafe-59d03c27bae3");

 45     // 自定义

 46     private final String NAME = "Bluetooth_Socket";

 47     // 客户端。

 48     private BluetoothSocket clientSocket;

 49     private BluetoothDevice device;

 50     //  

 51     private AcceptThread acceptThread;

 52     // 输出流(从客户端往服务端进行输出)。

 53     private OutputStream os;

 54     

 55     private Handler handler = new Handler() {

 56         public void handleMessage(Message msg) {

 57             Toast.makeText(Main.this, String.valueOf(msg.obj),

 58                     Toast.LENGTH_LONG).show();

 59             super.handleMessage(msg);

 60         }

 61     };

 62 

 63     @Override

 64     public void onCreate(Bundle savedInstanceState) {

 65         super.onCreate(savedInstanceState);

 66 

 67         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

 68         setContentView(R.layout.main);

 69         

 70         lvDevices = (ListView) findViewById(R.id.lvDevices);

 71 

 72         // 得到 BluetoothAdapter对象。

 73         bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

 74 

 75         // 得到已经配对的蓝牙,显示出来

 76         Set<BluetoothDevice> pairedDevices = bluetoothAdapter

 77                 .getBondedDevices();   

 78         if (pairedDevices.size() > 0) {  // 已经配完对的。

 79             for (BluetoothDevice device : pairedDevices) {

 80                 bluetoothDevices.add(device.getName() + ":"

 81                         + device.getAddress() + "\n");

 82             }

 83         }

 84 

 85         // 将所有设备,显示在列表上。

 86         arrayAdapter = new ArrayAdapter<String>(this,

 87                 android.R.layout.simple_list_item_1, android.R.id.text1,

 88                 bluetoothDevices);

 89 

 90         lvDevices.setAdapter(arrayAdapter);

 91         lvDevices.setOnItemClickListener(this);

 92         

 93         // 每找到一个设备,发送一个广播。

 94         IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

 95         this.registerReceiver(receiver, filter);

 96 

 97         // 全部搜索完后,发送一个广播。

 98         filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

 99         this.registerReceiver(receiver, filter);

100         

101         // 实例化,并且启动。

102         acceptThread = new AcceptThread();

103         acceptThread.start();

104     }

105 

106     public void onClick_Search(View view) {

107         // 显示进度条,扫描状态。

108         setProgressBarIndeterminateVisibility(true);

109         setTitle("正在扫描...");

110         // 判断是否正在搜索。

111         if (bluetoothAdapter.isDiscovering()) {

112             bluetoothAdapter.cancelDiscovery();

113         }

114         bluetoothAdapter.startDiscovery();

115     }

116 

117     /** 广播接收器 */ 

118     private final BroadcastReceiver receiver = new BroadcastReceiver() {

119         @Override

120         public void onReceive(Context context, Intent intent) {

121             String action = intent.getAction();

122             // 当搜索到一个设备时

123             if (BluetoothDevice.ACTION_FOUND.equals(action)) {

124                 // 获得这个设备的信息。

125                 BluetoothDevice device = intent

126                         .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

127                 // 判断当前设备没有被绑定。

128                 if (device.getBondState() != BluetoothDevice.BOND_BONDED) {

129                     bluetoothDevices.add(device.getName() + ":"

130                             + device.getAddress() + "\n");

131                     arrayAdapter.notifyDataSetChanged();

132                 }

133             // 已经完成的情况。

134             } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED

135                     .equals(action)) {

136                 // 关闭进度条。

137                 setProgressBarIndeterminateVisibility(false);

138                 setTitle("连接蓝牙设备");

139             }

140         }

141     };

142 

143     @Override    /** 客户端 */ 

144     public void onItemClick(AdapterView<?> parent, View view, int position,

145             long id) {

146         String s = arrayAdapter.getItem(position);

147         // 得到地址,相当于ip

148         String address = s.substring(s.indexOf(":") + 1).trim();

149 

150         try {

151             // 判断是否在搜索

152             if (bluetoothAdapter.isDiscovering()) {  

153                 bluetoothAdapter.cancelDiscovery();

154             }

155             try {

156                 if (device == null) {

157                     // 得到远程设备。

158                     device = bluetoothAdapter.getRemoteDevice(address);

159                 }

160                 if (clientSocket == null) {

161                     // 得到UUID

162                     clientSocket = device

163                             .createRfcommSocketToServiceRecord(MY_UUID);

164                     // 开始连接。

165                     clientSocket.connect();

166                     // 获得输出流。

167                     os = clientSocket.getOutputStream();

168                 }

169             } catch (Exception e) {

170                 // TODO: handle exception

171             }

172             if (os != null) {

173                 os.write("发送信息到其他蓝牙设备".getBytes("utf-8"));

174             }

175         } catch (Exception e) {

176             // TODO: handle exception

177         }

178     }

179 

180     /** 服务端的东西 */  

181     private class AcceptThread extends Thread {

182         private BluetoothServerSocket serverSocket;

183         private BluetoothSocket socket;

184         private InputStream is;

185         private OutputStream os;

186 

187         public AcceptThread() {

188             try {

189                 serverSocket = bluetoothAdapter

190                         .listenUsingRfcommWithServiceRecord(NAME, MY_UUID);

191             } catch (Exception e) {

192                 // TODO: handle exception

193             }

194         }

195 

196         public void run() {  

197             // 截获 客户端的  信息。

198             try {

199                 socket = serverSocket.accept();

200                 is = socket.getInputStream();

201                 os = socket.getOutputStream();

202 

203                 while (true) {

204                     byte[] buffer = new byte[128];

205                     int count = is.read(buffer);

206                     Message msg = new Message();

207                     msg.obj = new String(buffer, 0, count, "utf-8");

208                     handler.sendMessage(msg);

209                 }

210             } catch (Exception e) {

211                 // TODO: handle exception

212             }

213 

214         }

215     }

216 

217 }
1 <uses-permission android:name="android.permission.BLUETOOTH" />

2 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

 

 

 
 
 
 
 

你可能感兴趣的:(技术)