蓝牙开发bluetoothchatserviceSetServiceState去开启pan服务,为什么总是报ERROR_SERVICE_DOES_NOT_EXIST错误?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&评论-3665&
trackbacks-6
&前言   本章内容是
android.bluetooth.BluetoothAdapter,为Android蓝牙部分的章节翻译。本地蓝牙设备的适配类,所有的蓝牙操作都要通过该类完成。版本为 Android
r1,翻译来自中山大学的"Android Club SYSU",欢迎访问他们的WIKI:,再次感谢"Android Club SYSU"!期待你一起参与Android中文API的翻译,联系我 。
& 声明   欢迎转载,但请保留文章原始出处:)     Android Club SYSU:
    博客园:     Android中文翻译组:
& 正文   一、结构
public final class BluetoothAdapter extends Object
java.lang.Object
android.bluetooth.BluetoothAdapter
&  二、概述
  代表本地的蓝牙适配器设备。BluetoothAdapter类让用户能执行基本的蓝牙任务。例如: 初始化设备的搜索,查询可匹配的设备集,使用一个已知的MAC地址来初始化一个BluetoothDevice类,创建一个 BluetoothServerSocket类以监听其它设备对本机的连接请求等。
  为了得到这个代表本地蓝牙适配器的 BluetoothAdapter类,调用getDefaultAdapter()这一静态方法。这是所有蓝牙动作使用的第一步。当拥有本地适配器以后, 用户可以获得一系列的BluetoothDevice对象,这些对象代表所有拥有getBondedDevice()方法的已经匹配的设备;用 startDiscovery()方法来开始设备的搜寻;或者创建一个BluetoothServerSocket类,通过 listenUsingRfcommWithServiceRecord(String, UUID)方法来监听新来的连接请求。
  Note:大部分方法需要BLUETOOTH权限,一些方法同时需要权限。
&&&&&&&&&&
&  三、常量
    String &&&& ACTION_DISCOVERY_FINISHED &&
  广播事件:本地蓝牙适配器已经完成设备的搜寻过程。    需要权限接收。
  常量值: "android.bluetooth.adapter.action.DISCOVERY_FINISHED"
  String &&&& ACTION_DISCOVERY_STARTED &&&
  广播事件:本地蓝牙适配器已经开始对远程设备的搜寻过程。
  它通常牵涉到一个大概需时12秒的查询扫描过程,紧跟着是一个对每个获取到自身蓝牙名称的新设备的页面扫描。
&&&&&&&&   用户会发现一个把常量通知为远程蓝牙设备的注册。 设备查找是一个重量级过程。当查找正在进行的时候,用户不能尝试对新的远程蓝牙设备进行连接,同时存在的连接将获得有限制的带宽以及高等待时间。用户可用类来取消正在执行的查找进程。
  需要权限接收。
  常量值: "android.bluetooth.adapter.action.DISCOVERY_STARTED"
  String &&&& ACTION_LOCAL_NAME_CHANGED &&&&&
  广播活动:本地蓝牙适配器已经更改了它的蓝牙名称。
  该名称对远程蓝牙设备是可见的。
  它总是包含了一个带有名称的EXTRA_LOCAL_NAME附加域。
  需要权限接收。
  常量值: "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED"
  String &&&& ACTION_REQUEST_DISCOVERABLE &&&&&
  Activity活动:显示一个请求被搜寻模式的系统活动。如果蓝牙模块当前未打开,该活动也将请求用户打开蓝牙模块。
  被搜寻模式和等价。当远程设备执行查找进程的时候,它允许其发现该蓝牙适配器。
  从隐私安全考虑,Android不会将被搜寻模式设置为默认状态。
  该意图的发送者可以选择性地运用这个附加域去请求发现设备的持续时间。普遍来说,对于每一请求,默认的持续时间为120秒,最大值则可达到300秒。
  Android 运用回收方法来传递该活动结果的通知。被搜寻的时间(以秒为单位)将通过resultCode值来显示,如果用户拒绝被搜寻,或者设备产生了错 误,则通过值来显示。
  每当扫描模式变化的时候,应用程序可以为通过值来监听全局的消息通知。比如,当设备停止被搜寻以后,该消息可以被系统通知給应用程序。
  需要权限
  常量值: "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"
  String &&&& ACTION_REQUEST_ENABLE
  Activity活动:显示一个允许用户打开蓝牙模块的系统活动。
  当蓝牙模块完成打开工作,或者当用户决定不打开蓝牙模块时,系统活动将返回该值。
  Android 运用回收方法来传递该活动结果的通知。如果蓝牙模块被打开,将通过resultCode值来显示;如果用户拒绝该请求,或者设备产生了错误,则通过值来显示。
&&&&&&&&   每当蓝牙模块被打开或者关闭,应用程序可以为通过值来监听全局的消息通知。
  需要权限
  常量值: "android.bluetooth.adapter.action.REQUEST_ENABLE"
  String &&&& ACTION_SCAN_MODE_CHANGED &&&&&&&
  广播活动:指明蓝牙扫描模块或者本地适配器已经发生变化
  它总是包含和。这两个附加域各自包含了新的和旧的扫描模式。
  需要权限
  常量值: "android.bluetooth.adapter.action.SCAN_MODE_CHANGED"
  String &&&& ACTION_STATE_CHANGED &&
  广播活动:本来的蓝牙适配器的状态已经改变。
  例如:蓝牙模块已经被打开或者关闭。
  它总是包含和。这两个附加域各自包含了新的和旧的状态。
  需要权限接收
  常量值: "android.bluetooth.adapter.action.STATE_CHANGED"
  int &ERROR &&
  标记该类的错误值。确保和该类中的任意其它整数常量不相等。它为需要一个标记错误值的函数提供了便利。例如:
  Intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
  常量值: - (0x)
  String &&&& EXTRA_DISCOVERABLE_DURATION &&&&
  试图在常量中作为一个可选的整型附加域,来为短时间内的设备发现请求一个特定的持续时间。默认值为120秒,超过300秒的请求将被限制。这些值是可以变化的。
  常量值: "android.bluetooth.adapter.extra.DISCOVERABLE_DURATION"
  String &&&& EXTRA_LOCAL_NAME &&
  试图在常量中作为一个字符串附加域,来请求本地蓝牙的名称。
  常量值: "android.bluetooth.adapter.extra.LOCAL_NAME"
  String &&&& EXTRA_PREVIOUS_SCAN_MODE &
  试图在常量中作为一个整型附加域,来请求以前的扫描模式。可能值有: , ,
  常量值: "android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE"
  String &&&& EXTRA_PREVIOUS_STATE &&&&&
  试图在常量中作为一个整型附加域,来请求以前的供电状态。 可能值有: , , ,
  常量值: "android.bluetooth.adapter.extra.PREVIOUS_STATE"
  String &&&& EXTRA_SCAN_MODE &&&&
  试图在常量中作为一个整型附加域,来请求当前的扫描模式.可能值有: , ,
  常量值: "android.bluetooth.adapter.extra.SCAN_MODE"
  String &&&& EXTRA_STATE &&&&&&&&
  试图在常量中作为一个整型附加域,来请求当前的供电状态。 可能值有: , , ,
  常量值: "android.bluetooth.adapter.extra.STATE"
  int &SCAN_MODE_CONNECTABLE &&&&&&
  指明在本地蓝牙适配器中,查询扫描功能失效,但页面扫描功能有效。因此该设备不能被远程蓝牙设备发现,但如果以前曾经发现过该设备,则远程设备可以对其进行连接。
  常量值: 21 (0x)
  int &SCAN_MODE_CONNECTABLE_DISCOVERABLE &&&
  指明在本地蓝牙适配器中,查询扫描功能和页面扫描功能都有效。因此该设备既可以被远程蓝牙设备发现,也可以被其连接。
  常量值: 23 (0x)
  int &SCAN_MODE_NONE &&&&&
  指明在本地蓝牙适配器中,查询扫描功能和页面扫描功能都失效. 因此该设备既不可以被远程蓝牙设备发现,也不可以被其连接。
  常量值: 20 (0x)
  int &STATE_OFF &&&&
  指明本地蓝牙适配器模块已经关闭
  常量值: 10 (0x0000000a)
  int &STATE_ON &&&&&
  指明本地蓝牙适配器模块已经打开,并且准备被使用。
  常量值: 12 (0x0000000c)
  int &STATE_TURNING_OFF &&
  指明本地蓝牙适配器模块正在关闭。本地客户端可以立刻尝试友好地断开任意外部连接。
  常量值: 13 (0x0000000d)
  int &STATE_TURNING_ON &&&
  指明本地蓝牙适配器模块正在打开. 然而本地客户在尝试使用这个适配器之前需要为状态而等待。
  常量值: 11 (0x0000000b)
&&  四、公共方法
  public boolean cancelDiscovery ()
  取消当前的设备发现查找进程
  需要权限。
  因为对蓝牙适配器而言,查找是一个重量级的过程,因此这个方法必须在尝试连接到远程设备前使用用connect()方法进行调用。发现的过程不会由活动来进行管理,但是它会作为一个系统服务来运行,因此即使它不能直接请求这样的一个查询动作,也必需取消该搜索进程。
  如果蓝牙状态不是,这个API将返回false。蓝牙打开后,等待ACTION_STATE_CHANGED更新成STATE_ON。
  返回值
  成功则返回true,有错误则返回false。
  public static boolean checkBluetoothAddress (String address)
  验证皆如"00:43:A8:23:10:F0"之类的蓝牙地址。
  字母必须为大写才有效。
  address
字符串形式的蓝牙模块地址
  返回值
  地址正确则返回true,否则返回false。
  public boolean disable ()
  关闭本地蓝牙适配器&#8212;不能在没有明确关闭蓝牙的用户动作中使用。
  这个方法友好地停止所有的蓝牙连接,停止蓝牙系统服务,以及对所有基础蓝牙硬件进行断电。
  没有用户的直接同意,蓝牙永远不能被禁止。这个disable()方法只提供了一个应用,该应用包含了一个改变系统设置的用户界面(例如&#8220;电源控制&#8221;应用)。
  这是一个异步调用方法:该方法将马上获得返回值,用户要通过监听ACTION_STATE_CHANGED值来获取随后的适配器状态改变的通知。如果该调用 返回true值,则该适配器状态会立刻从STATE_ON转向STATE_TURNING_OFF,稍后则会转为STATE_OFF或者 STATE_ON。如果该调用返回false,那么系统已经有一个保护蓝牙适配器被关闭的问题&#8212;比如该适配器已经被关闭了。
  需要权限。
&&&&&&&&&&&&&&&& 返回值
  如果蓝牙适配器的停止进程已经开启则返回true,如果产生错误则返回false。
  public boolean enable ()
&&&&&&&&&& 打开本地蓝牙适配器&#8212;不能在没有明确打开蓝牙的用户动作中使用。
  该方法将为基础的蓝牙硬件供电,并且启动所有的蓝牙系统服务。
  没有用户的直接同意,蓝牙永远不能被禁止。如果用户为了创建无线连接而打开了蓝牙模块,则其需要ACTION_REQUEST_ENABLE值,该值将提出 一个请求用户允许以打开蓝牙模块的会话。这个enable()值只提供了一个应用,该应用包含了一个改变系统设置的用户界面(例如&#8220;电源控制&#8221;应用)。
  这是一个异步调用方法:该方法将马上获得返回值,用户要通过监听ACTION_STATE_CHANGED值来获取随后的适配器状态改变的通知。如果该调用 返回true值,则该适配器状态会立刻从STATE_OFF转向STATE_TURNING_ON,稍后则会转为STATE_OFF或者 STATE_ON。如果该调用返回false,那么说明系统已经有一个保护蓝牙适配器被打开的问题&#8212;比如飞行模式,或者该适配器已经被打开。
  需要权限。
  返回值&&&&
  如果蓝牙适配器的打开进程已经开启则返回true,如果产生错误则返回false。
  public String getAddress ()
  返回本地蓝牙适配器的硬件地址
  例如: "00:11:22:AA:BB:CC"
  需要权限。
  返回值&&&&
  字符串形式的蓝牙模块地址
  public Set&BluetoothDevice& getBondedDevices ()
  返回已经匹配到本地适配器的BluetoothDevice类的对象集合
  如果蓝牙状态不是,这个API将返回false。蓝牙打开后,等待ACTION_STATE_CHANGED更新成STATE_ON。
  需要权限。
  返回值
  未被修改的BluetoothDevice类的对象集合,如果有错误则返回null。
  public static synchronized BluetoothAdapter getDefaultAdapter ()
  获取对默认本地蓝牙适配器的的操作权限。
  目前Andoird只支持一个蓝牙适配器,但是API可以被扩展为支持多个适配器。该方法总是返回默认的适配器。
  返回值
  返回默认的本地适配器,如果蓝牙适配器在该硬件平台上不能被支持,则返回null。
  public String getName ()
  获取本地蓝牙适配器的蓝牙名称
  这个名称对于外界蓝牙设备而言是可见的。
  需要权限。
  返回值
  该蓝牙适配器名称,如果有错误则返回null
  public BluetoothDevice getRemoteDevice (String address)
  为给予的蓝牙硬件地址获取一个BluetoothDevice对象。
&&&&&&&&&& 合法的蓝牙硬件地址必须为大写,格式类似于"00:11:22:33:AA:BB"。checkBluetoothAddress(String)方法可以用来验证蓝牙地址的正确性。
  BluetoothDevice类对于合法的硬件地址总会产生返回值,即使这个适配器从未见过该设备。
  address
合法的蓝牙MAC地址
  IllegalArgumentException &&&& 如果地址不合法
  public int getScanMode ()
  获取本地蓝牙适配器的当前蓝牙扫描模式
  蓝牙扫描模式决定本地适配器可连接并且/或者可被远程蓝牙设备所连接。
  可能值有: SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE.
  如果蓝牙状态不是,这个API将返回false。蓝牙打开后,等待ACTION_STATE_CHANGED更新成STATE_ON。
  需要权限。
&&&&&   返回值
  扫描模式
  public int getState ()
  获取本地蓝牙适配器的当前状态
  可能值有 STATE_OFF, STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF.
需要BLUETOOTH类
  需要权限。
&&&&&&&&&&   返回值
  蓝牙适配器的当前状态
  public boolean isDiscovering ()
  如果当前蓝牙适配器正处于设备发现查找进程中,则返回真值
  设备查找是一个重量级过程。当查找正在进行的时候,用户不能尝试对新的远程蓝牙设备进行连接,同时存在的连接将获得有限制的带宽以及高等待时间。用户可用cencelDiscovery()类来取消正在执行的查找进程。
  应用程序也可以为ACTION_DISCOVERY_STARTED或者ACTION_DISCOVERY_FINISHED进行注册,从而当查找开始或者完成的时候,可以获得通知。
  如果蓝牙状态不是,这个API将返回false。蓝牙打开后,等待ACTION_STATE_CHANGED更新成STATE_ON。
  需要权限。
&&&&&&&&&&&&&&&& 返回值
  如果正在查找,则返回true
  public boolean isEnabled ()
  如果蓝牙正处于打开状态并可用,则返回真值
  与getBluetoothState()==STATE_ON 等价
  需要权限。
&&&&&&&&&&&&&&&& 返回值
  如果本地适配器已经打开,则返回true
  public BluetoothServerSocket listenUsingRfcommWithServiceRecord (String name, UUID uuid)
  创建一个正在监听的安全的带有服务记录的无线射频通信(RFCOMM)蓝牙端口。
  一个对该端口进行连接的远程设备将被认证,对该端口的通讯将被加密。
  使用accpet()方法可以获取从监听处新来的连接
  该系统分配一个未被使用的无线射频通信通道来进行监听。
  该系统也将注册一个服务探索协议(SDP)记录,该记录带有一个包含了特定 的通用唯一识别码(Universally Unique Identifier,UUID),服务器名称和自动分配通道的本地SDP服务。远程蓝牙设备可以用相同的UUID来查询自己的SDP服务器,并搜寻连接 到了哪个通道上。如果该端口已经关闭,或者如果该应用程序异常退出,则这个SDP记录会被移除。
  使用从另一使用相同的设备来连接到这个端口
  需要权限。
  name &&&&& SDP记录下的服务器名
  uuid &&&&&&& SDP记录下的UUID
&&&&&&&&&&&&&&&& 返回值
  一个正在监听的无线射频通信蓝牙服务端口
  IOException && 产生错误,比如蓝牙设备不可用,或者许可无效,或者通道被占用。
  public boolean setName (String name)
  设置蓝牙或者本地蓝牙适配器的昵称.
  这个名字对于外界蓝牙设备而言是可见的。
  合法的蓝牙名称最多拥有248位UTF-8字符,但是很多外界设备只能显示前40个字符,有些可能只限制前20个字符。
  如果蓝牙状态不是,这个API将返回false。蓝牙打开后,等待ACTION_STATE_CHANGED更新成STATE_ON。
  需要权限。
  name &&&&& 一个合法的蓝牙名称
  返回值
  如果该名称已被设定,则返回true,否则返回false
  public boolean startDiscovery ()
  开始对远程设备进行查找的进程
  它通常牵涉到一个大概需时12秒的查询扫描过程,紧跟着是一个对每个获取到自身蓝牙名称的新设备的页面扫描。
  这是一个异步调用方法:该方法将马上获得返回值,注册ACTION_DISCOVERY_STARTED and ACTION_DISCOVERY_FINISHED意图准确地确定该探索是处于开始阶段或者完成阶段。注册ACTION_FOUND以活动远程蓝牙设备 已找到的通知。
  设备查找是一个重量级过程。当查找正在进行的时候,用户不能尝试对新的远程蓝牙设备进行连接,同时存在的连接将获得有限制的带宽以 及高等待时间。用户可用cencelDiscovery()类来取消正在执行的查找进程。发现的过程不会由活动来进行管理,但是它会作为一个系统服务来运 行,因此即使它不能直接请求这样的一个查询动作,也必需取消该搜索进程。
  设备搜寻只寻找已经被连接的远程设备。许多蓝牙设备默认不会被搜寻到,并且需要进入到一个特殊的模式当中。
  如果蓝牙状态不是,这个API将返回false。蓝牙打开后,等待ACTION_STATE_CHANGED更新成STATE_ON。
  需要权限。
  返回值
  成功返回true,错误返回false。
&  五、补充
&&&&&&&&  文章精选
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&  关于蓝牙的文章,大家还可以搜一下EOE期刊第六期:数据通信,里面能获取更多资料。(补充)&&结束  关于Android蓝牙这篇文章已经有被转载,这里做了整理并简单的审核了一下,补充了少数几处漏翻的部分,再次感谢他们!&
阅读(...) 评论()3143人阅读
C/C++(49)
#include &StdAfx.h&
#include &BlueTooth.h&
CBlueTooth::CBlueTooth(void)
m_Ary_RemoteBthDevInfo.SetSize ( 0, 10*sizeof(BLUETOOTH_DEVICE_INFO) );
m_Ary_LocalRadioInfo.SetSize ( 0, 10*sizeof(t_LocalRadioInfo) );
CBlueTooth::~CBlueTooth(void)
RemoveAll_RemoteBthDevInfo ();
RemoveAllLocalRadio ();
// 用 Socket 函数搜索附近的蓝牙设备,成功时返回设备数,否则返回-1
int CBlueTooth::WSAScanNearbyBthDev ()
m_Ary_RemoteBthDevInfo.RemoveAll ();
WSAQUERYSET
CHAR buf[5000];
double __ // ensure proper alignment
LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET)
DWORD dwSize = sizeof(buf);
BOOL bHaveN
ZeroMemory(&wsaq, sizeof(wsaq));
wsaq.dwSize = sizeof(wsaq);
wsaq.dwNameSpace = NS_BTH;
wsaq.lpcsaBuffer = NULL;
if (ERROR_SUCCESS != WSALookupServiceBegin (&wsaq, LUP_CONTAINERS, &hLookup))
TRACE ( _T(&WSALookupServiceBegin failed\n&) );
return -1;
ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
pwsaResults-&dwSize = sizeof(WSAQUERYSET);
pwsaResults-&dwNameSpace = NS_BTH;
pwsaResults-&lpBlob = NULL;
while (ERROR_SUCCESS == WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults))
ASSERT (pwsaResults-&dwNumberOfCsAddrs == 1);
BTH_ADDR b = ((SOCKADDR_BTH *)pwsaResults-&lpcsaBuffer-&RemoteAddr.lpSockaddr)-&btA
bHaveName = pwsaResults-&lpszServiceInstanceName && *(pwsaResults-&lpszServiceInstanceName);
t_RemoteBthDevInfo RemoteBthDevI
if ( bHaveName )
StringCchPrintf ( RemoteBthDevInfo.szName, sizeof(RemoteBthDevInfo.szName), _T(&%s&),
pwsaResults-&lpszServiceInstanceName );
RemoteBthDevInfo.Address.ullLong =
TRACE (L&%s ( %04x%08x )\n&, RemoteBthDevInfo.szName, GET_NAP(b), GET_SAP(b) );
m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
WSALookupServiceEnd(hLookup);
return (int)m_Ary_RemoteBthDevInfo.GetSize();
BOOL AUTHENTICATION_CALLBACK (LPVOID pvParam, PBLUETOOTH_DEVICE_INFO pDevice)
t_AUTHENTICATION_CALLBACK_Para *pAUTHENTICATION_CALLBACK_Para = (t_AUTHENTICATION_CALLBACK_Para*)pvP
if ( pAUTHENTICATION_CALLBACK_Para )
pDevice-&fAuthenticated = TRUE;
DWORD result = BluetoothUpdateDeviceRecord ( pDevice );
ASSERT ( result == ERROR_SUCCESS );
result = BluetoothSendAuthenticationResponse ( pAUTHENTICATION_CALLBACK_Para-&hRadio, pDevice, AUTHENTICATION_PASSKEY );
if ( result == ERROR_SUCCESS )
return TRUE;
return FALSE;
// 用蓝牙 APIs 搜索附近的蓝牙设备,成功时返回设备数,否则返回-1
int CBlueTooth::ScanNearbyBthDev (
HANDLE hRadio,
BOOL fReturnAuthenticated/* = TRUE*/,
BOOL fReturnRemembered/* = TRUE*/,
BOOL fReturnUnknown/* = TRUE*/,
BOOL fReturnConnected/* = TRUE*/,
BOOL fIssueInquiry/* = FALSE*/,
UCHAR cTimeoutMultiplier/* = 30*/
RemoveAll_RemoteBthDevInfo ();
CWaitCursor WaitC
BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
BLUETOOTH_DEVICE_SEARCH_PARAMS
HBLUETOOTH_DEVICE_FIND
ZeroMemory(&bdsp, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS));
bdsp.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
bdsp.hRadio = hR
bdsp.fReturnAuthenticated = fReturnA
bdsp.fReturnRemembered = fReturnR
bdsp.fReturnUnknown = fReturnU
bdsp.fReturnConnected = fReturnC
bdsp.fIssueInquiry = fIssueI
bdsp.cTimeoutMultiplier = cTimeoutM
hbf = BluetoothFindFirstDevice(&bdsp, &bdi);
if (hbf == NULL) return -1;
while(true)
TRACE ( _T(&%s ( %s )\n&), bdi.szName, FormatBthAddress(bdi.Address.rgBytes) );
t_RemoteBthDevInfo RemoteBthDevI
RemoteBthDevInfo.hRadio = hR
RemoteBthDevInfo.Address.ullLong = bdi.Address.ullL
_snwprintf_s ( RemoteBthDevInfo.szName, LENGTH(RemoteBthDevInfo.szName), _T(&%s&), bdi.szName );
// 枚举服务
EnumerateInstalledServices ( RemoteBthDevInfo );
// 注册配对回调函数
RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para = new t_AUTHENTICATION_CALLBACK_P
if ( RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para )
RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para-&lpBlueTooth =
RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para-&hRadio = hR
BluetoothRegisterForAuthentication ( &bdi, &RemoteBthDevInfo.hRegHandle, AUTHENTICATION_CALLBACK, RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para );
m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
if ( !BluetoothFindNextDevice(hbf, &bdi) )
BluetoothFindDeviceClose(hbf);
return (int)m_Ary_RemoteBthDevInfo.GetSize();
// 用向导手工搜索附近的蓝牙设备并建立连接,得到设备的详细信息,成功时返回设备数
int CBlueTooth::ScanNearbyBthDev_Wizard (
HWND hwndParent,
HANDLE hRadio,
pszInfo/*=NULL*/,
If not NULL, sets the &information& text
fForceAuthentication/*=FALSE*/,
If TRUE, authenication will be forced before returning
fShowAuthenticated/*=FALSE*/,
If TRUE, authenticated devices will be shown in the picker
fShowRemembered/*=TRUE*/,
If TRUE, remembered devices will be shown in the picker
fShowUnknown/*=TRUE*/,
If TRUE, unknown devices that are not authenticated or &remember& will be shown.
fAddNewDeviceWizard/*=TRUE*/,
If TRUE, invokes the add new device wizard.
fSkipServicesPage/*=FALSE*/,
If TRUE, skips the &Services& page in the wizard.
PFN_DEVICE_CALLBACK pfnDeviceCallback/*=NULL*/, //
If non-NULL, a callback that will be called for each device. If the
the callback returns TRUE, the item will be added. If the callback is
is FALSE, the item will not be shown.
pvParam/*=NULL*/
Parameter to be passed to pfnDeviceCallback as the pvParam.
RemoveAll_RemoteBthDevInfo ();
BLUETOOTH_SELECT_DEVICE_PARAMS btsdp = { sizeof(btsdp) };
btsdp.hwndParent = hwndP
btsdp.pszInfo = pszI
btsdp.fForceAuthentication = fForceA
btsdp.fShowAuthenticated = fShowA
btsdp.fShowRemembered = fShowR
btsdp.fShowUnknown = fShowU
btsdp.fAddNewDeviceWizard = fAddNewDeviceW
btsdp.fSkipServicesPage = fSkipServicesP
btsdp.pfnDeviceCallback = pfnDeviceC
btsdp.pvParam = pvP
BOOL b = BluetoothSelectDevices( &btsdp );
BLUETOOTH_DEVICE_INFO *pbtdi = btsdp.pD
for ( ULONG cDevice = 0; cDevice & umD cDevice ++ )
if ( pbtdi-&fAuthenticated || pbtdi-&fRemembered )
t_RemoteBthDevInfo RemoteBthDevI
RemoteBthDevInfo.hRadio = hR
RemoteBthDevInfo.Address = pbtdi-&A
_snwprintf_s ( RemoteBthDevInfo.szName, LENGTH(RemoteBthDevInfo.szName), _T(&%s&), pbtdi-&szName );
EnumerateInstalledServices ( RemoteBthDevInfo );
m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
pbtdi = (BLUETOOTH_DEVICE_INFO *) ((LPBYTE)pbtdi + pbtdi-&dwSize);
BluetoothSelectDevicesFree( &btsdp );
return (int)m_Ary_RemoteBthDevInfo.GetSize();
// 根据远程蓝牙设备的地址获取详细信息
BOOL CBlueTooth::BluetoothGetDeviceInfo ( IN t_RemoteBthDevInfo& RemoteBthDevInfo, OUT BLUETOOTH_DEVICE_INFO *pbtdi )
BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
bdi.Address.ullLong = RemoteBthDevInfo.Address.ullL
if ( ERROR_SUCCESS != ::BluetoothGetDeviceInfo ( RemoteBthDevInfo.hRadio, &bdi ) )
return FALSE;
if ( pbtdi ) memcpy ( pbtdi, &bdi, sizeof(BLUETOOTH_DEVICE_INFO) );
return TRUE;
BOOL CBlueTooth::BluetoothSetServiceState ( HANDLE hRadio, BLUETOOTH_DEVICE_INFO &bdi, GUID guidService, DWORD dwServiceFlags )
DWORD result = ::BluetoothSetServiceState(hRadio, &bdi, &guidService, dwServiceFlags);
if ( ERROR_SUCCESS != result && ERROR_SERVICE_DOES_NOT_EXIST != result )
TRACE ( _T(&BluetoothSetServiceState failed : %s\n&), hwFormatMessage (result) );
return FALSE;
return TRUE;
// 枚举已安装的服务
int CBlueTooth::EnumerateInstalledServices( t_RemoteBthDevInfo& RemoteBthDevInfo )
BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
return -1;
BluetoothSetServiceState ( RemoteBthDevInfo.hRadio, bdi, SerialPortServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );
BluetoothSetServiceState ( RemoteBthDevInfo.hRadio, bdi, LANAccessUsingPPPServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );
BluetoothSetServiceState ( RemoteBthDevInfo.hRadio, bdi, DialupNetworkingServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );
if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
return -1;
DWORD numServices = LENGTH(RemoteBthDevInfo.guidServices);
DWORD result = BluetoothEnumerateInstalledServices(RemoteBthDevInfo.hRadio,&bdi, &numServices, RemoteBthDevInfo.guidServices);
if ( ERROR_SUCCESS == result ) return numS
return -1;
// 显示序号为 nIndex 的蓝牙设备属性框
BOOL CBlueTooth::ShowPropertySheet(int nIndex, HWND hwdParent/*=NULL*/)
if ( nIndex & 0 || nIndex &=m_Ary_RemoteBthDevInfo.GetSize() )
return FALSE;
t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt ( nIndex );
BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
return FALSE;
return BluetoothDisplayDeviceProperties ( hwdParent, &bdi );
// 请求与远程蓝牙设备配对
BOOL CBlueTooth::RequestAuthenticateDevice(int nIndex, HWND hwdParent/*=NULL*/, DWORD *presult/*=NULL*/)
if ( nIndex & 0 || nIndex &=m_Ary_RemoteBthDevInfo.GetSize() )
return FALSE;
t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt ( nIndex );
BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
return FALSE;
if ( bdi.fAuthenticated ) return TRUE; // 已经配对了
bdi.fAuthenticated = TRUE;
VERIFY ( ERROR_SUCCESS == BluetoothUpdateDeviceRecord ( &bdi ) );
DWORD result = BluetoothAuthenticateDevice ( hwdParent, RemoteBthDevInfo.hRadio, &bdi, AUTHENTICATION_PASSKEY, (ULONG)wcslen(AUTHENTICATION_PASSKEY) );
if ( presult ) *presult =
if ( result == ERROR_SUCCESS ) return TRUE;
return FALSE;
CString CBlueTooth::FormatBthAddress(BYTE *BthAddress)
ASSERT ( BthAddress );
BLUETOOTH_ADDRESS A
ASSERT_ADDRESS ( BthAddress, LENGTH(Address.rgBytes)*sizeof(TCHAR) );
CString csBthA
for ( int i=0; i&LENGTH(Address.rgBytes); i++ )
CString csN
csNode.Format ( _T(&%.2x&), BthAddress[LENGTH(Address.rgBytes)-i-1] );
if ( !csBthAddress.IsEmpty() ) csBthAddress += &:&;
csBthAddress += csN
return csBthA
// 枚举本地蓝牙设备,返回本地蓝牙设备数
int CBlueTooth::EnumerateLocalRadios(void)
m_Ary_LocalRadioInfo.RemoveAll ();
HANDLE hRadio = NULL;
BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) };
HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio( &btfrp, &hRadio );
if ( NULL != hFind )
if ( hRadio )
t_LocalRadioInfo LocalRadioI
LocalRadioInfo.hRadio = hR
if ( ERROR_SUCCESS == BluetoothGetRadioInfo ( hRadio, &LocalRadioInfo.RadioInfo ) )
// 千万注意:以下代码让蓝牙虚拟传出串口能正常工作,我是花了一个通宵的时间才找到这个原因的。
if (FALSE == BluetoothEnableDiscovery(hRadio, TRUE))
TRACE(_T(&%s\n&), hwFormatMessage(GetLastError()));
if (FALSE == BluetoothEnableIncomingConnections(hRadio, TRUE))
TRACE(_T(&%s\n&), hwFormatMessage(GetLastError()));
m_Ary_LocalRadioInfo.Add ( LocalRadioInfo );
} while( BluetoothFindNextRadio( hFind, &hRadio ) );
BluetoothFindRadioClose( hFind );
return (int)m_Ary_LocalRadioInfo.GetSize ();
void CBlueTooth::RemoveAllLocalRadio(void)
for ( int i=0; i&m_Ary_LocalRadioInfo.GetSize(); i++ )
t_LocalRadioInfo &LocalRadioInfo = m_Ary_LocalRadioInfo.GetAt(i);
if ( LocalRadioInfo.hRadio )
CloseHandle ( LocalRadioInfo.hRadio );
m_Ary_LocalRadioInfo.RemoveAll ();
void CBlueTooth::RemoveAll_RemoteBthDevInfo(void)
for ( int i=0; i&m_Ary_RemoteBthDevInfo.GetSize(); i++ )
t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt(i);
if ( RemoteBthDevInfo.hRegHandle )
BluetoothUnregisterAuthentication ( RemoteBthDevInfo.hRegHandle );
if ( RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para )
delete RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_P
m_Ary_RemoteBthDevInfo.RemoveAll ();
int CBlueTooth::Test(void)
&#65279;&#65279;
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1020486次
积分:10682
积分:10682
排名:第896名
原创:267篇
转载:76篇
译文:10篇
评论:148条}

我要回帖

更多关于 bluetoothchatservice 的文章

更多推荐

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

点击添加站长微信