详解Android——蓝⽛技术带你实现终端间数据传输
蓝⽛技术在智能硬件⽅⾯有很多⽤武之地,今天我就为⼤家分享⼀下蓝⽛在Android系统下的使⽤⽅法技巧,并实现⼀下两个
终端间数据的传输。
蓝⽛(Bluetooth)是⼀种短距离的⽆线通信技术标准,蓝⽛协议分为4层,即核⼼协议层、电缆替代协议层、电话控制协议层
和采纳的其它协议层。
这4种协议中最重要的是核⼼协议。蓝⽛的核⼼协议包括基带、链路管理、逻辑链路控制和适应协议四部分。其中链路管理
(LMP)负责蓝⽛组件间连接的建⽴。逻辑链路控制与适应协议(L2CAP)位于基带协议层上,属于数据链路层,是⼀个为
⾼层传输和应⽤层协议屏蔽基带协议的适配协议。
1.打开和关闭蓝⽛
第⼀种⽅法相对简单,直接调⽤系统对话框启动蓝⽛:
在AndroidManifest⽂件中添加需要的权限,⾼版本也不需要动态授权:
startActivityForResult(newIntent(_REQUEST_ENABLE),1);
如果不想让⽤户看到这个对话框,那么我们还可以选择第⼆种⽅法,进⾏静默开启蓝⽛。
第⼆种⽅法,静默开启,不会有⽅法⼀的对话框:
在AndroidManifest⽂件中添加需要的权限:
android:name="oth_le"
android:required="true"/>
由于蓝⽛所需要的权限包含DangerousPermissions,所以我们需要在Java代码中进⾏动态授权处理:
privatestaticfinalintREQUEST_BLUETOOTH_PERMISSION=10;
privatevoidrequestBluetoothPermission(){
//判断系统版本
if(_INT>=23){
//检测当前app是否拥有某个权限
intcheckCallPhonePermission=elfPermission(this,
_COARSE_LOCATION);
//判断这个权限是否已经授权过
if(checkCallPhonePermission!=SION_GRANTED){
//判断是否需要向⽤户解释,为什么要申请该权限
if(ShowRequestPermissionRationale(this,
_COARSE_LOCATION))
xt(this,"Needbluetoothpermission.",
_SHORT).show();
tPermissions(this,newString[]
{_COARSE_LOCATION},REQUEST_BLUETOOTH_PERMISSION);
return;
}el{
}
}el{
}
}
接下来我们就可以静默开启蓝⽛了:
BluetoothAdaptermBluetoothAdapter=aultAdapter();
();//开启
//e();//关闭
下⾯我们来看⼀下如何通过代码搜索蓝⽛设备。
2.通过代码搜索蓝⽛设备
搜索分为主动搜索和被动搜索。
我们开始进⾏主动搜索:
(1)创建BluetoothAdapter对象
TextViewtvDevices=(TextView)findViewById(_devices);
BluetoothAdaptermBluetoothAdapter=aultAdapter();
(2)我们先获取并显⽰⼀下已经配对的蓝⽛设备列表
//获取已经配对的蓝⽛设备
Set
if(()>0){
for(BluetoothDevicedevice:pairedDevices){
(e()+":"+ress());
}
}
(3)下⾯我们定义⼴播接收器
//设置⼴播信息过滤
IntentFilterfilter=newIntentFilter();
ion(_FOUND);//每搜索到⼀个设备就会发送⼀个该⼴播
ion(_DISCOVERY_FINISHED);//当全部搜索完后发送该⼴播
ority(_VALUE);//设置优先级
//注册蓝⽛搜索⼴播接收者,接收并处理搜索结果
erReceiver(receiver,filter);
蓝⽛设备的⼴播接收器如下:
/**
*定义⼴播接收器
*/
privatefinalBroadcastReceiverreceiver=newBroadcastReceiver(){
@Override
publicvoidonReceive(Contextcontext,Intentintent){
Stringaction=ion();
if(_(action)){
BluetoothDevicedevice=celableExtra(_DEVICE);
if(dState()!=_BONDED){
(e()+":"+ress());
}
}elif(_DISCOVERY_(action)){
//已搜素完成
}
}
};
(4)我们创建⼀个Button按钮,当点击Button时进⾏搜索,Button点击事件如下:
//如果当前在搜索,就先取消搜索
if(overing()){
Discovery();
}
//开启搜索
iscovery();
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。这两个类
都在oth包中。
⽆论是BluetoothSocket,还是BluetoothServerSocket,都需要⼀个UUID(全局唯⼀标识符,UniversallyUnique
Identifier),UUID相当于Socket的端⼝,⽽蓝⽛地址相当于Socket的IP。
我们开始进⾏模拟⼀个蓝⽛数据的传输:
⾸先来看客户端:
(1)定义全局常量变量
privateListViewlvDevices;
privateBluetoothAdaptermBluetoothAdapter;
privateList
privateArrayAdapter
privatefinalUUIDMY_UUID=UUID
.fromString("abcd1234-ab12-ab12-ab12-abcdef123456");//随便定义⼀个
privateBluetoothSocketclientSocket;
privateBluetoothDevicedevice;
privateOutputStreamos;//输出流
(2)在onCreate⽅法中做初始化操作
mBluetoothAdapter=aultAdapter();
lvDevices=(ListView)findViewById(_devices);
//获取已经配对的蓝⽛设备
Set
if(()>0){
for(BluetoothDevicedevice:pairedDevices){
(e()+":"+ress());
}
}
arrayAdapter=newArrayAdapter
_list_item_1,1,bluetoothDevices);
pter(arrayAdapter);
temClickListener(this);//Activity实现OnItemClickListener接⼝
//每搜索到⼀个设备就会发送⼀个该⼴播
IntentFilterfilter=newIntentFilter(_FOUND);
erReceiver(receiver,filter);
//当全部搜索完后发送该⼴播
filter=newIntentFilter(_DISCOVERY_FINISHED);
erReceiver(receiver,filter);
蓝⽛设备的⼴播接收器如下:
/**
*定义⼴播接收器
*/
privatefinalBroadcastReceiverreceiver=newBroadcastReceiver(){
@Override
publicvoidonReceive(Contextcontext,Intentintent){
Stringaction=ion();
if(_(action)){
BluetoothDevicedevice=celableExtra(_DEVICE);
if(dState()!=_BONDED){
(e()+":"+ress());
DataSetChanged();//更新适配器
}
}elif(_DISCOVERY_(action)){
//已搜素完成
}
}
};
(4)我们创建⼀个Button按钮,当点击Button时进⾏搜索,Button点击事件如下:
//如果当前在搜索,就先取消搜索
if(overing()){
Discovery();
}
//开启搜索
iscovery();
(5)接下来我们设置列表的点击事件:
@Override
publicvoidonItemClick(AdapterView<?>parent,Viewview,intposition,longid){
Strings=m(position);
Stringaddress=ing(f(":")+1).trim();//把地址解析出来
//主动连接蓝⽛服务端
try{
//判断当前是否正在搜索
if(overing()){
Discovery();
}
try{
if(device==null){
//获得远程设备
device=oteDevice(address);
}
if(clientSocket==null){
//创建客户端蓝⽛Socket
clientSocket=RfcommSocketToServiceRecord(MY_UUID);
//开始连接蓝⽛,如果没有配对则弹出对话框提⽰我们进⾏配对
t();
//获得输出流(客户端指向服务端输出⽂本)
os=putStream();
}
}catch(Exceptione){
}
if(os!=null){
//往服务端写信息
("蓝⽛信息来了".getBytes("utf-8"));
}
}catch(Exceptione){
}
}
接下来看服务端:
服务端使⽤的是另⼀部⼿机,接受上⾯⼿机通过蓝⽛发送过来的信息并显⽰。
(1)定义全局常量变量:
privateBluetoothAdaptermBluetoothAdapter;
privateAcceptThreadacceptThread;
privatefinalUUIDMY_UUID=UUID
.fromString("abcd1234-ab12-ab12-ab12-abcdef123456");//和客户端相同的UUID
privatefinalStringNAME="Bluetooth_Socket";
privateBluetoothServerSocketrverSocket;
privateBluetoothSocketsocket;
privateInputStreamis;//输⼊流
(2)定义服务端线程类:
privateHandlerhandler=newHandler(){
publicvoidhandleMessage(Messagemsg){
xt(getApplicationContext(),f(),
_LONG).show();
Message(msg);
}
};
//服务端监听客户端的线程类
privateclassAcceptThreadextendsThread{
publicAcceptThread(){
try{
rverSocket=UsingRfcommWithServiceRecord(NAME,MY_UUID);
}catch(Exceptione){
}
}
publicvoidrun(){
try{
socket=();
is=utStream();
while(true){
byte[]buffer=newbyte[1024];
intcount=(buffer);
Messagemsg=newMessage();
=newString(buffer,0,count,"utf-8");
ssage(msg);
}
}
catch(Exceptione){
}
}
}
(3)在onCreate⽅法中初始化线程类并开启
mBluetoothAdapter=aultAdapter();
acceptThread=newAcceptThread();
();
我们运⾏程序看⼀下效果图:
点击“搜索蓝⽛设备”按钮,就会搜索到另⼀台⼿机的蓝⽛信息,我们点击条⽬,另⼀台⼿机会出现如下变化:
弹出Toast,此时证明我们的蓝⽛数据已经传输过来了。
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
本文发布于:2023-03-09 05:53:36,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/1678312417190963.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:如何用蓝牙传照片.doc
本文 PDF 下载地址:如何用蓝牙传照片.pdf
留言与评论(共有 0 条评论) |