版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】Android中怎么实现蓝牙通信
这期内容当中在下将会给大家带来有关Android中怎么实现蓝牙通信,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一:注意事项
1:android6.0使用蓝牙时,需要开启gps定位权限,不然无法搜索其它蓝牙设备。二:权限
1:权限配置<!--允许程序连接到已配对的蓝牙设备-->
<uses-permission
android:name="android.permission.BLUETOOTH"
/>
<!--
允许程序发现和配对蓝牙设备
-->
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
/>
<!--android
6.0
涉及到的权限-->
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
/>
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
/>
<!--
在SDCard中创建与删除文件的权限
-->
<uses-permission
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!--
往SDCard写入数据的权限
-->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2:动态权限代码
由于需要用到存储卡,定位等,android6.0以上需要代码动态设置。
a)获取定位设置if
(Build.VERSION.SDK_INT
>=
23)
{
boolean
isLocat
=
isLocationOpen(getApplicationContext());
Toast.makeText(mContext,
"isLo:"
+
isLocat,
Toast.LENGTH_LONG).show();
//开启位置服务,支持获取ble蓝牙扫描结果
if
(!isLocat)
{
Intent
enableLocate
=
new
Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(enableLocate,
1);
}
}
/**
*
判断位置信息是否开启
*
*
@param
context
*
@return
*/
private
static
boolean
isLocationOpen(final
Context
context)
{
LocationManager
manager
=
(LocationManager)
context.getSystemService(Context.LOCATION_SERVICE);
//gps定位
boolean
isGpsProvider
=
manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
//网络定位
boolean
isNetWorkProvider
=
manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
return
isGpsProvider
||
isNetWorkProvider;
}b)存储卡权限设置if
(Build.VERSION.SDK_INT
>=
23)
{
int
write
=
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
int
read
=
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
//动态请求读写sd卡权限
if
(write
!=
PackageManager.PERMISSION_GRANTED
||
read
!=
PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new
String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE},
SD_CARD);
}
}然后通过onRequestPermissionsResult()方法获取动态权限的结果:@Override
public
void
onRequestPermissionsResult(int
requestCode,
String[]
permissions,
int[]
grantResults)
{
switch
(requestCode){
case
SD_CARD:
if(grantResults.length>0&&grantResults[0]
==
PackageManager.PERMISSION_GRANTED){
//允许访问
}else{
Toast.makeText(mContext,"您拒绝了程序访问存储卡",Toast.LENGTH_LONG).show();
}
break;
case
COARES_LOCATION:
break;
}
}
三:蓝牙搜索android.bluetooth.BluetoothAdapter是蓝牙开发用得比较多,并且比较重要的一个类,可以设备蓝牙名称,打开,关闭,搜索等常规操作。
1蓝牙打开,以及搜索
蓝牙打开和关闭信息使用BluetoothAdapter.ACTION_STATE_CHANGED去接收广播BluetoothAdapter
mBluetoothAdapter
=
BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.setName("blueTestPhone");
//判断蓝牙是否打开
boolean
originalBluetooth
=
(mBluetoothAdapter
!=
null
&&
mBluetoothAdapter.isEnabled());
if
(originalBluetooth)
{
mBluetoothAdapter.startDiscovery();
}
else
if
(originalBluetooth
==
false)
{
mBluetoothAdapter.enable();
}蓝牙打开后,我们可以获取设备的蓝牙信息StringBuilder
sb
=
new
StringBuilder();
//获取本机蓝牙名称
String
name
=
mBluetoothAdapter.getName();
//获取本机蓝牙地址
String
address
=
mBluetoothAdapter.getAddress();搜索完成后,通过BluetoothDevice.ACTION_FOUND广播去接收结果,广播代码如下(注意:可能出现设备搜索不到的情况,设备需要开启允许周围设备搜索,或者通过程序来控制允许搜索的时间范围)
/*确保蓝牙被发现,在荣耀8手机上,设置了还是默认的2分钟,所以以下几句代码程序中没有,*/
Intent
discoverableIntent
=
new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//设置可见状态的持续时间为300秒,但是最多是300秒
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
300);
startActivityForResult(discoverableIntent,
REQUEST_DISCOVERABLE_BLUETOOTH);
private
void
initSearchBroadcast()
{
IntentFilter
intentFilter
=
new
IntentFilter();
//发现设备
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
//设备配对状态改变
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//蓝牙设备状态改变
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
//开始扫描
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
//结束扫描
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//其它设备请求配对
intentFilter.addAction(ACTION_PAIRING_REQUEST);
//intentFilter.addAction(BluetoothAdapter.CONNECTION_STATE_CHANGED);
registerReceiver(bluetoothReceiver,
intentFilter);
}
private
BroadcastReceiver
bluetoothReceiver
=
new
BroadcastReceiver()
{
@Override
public
void
onReceive(Context
context,
Intent
intent)
{
String
action
=
intent.getAction();
Logger.e(TAG
+
"mBluetoothReceiver
action
="
+
action);
try
{
if
(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action))
{//开始扫描
setProgressBarIndeterminateVisibility(true);
log1.setText("正在扫描设备,请稍候...");
}
else
if
(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
{//结束扫描
Logger.e(TAG
+
"设备搜索完毕");
setProgressBarIndeterminateVisibility(false);
log1.setText("扫描完成");
bondAdapter.notifyDataSetChanged();
unbondAdapter.notifyDataSetChanged();
scanStatus
=
false;
}
else
if
(BluetoothDevice.ACTION_FOUND.equals(action))
{//发现设备
findDevice(intent);
}
else
if
(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action))
{//蓝牙配对状态的广播
BluetoothDevice
device
=
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Logger.e(TAG
+
device.getName()
+
"蓝牙配对广播:"
+
device.getBondState());
switch
(device.getBondState())
{
case
BluetoothDevice.BOND_BONDING:
Logger.e(TAG
+
device.getName()
+
"蓝牙配对广播
正在配对");
break;
case
BluetoothDevice.BOND_BONDED:
Logger.e(TAG
+
device.getName()
+
"蓝牙配对广播
完成配对,本机自动配对");
bondDevices.add(device);
unbondDevices.remove(device);
bondAdapter.notifyDataSetChanged();
unbondAdapter.notifyDataSetChanged();
break;
case
BluetoothDevice.BOND_NONE:
Logger.e(TAG
+
device.getName()
+
"蓝牙配对广播
取消配对");
unbondDevices.add(device);
bondDevices.remove(device);
unbondAdapter.notifyDataSetChanged();
bondAdapter.notifyDataSetChanged();
default:
break;
}
}
else
if
(action.equals(ACTION_PAIRING_REQUEST))
{//其它设备蓝牙配对请求
BluetoothDevice
btDevice
=
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int
state
=
intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
BluetoothDevice.BOND_NONE);
//当前的配对的状态
try
{
String
path
=
Environment.getExternalStorageDirectory()
+
"/blueTest/";
String
deviceName
=
btDevice.getName();
Logger.e(TAG
+
"蓝牙
匹配信息:"
+
deviceName
+
","
+
btDevice.getAddress()
+
",state:"
+
state);
//1.确认配对,高版本无效,蓝牙配对不是zuk的问题,而是安卓6.0的bug,凡是遇到蓝牙适配问题的,请同时打开蓝牙和定位,再去配对,基本90%都没有问题了。
Object
object
=
ClsUtils.setPairingConfirmation(btDevice.getClass(),
btDevice,
true);
//2.终止有序广播,如果没有将广播终止,则会出现一个一闪而过的配对框。
abortBroadcast();
//3.调用setPin方法进行配对...
boolean
ret
=
ClsUtils.setPin(btDevice.getClass(),
btDevice,
PWD);
}
catch
(Exception
e)
{
//
TODO
Auto-generated
catch
block
e.printStackTrace();
Toast.makeText(mContenxt,
"error:"
+
btDevice
+
","
+
state,
Toast.LENGTH_LONG).show();
}
}
else
if
(action.equals(BluetoothAdapter.ACTION_STATE_CHANGED))
{//蓝牙开关状态
//
BluetoothDevice
device
=
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int
statue
=
mBluetoothAdapter.getState();
switch
(statue)
{
case
BluetoothAdapter.STATE_OFF:
Logger.e("蓝牙状态:,蓝牙关闭");
ClsUtils.closeDiscoverableTimeout(mBluetoothAdapter);
break;
case
BluetoothAdapter.STATE_ON:
Logger.e("蓝牙状态:,蓝牙打开");
ClsUtils.setDiscoverableTimeout(1000
*
60,
mBluetoothAdapter);
scanBluetooth();
break;
case
BluetoothAdapter.STATE_TURNING_OFF:
Logger.e("蓝牙状态:,蓝牙正在关闭");
mBluetoothAdapter.cancelDiscovery();
break;
case
BluetoothAdapter.STATE_TURNING_ON:
Logger.e("蓝牙状态:,蓝牙正在打开");
break;
}
}
}
catch
(Exception
e)
{
e.printStackTrace();
}
}
};
//发现设备的代码如下
private
void
findDevice(Intent
intent)
throws
Exception{
//获取到设备对象
BluetoothDevice
device
=
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String
str
=
device.getName()
+
"|"
+
device.getAddress();
Logger.e("扫描到设备:"
+
str);
if
(device.getBondState()
==
BluetoothDevice.BOND_BONDED)
{//判断当前设备地址下的device是否已经配对
if
(!bondDevices.contains(device))
{
bondDevices.add(device);
}
}
else
{
if
(!unbondDevices.contains(device))
{
unbondDevices.add(device);
}
if
(device.getName().equals(TEST_DEVICE_NAME))
{
boolean
bondStatus
=
ClsUtils.createBond(device.getClass(),
device);
Logger.i(TAG
+
"
bondStatus:"
+
bondStatus);
}
}
Log.e("error",
"搜索完毕,准备刷新!");
bondAdapter.notifyDataSetChanged();
unbondAdapter.notifyDataSetChanged();
}四:蓝牙配对
正常情况下,蓝牙匹配需要弹出一个匹配确认框,如下图,但我想实现的是,匹配其中一方,不能手动点击配对,因为发起蓝牙连接的设备是android设备,是不能触摸的,所以就要通过程序来解决这个问题,特别声明:(测试的android设备,版本为5.x,并且已经root,没有root的设备,或者不是android5.x不清楚能否实现自动匹配,因为我只有这个测试设备)。1当我们搜索到目标手机的蓝牙后,android设备主动发起连接请求,代码如下
if
(device.getName().equals(TEST_DEVICE_NAME))
{
boolean
bondStatus
=
ClsUtils.createBond(device.getClass(),
device);
Logger.i(TAG
+
"
bondStatus:"
+
bondStatus);
}
//发起蓝牙匹配请求
public
boolean
createBond(Class
btClass,
BluetoothDevice
btDevice)
throws
Exception
{
Method
createBondMethod
=
btClass.getMethod("createBond");
Boolean
returnValue
=
(Boolean)
createBondMethod.invoke(btDevice);
return
returnValue.booleanValue();
}2当被匹配方点击配对后,系统会通过BluetoothDevice.ACTION_BOND_STATE_CHANGED广播告诉android设备,此时android设备就可以自动确认,通过这个流程来完成整个蓝牙的配对,具体代码如下
BluetoothDevice
btDevice
=
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int
state
=
intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
BluetoothDevice.BOND_NONE);
//当前的配对的状态
try
{
String
path
=
Environment.getExternalStorageDirectory()
+
"/blueTest/";
String
deviceName
=
btDevice.getName();
Logger.e(TAG
+
"蓝牙
匹配信息:"
+
deviceName
+
","
+
btDevice.getAddress()
+
",state:"
+
state);
if(deviceName.equals(TEST_DEVICE_NAME)){//TEST_DEVICE_NAME
为被匹配蓝牙设备的名称,自己手动定义
Object
object
=
ClsUtils.setPairingConfirmation(btDevice.getClass(),
btDevice,
true);
abortBroadcast();
boolean
ret
=
ClsUtils.setPin(btDevice.getClass(),
btDevice,
PWD);
}
}
catch
(Exception
e)
{
//
TODO
Auto-generated
catch
block
e.printStackTrace();
Toast.ma
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年敦化市事业单位公开招聘工作人员笔试模拟试题及答案解析
- 《消防年度检测服务合同模板》
- 前台工作中的团队协作计划
- 环保行业加大可再生能源开发计划
- 管理者如何支持员工职业发展计划
- 精细化管理在病房的应用计划
- 学生社团活动支持策略计划
- 开展班级读书分享会的规划计划
- 自我管理与职业发展计划
- 提高语言表达能力提升沟通效果计划
- XX项目不动产权籍调查技术设计书
- 钢筋混凝土结构水泥砂浆钢筋网结构加固方案
- 集成电路测试课件
- 化工技术经济学总概课件
- 公务用车外出派车单
- 家具行业安全事故应急救援预案w
- 胃食管反流病的外科手术适应症及手术技巧课件
- 《合理用药健康教育》课件
- 地下水资源过度开采课件
- 五一劳动节主题班会这些事我来做主PPT课件(带内容)
- (电子对抗技术)课件
评论
0/150
提交评论