Android蓝牙开发(一)_android 蓝牙 从事开发_000wen_Android的博客-程序员秘密

Android蓝牙开发浅谈

转自:http://www.eoeandroid.com/thread-18993-7-1.html

对于一般的软件开发人员来说,蓝牙是很少用到的,尤其是Android的蓝牙开发,国内的例子很少     Android对于蓝牙开发从2.0版本的sdk才开始支持,而且模拟器不支持,测试至少需要两部手机,所以制约了很多技术人员的开发,刚巧这段时间公司有蓝牙开发的需求,我看了很多国内、国外的资料,又研究了一下J2ME的蓝牙开发(为了找找思路),虽然我想要的功能还没实现(我曾经在很多论坛里问了很多遍,苦于没有高人解答..),我要实现的功能是连接一个硬件设备,凡是跟硬件沾上边的,都让软件人员开发头疼..


好了,废话不说了,鉴于很多开发人员现在也有蓝牙开发的需求,也为了大家少走些弯路,先将我积攒的一点点在Android蓝牙开发经验与大家分享一下!


首先,要操作蓝牙,先要在AndroidManifest.xml里加入权限

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

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


然后,看下api,Android所有关于蓝牙开发的类都在android.bluetooth包下,如下图,只有8个类

                1.jpg

 


而我们需要用到了就只有几个而已:

    1.BluetoothAdapter 顾名思义,蓝牙适配器,直到我们建立bluetoothSocket连接之前,都要不断操作它

      BluetoothAdapter里的方法很多,常用的有以下几个:

      cancelDiscovery() 根据字面意思,是取消发现,也就是说当我们正在搜索设备的时候调用这个方法将不再继续搜索

      disable()关闭蓝牙

      enable()打开蓝牙,这个方法打开蓝牙不会弹出提示,更多的时候我们需要问下用户是否打开,一下这两行代码同样是打开蓝牙,不过会提示用户:

Intemtenabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enabler,reCode);//同startActivity(enabler);

      getAddress()获取本地蓝牙地址

      getDefaultAdapter()获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdapter

      getName()获取本地蓝牙名称

      getRemoteDevice(String address)根据蓝牙地址获取远程蓝牙设备

      getState()获取本地蓝牙适配器当前状态(感觉可能调试的时候更需要)

      isDiscovering()判断当前是否正在查找设备,是返回true

      isEnabled()判断蓝牙是否打开,已打开返回true,否则,返回false

     listenUsingRfcommWithServiceRecord(String name,UUID uuid)根据名称,UUID创建并返回BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步

      startDiscovery()开始搜索,这是搜索的第一步

    2.BluetoothDevice看名字就知道,这个类描述了一个蓝牙设备

      createRfcommSocketToServiceRecord(UUIDuuid)根据UUID创建并返回一个BluetoothSocket


这个方法也是我们获取BluetoothDevice的目的——创建BluetoothSocket


这个类其他的方法,如getAddress(),getName(),同BluetoothAdapter

    3.BluetoothServerSocket如果去除了Bluetooth相信大家一定再熟悉不过了,既然是Socket,方法就应该都差不多,


这个类一种只有三个方法


两个重载的accept(),accept(inttimeout)两者的区别在于后面的方法指定了过时时间,需要注意的是,执行这两个方法的时候,直到接收到了客户端的请求(或是过期之后),都会阻塞线程,应该放在新线程里运行!


还有一点需要注意的是,这两个方法都返回一个BluetoothSocket,最后的连接也是服务器端与客户端的两个BluetoothSocket的连接

      close()这个就不用说了吧,翻译一下——关闭!

    4.BluetoothSocket,跟BluetoothServerSocket相对,是客户端


一共5个方法,不出意外,都会用到

      close(),关闭

      connect()连接

      getInptuStream()获取输入流

      getOutputStream()获取输出流

      getRemoteDevice()获取远程设备,这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备

 

1、获取本地蓝牙适配器

      BluetoothAdapter
mAdapter= BluetoothAdapter.getDefaultAdapter();

      2、打开蓝牙

      if(!mAdapter.isEnabled()){

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

Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enabler, REQUEST_ENABLE);

      //不做提示,强行打开

      // mAdapter.enable();

}

      3、搜索设备


1)
刚才说过了mAdapter.startDiscovery()

是第一步,可以你会发现没有返回的蓝牙设备,怎么知道查找到了呢?向下看,不要急

        2)定义BroadcastReceiver,关于BroadcastReceiver不多讲了,不是今天的讨论内容,代码如下



BroadcastReceiver mReceiver = new BroadcastReceiver() {



public void onReceive(Context context, Intent intent) {


String action = intent.getAction();

                   //找到设备


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



BluetoothDevice device = intent

.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);



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



Log.v(TAG, "find device:" + device.getName()

+ device.getAddress());



}


}


         //
搜索完成


        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED

.equals(action)) {


setTitle("
搜索完成");


if (mNewDevicesAdapter.getCount() == 0) {


Log.v(TAG,"find over");


}


}


//
执行更新列表的代码


}


};


  
这样,没当查找到新设备或是搜索完成,相应的操作都在上段代码的两个if里执行了,不过前提是你要先注册

BroadcastReceiver,具体代码如下


IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);


registerReceiver(mReceiver, filter);


filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);


registerReceiver(mReceiver, filter);


(这段代码,一般写在onCreate()里..)


3
建立连接,首先Android sdk(2.0以上版本)支持的蓝牙连接是通过BluetoothSocket建立连接(说的不对请高人指正),服务器端(BluetoothServerSocket)和客户端(BluetoothSocket)需指定同样的UUID,才能建立连接,因为建立连接的方法会阻塞线程,所以服务器端和客户端都应启动新线程连接

         1)服务器端:


//UUID
格式一般是"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"可到

        //http://www.uuidgenerator.com 申请


BluetoothServerSocket serverSocket = mAdapter. listenUsingRfcommWithServiceRecord(serverSocketName,UUID);


serverSocket.accept();


2)
客户端:


//
还记得我们刚才在BroadcastReceiver获取了BLuetoothDevice么?


BluetoothSocket clienSocket=dcvice. createRfcommSocketToServiceRecord(UUID);


clienSocket.connect();


4
、数据传递,通过以上操作,就已经建立的BluetoothSocket连接了,数据传递无非是通过流的形式


1
)获取流


inputStream = socket.getInputStream();


outputStream = socket.getOutputStream();


2
)写出、读入


这是基础的东西,在这就不多赘述了



终于写完了,这是我这两天的学习经验,希望对有蓝牙需求的朋友有所帮助!另外,之前我们提过

android.bluetooth下有8个类,还有4个类没有用到,那4个类里定义的都是常量,我也没用到它们..


最后把我找到的几个蓝牙的例子附在后面,希望从事软件开发,尤其是Android开发的朋友以后多沟通、多分享!

 

补充一下,使设备能够被搜索
Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(enabler,REQUEST_DISCOVERABLE);
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/aiguoguo000/article/details/51132010

智能推荐

SVR回归_weixin_30249203的博客-程序员秘密

1.python支持向量机回归svr预测https://blog.csdn.net/u012581541/article/details/51181041https://www.cnblogs.com/Lin-Yi/p/8971845.htmlhttps://blog.csdn.net/zhurui_idea/article/details/60329731http://www.d...

Android之拷贝文件夹到sdcard路径下_android预置文件到sdcard_LVXIANGAN的博客-程序员秘密

项目中遇到需求:需要预置文件夹到sdcard路径下,sdcard路径是开机启动时才进行挂载,所以没有办法在ROM制作的时候进行拷贝。解决方案:1、将需要存放到sdcard路径下的文件夹打包成zip文件2、放到apk的assets路径下3、apk加载后,把assets路径的zip文件,拷贝到sdcard路径,然后再进行解压。应用共有三个类:1.MainActivity.java2.CopyIntentService.java3.ZipUtils.java下面就介..

STM8L IWDG WWDG 看门狗最大等待时间_wwdg->cr = 0x80;_叶子丶de花的博客-程序员秘密

IWDG 最大等待时间是:1724.63msWWDG 最大等待时间是:393.216ms如果无法达到要求可以调用:WWDG-&gt;CR = 0X80; 实现无条件复位。IWDG不同设置最大时间:WWDG 不同设置最大时间:

Silverlight 引路蜂二维图形库示例:包定义_iteye_9252的博客-程序员秘密

引路蜂二维图形库Graphics 2D API实现了移动平台(Java ME,Blackberry,iPhone,Android,Windows Phone)上图形引擎,它能够以一种统一的方式处理各种基本图形(Shape),路径(Path),文本(Texts),适量字体及图像。 简单的说来,Graphics 2D API实现了与之对应的Java SE上类似的二维图形库API。主要功能如下:...

基于Matlab的数字图像处理实验:直方图均衡化、傅里叶变换、图像平滑、图像锐化_傅立叶变换时需要掩模_diadestiny的博客-程序员秘密

author:GUET_diadestiny一、 实验题目:用MATLAB或VC或Delphi等实现图像直方图均衡化的算法二、 实验目的掌握直方图均衡化算法的基本原理三、 实验内容读取MATLAB自带图像,对该图像进行直方图均衡化,显示处理前后的图像及直方图的变化,附上代码及相关说明。clc;clear;close all;path(path,'D:\R2019a\toolbox\images\imdata');% 读取路径图像信息im=imread('trees.tif')

月薪上万,却依然不被世界所理解。程序员访谈(二)_chudubai0728的博客-程序员秘密

点击上方关注我们,让小care关爱你! 有一个“月入五万却像月入五千样子”的群体,以“收入高”、“脑回路简单”、“一成不变”等标签在江湖上留下诸多传说。他们可以凭自己一双手写出的代码吸引来创业公司的前两轮融资,也会骄傲地说,“我们就是在改变世界” 走近生活,梦想着用技术改变世界的程序员们...

随便推点

指令寻址方式综合题_weixin_43638873的博客-程序员秘密

综合题1:首先需要想到这个:第(1)题:按照讲解老师的说法,这个题出的有问题,我想应该是因为上面那个表格中有不少的量要依赖估算的缘故。视频给出的答案只是一种通常情况,有一些特例是可以将其驳倒的。第(2)题和这个有关:访存次数最少的就是执行速度最快的,第(2)题:答案中没有提到立即寻址,这是因为在立即寻址中,指令本身的长度可能会更长(可能会不止一个字长),从而导致取值时的访存次数增加,所以它的执行时间就不一定是最快的了。第(3)题:综合题2:...

在前端页面时间戳的转化_前端转时间戳_日常爆炸的菜鸟的博客-程序员秘密

本人是后端人员,因没有前端人员,只能自己写前端代码。在一次处理时间格式时,Date类型数据用 JSON 传到前端时,被转化为时间戳格式,但是我要显示在前端页面的不是这种格式,只能去改格式,后来查到可以用js进行时间戳改类型为 yyyy-MM-dd HH:mm:ss,修改成功方法获取数据// 通过id获取修改的客户信息function editCustomer(url, id) { ...

网络安全之应急响应_网络安全应急响应_赤赤三的博客-程序员秘密

应急响应(是有一整套流程的): 原理: 一个组织为了应对各种意外事件的发生所做的准备以及在事件发生后所采取的措施 阶段: 准备-&gt;启动-&gt;抑制-&gt;根除-&gt;恢复-&gt;跟进 准备应急工具,相应的应急文档、合同、保密协议,开会沟通 启动:讨论这个是怎么进来的 抑制:切断受感染主机,拔网线,网络隔离 根除:查找病毒木马,分析日志,溯源,打补丁 恢复:业务恢复 跟进:监控,看是否还会进来 详细流程: 准备阶段: ..

什么是前后端分离_前后端分离什么意思_leon9512的博客-程序员秘密

前戏前后端分离已成为互联网项目开发的业界标准使用方式,通过nginx+tomcat的方式(也可以中间加一个nodejs)有效的进行解耦,并且前后端分离会为以后的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客户端,例如:浏览器,车载终端,安卓,IOS等等)打下坚实的基础。这个步骤是系统架构从猿进化成人的必经之路。核心思想是前端html页面通过ajax调用后端的restuful ...

Hadoop中的文件压缩和压缩算法配置详解_hadoop 压缩配置 csdn_皮哥四月红的博客-程序员秘密

在MapReduce的Shuffle阶段,可以看到数据通过大量的拷贝,从map阶段输出的数据,都要通过网络拷贝,发送到reduce阶段,这一过程中,涉及到大量的网络IO,如果数据能够进行压缩,那么数据的发送量就会少得多,那么如何配置hadoop的文件压缩呢,以及hadoop当中的文件压缩支持哪些压缩算法呢?1、hadoop当中支持的压缩算法文件压缩有两大好处,节约磁盘空间,加速数据在网络和磁盘上的传输前面我们的hadoop的版本经过我们重新编译之后,我们可以看到我们的hadoop已经支持所有的压

黑马程序员Java课程笔记004方法与方法重载_三千步的博客-程序员秘密

java课程笔记004第一章 开发工具IntelliJ IDEA1.1 IDEA常用快捷键第二章 方法2.1 复习简单方法的使用2.2 方法的定义格式2.3 有参数和无参数的方法2.4 有返回值和无返回值方法2.5 相关练习方法的注意事项第一章 开发工具IntelliJ IDEA1.1 IDEA常用快捷键file–&gt;settings–&gt;editor–&gt;font 改变字体大小快捷键功能Alt+Enter导入包,自动修正代码Ctrl+Y删除光标所在行