
蓝牙技术在智能硬件方面有很多用武之地,今天我就为大家分享一下蓝牙在AndroID系统下的使用方法技巧,并实现一下两个终端间数据的传输。
蓝牙(Bluetooth)是一种短距离的无线通信技术标准,蓝牙协议分为4层,即核心协议层、电缆替代协议层、电话控制协议层和采纳的其它协议层。
这4种协议中最重要的是核心协议。蓝牙的核心协议包括基带、链路管理、逻辑链路控制和适应协议四部分。其中链路管理(LMP)负责蓝牙组件间连接的建立。逻辑链路控制与适应协议(L2CAP)位于基带协议层上,属于数据链路层,是一个为高层传输和应用层协议屏蔽基带协议的适配协议。
1.打开和关闭蓝牙
第一种方法相对简单,直接调用系统对话框启动蓝牙:
在AndroIDManifest文件中添加需要的权限,高版本也不需要动态授权:
<uses-permission androID:name="androID.permission.BLUetoOTH" />
startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE),1);
如果不想让用户看到这个对话框,那么我们还可以选择第二种方法,进行静默开启蓝牙。
第二种方法,静默开启,不会有方法一的对话框:
在AndroIDManifest文件中添加需要的权限:
<!-- 已适配AndroID6.0 --><uses-permission androID:name="androID.permission.BLUetoOTH" /><uses-permission androID:name="androID.permission.BLUetoOTH_admin" /><uses-permission androID:name="androID.permission.ACCESS_FINE_LOCATION" /> <uses-permission androID:name="androID.permission.ACCESS_COARSE_LOCATION" /> <uses-feature androID:name="androID.harDWare.bluetooth_le" androID:required="true" />
由于蓝牙所需要的权限包含Dangerous Permissions,所以我们需要在Java代码中进行动态授权处理:
private static final int REQUEST_BLUetoOTH_PERMISSION=10;private voID requestBluetoothPermission(){ //判断系统版本 if (Build.VERSION.SDK_INT >= 23) { //检测当前app是否拥有某个权限 int checkCallPhonePermission = ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION); //判断这个权限是否已经授权过 if(checkCallPhonePermission != PackageManager.PERMISSION_GRANTED){ //判断是否需要 向用户解释,为什么要申请该权限 if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_COARSE_LOCATION)) Toast.makeText(this,"Need bluetooth permission.",Toast.LENGTH_SHORT).show(); ActivityCompat.requestPermissions(this,new String[] {Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_BLUetoOTH_PERMISSION); return; }else{ } } else { }}接下来我们就可以静默开启蓝牙了:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();mBluetoothAdapter.enable(); //开启//mBluetoothAdapter.disable(); //关闭
下面我们来看一下如何通过代码搜索蓝牙设备。
2.通过代码搜索蓝牙设备
搜索分为主动搜索和被动搜索。
我们开始进行主动搜索:
(1)创建BluetoothAdapter对象
TextVIEw tvDevices = (TextVIEw)findVIEwByID(R.ID.tv_devices);BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
(2)我们先获取并显示一下已经配对的蓝牙设备列表
//获取已经配对的蓝牙设备Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();if (pairedDevices.size() > 0) { for (BluetoothDevice device : pairedDevices) { tvDevices.append(device.getname() + ":" + device.getAddress()); }}(3)下面我们定义广播接收器
// 设置广播信息过滤IntentFilter filter = new IntentFilter();filter.addAction(BluetoothDevice.ACTION_FOUND);//每搜索到一个设备就会发送一个该广播filter.addAction(BluetoothAdapter.ACTION_disCOVERY_FINISHED);//当全部搜索完后发送该广播filter.setPriority(Integer.MAX_VALUE);//设置优先级// 注册蓝牙搜索广播接收者,接收并处理搜索结果this.registerReceiver(receiver,filter);
蓝牙设备的广播接收器如下:
/** * 定义广播接收器 */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) { tvDevices.append(device.getname() + ":"+ device.getAddress()); } } else if (BluetoothAdapter.ACTION_disCOVERY_FINISHED.equals(action)) { //已搜素完成 } }};(4)我们创建一个button按钮,当点击button时进行搜索,button点击事件如下:
//如果当前在搜索,就先取消搜索if (mBluetoothAdapter.isdiscovering()) { mBluetoothAdapter.canceldiscovery();}//开启搜索mBluetoothAdapter.startdiscovery();3.蓝牙的UUID
两个蓝牙设备进行连接时需要使用同一个UUID。但很多读者可能发现,有很多型号的手机(可能是非AndroID系统的手机)之间使用了不同的程序也可以使用蓝牙进行通讯。从表面上看,它们之间几乎不可能使用同一个UUID。
UUID的格式如下:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
UUID的格式被分成5段,其中中间3段的字符数相同,都是4,第1段是8个字符,最后一段是12个字符。所以UUID实际上是一个8-4-4-4-12的字符串。
实际上,UUID和TCP的端口一样,也有一些默认的值。例如,将蓝牙模拟成串口的服务就使用了一个标准的UUID:
00001101-0000-1000-8000-00805F9B34FB
除此之外,还有很多标准的UUID,如下面就是两个标准的UUID:
信息同步服务:00001104-0000-1000-8000-00805F9B34FB
文件传输服务:00001106-0000-1000-8000-00805F9B34FB
4.蓝牙终端间数据传输
通过蓝牙传输数据与Socket类似。在网络中使用Socket和ServerSocket控制客户端和服务端的数据读写。而蓝牙通讯也由客户端和服务端Socket来完成。蓝牙客户端Socket是BluetoothSocket,蓝牙服务端Socket是BluetoothServerSocket。这两个类都在androID.bluetooth包中。
无论是BluetoothSocket,还是BluetoothServerSocket,都需要一个UUID(全局唯一标识符,Universally Unique IDentifIEr),UUID相当于Socket的端口,而蓝牙地址相当于Socket的IP。
我们开始进行模拟一个蓝牙数据的传输:
首先来看客户端:
(1)定义全局常量变量
private ListVIEw lvDevices;private BluetoothAdapter mBluetoothAdapter;private List<String> bluetoothDevices = new ArrayList<String>();private ArrayAdapter<String> arrayAdapter;private final UUID MY_UUID = UUID .fromString("abcd1234-ab12-ab12-ab12-abcdef123456");//随便定义一个private BluetoothSocket clIEntSocket;private BluetoothDevice device; private OutputStream os;//输出流(2)在onCreate方法中做初始化 *** 作
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();lvDevices = (ListVIEw) findVIEwByID(R.ID.lv_devices);//获取已经配对的蓝牙设备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);//Activity实现OnItemClickListener接口//每搜索到一个设备就会发送一个该广播IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);this.registerReceiver(receiver,filter);//当全部搜索完后发送该广播filter = new IntentFilter(BluetoothAdapter.ACTION_disCOVERY_FINISHED);this.registerReceiver(receiver,filter);蓝牙设备的广播接收器如下:
/** * 定义广播接收器 */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()); arrayAdapter.notifyDataSetChanged();//更新适配器 } } else if (BluetoothAdapter.ACTION_disCOVERY_FINISHED.equals(action)) { //已搜素完成 } }};(4)我们创建一个button按钮,当点击button时进行搜索,button点击事件如下:
//如果当前在搜索,就先取消搜索if (mBluetoothAdapter.isdiscovering()) { mBluetoothAdapter.canceldiscovery();}//开启搜索mBluetoothAdapter.startdiscovery();(5)接下来我们设置列表的点击事件:
@OverrIDepublic 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(); } try { if (device == null) { //获得远程设备 device = mBluetoothAdapter.getRemoteDevice(address); } if (clIEntSocket == null) { //创建客户端蓝牙Socket clIEntSocket = device.createRfcommSocketToServiceRecord(MY_UUID); //开始连接蓝牙,如果没有配对则d出对话框提示我们进行配对 clIEntSocket.connect(); //获得输出流(客户端指向服务端输出文本) os = clIEntSocket.getoutputStream(); } } catch (Exception e) { } if (os != null) { //往服务端写信息 os.write("蓝牙信息来了".getBytes("utf-8")); } } catch (Exception e) { }}接下来看服务端:
服务端使用的是另一部手机,接受上面手机通过蓝牙发送过来的信息并显示。
(1)定义全局常量变量:
private BluetoothAdapter mBluetoothAdapter;private AcceptThread acceptThread;private final UUID MY_UUID = UUID .fromString("abcd1234-ab12-ab12-ab12-abcdef123456");//和客户端相同的UUIDprivate final String name = "Bluetooth_Socket";private BluetoothServerSocket serverSocket;private BluetoothSocket socket;private inputStream is;//输入流(2)定义服务端线程类:
private Handler handler = new Handler() { public voID handleMessage(Message msg) { Toast.makeText(getApplicationContext(),String.valueOf(msg.obj),Toast.LENGTH_LONG).show(); super.handleMessage(msg); }};//服务端监听客户端的线程类private class AcceptThread extends Thread { public AcceptThread() { try { serverSocket = mBluetoothAdapter.ListenUsingRfcommWithServiceRecord(name,MY_UUID); } catch (Exception e) { } } public voID run() { try { socket = serverSocket.accept(); is = socket.getinputStream(); while(true) { byte[] buffer =new byte[1024]; int count = is.read(buffer); Message msg = new Message(); msg.obj = new String(buffer,count,"utf-8"); handler.sendMessage(msg); } } catch (Exception e) { } }}(3)在onCreate方法中初始化线程类并开启
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();acceptThread = new AcceptThread();acceptThread.start();
我们运行程序看一下效果图:
点击“搜索蓝牙设备”按钮,就会搜索到另一台手机的蓝牙信息,我们点击条目,另一台手机会出现如下变化:
d出Toast,此时证明我们的蓝牙数据已经传输过来了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的详解Android――蓝牙技术 带你实现终端间数据传输全部内容,希望文章能够帮你解决详解Android――蓝牙技术 带你实现终端间数据传输所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)