安卓安卓手机连接蓝牙鼠标标是怎么实现的

Android平台支持蓝牙网络协议栈,实现蓝牙设备之间数据的无线传输。
本文档描述了怎样利用android平台提供的蓝牙API去实现蓝牙设备之间的通信,蓝牙设备之间的通信主要包括了四个步骤:设置蓝牙设备、寻找局域网内可能或者匹配的设备、连接设备和设备之间的数据传输。以下是建立蓝牙连接的所需要的一些基本类:
&&类:代表了一个本地的蓝牙适配器。他是所有蓝牙交互的的入口点。利用它你可以发现其他蓝牙设备,查询绑定了的设备,使用已知的MAC地址实例化一个蓝牙设备和建立一个(作为服务器端)来监听来自其他设备的连接。
&&类:代表了一个远端的蓝牙设备,使用它请求远端蓝牙设备连接或者获取远端蓝牙设备的名称、地址、种类和绑定状态。(其信息是封装在bluetoothsocket中)。
&&Bluetoothsocket类:代表了一个蓝牙套接字的接口(类似于tcp中的套接字),他是应用程序通过输入、输出流与其他蓝牙设备通信的连接点。
&&Blueboothserversocket类:代表打开服务连接来监听可能到来的连接请求(属于server端),为了连接两个蓝牙设备必须有一个设备作为服务器打开一个服务套接字。当远端设备发起连接连接请求的时候,并且已经连接到了的时候,Blueboothserversocket类将会返回一个bluetoothsocket。
&&Bluetoothclass类:描述了一个蓝牙设备的一般特点和能力。他的只读属性集定义了设备的主、次设备类和一些相关服务。然而,他并没有准确的描述所有该设备所支持的蓝牙文件和服务,而是作为对设备种类来说的一个小小暗示。
下面说说具体的编程实现:
必须确定你的设备支持蓝牙,并保证他可以用。如果你的设备支持蓝牙,将它使能。当然,有两种方法,一种是在你的系统设置里开启蓝牙,另外一中是在你的应用程序里启动蓝牙功能,第一种方法就不讲了,具体讲一个第二种方法:
&首先通过调用静态方法获取蓝牙适配器bluetoothadapter,以后你就可以使用该对象了。如果返回为空,the story is over。
&Eg:BluetoothAdapter&mBluetoothAdapter&=&BluetoothAdapter.getDefaultAdapter();if&(mBluetoothAdapter&==&null)&{& &&// Device does not support Bluetooth}
其次,调用来查询当前蓝牙设备的状态,如果返回为false,则表示蓝牙设备没有开启,接下来你需要封装一个请求到intent里面,调用方法使能蓝牙设备,例如:
if&(!mBluetoothAdapter.isEnabled())&{&&&&&&&&&&&&&Intent&enableBtIntent&=&newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);& & startActivityForResult(enableBtIntent,&REQUEST_ENABLE_BT);}
至此,如不出意外,恭喜你的蓝牙设备已经开启了,接下来需要查找周边可能存在的蓝牙设备了。
查找设备:
&&使用bluetoothadapter类里的方法,你可以查找远端设备(不过蓝牙查找的范围好像是在十米以内吧)或者查询在你手机上已经匹配(或者说绑定)的其他手机了。当然需要确定对方蓝牙设备已经开启或者已经开启了&被发现使能&功能(对方设备是可以被发现的是你能够发起连接的前提条件)。如果该设备是可以被发现的,会反馈回来一些对方的设备信息,比如名字、MAC地址等,利用这些信息,你的设备就可以选择去向对方初始化一个连接。
如果你是第一次与该设备连接,那么一个配对的请求就会自动的显示给用户。当设备配对好之后,他的一些基本信息(主要是名字和MAC)被保存下来并可以使用蓝牙的API来读取。使用已知的MAC地址就可以对远端的蓝牙设备发起连接请求。
&&匹配好的设备和连接上的设备的不同点:匹配好只是说明对方设备发现了你的存在,并拥有一个共同的识别码,并且可以连接。连接上:表示当前设备共享一个RFCOMM信道并且两者之间可以交换数据。也就是是说蓝牙设备在建立RFCOMM信道之前,必须是已经配对好了的。
&怎么查询匹配好的设备:
&在建立连接之前你必须先查询配对好了的蓝牙设备集(你周围的蓝牙设备可能不止一个),以便你选取哪一个设备进行通信,例如你可以你可以查询所有配对的蓝牙设备,并使用一个数组适配器将其打印显示出来:
&&Set&BluetoothDevice&&pairedDevices&=&mBluetoothAdapter.getBondedDevices();// If there are paired devicesif&(pairedDevices.size()&&&0)&{& &&// Loop through paired devices&&&&for&(BluetoothDevice&device&:&pairedDevices)&{& & & &&// Add the name and address to an array adapter to show in a ListView& & & & mArrayAdapter.add(device.getName()&+&"/n"&+&device.getAddress());& &&}
建立一个蓝牙连接只需要MAC地址就已经足够了。
扫描设备:
&&&扫描设备,只需要简单的调用方法,这个扫描的过程大概持续是12秒,应用程序为了动作需要注册一个BroadcastReceiver来接受设备扫描到的信息。对于每一个设备,系统都会广播动作。例如:
&&&// Create a BroadcastReceiver for ACTION_FOUNDprivate&final&BroadcastReceiver&mReceiver&=&new&BroadcastReceiver()&{& &&public&void&onReceive(Context&context,&Intent&intent)&{& & & &&String&action&=&intent.getAction();& & & &&// When discovery finds a device& & & &&if&(BluetoothDevice.ACTION_FOUND.equals(action))&{& & & & & &&// Get the BluetoothDevice object from the Intent& & & & & &&BluetoothDevice&device&=&intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);& & & & & &&// Add the name and address to an array adapter to show in a ListView& & & & & & mArrayAdapter.add(device.getName()&+&"/n"&+&device.getAddress());& & & &&}& &&}};// Register the BroadcastReceiverIntentFilter&filter&=&new&IntentFilter(BluetoothDevice.ACTION_FOUND);registerReceiver(mReceiver,&filter);&// Don't forget to unregister during onDestroy
注意:扫描的过程是一个很耗费资源的过程,一旦你找到你需要的设备之后,在发起连接请求之前,确保你的程序调用方法停止扫描。显然,如果你已经连接上一个设备,启动扫描会减少你的通信带宽。
&&使能被发现:Enabling discoverability
&&如果你想使你的设备能够被其他设备发现,将动作封装在intent中并调用方法就可以了。他将在不使你应用程序退出的情况下使你的设备能够被发现。缺省情况下的使能时间是120秒,当然你可以可以通过添加字段来改变使能时间(最大不超过300秒,这是出于对你设备上的信息安全考虑)。例如:
Intent&discoverableIntent&=&newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,&300);startActivity(discoverableIntent);
运行该段代码之后,系统会弹出一个对话框来提示你启动设备使能被发现(次过程中如果你的蓝牙功能没有开启,系统会帮你开启),并且如果你准备对该远端设备发现一个连接,你不需要开启使能设备被发现功能,以为该功能只是在你的应用程序作为服务器端的时候才需要。
连接设备:
&&在你的应用程序中,想建立两个蓝牙设备之间的连接,你必须实现客户端和服务器端的代码(因为任何一个设备都必须可以作为服务端或者客户端)。一个开启服务来监听,一个发起连接请求(使用服务器端设备的MAC地址)。当他们都拥有一个蓝牙套接字在同一RFECOMM信道上的时候,可以认为他们之间已经连接上了。服务端和客户端通过不同的方式或其他们的蓝牙套接字。当一个连接监听到的时候,服务端获取到蓝牙套接字。当客户可打开一个FRCOMM信道给服务器端的时候,客户端获取到蓝牙套接字。
&注意:在此过程中,如果两个蓝牙设备还没有配对好的,android系统会通过一个通知或者对话框的形式来通知用户。RFCOMM连接请求会在用户选择之前阻塞。如下图:
服务端的连接:
&当你想要连接两台设备时,一个必须作为服务端(通过持有一个打开的bluetoothserversocket),目的是监听外来连接请求,当监听到以后提供一个连接上的bluetoothsocket给客户端,当客户端从bluetoothserversocket得到bluetoothsocket以后就可以销毁bluetoothserversocket,除非你还想监听更多的连接请求。
&&建立服务套接字和监听连接的基本步骤:
&首先通过调用方法来获取bluetoothserversocket对象,参数string代表了该服务的名称,UUID代表了和客户端连接的一个标识(128位格式的字符串ID,相当于pin码),UUID必须双方匹配才可以建立连接。其次调用accept()方法来监听可能到来的连接请求,当监听到以后,返回一个连接上的蓝牙套接字bluetoothsocket。最后,在监听到一个连接以后,需要调用close()方法来关闭监听程序。(一般蓝牙设备之间是点对点的传输)
注意:accept()方法不应该放在主Acitvity里面,因为他是一种阻塞调用(在没有监听到连接请求之间程序就一直停在那里)。解决方法是新建一个线程来管理。例如:
&private&class&AcceptThread&extends&Thread&{& &&private&final&BluetoothServerSocket&mmServerS& &&public&AcceptThread()&{& & & &&// Use a temporary object that is later assigned to mmServerSocket,& & & &&// because mmServerSocket is final& & & &&BluetoothServerSocket&tmp&=&& & & &&try&{& & & & & &&// MY_UUID is the app's UUID string, also used by the client code& & & & & & tmp&=&mAdapter.listenUsingRfcommWithServiceRecord(NAME,&MY_UUID);& & & &&}&catch&(IOException&e)&{&}& & & & mmServerSocket&=&& &&}& &&public&void&run()&{& & & &&BluetoothSocket&socket&=&& & & &&// Keep listening until exception occurs or a socket is returned& & & &&while&(true)&{& & & & & &&try&{& & & & & & & & socket&=&mmServerSocket.accept();& & & & & &&}&catch&(IOException&e)&{& & & & & & & &&& & & & & &&}& & & & & &&// If a connection was accepted& & & & & &&if&(socket&!=&null)&{& & & & & & & &&// Do work to manage the connection (in a separate thread)& & & & & & & & manageConnectedSocket(socket);& & & & & & & & mmServerSocket.close();& & & & & & & &&& & & & & &&}& & & &&}& &&}& &&/** Will cancel the listening socket, and cause the thread to finish */& &&public&void&cancel()&{& & & &&try&{& & & & & & mmServerSocket.close();& & & &&}&catch&(IOException&e)&{&}& &&}}
客户端的连接:
&&为了初始化一个与远端设备的连接,需要先获取代表该设备的一个bluetoothdevice对象。通过bluetoothdevice对象来获取bluetoothsocket并初始化连接:
&具体步骤:
&&使用bluetoothdevice对象里的方法来获取bluetoothsocket。UUID就是匹配码。然后,调用connect()方法来。如果远端设备接收了该连接,他们将在通信过程中共享RFFCOMM信道,并且connect()方法返回。例如:
&&private&class&ConnectThread&extends&Thread&{& &&private&final&BluetoothSocket&mmS& &&private&final&BluetoothDevice&mmD& &&public&ConnectThread(BluetoothDevice&device)&{& & & &&// Use a temporary object that is later assigned to mmSocket,& & & &&// because mmSocket is final& & & &&BluetoothSocket&tmp&=&& & & & mmDevice&=&& & & &&// Get a BluetoothSocket to connect with the given BluetoothDevice& & & &&try&{& & & & & &&// MY_UUID is the app's UUID string, also used by the server code& & & & & & tmp&=&device.createRfcommSocketToServiceRecord(MY_UUID);& & & &&}&catch&(IOException&e)&{&}& & & & mmSocket&=&& &&}& &&public&void&run()&{& & & &&// Cancel discovery because it will slow down the connection& & & & mAdapter.cancelDiscovery();& & & &&try&{& & & & & &&// Connect the device through the socket. This will block& & & & & &&// until it succeeds or throws an exception& & & & & & mmSocket.connect();& & & &&}&catch&(IOException&connectException)&{& & & & & &&// U close the socket and get out& & & & & &&try&{& & & & & & & & mmSocket.close();& & & & & &&}&catch&(IOException&closeException)&{&}& & & & & &&& & & &&}& & & &&// Do work to manage the connection (in a separate thread)& & & & manageConnectedSocket(mmSocket);& &&}& &&/** Will cancel an in-progress connection, and close the socket */& &&public&void&cancel()&{& & & &&try&{& & & & & & mmSocket.close();& & & &&}&catch&(IOException&e)&{&}& &&}
&注意:conncet()方法也是阻塞调用,一般建立一个独立的线程中来调用该方法。在设备discover过程中不应该发起连接connect(),这样会明显减慢速度以至于连接失败。且数据传输完成只有调用close()方法来关闭连接,这样可以节省系统内部资源。
管理连接(主要涉及数据的传输):
&当设备连接上以后,每个设备都拥有各自的bluetoothsocket。现在你就可以实现设备之间数据的共享了。
1.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&首先通过调用和方法来获取输入输出流。然后通过调用&和&.方法来读取或者写数据。
2.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&实现细节:以为读取和写操作都是阻塞调用,需要建立一个专用现成来管理。
3.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&private&class&ConnectedThread&extends&Thread&{& &&private&final&BluetoothSocket&mmS& &&private&final&InputStream&mmInS& &&private&final&OutputStream&mmOutS& &&public&ConnectedThread(BluetoothSocket&socket)&{& & & & mmSocket&=&& & & &&InputStream&tmpIn&=&& & & &&OutputStream&tmpOut&=&& & & &&// Get the input and output streams, using temp objects because& & & &&// member streams are final& & & &&try&{& & & & & & tmpIn&=&socket.getInputStream();& & & & & & tmpOut&=&socket.getOutputStream();& & & &&}&catch&(IOException&e)&{&}& & & & mmInStream&=&tmpIn;& & & & mmOutStream&=&tmpO& &&}& &&public&void&run()&{& & & &&byte[]&buffer&=&new&byte[1024];&&// buffer store for the stream& & & &&int&&// bytes returned from read()& & & &&// Keep listening to the InputStream until an exception occurs& & & &&while&(true)&{& & & & & &&try&{& & & & & & & &&// Read from the InputStream& & & & & & & & bytes&=&mmInStream.read(buffer);& & & & & & & &&// Send the obtained bytes to the UI Activity& & & & & & & & mHandler.obtainMessage(MESSAGE_READ,&bytes,&-1,&buffer)& & & & & & & & & & & &&.sendToTarget();& & & & & &&}&catch&(IOException&e)&{& & & & & & & &&& & & & & &&}& & & &&}& &&}& &&/* Call this from the main Activity to send data to the remote device */& &&public&void&write(byte[]&bytes)&{& & & &&try&{& & & & & & mmOutStream.write(bytes);& & & &&}&catch&(IOException&e)&{&}& &&}& &&/* Call this from the main Activity to shutdown the connection */& &&public&void&cancel()&{& & & &&try&{& & & & & & mmSocket.close();& & & &&}&catch&(IOException&e)&{&}& &&}}
阅读(...) 评论()Ta最近发表(1)
今天无聊用笔记本的蓝牙鼠标连接 手机成功了
23953 次浏览
10 位用户参与讨论
本帖最后由 lxxgg 于
22:24 编辑
& &今天网上看了书腻了。突然想到咱的手机是不是能用蓝牙鼠标,就到网上查了下 都没HD2的介绍,只看到有WM6下的连接键盘的,还找到个视频 /v_show/id_XMjc5MjkwNjE2.html&&看用苹果鼠标连接安卓系统的,看去是连接上了就是没鼠标箭头 操作不行,后来用了个啥软件把鼠标运动轨迹屏幕上画出来 来指示鼠标位置。结果屏幕移动都花了 一堆的线,看着很不习惯,本来想放弃了,后来想想也试下 还不知道有没用的
& && &键盘我是没,蓝牙鼠标到有笔记本用的。所以就试了下 断开笔记本的,手机上打开蓝牙搜索 鼠标上按下对码,查到设备 输入密码0000 对码连接成功。
结果惊奇的发现屏幕上出现个鼠标箭头 哈哈。和电脑上一样 鼠标移动点击很方便 左键点击 右键返回键 玩了下小鸟 不错啊 使用方便啊 打的准多了 哈哈。由于相机在公司 本来想拍个视频看下的 等明天有空了在弄个 先放几个图片看下
连接的图片 找到鼠标连接密码0000
连接后出现小箭头了&&消息栏上面
主屏幕几个操作 拉下消息栏 和屏幕左移动滚屏切换 用的是GO 桌面 咕噜噜股滚的效果 呵呵 鼠标按着滚1半截图
进了几个游戏 小鸟操作就简单多了 还有捕鱼,可惜没蓝牙键盘 动作游戏还没直接屏幕虚拟键盘好
用了几个常用软件 QQ UC&&等操作都不错 和电脑一样了 电影快进比较方便准点。网页网址也点的准啊
相机操作 直接对这笔记本屏幕照的
现在就郁闷 HD2没 高清视频输出口了 要是有的话就直接接电视了 可以电视上看电影电视 玩游戏了,不就和现在那些安卓机顶盒一样了,等那天手机淘汰了 可以当机顶盒用了,就不用电信IPTV了 这个比他那功能强大多了 电影也多 软件随便装。
& &&&唯一不好的是右键不熟悉啊 电脑上操作 空的时候习惯随便按下右键,再手机是上不小心按去就返回键,不是退出就是网页返回上1页,还有中键按下相当于手机的功能键,就是滚轮不好,只能上下滚 选的时候是直线上下选的到底不会切换第2行。。
精彩评论10
头像被屏蔽
提示: 作者被禁止或删除 内容自动屏蔽
连接测试成功,哈哈,谢谢楼主
有意思····
路过进来看看!
还能这么晚,得亏楼主想的到
改天我整个蓝牙鼠标也试试
高手中的高高手
奇怪!!我能搜到但是怎么连接不上咧!!!
我的V880开始不支持,后来刷了一个CM的系统,因为要蓝牙支持HID才可以蓝牙鼠标首次成功连接、控制Android手机(小米手机)-科技视频-搜狐视频
蓝牙鼠标首次成功连接、控制Android手机(小米手机)
<span class="c-black" data-rss-fanscount=" 人订阅
视频介绍:
蓝牙鼠标首次成功连接、控制Android手机(小米手机)
推荐出品人
科技热播榜关于安卓手机外接OTG鼠标的探索_android吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:1,122,842贴子:
关于安卓手机外接OTG鼠标的探索收藏
本人手机note1,最近买了条OTG线在家捣鼓,发现一些有意思的东西:我使用无线鼠标,有线鼠标均可操作,但无线鼠标更为流畅,且比有线鼠标省电(几乎不费电)有的牌子鼠标是不兼容的 ;在手机系统是2.3.x时鼠标左键点击,右键返回,滚轮可滚动页面,滚轮点击可打开菜单,十分顺畅和电脑无异;但在升级4.0.4后鼠标左右键都变成了点击,滚轮可滚动页面,但点击滚轮出菜单的功能没有了,到国外论坛查阅原因是4.0.4系统BUG,不刷机暂时无法使用,但在换了有侧键的鼠标后就发现侧键点击代表返回。。。。。我现在使用4.0系统感觉鼠标没以前那么方便了我安装的手势操作软件GMD gesture control,使用鼠标进行手势操作是无效的,包括系统自带手势操作和S-pen手势操作也都无效;用鼠标玩游戏时无法替代陀螺仪或滑动切换视角,比如安卓CS,用鼠标可点击菜单,但在游戏中无法利用鼠标像电脑一样操作枪,只能用手滑动屏幕;鼠标在待机时动一下,手机待机就会解除,鼠标不动过一会光标就会消失; 系统中可以设置鼠标滑动速率,其他选项均无法设置;希望谷歌在下一代安卓里能改进一下鼠标体验:修复4.0.4bug,加入鼠标设置选项,鼠标可支持代替陀螺仪。。。。。
千锋android,Android混合式开发课程讲师授课,两周免费试听,0基础学习!千锋android线路图「点击获取」,足不出户挑工作,学员&企业零距离,名师传道授业.
好贴自顶呱~
到4.3好像都完全不支持了!
鼠标。。。
塞班的otg可以外接光驱的!
为什么我用来玩飞机 滑动的时候明显 不太流畅啊?????
4.2也是这样
上海达内android培训,先就业后付款,&免费试学7天&.android名师手把手教学.
没有用鼠标的必要吧
为什么不用蓝牙鼠标再mhl输出到电视~
我的手机连OTG线接鼠标没反应
,怎么回事
是鼠标的问题
还是手机不支持啊
我的手机是安卓4.7的
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或}

我要回帖

更多关于 安卓蓝牙开发实现通信 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信