精华内容
下载资源
问答
  • Android开发蓝牙与ble设备的通讯,实现扫描、连接、读写功能。 对应博客地址:http://blog.csdn.net/qq_34947883/article/details/78815237 希望可以帮到大家。
  • Android开发蓝牙与ble设备的通讯,实现扫描、连接、读写功能。 对应博客地址:http://blog.csdn.net/qq_34947883/article/details/78815237 希望可以帮到大家。
  • 官网:...使用前保证Android SDK是最新的,同时在Edit->ProjectSettings->Player->Identification中选择合适的Android版本以生成APK。本人手机Android7.1,与HC05蓝牙模块连接,亲测可用
  • Android开发蓝牙与ble设备的通讯,实现扫描、连接、读写功能。 对应博客地址:http://blog.csdn.net/qq_34947883/article/details/78815237 希望可以帮到大家。
  • 最近公司开发需要用到蓝牙,花了大约一天的时间总结整理了一下。主要是为了以后自己方便看。有需要的朋友可以看下。欢迎一起讨论。后面会带上博客。里面是实现了蓝牙搜索,配对,连接,数据互传。
  • Android利用蓝牙广播数据,用于不同设备间通讯,Android和可穿戴设备间通讯.
  • android端通过蓝牙地址获得蓝牙设备对象,实现android设备的蓝牙配对、连接与接收数据

    首先是此部分涉及到的类

    • BluetoothAdapter 蓝牙适配器,即该类里面包含了蓝牙使用中常用到的一些API。
    • BroadcastReceiver 广播接收者,不难猜测,蓝牙设备开启或者关闭、搜索到周边设备就要来通知应用,那么Android系统就会以广播的方式来通知。
    • BluetoothDevice 蓝牙设备,即一个相当于蓝牙设备的类,实现了Parcelable接口,用于Android的IPC通信机制。里面实在广播时发送的蓝牙的相关信息:蓝牙名称,地址,类型和uuid等。

    蓝牙配对操作

    public void makePair(Context context, String address,
                MakePariBlueToothListener mMakePariListener) throws Exception {
            this.mMakePariListener = mMakePariListener;
            this.context = context;
            IntentFilter iFilter = new IntentFilter(
                    BluetoothDevice.ACTION_BOND_STATE_CHANGED);
            context.registerReceiver(mSearchReceiver, iFilter);
    
            enableBlueTooth();
            BluetoothDevice device = BTadapter.getRemoteDevice(address);
    
            device.createBond();
        }

    在蓝牙配对过程中,设备会以广播的方式告知应用配对的过程和结果如:配对开始、配对成功与失败、配对结束等,所以这里创建一个MakePariBlueToothListener 的配对监听器的接口,在配对的广播中调用监听器的各个结果由用户处理配对结果。所以要传递一个配对监听器的对象,还有注册广播接收者。
    之后依据对方蓝牙地址,获取蓝牙设备对象BluetoothDevice,调用Android的api的device.createBond()方法开始蓝牙配对,之后再以广播的方式获取到配对结果。

    public interface MakePariBlueToothListener {
    
        public void whilePari(BluetoothDevice device);
    
        public void pairingSuccess(BluetoothDevice device);
    
        public void cancelPari(BluetoothDevice device);
    }

    在开始配对后调用whilePari( )方法,并将配对的蓝牙设备对象返回给调用者。
    在配对成功后调用pairingSuccess( )方法,也将配对的蓝牙设备对象返回给调用者。
    在配对失败或者取消后调用cancelPari( )方法,也将配对的蓝牙设备对象返回给调用者。

    广播接收者的处理:

    private BroadcastReceiver mSearchReceiver = new BroadcastReceiver() {
    
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                // TODO Auto-generated method stub
                String action = arg1.getAction();
                switch (action) {
                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                    device = arg1.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    switch (device.getBondState()) {
                    case BluetoothDevice.BOND_BONDING:// 正在配对
                        mMakePariListener.whilePari(device);
                        break;
                    case BluetoothDevice.BOND_BONDED:// 配对结束
                        mMakePariListener.pairingSuccess(device);
                        break;
                    case BluetoothDevice.BOND_NONE:// 取消配对/未配对
                        mMakePariListener.cancelPari(device);
                    default:
                        break;
                    }
                    break;
                }
            }
        };

    在广播接收者中,接收到ACTION_BOND_STATE_CHANGED的广播时,说明配对时蓝牙设备的关系状态发生改变,依据改变的状态,调用之前的蓝牙配对监听器的不同方法。
    在收到BOND_BONDING的状态时说明开始配对了,就调用监听器的whilePari( )方法。
    接收到BOND_BONDED的状态时说明已经配对了,并且配对成功了,就可以调用监听器的pairingSuccess( )方法。
    接收到BOND_NONE就表示配对失败了,或者是配对取消了,就可以调用监听器的cancelPari( )方法。
    统一由用户做出不同的相应操作。

    蓝牙连接与接收数据操作

    public BluetoothSocket getBluetoothSocket(String address)
                throws IOException {
            BluetoothDevice device = BTadapter.getRemoteDevice(address);
            BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID
                    .fromString(BlueTooth.MY_UUID));
            return socket;
        }

    首先依据对方的蓝牙地址获取蓝牙设备对象,再从蓝牙设备对象中获取设备连接的Socket,而UUID是由Android设备统一的蓝牙的通用唯一识别码 ,获取到socket后就可以直接在socket中得到对应的输入流和输出流了

    socket.connect();
    InputStream is = socket.getInputStream();

    这里就是先通过socket建立连接后,获取一个输入流的对象,之后就流的操作了,也不再多说了。

    下面贴出整合蓝牙操作的Java源代码:
    码云链接:https://gitee.com/D_inasour/codes/8c5yt4nd2xb9uzml10h7e16
    csdn资源链接:http://download.csdn.net/download/d_inosaur/9946750

    欢迎入门学习交流,系统收费0.1,勿在意:
    欢迎入门学习交流,系统收费0.1,勿在意

    展开全文
  • android开发蓝牙通信

    2017-11-20 08:51:16
    android蓝牙开发,两个手机之间的蓝牙通信,包括自动配对,连接,发送文件
  • VS2019 Xamarin.Android开发蓝牙通讯

    千次阅读 2019-12-18 19:22:33
    注意:不要选成移动应用xamarin.Forms要选android应用(Xamarin)xamarin.Forms 和Xamarin.Android还是有区别的。小项目就用Xamarin.Android就好了 选择空白模板 作为通讯App 必定需要 Server端 所以我们在这里在...

    第一步

    新建项目

    注意:不要选成移动应用xamarin.Forms要选android应用(Xamarin) xamarin.Forms 和 Xamarin.Android还是有区别的。小项目就用Xamarin.Android就好了

    选择空白模板

    作为通讯App 必定需要 Server端 所以我们在这里在新建一个Client端 原本的app1项目作为server端

    在解决方案上右键 添加新的项目

    继续选 Android 应用

    起名字叫app1Client

    继续选空白模板

    OK到这里第一步建立项目就完成了

    下一步我们将开始配置项目了。

    第二步

    配置项目

    Android在使用蓝牙时需要添加4个权限

    在app1项目上 右键属性 Android清单 内找到 所需权限 勾选

    BLUETOOTH(利用这个权限去执行蓝牙通信)

    BLUETOOTH_PRIVILEGED(配对连接时需要)

    BLUETOOTH_ADMIN(让app拥有启动设备发现或操纵蓝牙设置,必须声明BLUETOOTH_ADMIN权限)

    注意:真机android版本6.0及以上使用蓝牙搜索需要开发权限ACCESS_COARSE_LOCATION、ACCESS_FINE_LOCATION

    将App1 和 App1Client 2个项目都添加上述权限

    第三步 编写代码

    怎么添加界面和按钮一类的我就不详细写了 这里主要写怎么实现通讯的部分

    1.获得蓝牙设备 这需要用到 BluetoothAdapter 这个类 

    private readonly BluetoothAdapter localAdapter; 
    localAdapter = BluetoothAdapter.DefaultAdapter;

    localAdapter 就是默认蓝牙适配器了

    BluetoothAdapter 类 提供了 蓝牙适配器的状态 以及打开蓝牙 关闭蓝牙等一些方法 具体内容请自己点进该类查看

    2获取建立服务端的监听和通讯线程

    我先写下思路 我们首先需要一个线程来监听是否有客户端来请求建立连接

    如果建立连接成功就去建立一个通讯线程来读取Client端发来的数据..是不是很简单

    下面我们来是实现

    监听线程方法

    //在你想要启动监听线程的地方添加这个线程
    Thread t = new Thread(Monitor); 
    t.Start();
    
    public void Monitor()
            {
                BluetoothServerSocket serverSock = localAdapter.ListenUsingRfcommWithServiceRecord("Bluetooth", Java.Util.UUID.FromString("0000-0000-0000-0000-1234567"));
                BluetoothSocket sock = null;
                while (true)
                {
                    try
                    {
                        sock = serverSock.Accept();
                    }
                    catch (System.Exception)
                    {
                    }
                    Thread t = new Thread(Connected);
                    t.Start(sock);
                }

    核心方法 localAdapter.ListenUsingRfcommWithServiceRecord

            //
            // 摘要:
            //     Create a listening, secure RFCOMM Bluetooth socket with Service Record.
            //
            // 参数:
            //   name:
            //     service name for SDP record
            //
            //   uuid:
            //     uuid for SDP record
            //
            // 返回结果:
            //     To be added.
            //
            // 异常:
            //   T:Java.IO.IOException:
            //     on error, for example Bluetooth not available, or insufficient permissions, or
            //     channel in use.
            //
            // 言论:
            //     Portions of this page are modifications based on work created and shared by the
            //     Android Open Source Project and used according to terms described in the Creative
            //     Commons 2.5 Attribution License.
            [Register("listenUsingRfcommWithServiceRecord", "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;", "")]
            public BluetoothServerSocket ListenUsingRfcommWithServiceRecord(string name, UUID uuid);

    public BluetoothServerSocket ListenUsingRfcommWithServiceRecord(string name, UUID uuid); 该方法 需要个一个连接名称和一个 UUID 并返回一个BluetoothServerSocket 对象 如果你会Socket的话接下来就很简单了。

    BluetoothServerSocket 类提供了几个建立连接的方法

    Accept()方法返回了一个BluetoothSocket对象

    BluetoothSocket 类提供了蓝牙适配输入输出流的操作

    public Stream OutputStream { get; } //输入流 读操作使用该流
    public Stream InputStream { get; } //输出流 写操作使用该流
    public BluetoothDevice RemoteDevice { get; } //远程设备属性

    接下来我们要实现通讯线程

                    Thread t = new Thread(Connected);
                    t.Start(sock);

    当建立连接成功 执行该代码来新建一个通讯线程 

    由于通讯线程需要该连接的套接字 所以我们要把建立连接成功后的套接字作为参数传递到线程函数内

    通讯线程方法

            public void Connected(object sock)
            {
                BluetoothSocket mSock = (BluetoothSocket)sock;
                byte[] rebuf = new byte[1024];         
                while (true)
                {
                    int len =  mSock.InputStream.Read(rebuf,0, rebuf.Length);
    
                    if (len > 0)
                    {
                        byte[] rebuf2 = new byte[len];
                        Array.Copy(rebuf, 0, rebuf2, 0, len);
                        string str = System.Text.Encoding.ASCII.GetString(rebuf2);
                        Toast.MakeText(this, str, ToastLength.Short).Show();
    
                    }
                    Thread.Sleep(100);
                    
                }

    由于线程启动时传递的参数只能是Object对象所以先将 Object对象转换为BluetoothSocket 对象  BluetoothSocket mSock = (BluetoothSocket)sock;

    然后我们在新建一个缓冲区 用来读取数据 由于我们现在还不知道将要读取的数据有多大。我们可以先建立一个和蓝牙读取缓冲区大小一样的byte数组 byte[] rebuf = new byte[1024]; 当然我这里只用了1KB 蓝牙的读取缓冲区默认好像是4KB 

    接下来我们就每100毫秒区读一下是否有数据 当然你可以用更快的速度来读取如果你一个包的大小很小的话

    //
            // 摘要:
            //     当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。
            //
            // 参数:
            //   buffer:
            //     字节数组。 当此方法返回时,此缓冲区包含指定的字符数组,此数组中 offset 和 (offset + count - 1) 之间的值被从当前源中读取的字节所替换。
            //
            //   offset:
            //     buffer 中的从零开始的字节偏移量,从此处开始存储从当前流中读取的数据。
            //
            //   count:
            //     要从当前流中最多读取的字节数。
            //
            // 返回结果:
            //     读入缓冲区中的总字节数。 如果很多字节当前不可用,则总字节数可能小于请求的字节数;如果已到达流结尾,则为零 (0)。
            //
            // 异常:
            //   T:System.ArgumentException:
            //     offset 和 count 的总和大于缓冲区长度。
            //
            //   T:System.ArgumentNullException:
            //     buffer 为 null。
            //
            //   T:System.ArgumentOutOfRangeException:
            //     offset 或 count 为负数。
            //
            //   T:System.IO.IOException:
            //     出现 I/O 错误。
            //
            //   T:System.NotSupportedException:
            //     流不支持读取。
            //
            //   T:System.ObjectDisposedException:
            //     在流关闭后调用方法。
            public abstract int Read(byte[] buffer, int offset, int count);
    
    
            int len =  mSock.InputStream.Read(rebuf,0, rebuf.Length);

    Read方法返回一个int 类型的对象 表示读到的数据长度

    如果数据长度 > 0

    我们就可以解析了

    byte[] rebuf2 = new byte[len];                   
    Array.Copy(rebuf, 0, rebuf2, 0, len);
    string str = System.Text.Encoding.ASCII.GetString(rebuf2);
    
    

    新建一个 读取到长度大小的byte数组 将读到的数据拷贝到新的数组内进行解析。到这一步 一个最基础的服务端就完成了

    To be continued .......

    下集预告:明天我们将讲解如何写一个客户端来与服务端建立连接

    -------------------------------------------------------------------------------------------------

    本想把客户端的也好好写一篇。可惜工作太忙时间有限。

    我把源码放出来。。

    BLETEST.rar_Xamarin蓝牙通讯-Android代码类资源-CSDN下载

    有需求的自己下载吧

    ----------------------------------------------------------------------------------------

    对一些大家提出的问题回答

    1.说缺少文件的。应该是缺少Xamarin

    感谢下载 Xamarin - Visual Studio

     添加Xamarin

    2.无法连接服务端的

     

    请修改client端

    MainActivity.cs文件内的代码

    void Monitor() 函数内我限定了服务端是HUAWEI P30的设备,请修改为你自己做服务端的设备名称。

    展开全文
  • Android蓝牙串口开发指南
  • 此demo是用来开启蓝牙耳机的Sco模式,进而行录音,然后保存到手机sd卡中的。
  • 它引用了一个Handler对象,以便others能够向它发送消息。该类允许跨进程间基于Message的通信(即两个进程间可以通过Message进行通信),在服务端使用Handler创建一个 Messenger,客户端持有这个Messenger就可以与...
  • 这个demo实现了Android蓝牙开发,创建客户端,服务端。并实现互发消息,接收消息
  • Android5.0蓝牙开发

    2019-03-12 13:39:35
    这是一个用于帮助开发者更好的了解封装包的API,以便于新手更快,更准的上手
  • 作者Jasonchenlijian,源码FastBle,Android BLE 蓝牙快速开发框架,使用回调方式处理:scan、connect、notify、indicate、write、read等一系列蓝牙操作。每一个characteristic会与一个callback形成一一对应的监听...
  • android开发蓝牙demo

    2013-03-29 16:01:05
    android开发蓝牙demo
  • Android studio写了个程序来连接其他设备,但在连接时候出了问题,报错read failed, socket might closed or timeout, read ret: -1,似乎都是socket.connect出问题,uuid也换了挺多都不行,也试过用端口设1值连接...
  • 本例子是一个android蓝牙接收单片机数据并绘制波形的例子。测试可以正常连接另外一个手机,例子里面只实现了蓝牙数据接收,蓝牙数据的发送没有实现。接收到数据以后会绘制不同的图,源码有很详细的注释,需要的朋友...
  • Android蓝牙开发

    2017-03-26 20:39:11
    Android蓝牙开发
  • 讲解了打开蓝牙设备和搜索蓝牙设备,这篇文章来讲解蓝牙配对和蓝牙连接 1.蓝牙配对 搜索到蓝牙设备后,将设备信息填充到listview中,点击listiew则请求配对 蓝牙配对有点击配对和自动配对,点击配对就是我们...

    上篇文章:https://blog.csdn.net/huangliniqng/article/details/82185983

    讲解了打开蓝牙设备和搜索蓝牙设备,这篇文章来讲解蓝牙配对和蓝牙连接

    1.蓝牙配对

       搜索到蓝牙设备后,将设备信息填充到listview中,点击listiew则请求配对

      蓝牙配对有点击配对和自动配对,点击配对就是我们选择设备两个手机弹出配对确认框,点击确认后配对

      自动配对就是搜索到蓝牙设备后自动配对不需要输入pin码,但在基本开发中都不采用这种方式,所以这里说的是第一种配对方式

      点击配对,调用

    BluetoothDevice.class.getMethod
    

    进行配对,代码如下:

    Method method = BluetoothDevice.class.getMethod("createBond");
    Log.e(getPackageName(), "开始配对");
    method.invoke(listdevice.get(position));

    invoke传的参数就是要配对的设备(我这里是存在list中所以从list中取)

    点击之后怎会弹出配对确认框,且必须被配对的手机也点击确认配对才可以配对成功如图:

    同样的,如果我们想要配对的设备取消配对

    只需要将creatBond改为removeBond

    2.蓝牙连接:

      配对成功之后,就可以进行蓝牙连接了,蓝牙连接操作比较耗时,可以在一个线程中进行:

    调用自己定义的

    connect(listdevice.get(position));

    同样传递的参数也是设备device

    首先声明蓝牙套接字:

    private BluetoothSocket mBluetoothSocket;
    mBluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(BltContant.SPP_UUID);

    BltContant.SPP_UUID是一个UUID常量,至于UUID是什么,大家可以自行百度,因为详细的文章已经很多了。

    连接的时候要先判断蓝牙是否在扫描,如果在扫描就停止扫描,并且没有连接才进行连接,代码如下:

    if (bluetoothadapter.isDiscovering()) {
        bluetoothadapter.cancelDiscovery();
    }
    if (!mBluetoothSocket.isConnected()) {
        mBluetoothSocket.connect();
    }

    比如我们让其连接成功后,跳转到消息通讯界面,界面中有edittext输入框并显示当前连接的设备名称如图所示:

    在这里我们需要注意的是,当连接成功时,我们要让被连接的那部手机也自动跳转到聊天页面,所以我们要开启蓝牙服务端等待设备的连接,当设备连接时,自动跳转页面,蓝牙服务端代码如下:

    /**
     * 开启服务端
     */
    public void startBluService() {
    
        while (true) {
            try {
                if (getBluetoothServerSocket() == null){
                    Log.e("在这里获取的为空","在这里获取的为空");
                }
                bluetoothSocket = getBluetoothServerSocket().accept();
                if (bluetoothSocket != null) {
                    APP.bluetoothSocket = bluetoothSocket;
                    EventBus.getDefault().post(new BluRxBean(SERVER_ACCEPT, bluetoothSocket.getRemoteDevice()));
                    //如果你的蓝牙设备只是一对一的连接,则执行以下代码
                    getBluetoothServerSocket().close();
                    //如果你的蓝牙设备是一对多的,则应该调用break;跳出循环
                    //break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    服务端运行也在一个线程中,一直处于等待状态直到有设备连接进来。

    下篇文章 蓝牙通信:https://blog.csdn.net/huangliniqng/article/details/82189735

    欢迎关注技术公众号,微信号搜索ColorfulCode 代码男人

    分享技术文章,投稿分享,不限技术种类,不限技术深度,让更多人因为分享而受益。

    展开全文
  • 用C#语言 xamarin.android 开发蓝牙打印功能,用vs2017开发的源码,还包括引用java jar 包
  • android开发蓝牙的一个简单例子,服务端和客户端的收发文字信息,用于安卓蓝牙开发入门再好不过了
  • Android蓝牙开发必备,是初学者,初级工程师学习Android 蓝牙的必备手册。 主要分为三部分 1.打开蓝牙; 2.查找附近已配对或可用的设备; 3.连接设备; 4.设备间数据 交换。
  • Android蓝牙开发源代码,连接蓝牙打印机,打印标签、条码等。 Android 蓝牙打印机(ESC/POS 热敏打印机),打印小票和图片,对蓝牙配对和连接打印功能进行了封装,让你超快实现蓝牙打印功能。
  • android蓝牙传输文件

    2018-07-20 10:00:34
    蓝牙聊天程序,包括搜索连接,如何发送数据,客户端和服务端
  • android 好用的ble蓝牙调试助手,方便操作,查看服务的UUID
  • Android蓝牙开发全面总结

    万次阅读 多人点赞 2017-11-03 15:19:37
    应用程序层通过安卓API来调用蓝牙的相关功能,这些API使程序无线连接到蓝牙设备,并拥有P2P或者多端无线连接的特性。 蓝牙的功能: 1、扫描其他蓝牙设备 2、为可配对的蓝牙设备查询蓝牙适配器 3、建立...

    基本概念

    安卓平台提供对蓝牙的通讯栈的支持,允许设别和其他的设备进行无线传输数据。应用程序层通过安卓API来调用蓝牙的相关功能,这些API使程序无线连接到蓝牙设备,并拥有P2P或者多端无线连接的特性。

    蓝牙的功能:

    1、扫描其他蓝牙设备

    2、为可配对的蓝牙设备查询蓝牙适配器

    3、建立RFCOMM通道(其实就是尼玛的认证)

    4、通过服务搜索来链接其他的设备

    5、与其他的设备进行数据传输

    6、管理多个连接

    蓝牙建立连接必须要求:

    1、打开蓝牙

    2、查找附近已配对或可用设备

    3、连接设备

    4、设备间数据交互

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

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

    Android所有关于蓝牙开发的类都在android.bluetooth包下,只有8个类

    1.BluetoothAdapter 蓝牙适配器

    直到我们建立bluetoothSocket连接之前,都要不断操作它BluetoothAdapter里的方法很多,常用的有以下几个:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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()开始搜索,这是搜索的第一步
     
    使用BluetoothAdapter的startDiscovery()方法来搜索蓝牙设备
    startDiscovery()方法是一个异步方法,调用后会立即返回。该方法会进行对其他蓝牙设备的搜索,该过程会持续 12 秒。该方法调用后,搜索过程实际上是在一个System Service中进行的,所以可以调用cancelDiscovery()方法来停止搜索(该方法可以在未执行discovery请求时调用)。
    请求Discovery后,系统开始搜索蓝牙设备,在这个过程中,系统会发送以下三个广播:
    ACTION_DISCOVERY_START:开始搜索
    ACTION_DISCOVERY_FINISHED:搜索结束
    ACTION_FOUND:找到设备,这个Intent中包含两个extra fields:EXTRA_DEVICE和EXTRA_CLASS,分别包含BluetooDevice和BluetoothClass。
    我们可以自己注册相应的BroadcastReceiver来接收响应的广播,以便实现某些功能

    2.BluetoothDevice 描述了一个蓝牙设备

    1
    2
    3
    4
    createRfcommSocketToServiceRecord(UUIDuuid)根据UUID创建并返回一个BluetoothSocket
    getState() 蓝牙状态这里要说一下,只有在 BluetoothAdapter.STATE_ON 状态下才可以监听,具体可以看andrid api;
    这个方法也是我们获取BluetoothDevice的目的――创建BluetoothSocket
    这个类其他的方法,如getAddress(),getName(),同BluetoothAdapter

    3.BluetoothServerSocket

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void    close()
    Closes the object and release any system resources it holds.
    void    connect()
    Attempt to connect to a remote device.
    InputStream getInputStream()
    Get the input stream associated with  this  socket.
    OutputStream    getOutputStream()
    Get the output stream associated with  this  socket.
    BluetoothDevice getRemoteDevice()
    Get the remote device  this  socket is connecting, or connected, to.
    获取远程设备,该套接字连接,或连接到---。
    boolean isConnected()
    Get the connection status of  this  socket, ie, whether there is an active connection with remote device.
    判断当前的连接状态

    4.BluetoothSocket

    跟BluetoothServerSocket相对,是客户端一共5个方法,不出意外,都会用到

    1
    2
    3
    4
    5
    close(),关闭
    connect()连接
    getInptuStream()获取输入流
    getOutputStream()获取输出流
    getRemoteDevice()获取远程设备,这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备

    5、BluetoothClass

    代表一个描述了设备通用特性和功能的蓝牙类。比如,一个蓝牙类会指定皆如电话、计算机或耳机的通用设备类型,可以提供皆如音频或者电话的服务。

    每个蓝牙类都是有0个或更多的服务类,以及一个设备类组成。设备类将被分解成主要和较小的设备类部分。

    BluetoothClass 用作一个能粗略描述一个设备(比如关闭用户界面上一个图标的设备)的线索,但当蓝牙服务事实上是被一个设备所支撑的时候,BluetoothClass的 介绍则不那么可信任。精确的服务搜寻通过SDP请求来完成。当运用createRfcommSocketToServiceRecord(UUID) 和listenUsingRfcommWithServiceRecord(String, UUID)来创建RFCOMM端口的时候,SDP请求就会自动执行。

    使用getBluetoothClass()方法来获取为远程设备所提供的类。

    两个内部类:

    class   BluetoothClass.Device

    定义所有设备类的常量

    class   BluetoothClass.Service

    定义所有服务类的常量

    公共方法:

    public int describeContents ()

    描述包含在可封装编组的表示中所有特殊对象的种类。

    返回值 

    一个指示被Parcelabel所排列的特殊对象类型集合的位掩码。

    public boolean equals (Object o)

    比较带有特定目标的常量。如果他们相等则标示出来。 为了保证其相等,o必须代表相同的对象,该对象作为这个使用类依赖比较的常量。通常约定,该比较既要可移植又需灵活。

    当且仅当o是一个作为接收器(使用==操作符来做比较)的精确相同的对象是,这个对象的实现才返回true值。子类通常实现equals(Object)方法,这样它才会重视这两个对象的类型和状态。

    通常约定,对于equals(Object)和hashCode() 方法,如果equals对于任意两个对象返回真值,那么hashCode()必须对这些对象返回相同的纸。这意味着对象的子类通常都覆盖或者都不覆盖这两个方法。

    参数

    o   需要对比常量的对象

    返回值

    如果特定的对象和该对象相等则返回true,否则返回false。

    public int getDeviceClass ()

    返回BluetoothClass中的设备类部分(主要的和较小的)

    从函数中返回的值可以和在BluetoothClass.Device中的公共常量做比较,从而确定哪个设备类在这个蓝牙类中是被编码的。

    返回值

    设备类部分

    public int getMajorDeviceClass ()

    返回BluetoothClass中设备类的主要部分

    从函数中返回的值可以和在BluetoothClass.Device.Major中的公共常量做比较,从而确定哪个主要类在这个蓝牙类中是被编码的。

    返回值

    主要设备类部分

    public boolean hasService (int service)

    如果该指定服务类被BluetoothClass所支持,则返回true

    在BluetoothClass.Service中,合法的服务类是公共常量,比如AUDIO类。

    参数

    service 合法服务类

    返回值

    如果该服务类可被支持,则返回true

    public int hashCode ()

    返回这个对象的整型哈希码。按约定,任意两个在equals(Object)中返回true的对象必须返回相同的哈希码。这意味着对象的子类通常通常覆盖或者都不覆盖这两个方法。

    注意:除非同等对比信息发生改变,否则哈希码不随时间改变而改变。

    public String toString ()  

    返回这个对象的字符串,该字符串包含精确且可读的介绍。系统鼓励子类去重写该方法,并且提供了能对该对象的类型和数据进行重视的实现方法。默认的实现方法只是简单地把类名、“@“符号和该对象hashCode()方法的16进制数连接起来(如下列所示的表达式):

    1
    2
    3
    4
    5
    public  void  writeToParcel (Parcel out,  int  flags)
    将类的数据写入外部提供的Parcel中
    参数
    out     对象需要被写入的Parcel
    flags  和对象需要如何被写入有关的附加标志。可能是 0 ,或者可能是PARCELABLE_WRITE_RETURN_VALUE。

    以上是蓝牙主要操作的类。

    基本用法:

    1、获取本地蓝牙适配器

    1
    BluetoothAdapter mAdapter= BluetoothAdapter.getDefaultAdapter();

    2、打开蓝牙

    1
    2
    3
    4
    5
    6
    7
    if (!mAdapter.isEnabled()){
    //弹出对话框提示用户是后打开
    Intent enabler =  new  Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enabler, REQUEST_ENABLE);
    //不做提示,强行打开,此方法需要权限&lt;uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" /&gt;
    // mAdapter.enable();
    }

    3、搜索设备

    1)mAdapter.startDiscovery() 是第一步,可能你会发现没有返回的蓝牙设备

    2)定义BroadcastReceiver,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // 创建一个接收ACTION_FOUND广播的BroadcastReceiver
    private  final  BroadcastReceiver mReceiver =  new  BroadcastReceiver() {
          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);
                    // 将设备名称和地址放入array adapter,以便在ListView中显示
                    mArrayAdapter.add(device.getName() +  "/n"  + device.getAddress());
               } else  if  (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    if  (mNewDevicesAdapter.getCount() ==  0 ) {
                         Log.v(TAG,  "find over" );
                    }
              }
         };
    // 注册BroadcastReceiver
    IntentFilter filter =  new  IntentFilter(BluetoothDevice.ACTION_FOUND);
    registerReceiver(mReceiver, filter);  // 不要忘了之后解除绑定

    4、建立连接

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

    1
    2
    3
    4
    //UUID格式一般是"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"可到
    BluetoothServerSocket serverSocket = mAdapter. listenUsingRfcommWithServiceRecord(serverSocketName,UUID);
    serverSocket.accept();

    2)客户端:

    1
    2
    3
    //通过BroadcastReceiver获取了BLuetoothDevice
    BluetoothSocket clienSocket=dcvice. createRfcommSocketToServiceRecord(UUID);
    clienSocket.connect();

    5、数据传递

    通过以上操作,就已经建立的BluetoothSocket连接了,数据传递是通过流

    1)获取流

    1
    2
    inputStream = socket.getInputStream();
         outputStream = socket.getOutputStream();

    2)写出、读入(JAVA常规操作)

    补充一下,使设备能够被搜索

    1
    2
    Intent enabler =  new  Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
         startActivityForResult(enabler,REQUEST_DISCOVERABLE);

    关于蓝牙连接:

    可以直接用以下代码进行连接:

    1
    2
    3
    4
    5
    6
    final  String SPP_UUID =  "00001101-0000-1000-8000-00805F9B34FB" ;
    UUID uuid = UUID.fromString(SPP_UUID);
    BluetoothSocket socket;
    socket = device.createInsecureRfcommSocketToServiceRecord(uuid);
    adapter.cancelDiscovery();
    socket.connect();

    1.startDiscovey有可能启动失败

    一般程序中会有两步:开启蓝牙、开始寻找设备。顺序执行了开启蓝牙-寻找设备的步骤,但是由于蓝牙还没有完全打开,就开始寻找设备,导致寻找失败。

    解决办法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    adapter = BluetoothAdapter.getDefaultAdapter();
    if  (adapter ==  null )      {
    // 设备不支持蓝牙
    }
    // 打开蓝牙
    if  (!adapter.isEnabled()){
         adapter.enable();
         adapter.cancelDiscovery();
    }
    // 寻找蓝牙设备,android会将查找到的设备以广播形式发出去
    while  (!adapter.startDiscovery()){
         Log.e( "BlueTooth" "尝试失败" );
         try  {
             Thread.sleep( 100 );
         catch  (InterruptedException e) {
             e.printStackTrace();
         }
    }

    2.接收数据转换

    使用socket.getInputStream接收到的数据是字节流,这样的数据是没法分析的,所以很多情况需要一个byte转十六进制String的函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public  static  String bytesToHex( byte [] bytes) {
         char [] hexChars =  new  char [bytes.length *  2 ];
         for  int  j =  0 ; j &lt; bytes.length; j++ ) {
             int  v = bytes[j] &amp;  0xFF ;
             hexChars[j *  2 ] = hexArray[v &gt;&gt;&gt;  4 ];
             hexChars[j *  2  1 ] = hexArray[v &amp;  0x0F ];
         }
         return  new  String(hexChars);
    }
    展开全文
  • 请问各位大神:是否可以通过蓝牙发送一条强制下线广播,使接受到广播的设备强制下线?如果可以的话,请问应该如何实现?谢谢!!!
  • Android蓝牙开发—经典蓝牙详细开发流程

    万次阅读 多人点赞 2018-07-16 13:41:12
    Android蓝牙开发前,首先要区分是经典蓝牙开发还是BLE(低功耗)蓝牙开发,它们的开发是有区别的,如果还分不清经典蓝牙和BLE(低功耗)蓝牙的小伙伴,可以先看Android蓝牙开发—经典蓝牙和BLE(低功耗)蓝牙的区别 ...
  • Android BLE 蓝牙开发框架,使用回调方式处理,搜索、连接、notify、indicate、读、写等一系列蓝牙操作

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,406
精华内容 12,162
关键字:

安卓开发蓝牙