蓝牙技术
蓝牙(Bluetooth)是一种短距离的无线通信技术标准。
打开和关闭蓝牙设备:
蓝牙数据传输:
蓝牙的野史:
蓝牙的名字来源于10世纪丹麦国王Harald Blatand,英文名字是Harald Bluetooth,没错,这个蓝牙就是那个蓝牙。因为这个国王将挪威、瑞典和丹麦统一起来,这就像这项技术把无线通信统一起来一样,所以,无线行业协会组织人员讨论后,就用这个名字命名了。
蓝牙的协议:
蓝牙的协议分为4层:
核心协议层、
电缆替代协议层、
电话控制协议层、
其他协议层
其中,核心协议层是最重要的部分。包括基带、链路管理、逻辑链路控制和适应协议四部分。其中链路管理(LMP)负责蓝牙组件间的连接的建立。
逻辑链路控制和适应协议(L2CAP)位于基带协议层之上,属于数据链路层,是一个为高层传输和应用层协议屏蔽基带协议的适配协议。
打开和关闭蓝牙设备:
第一种方式:
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent,1);
会出现一个窗口请求权限供用户选择是否打开。
第二种方式:
必须设置权限:
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
然后代码实现:
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); //调用enable就把蓝牙打开 adapter.enable(); //调用disable就把蓝牙关闭 adapter.disable();
蓝牙数据传输:
通过蓝牙传输数据与Socket类似。在网络中使用Socket和ServerSocket控制客户端和服务端的数据读写。而蓝牙通讯也由客户端和服务端Socket来完成。蓝牙客户端Socket是BluetoothSocket,蓝牙服务端Socket是BluetoothServerSocket。这两个类都在android.bluetooth包中。
无论是BluetoothSocket,还是
BluetoothSocket,都需要一个UUID(全局唯一标识符,Universally Unique Identifier)。
格式如下:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
UUID的格式被分成5段,形成一个8-4-4-4-12的字符串。
例子:在两个Android设备中传输数据。
先完成蓝牙的搜索功能,并连接另一部设备,再在两部设备中传输数据
package com.sadaharu.jacksom.bluetooth; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.UUID; public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{ private BluetoothAdapter mBluetoothAdapter; private ListView lvDevices; private List<String> bluetoothDevices = new ArrayList<>(); private ArrayAdapter<String> arrayAdapter; private final UUID MY_UUID = UUID.randomUUID(); private final String NAME = "Bluetooth_Socket"; private BluetoothSocket clientSocket; private BluetoothDevice device; private AcceptThread acceptThread; private OutputStream os; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /*//蓝牙的打开方式一: Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent,1); //蓝牙的打开方式二: BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); //调用enable就把蓝牙打开 adapter.enable(); //调用disable就把蓝牙关闭 adapter.disable();*/ lvDevices = (ListView) findViewById(R.id.lvDevices); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); acceptThread = new AcceptThread(); acceptThread.start(); //已经配过对的,存储在这个集合里 Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); //将已经配对过的设备显示出来 if (pairedDevices.size() > 0) { for (BluetoothDevice device : pairedDevices) { bluetoothDevices.add(device.getName() + ":" + device.getAddress()); } } arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, android.R.id.text1,bluetoothDevices); lvDevices.setAdapter(arrayAdapter); lvDevices.setOnItemClickListener(this); //找到一个设备会发送广播 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(receiver, filter); //全部搜索完成会发送一个广播 filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); this.registerReceiver(receiver, filter); } //按钮监听方法 public void onClick_Search(View view) { //设置一个进度条显示正在扫描 setProgressBarVisibility(true); setTitle("正在扫描……"); if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } mBluetoothAdapter.startDiscovery(); } private final BroadcastReceiver receiver = 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) { bluetoothDevices.add(device.getName() + ":" + device.getAddress() + "\n"); arrayAdapter.notifyDataSetChanged(); } } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { setProgressBarVisibility(false); setTitle("搜索已经完成"); } } }; @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String s = arrayAdapter.getItem(position); String address = s.substring(s.indexOf(":") + 1).trim(); try{ if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } if (device == null) { device = mBluetoothAdapter.getRemoteDevice(address); } if (clientSocket == null) { clientSocket = device.createRfcommSocketToServiceRecord(MY_UUID); clientSocket.connect(); os = clientSocket.getOutputStream(); } }catch (Exception e ) { } if (os != null) { try { os.write("发送信息到其他蓝牙设备".getBytes("utf-8")); } catch (IOException e) { e.printStackTrace(); } } } //服务端 private Handler handler = new Handler() { public void handlerMessage(Message msg) { Toast.makeText(MainActivity.this,String.valueOf(msg.obj),Toast.LENGTH_LONG).show(); super.handleMessage(msg); } }; private class AcceptThread extends Thread { private BluetoothServerSocket serverSocket; private BluetoothSocket socket; private InputStream is; private OutputStream os; public AcceptThread() { try { serverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME,MY_UUID); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { socket = serverSocket.accept(); is = socket.getInputStream(); os = socket.getOutputStream(); //有数据就从客户端读入,没有数据就阻塞 while (true) { byte[] buffer = new byte[128]; int count = is.read(buffer); Message msg = new Message(); msg.obj = new String(buffer, 0,count,"utf-8"); handler.sendMessage(msg); } } catch (IOException e) { e.printStackTrace(); } } } }
例子代码的地址:
github:https://github.com/sadaharusong/Bluetooth/