android蓝牙系列——基础科普以及搜索蓝牙设备显示列表

摘要

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

下面概念相关的可去原文查看:http://www.epx.com.br/artigos/bluetooth_gatt.php

一.蓝牙简介

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

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

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

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

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

二.蓝牙的工作原理

1.蓝牙通信的主从关系

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

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

2.蓝牙的呼叫过程

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

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

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

三.蓝牙 Android 编程应用

1.相关部署

参考获取本地蓝牙

2.UUID

1.1 认识一下 UUID UUID 含义是通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标 准,也是被开源软件基金会 (Open Software Foundation, OSF) 的组织应用在分布式计算 环境 (Distributed Computing Environment, 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.蓝牙权限

<uses-permissionandroid:name="android.permission.BLUETOOTH"/>

<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>

3.编写程序

activity_main.xml

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

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

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

<Button

android:id="@+id/btnSearch"

android:layout_width="match_parent"

android:layout_height="wrap_content"

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

<TextView

android:id="@+id/tvDevices"

android:layout_width="wrap_content"

android:layout_height="wrap_content" />

</LinearLayout>

步骤分析

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

// 获取本地蓝牙适配器

mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();

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

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

if (mBluetoothAdapter == null) {

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

finish();

}

3.判断蓝牙是否打开

// 判断是否打开蓝牙

if (!mBluetoothAdapter.isEnabled()) {

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

Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(intent, 1);

// 不做提示,强行打开

// mBluetoothAdapter.enable();

}

4.获取已经配对的设备// 获取已经配对的设备    SetpairedDevices = mBluetoothAdapter.getBondedDevices();

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

if (pairedDevices.size() > 0) {

for (BluetoothDevice device : pairedDevices) {

// 遍历到列表中

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

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

}

}

5.搜索的点击事件

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.btnSearch:

//设置进度条

setProgressBarIndeterminateVisibility(true);

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

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

if (mBluetoothAdapter.isDiscovering()) {

mBluetoothAdapter.cancelDiscovery();

}

// 开始搜索

mBluetoothAdapter.startDiscovery();

break;

}

}

6.搜索的广播

1.注册广播

/**

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

*/

// 找到设备的广播

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

// 注册广播

registerReceiver(receiver, filter);

// 搜索完成的广播

filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

// 注册广播

registerReceiver(receiver, filter);

1.广播接收器

// 广播接收器

private final BroadcastReceiver receiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

// 收到的广播类型

String action = intent.getAction();

// 发现设备的广播

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

// 从intent中获取设备

BluetoothDevice device = intent

.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// 判断是否配对过

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

// 添加到列表

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

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

}

// 搜索完成

} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED

.equals(action)) {

//关闭进度条

setProgressBarIndeterminateVisibility(true);

setTitle("搜索完成!");

}

}

};

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

MainActivity

package com.lgl.bluetoothget;

import java.util.Set;

import android.app.Activity;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

// 本地蓝牙适配器

private BluetoothAdapter mBluetoothAdapter;

// 搜索到蓝牙添加

private TextView tvDevices;

// 搜索蓝牙的按钮

private Button btnSearch;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

}

private void initView() {     

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

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

   btnSearch.setOnClickListener(this);     

   // 获取本地蓝牙适配器     

   mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();     

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

   if (mBluetoothAdapter == null) {         

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

      finish();     

   }     

   // 判断是否打开蓝牙   

   if (!mBluetoothAdapter.isEnabled()) {        

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

    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);            

    startActivityForResult(intent, 1);           

     // 不做提示,强行打开         

     // mBluetoothAdapter.enable();     

   }     

   // 获取已经配对的设备      

  SetpairedDevices = mBluetoothAdapter

.getBondedDevices();

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

if (pairedDevices.size() > 0) {

for (BluetoothDevice device : pairedDevices) {

// 遍历到列表中

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

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

}

}

/**

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

*/

// 找到设备的广播

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

// 注册广播

registerReceiver(receiver, filter);

// 搜索完成的广播

filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

// 注册广播

registerReceiver(receiver, filter);

}

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.btnSearch:

// 设置进度条

setProgressBarIndeterminateVisibility(true);

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

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

if (mBluetoothAdapter.isDiscovering()) {

mBluetoothAdapter.cancelDiscovery();

}

// 开始搜索

mBluetoothAdapter.startDiscovery();

break;

}

}

// 广播接收器

private final BroadcastReceiver receiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

// 收到的广播类型

String action = intent.getAction();

// 发现设备的广播

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

// 从intent中获取设备

BluetoothDevice device = intent

.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// 判断是否配对过

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

// 添加到列表

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

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

}

// 搜索完成

} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED

.equals(action)) {

// 关闭进度条

setProgressBarIndeterminateVisibility(true);

setTitle("搜索完成!");

}

}

};

}

我们运行一下

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容