【移动应用开发技术】Android中怎么实现蓝牙通信_第1页
【移动应用开发技术】Android中怎么实现蓝牙通信_第2页
【移动应用开发技术】Android中怎么实现蓝牙通信_第3页
【移动应用开发技术】Android中怎么实现蓝牙通信_第4页
【移动应用开发技术】Android中怎么实现蓝牙通信_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论