配色: 字号:
Android BLE与终端通信(二)——Android Bluetooth基础搜索蓝牙设备显示列表
2016-10-17 | 阅:  转:  |  分享 
  
AndroidBLE与终端通信(二)——AndroidBluetooth基础搜索蓝牙设备显示列表

第一篇算是个热身,这一片开始来写些硬菜了,这篇就是实际和蓝牙打交道了,所以要用到真机调试哟,这篇我会把基本上要讲的概念都通俗易懂的来一遍,这样我们脑子里先有个逻辑,我们就好操作了,先看一下我们的剖析图



一.蓝牙简介



蓝牙这个名称来自于第十世纪的一位丹麦国王哈拉尔蓝牙王,Blatand在英文里的意思就是哈拉尔蓝牙王

可以被解释为Bluetooth(蓝牙)因为国王喜欢吃蓝莓,牙龈每天都是蓝色的所以叫蓝牙。

在行业协会筹备阶段,需要一个极具有表现力的名字来命名这项高新技术。行业组织人员,在经过一夜关于欧洲历史和未来无线技术发展的讨论后,有些人认为用Blatand国王的名字命名再合适不过了。Blatand国王将挪威,瑞典和丹麦统一起来;他的口齿伶俐,善于交际,就如同这项即将面世的技术,技术将被定义为允许不同工业领域之间的协调工作,保持着各个系统领域之间的良好交流,例如计算机,手机和汽车行业之间的工作。名字于是就这么定下来了。

蓝牙的创始人是爱立信公司,爱立信早在1994年就已进行研发。1997年,爱立信与其他设备生产商联系,并激发了他们对该项技术的浓厚兴趣。1998年2月,跨国大公司,包括诺基亚、苹果、三星组成的一个特殊兴趣小组(SIG),他们共同的目标是建立一个全球性的小范围无线通信技术,即蓝牙。

而蓝牙这个标志的设计:它取自HaraldBluetooth名字中的「H」和「B」两个字母,用古北欧字母来表示,将这两者结合起来,就成为了蓝牙的logo

二.蓝牙的工作原理



1.蓝牙通信的主从关系



蓝牙技术规定每一对设备之间进行蓝牙通讯时,必须一个为主角色,另一为从角色,

才能进行通信,通信时,必须由主端进行查找,发起配对,建链成功后,双方即可收发数据。理论上,一个蓝牙主端设备,可同时与7个蓝牙从端设备进行通讯。一个具备蓝牙通讯功能的设备,可以在两个角色间切换,平时工作在从模式,等待其它主设备来连接,需要时,转换为主模式,向其它设备发起呼叫。一个蓝牙设备以主模式发起呼叫时,需要知道对方的蓝牙地址,配对密码等信息,配对完成后,可直接发起呼叫。

2.蓝牙的呼叫过程



蓝牙主端设备发起呼叫,首先是查找,找出周围处于可被查找的蓝牙设备。主端设备找到从端蓝牙设备后,与从端蓝牙设备进行配对,此时需要输入从端设备的PIN码,也有设备不需要输入PIN码。配对完成后,从端蓝牙设备会记录主端设备的信任信息,此时主端即可向从端设备发起呼叫,已配对的设备在下次呼叫时,不再需要重新配对。已配对的设备,做为从端的蓝牙耳机也可以发起建链请求,但做数据通讯的蓝牙模块一般不发起呼叫。链路建立成功后,主从两端之间即可进行双向的数据或语音通讯。在通信状态下,主端和从端设备都可以发起断链,断开蓝牙链路。

3.蓝牙一对一的串口数据传输应用



蓝牙数据传输应用中,一对一串口数据通讯是最常见的应用之一,蓝牙设备在出厂前即提前设好两个蓝牙设备之间的配对信息,主端预存有从端设备的PIN码、地址等,两端设备加电即自动建链,透明串口传输,无需外围电路干预。一对一应用中从端设备可以设为两种类型,一是静默状态,即只能与指定的主端通信,不被别的蓝牙设备查找;二是开发状态,既可被指定主端查找,也可以被别的蓝牙设备查找建链。

三.蓝牙Android编程应用



1.相关部署



AndroidBLE与终端通信(一)——AndroidBluetooth基础API以及简单使用获取本地蓝牙名称地址



下面依然会被提及

2.UUID



1.1认识一下UUIDUUID含义是通用唯一识别码(UniversallyUniqueIdentifier),这是一个软件建构的标准,也是被开源软件基金会(OpenSoftwareFoundation,OSF)的组织应用在分布式计算环境(DistributedComputingEnvironment,DCE)领域的一部分。

在蓝牙3.0及一下版本中,UUID被用于唯一标识一个服务,比如文件传输服务,串口服务、打印机服务等,如下:



蓝牙串口服务

SerialPortServiceClass_UUID=‘{00001101-0000-1000-8000-00805F9B34FB}’

LANAccessUsingPPPServiceClass_UUID=‘{00001102-0000-1000-8000-00805F9B34FB}’



拨号网络服务

DialupNetworkingServiceClass_UUID=‘{00001103-0000-1000-8000-00805F9B34FB}’



信息同步服务

IrMCSyncServiceClass_UUID=‘{00001104-0000-1000-8000-00805F9B34FB}’SDP_OBEXObjectPushServiceClass_UUID=‘{00001105-0000-1000-8000-00805F9B34FB}’



文件传输服务

OBEXFileTransferServiceClass_UUID=‘{00001106-0000-1000-8000-00805F9B34FB}’IrMCSyncCommandServiceClass_UUID=‘{00001107-0000-1000-8000-00805F9B34FB}’



蓝牙的连接有主从设备,提供服务的可以认为是从设备。主设备通过UUID访问从设备提供具有相同UUID的服务,从而建立客服端—服务器(C/S)模式。

四.实际应用



我们新建一个Eclipse工程:BluetoothGet



1.蓝牙协议



我们直接看图(简单的概念)



2.蓝牙权限









3.编写程序



activity_main.xml



布局很简单,就一个搜索按钮和一个textview的列表


xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">




android:id="@+id/btnSearch"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="搜索蓝牙设备"/>




android:id="@+id/tvDevices"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>







步骤分析



1.首先获取本地的蓝牙适配器



//获取本地蓝牙适配器

mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();



2.判断手机是否支持蓝牙



//判断手机是否支持蓝牙

if(mBluetoothAdapter==null){

Toast.makeText(this,"设备不支持蓝牙",Toast.LENGTH_SHORT).show();

finish();

}



3.判断蓝牙是否打开



//判断是否打开蓝牙

if(!mBluetoothAdapter.isEnabled()){

//弹出对话框提示用户是后打开

Intentintent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(intent,1);

//不做提示,强行打开

//mBluetoothAdapter.enable();

}



4.获取已经配对的设备



//获取已经配对的设备

SetpairedDevices=mBluetoothAdapter.getBondedDevices();

//判断是否有配对过的设备

if(pairedDevices.size()>0){

for(BluetoothDevicedevice:pairedDevices){

//遍历到列表中

tvDevices.append(device.getName()+":"+device.getAddress());

Log.i("已配对设备",tvDevices.getText().toString());

}

}



5.搜索的点击事件



@Override

publicvoidonClick(Viewv){

switch(v.getId()){

caseR.id.btnSearch:

//设置进度条

setProgressBarIndeterminateVisibility(true);

setTitle("正在搜索...");

//判断是否在搜索,如果在搜索,就取消搜索

if(mBluetoothAdapter.isDiscovering()){

mBluetoothAdapter.cancelDiscovery();

}

//开始搜索

mBluetoothAdapter.startDiscovery();

break;

}

}



6.搜索的广播



1.注册广播



/

异步搜索蓝牙设备——广播接收

/

//找到设备的广播

IntentFilterfilter=newIntentFilter(BluetoothDevice.ACTION_FOUND);

//注册广播

registerReceiver(receiver,filter);

//搜索完成的广播

filter=newIntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

//注册广播

registerReceiver(receiver,filter);



1.广播接收器



//广播接收器

privatefinalBroadcastReceiverreceiver=newBroadcastReceiver(){



@Override

publicvoidonReceive(Contextcontext,Intentintent){

//收到的广播类型

Stringaction=intent.getAction();

//发现设备的广播

if(BluetoothDevice.ACTION_FOUND.equals(action)){

//从intent中获取设备

BluetoothDevicedevice=intent

.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

//判断是否配对过

if(device.getBondState()!=BluetoothDevice.BOND_BONDED){

//添加到列表

tvDevices.append(device.getName()+":"

+device.getAddress()+"\n");

}

//搜索完成

}elseif(BluetoothAdapter.ACTION_DISCOVERY_FINISHED

.equals(action)){

//关闭进度条

setProgressBarIndeterminateVisibility(true);

setTitle("搜索完成!");

}

}

};



好了,到此,我们的程序算是完成了

MainActivity



packagecom.lgl.bluetoothget;



importjava.util.Set;



importandroid.app.Activity;

importandroid.bluetooth.BluetoothAdapter;

importandroid.bluetooth.BluetoothDevice;

importandroid.content.BroadcastReceiver;

importandroid.content.Context;

importandroid.content.Intent;

importandroid.content.IntentFilter;

importandroid.os.Bundle;

importandroid.util.Log;

importandroid.view.View;

importandroid.view.View.OnClickListener;

importandroid.widget.Button;

importandroid.widget.TextView;

importandroid.widget.Toast;



publicclassMainActivityextendsActivityimplementsOnClickListener{



//本地蓝牙适配器

privateBluetoothAdaptermBluetoothAdapter;

//搜索到蓝牙添加

privateTextViewtvDevices;

//搜索蓝牙的按钮

privateButtonbtnSearch;



@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);



initView();

}



privatevoidinitView(){

tvDevices=(TextView)findViewById(R.id.tvDevices);

btnSearch=(Button)findViewById(R.id.btnSearch);

btnSearch.setOnClickwww.shanxiwang.netListener(this);



//获取本地蓝牙适配器

mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();



//判断手机是否支持蓝牙

if(mBluetoothAdapter==null){

Toast.makeText(this,"设备不支持蓝牙",Toast.LENGTH_SHORT).show();

finish();

}



//判断是否打开蓝牙

if(!mBluetoothAdapter.isEnabled()){

//弹出对话框提示用户是后打开

Intentintent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(intent,1);

//不做提示,强行打开

//mBluetoothAdapter.enable();

}



//获取已经配对的设备

SetpairedDevices=mBluetoothAdapter

.getBondedDevices();



//判断是否有配对过的设备

if(pairedDevices.size()>0){

for(BluetoothDevicedevice:pairedDevices){

//遍历到列表中

tvDevices.append(device.getName()+":"+device.getAddress());

Log.i("已配对设备",tvDevices.getText().toString());

}

}



/

异步搜索蓝牙设备——广播接收

/

//找到设备的广播

IntentFilterfilter=newIntentFilter(BluetoothDevice.ACTION_FOUND);

//注册广播

registerReceiver(receiver,filter);

//搜索完成的广播

filter=newIntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

//注册广播

registerReceiver(receiver,filter);

}



@Override

publicvoidonClick(Viewv){

switch(v.getId()){

caseR.id.btnSearch:

//设置进度条

setProgressBarIndeterminateVisibility(true);

setTitle("正在搜索...");

//判断是否在搜索,如果在搜索,就取消搜索

if(mBluetoothAdapter.isDiscovering()){

mBluetoothAdapter.cancelDiscovery();

}

//开始搜索

mBluetoothAdapter.startDiscovery();

break;

}

}



//广播接收器

privatefinalBroadcastReceiverreceiver=newBroadcastReceiver(){



@Override

publicvoidonReceive(Contextcontext,Intentintent){

//收到的广播类型

Stringaction=intent.getAction();

//发现设备的广播

if(BluetoothDevice.ACTION_FOUND.equals(action)){

//从intent中获取设备

BluetoothDevicedevice=intent

.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

//判断是否配对过

if(device.getBondState()!=BluetoothDevice.BOND_BONDED){

//添加到列表

tvDevices.append(device.getName()+":"

+device.getAddress()+"\n");

}

//搜索完成

}elseif(BluetoothAdapter.ACTION_DISCOVERY_FINISHED

.equals(action)){

//关闭进度条

setProgressBarIndeterminateVisibility(true);

setTitle("搜索完成!");

}

}

};

}

我们运行一下



献花(0)
+1
(本文系网络学习天...首藏)