?!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 无码人妻精品一区二区三18禁,亚洲国产日韩欧美一区二区三区,西西人体444www大胆无码视频

亚洲精品92内射,午夜福利院在线观看免费 ,亚洲av中文无码乱人伦在线视色,亚洲国产欧美国产综合在线,亚洲国产精品综合久久2007

?div class="header_top">
Java知识分n|?- L学习(fn)从此开始!    
SpringBoot+SpringSecurity+Vue+ElementPlus权限pȝ实战评 震撼发布        

最新Java全栈׃实战评(免费)

springcloud分布式电(sh)商秒杀实战评

IDEA怹Ȁz?/h2>

66套java实战评无套路领?/h2>

锋哥开始收Java学员啦!

Python学习(fn)路线?/h2>

锋哥开始收Java学员啦!

Android开发之蓝牙详解 PDF 下蝲


旉:2020-06-24 15:10来源:http://www.sh6999.cn 作?锋  侉|举报
Android开发之蓝牙详解 PDF 下蝲
失效链接处理
Android开发之蓝牙详解 PDF 下蝲

本站整理下蝲Q?/strong>
链接Q?a target="_blank">https://pan.baidu.com/s/1wEG7qiwkqYLnHXAR_lufiA 
提取码:(x)21zd
 
相关截图Q?/strong>
 
主要内容Q?/strong>
Android 开发之蓝牙详解 一.概述 
q篇文章是我学习(fn) Android 开发官|以?qing)网上一些其他文章ȝ而来Q主要就是ؓ(f)了好
好研I一下蓝牙开发,看完q篇文章以后Q我们就知道了怎样使用蓝牙 API 完成建立蓝牙q?/div>
接的必要四步Q?.打开蓝牙Q?.查找附近已配Ҏ(gu)可用的设备;3.q接讑֤Q?.讑֤间数?/div>
交换。由于文章比较长Qؓ(f)了方便大家的学习(fn)Q所以将文章分ؓ(f)三篇Q这是第一?/div>
?基础 
1.API
所有的蓝牙 API 都在 android.bluetooth 包下.下面有一些类和接口的摘要Q我们需?/div>
它们来徏立蓝牙连?
BluetoothAdapter
代表本地蓝牙适配器(蓝牙无线Q。BluetoothAdapter 是所有蓝牙交互的入口。用这
个类Q你能够发现其他的蓝牙设备,查询已配对设备的列表Q用已知的 MAC 地址来实例化
一?BluetoothDevice 对象Qƈ且创Z?BluetoothServerSocket 对象来监听与其他讑֤
的通信?/div>
BluetoothDevice
代表一个远E的蓝牙讑֤。用这个类通过 BluetoothSocket 或查询诸如名U、地址?/div>
cd配对状态等讑֤信息来请求跟q程讑֤的连接?/div>
BluetoothSocket
代表蓝牙 socket 的接口(cM TCP ?SocketQ。这是允怸个应用程序跟另一个蓝?/div>
讑֤通过输入和输出进行数据交换的q接炏V?/div>
BluetoothServerSocket
代表一个打开的监听传入请求的服务接口Q类g TCP ?ServerSocketQ。ؓ(f)了连接两
?Android 讑֤Q一个设备必ȝq个cL开一个服务接口。当q程蓝牙讑֤h跟本讑֤
建立q接hӞ BluetoothServerSocket ?x)在q接被接收时q回一个被q接?/div>
BluetoothSocket 对象?/div>
BluetoothClass
描述了蓝牙设备的一般性特征和功能。这个类是一个只ȝ属性集Q这些属性定义了?/div>
备的主要和次要设备类和服务。但是,q个cdƈ不保证描qC讑֤所支持的所有的蓝牙配置
和服务,但是q种对设备类型的提示是有益的
BluetoothProfile
代表一个蓝牙配|的接口。蓝牙配|是Z蓝牙通信的设备间的无U接口规范。一个例
子是免提的配|。更多的配置讨论Q请看下文的用配|来工作?/div>
BluetoothHeadset
提供对用蓝牙x的移动电(sh)话的支持。它同时包含?Bluetooth Headset ?HandsKFree(v1.5)的配|?/div>
BluetoothA2dp
定义如何把高品质的音频通过蓝牙q接从一个设备流向另一个设备?ldquo;A2DP”?/div>
Advanced Audio Distribution Profile 的羃写?/div>
BluetoothHealth
代表一个健康保健设备配|的控制蓝牙服务的代理?/div>
BluetoothHealthCallback
用于实现 BluetoothHealth 回调的抽象类。你必须l承q个c,q实现它的回调方法,
来接收应用程序的注册状态和蓝牙通道状态变化的更新?/div>
BluetoothHealthAppConfiguration
代表蓝牙相关的第三方健康保健应用E序所注册的与q程蓝牙健康保健讑֤q行通信
的配|?/div>
BluetoothProfile.ServiceListener
BluetoothProfile IPC 客户端连接或断开服务的通知接口Q它是运行特俗配|的内部
服务Q?/div>
2.权限
Z在你的应用程序中使用蓝牙功能Q至要声明两个蓝牙权限QBLUETOOTH ?/div>
BLUETOOTH_ADMINQ中的一个?/div>
Z执行M蓝牙通信Q如hq接、接收连接和传输数据Q,你必ȝ?BLUETOOTH
权限?/div>
Z启动讑֤发现或维护蓝牙设|,你必ȝ?BLUETOOTH_ADMIN 权限。大多数需要这
个权限的应用E序Q仅仅是够发现本地的蓝牙讑֤。这个权限所授予的其他能力应该不
被用,除非是电(sh)源管理的应用E序Q它?x)在依据用户的请求来修改蓝牙讄。注意:(x)如果
你用了 BLUETOOTH_ADMIN 权限Q那么必要?BLUETOOTH 权限?/div>
在清单文件中声明如下权限Q?/div>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
3.讄蓝牙
在应用程序能够利用蓝牙通道通信之前Q需要确认设备是否支持蓝牙通信Q如果支持,
要确保它是可用的?/div>
如果不支持蓝牙,那么你应该有好的用所有蓝牙功能。如果支持蓝牙,但是被禁用的Q?/div>
那么你要在不d你的应用E序的情况下Q请求用户启用蓝牙功能,q种讄要?/div>
BluetoothAdapter 对象Q在以下两个步骤中完成?/div>
(1)获得 BluetoothAdapter 对象
BluetoothAdapter 对象是所有蓝牙活动都需要的Q要获得q个对象Q就要调用静态的
getDefaultAdapter() ???q?????q??一 ??????????????/div>
BluetoothAdapter 对象。整个系l有一个蓝牙适配器,你的应用E序能够使用q个对象?/div>
q行交互。如?getDefaultAdapter()Ҏ(gu)q回 nullQ那么该讑֤不支持蓝牙,你的处理?/div>
要在此结束。例如:(x)
BluetoothAdapter mBluetoothAdapter =BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter ==null){
// 讑֤不支持蓝?/div>
}
(2)启用蓝牙功能
接下来,你需要确保蓝牙是可用的。调?isEnabled()Ҏ(gu)来检查当前蓝牙是否可用?/div>
如果q个Ҏ(gu)q回 falseQ那么蓝牙是被禁用的。要甌启用蓝牙功能Q就要调用带?/div>
ACTION_REQUEST_ENABLE 操作意图?startActivityForResult()Ҏ(gu)。它?x)给pȝ讄发一
个启用蓝牙功能的hQ不l止你的应用E序Q。例如:(x)
if(!mAdapter.isEnabled()) {
 Intent intent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE );
 activity.startActivityForResult(intent, requestCode);
}
q时?x)显CZ个请求用户启用蓝牙功能的对话?/div>
如果用户点击允许Q那么系l会(x)开始启用蓝牙功能,完成启动q程Q有可能p|Q,?/div>
点会(x)q回l你的应用程序。传递给 startActivityForResult()Ҏ(gu)?requestCode 是一?/div>
你的应用E序中定义的整数Q它必须大于 0Q,pȝ?x)把它作为参数返回到你?/div>
onActivityResult()回调实现中?/div>
如果蓝牙功能启用成功Q你?Activity ?x)?onActivityResult()回调中接收到
RESULT_OK l果Q如果蓝牙没有被启动Q或者用户响应了拒绝Q,那么该结果编码是
RESULT_CANCELED?/div>
可选地Q你的应用程序还可以监听 ACTION_STATE_CHANGED q播 IntentQ无牙状?/div>
何时改变Q系l都?x)广播这?Intent。这个广播包含的附加字段 EXTRA_STATE ?/div>
EXTRA_PREVIOUS_STATE 中分别指明了新的和旧的蓝牙状态。这些附加字D中可能的值是Q?/div>
STATE_TURNING_ON、STATE_ON、STATE_TURNING_OFF ?STATE_OFF。监听这个广播对于在?/div>
用程序运行时蓝牙的状态是有用的?/div>
提示Q启用可发现能力?x)自动启动蓝牙功能。如果你计划在执行蓝牙活动之前,要始l?/div>
启用讑֤的可发现机制Q就可以跌上面的步骤,详细请参考下?ldquo;启用蓝牙可发?rdquo;?/div>
到此Q我们先l出一个例子,让大家理解一下:(x)
我们讄了四个按钮,分别用于判断是否支持蓝牙Q蓝牙是否开启,开启蓝牙,关闭?/div>
牙,׃使用的是模拟器,所以我们可以看到实验结果是当前讑֤不支持蓝牙,q且蓝牙?/div>
开启,点击后面两个按钮没反应,如果是在真是讑֤上,我们可以q行开启蓝牙和关闭蓝牙
的操作,大家下来可以试一试,下面l出代码Q?/div>
/**
* Created by lxn on 2016/3/4.
* 蓝牙理c?/div>
*/
public class BluetoothController {
 private BluetoothAdapter mAdapter;
 public BluetoothController(){
 mAdapter = BluetoothAdapter.getDefaultAdapter();
 }
 /**
 * 判断当前讑֤是否支持蓝牙
 * @return
 */
 public boolean isSupportBluetooth(){
 if(mAdapter!=null){
 return true;
 }
 return false;
 }
 /**
 * 获取蓝牙的状?/div>
 * @return
 */
 public boolean getBluetoothStatus(){
 if(mAdapter!=null){
 return mAdapter.isEnabled();
 }
 return false;
 }
 /**
 * 打开蓝牙
 * @param activity
 * @param requestCode
 */
 public void turnOnBluetooth(Activity activity,int requestCode){
 if(mAdapter!=null&&!mAdapter.isEnabled()) {
 Intent intent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE);
 activity.startActivityForResult(intent, requestCode);
 }
 }
 /**
 * 关闭蓝牙
 */
 public void turnOffBluetooth(){
 if(mAdapter!=null&&mAdapter.isEnabled()) {
 mAdapter.disable();
 }
 } }
public class MainActivity extends AppCompatActivity {
 public static final int REQUESTCODE_OPEN = 1;
 private BluetoothController mController = new BluetoothController();
 private BroadcastReceiver receiver = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 1);
 switch (state) {
 case BluetoothAdapter.STATE_OFF:
 Toast.makeText(MainActivity.this, " ?????", 
Toast.LENGTH_SHORT).show();
 break;
 case BluetoothAdapter.STATE_ON:
 Toast.makeText(MainActivity.this, " 蓝牙已打开 ", 
Toast.LENGTH_SHORT).show();
 break;
 case BluetoothAdapter.STATE_TURNING_ON:
 Toast.makeText(MainActivity.this, " ???开 ??", 
Toast.LENGTH_SHORT).show();
 break;
 case BluetoothAdapter.STATE_TURNING_OFF:
 Toast.makeText(MainActivity.this, " ??????", 
Toast.LENGTH_SHORT).show();
 break;
 default:
 Toast.makeText(MainActivity.this, " 未知状?", 
Toast.LENGTH_SHORT).show();
 }
 }
 };
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 IntentFilter filter = new 
IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
 registerReceiver(receiver, filter);
 }
 public void click(View view) {
 switch (view.getId()) {
 case R.id.btnIsSupport:
 boolean flag = mController.isSupportBluetooth();
 Toast.makeText(this, "flag = " + flag, 
Toast.LENGTH_SHORT).show();
 break;
 case R.id.btnIsTurnOn:
 boolean isTurnOn = mController.getBluetoothStatus();
 Toast.makeText(this, "isTurnOn" + isTurnOn, 
Toast.LENGTH_SHORT).show();
 break;
 case R.id.btnTurnOn:
 mController.turnOnBluetooth(this, REQUESTCODE_OPEN);
 break;
 case R.id.btnTrunOff:
 mController.turnOffBluetooth();
 break;
 }
 }
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{
 super.onActivityResult(requestCode, resultCode, data);
 if(resultCode==RESULT_OK){
 Toast.makeText(this, "l于打开?quot;, Toast.LENGTH_SHORT).show();
 }
 } }
4.查找讑֤
使用 BluetoothAdapter 对象Q能够通过讑֤发现或查询已配对的设备列表来扑ֈq程
的蓝牙设备?/div>
讑֤发现是一个扫描过E,该过E搜索本地区域内可用的蓝牙设备,然后h一些彼?/div>
相关的一些信息(q个q程被叫?ldquo;发现”?ldquo;查询”?ldquo;扫描”Q。但是,本地区域内的蓝牙
讑֤只有在它们也启用了可发现功能Ӟ才会(x)响应发现h。如果一个设备是可发现的Q那
么它?x)通过׃n某些信息Q如讑֤名称、类别和唯一?MAC 地址Q来响应发现h。用这
些信息,执行发现处理的设备能够有选择的初始化跟被发现讑֤的连接?/div>
一旦跟q程的设备徏立的首次q接Q配对请求就?x)自动的被展现给用户。当讑֤完成?/div>
对,相关讑֤的基本信息(如设备名U、类别和 MAC 地址Q就?x)被保存Qƈ能够使用蓝牙 API
来读取。用已知的q程讑֤?MAC 地址Q在M时候都能够初始化一个连接,而不需要执
行发现处理(假设讑֤在可q接的范围内Q?/div>
要记住配对和q接之间的差异。配Ҏ(gu)味着两个讑֤对彼此存在性的感知Q它们之间有
一个共享的用于验证的连接密钥,用这个密钥两个设备之间徏立被加密的连接。连接意味着
当前讑֤间共享一?RFCOMM 通道Qƈ且能够被用于讑֤间的数据传输。当?Android 蓝牙
API ?RFCOMM q接被徏立之前,要求讑֤之间配对。(在用蓝?API 初始化加密连接时Q?/div>
配对是自动被执行的。)
以下章节介绍如何发现已配对的讑֤Q或发现新的使用了可发现功能的设备?/div>
注意Q默?Android 讑֤是不可发现的。用戯够通过pȝ讄在限定的旉内变成可
发现的设备,或者应用程序能够请求用户启用可发现性,而不d应用E序。如何启用可?/div>
现性,?x)在下文来讨论?/div>
查询配对讑֤
在执行设备发C前,应该先查询已配对的设备集合,来看期望的设备是否是已知的?/div>
调用 getBondedDevices()Ҏ(gu)来完成这件工作。这个方法会(x)q回一个代表已配对讑֤?/div>
BluetoothDevice 对象的集合。例如,你能够查询所有的配对讑֤Q然后用一?/div>
ArrayAdapter 对象把每个已配对讑֤的名U显C给用户?/div>
 /**
 * 获取已经配对的设?/div>
 */
 public Set<BluetoothDevice> getConnetedDevices() {
 if (mAdapter != null && mAdapter.isEnabled()) {
 return mAdapter.getBondedDevices();
 }
 return null;
 }
Set<BluetoothDevice> connetedDevices = mController.getConnetedDevices();
 for(BluetoothDevice device:connetedDevices){
 adapter.add(device.getName()+"\n"+ device.getAddress());
 listView.setAdapter(adapter);
 } ?BluetoothDevice 对象来初始化一个连接所需要的所有信息就?MAC 地址。在q个
例子中,MAC 地址被作?ArrayAdapter 的一部分来保存,q显C给用户。随后,?MAC ?/div>
址能够被提取用于初始化q接?/div>
发现讑֤
单的调用 startDiscovery()Ҏ(gu)可以开始发现设备。该q程是异步的Qƈ且该?/div>
法会(x)立即q回一个布?yu)(dng)值来指明发现处理是否被成功的启动。通常发现q程?x)查询扫描大U?/div>
12 U,接下来获取扫描发现的每个讑֤的蓝牙名U?/div>
Z接收每个被发现设备的的信息,你的应用E序必须注册一?ACTION_FOUND cd?/div>
q播接收器。对应每个蓝牙设备,pȝ都会(x)q播 ACTION_FOUND cd?Intent。这?Intent
?x)携?EXTRA_DEVICE ?EXTRA_CLASS 附加字段Q这个两个字D分别包含了 BluetoothDevice
?BluetoothClass 对象。例如,下列演示了你如何注册和处理设备发现时的广播:(x)
//W一步:(x)注册q播
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
 registerReceiver(mReceiver, filter);//不要忘了?onDestory ?unregister
 W二部:(x)开始发?/div>
mController.startDiscovery();//开始搜索可发现的设?/div>
//W三?接收q播
 private BroadcastReceiver mReceiver = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
 String action = intent.getAction();
 //发现了设?/div>
 if(BluetoothDevice.ACTION_FOUND.equals(action)){
 Toast.makeText(MainActivity.this, " 发现讑֤ ", 
Toast.LENGTH_SHORT).show();
 //?Intent 中获取设备的 BluetoothDevice 对象
 BluetoothDevice device = 
intent.getParcelableExtra( BluetoothDevice.EXTRA_DEVICE);
 adapter.add(device.getName()+"\n"+ device.getAddress());
 listView.setAdapter(adapter);
 }
 }
 };
l果如下Q?/div>
可以看到Q我们已l把发现的设备展C到?ListView 中?/div>
警告Q执行设备发玎ͼ对于蓝牙适配器来说是一个沉重的q程Q它?x)消耗大量的资源?/div>
一旦发现要q接讑֤Q在试q接之前一定要认?cancelDiscovery()Ҏ(gu)来终止发现操
作。另外,如果已经有一个跟讑֤的连接,那么执行发现?x)明昄减少q接的可用带宽,?/div>
此在有连接的时候不应该执行发现处理?/div>
Android 开发之蓝牙详解(? 一.概述 
在第一?Android 开发之蓝牙详解(一)中我主要介绍了一些理论性的知识以及(qing)比较?/div>
的操作,比如控制蓝牙的状态,查找讑֤Q显C当前已q接的设备,今天我们看看其他?/div>
一些操作?/div>
?基础 
1.可发现模?/div>
在上一最后,我们介绍了如何发现设备,但是有些时候,我们当前讑֤是不可被发现
的,也就是说即我们打开了蓝牙其他设备也是无法搜索到的。所以我们要学学如何启用?/div>
备的可发现性。如果要让本地设备可以被其他讑֤发现Q那么就要调?/div>
ACTION_REQUEST_DISCOVERABLE 操作意图?startActivityForResult(Intent, int)Ҏ(gu)?/div>
q个Ҏ(gu)?x)向pȝ讄发出一个启用可发现模式的请求(不终止应用程序)。默认情况下Q?/div>
讑֤的可发现模式?x)持l?120 U。通过l?Intent 对象d EXTRA_DISCOVERABLE_DURATION
附加字段Q可以定义不同持l时间。应用程序能够设|的最大持l时间是 3600 U,0 意味
着讑֤始终是可发现的。Q何小?0 或大?3600 U的值都?x)自动的被设?120 U。例如,
以下代码把持l时间设|ؓ(f) 300 U:(x)
 Intent discoverableIntent = new
 Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
 //定义持箋旉
 
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 
300);
 startActivity(discoverableIntent);
效果图:(x)
如图所C,甌用户启用讑֤的可发现模式Ӟ?x)显C样一个对话框。如果响?ldquo;?/div>
喜?rdquo;Q那么设备的可发现模式会(x)持箋指定的时_(d)而且你的 Activity ?x)接收带有结果代?/div>
{于可发现设备持l时间的 onActivityResult()回调Ҏ(gu)的调用。如果用户响?ldquo;拒绝”
或有错误发生Q则l果代码{于 RESULT_CANCELED.
注意Q如果设备没有开启蓝牙功能,那么开启设备的可发现模式会(x)自动开启蓝牙?/div>
在可发现模式下,讑֤?x)静静的把这U模式保持到指定的时ѝ如果你惌在可发现?/div>
式被改变时获得通知Q那么你可以注册一?ACTION_SCAN_MODE_CHANGED cd?Intent q?/div>
播。这?Intent 对象中包含了 EXTRA_SCAN_MODE ?EXTRA_PREVIOUS_SCAN_MODE 附加字段Q?/div>
????????????????????????Q?/div>
SCAN_MODE_CONNECTABLE_DISCOVERABLEQSCAN_MODE_CONNECTABLE ?SCAN_MODE_NONEQ它?/div>
分别指明讑֤是在可发现模式下Q还是不在可发现模式下但依然可接收连接,或者是不在?/div>
发现模式下,不能接收q接?/div>
下面是示例代码:(x)
public class MainActivity extends Activity {
 public static final int TURN = 1;
 private BluetoothController mController = new BluetoothController();
 private BroadcastReceiver mReceiver = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
 int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,1);
 switch (mode){
 case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
 Toast.makeText(MainActivity.this, " ????????", 
Toast.LENGTH_SHORT).show();
 break;
 case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
 Toast.makeText(MainActivity.this, "现在不是可发现模式,但是
可以q接", Toast.LENGTH_SHORT).show();
 }
 }
 };
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 //注册q播Q监听模式改?/div>
 IntentFilter filter = new 
IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
 registerReceiver(mReceiver,filter);
 }
 public void click(View view){
 switch (view.getId()){
 case R.id.turnOn:
 mController.turnOnBluetooth(this, TURN);
 break;
 case R.id.canFind:
 Intent discoverableIntent = new
 Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
 //定义持箋旉
 
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 10);
 startActivity(discoverableIntent);
 break;
 }
 } }
如果你要初始化跟q程讑֤的连接,你不需要启用设备的可现性。只有在你想要把你的
应用E序作ؓ(f)服务端来接收输入q接Ӟ才需要启用可发现性,因ؓ(f)q程讑֤在跟你的讑֤
q接之前必须能够发现它?/div>
2.q接讑֤
Z让两个设备上的两个应用程序之间徏立连接,你必d时实现服务端和客L(fng)机制Q?/div>
因ؓ(f)一个设备必L开服务端口Q同时另一个设备必d始化跟服务端讑֤的连接(使用?/div>
务端?MAC 地址来初始化一个连接)。当服务端和客户端在相同?RFCOMM 通道上有一?/div>
BluetoothSocket q接Ӟ才能够被认ؓ(f)是服务端和客L(fng)之间建立了连接。这Ӟ每个?/div>
备能够获得输入和输出,q且能够彼此开始传输数据?/div>
服务端设备和客户端设备彼此获取所需?BluetoothSocket 的方法是不同的。服务端?/div>
在接收输入连接的时候接收到一?BluetoothSocket 对象。客L(fng)?x)在打开跟服务端?/div>
RFCOMM 通道时接收到一?BluetoothSocket 对象?/div>
一U实现技术是自动的准备一个设备作为服务端Q以便在每个讑֤都会(x)有一个服务套?/div>
字被打开Qƈ监听q接h。当另一个设备初始化一个跟服务端套接字的连接时Q它?yu)׃?x)?/div>
成一个客L(fng)。另一U方法,一个设备是明确?rdquo;host”q接Qƈ且根据要求打开一个服?/div>
套接字,而其他的讑֤只是单的初始化连接?/div>
注意Q如果两个设备之前没有配对,那么 Android 框架?x)在q接q程期间Q自动的昄
一个配对请求通知或对话框l用P如图 3 所C。因此在试图q接讑֤Ӟ你的应用E序?/div>
需要关心设备是否被配对。FRCOMM 的尝试性连接会(x)一直阻塞,一直到用户成功的配对,?/div>
者是因用hl配Ҏ(gu)配对时而失败?/div>
当你惌q接两个讑֤Ӟ一个必通过持有一个打开?BluetoothServerSocket 对象
来作为服务端。服务套接字的用途是监听输入的连接请求,q且在一个连接请求被接收Ӟ
提供一?BluetoothSocket q???????BluetoothServerSocket 对象中获?/div>
BluetoothSocket ӞBluetoothServerSocket 能够Qƈ且也应该Q被废弃Q除非你惌?/div>
收更多的q接?/div>
以下是徏立服务套接字和接收一个连接的基本q程?/div>
1. ??listenUsingRfcommWithServiceRecord(String, UUID) ?????一 ?/div>
BluetoothServerSocket 对象。该Ҏ(gu)中的 String 参数是一个可识别的你的服务端的名Uͼ
pȝ?x)自动的把它写入讑֤上?Service Discovery ProtocolQSDPQ数据库实体Q该名称
是Q意的Qƈ且可以简单的使用你的应用E序的名Uͼ。UUID 参数也会(x)被包含在 SDP 实体中,
q且是跟客户端设备连接的基本协议。也是_(d)当客L(fng)试跟服务端q接Ӟ它会(x)携带
一个它惌q接的服务端能够唯一识别?UUID。只有在q些 UUID 完全匚w的情况下Q连?/div>
才可能被接收?/div>
通过调用 accept()Ҏ(gu)Q启动连接请求。这是一个阻塞调用。只有在q接被接收或发生
异常的情况下Q该Ҏ(gu)才返回。只有在发送连接请求的q程讑֤所携带?UUID 跟监听服?/div>
套接字所注册的一?UUID 匚w的时候,该连接才被接收。连接成功,accept()Ҏ(gu)?x)返?/div>
一个被q接?BluetoothSocket 对象?/div>
除非你想要接收其他连接,否则要调?close()Ҏ(gu)。该Ҏ(gu)?x)释放服务套接字以?qing)?/div>
所占用的所有资源,但不?x)关闭被q接的已l有 accept()Ҏ(gu)所q回?BluetoothSocket
对象。跟 TCP/IP 不一P每个 RFCOMM 通道一ơ只允许q接一个客L(fng)Q因此在大多数情?/div>
下,在接收到一个连接套接字之后Q立卌?BluetoothServerSocket 对象?close()Ҏ(gu)
是有道理的?/div>
accept()Ҏ(gu)的调用不应该在主 Activity ?UI U程中被执行Q因调用是阻塞的Q?/div>
q会(x)L应用E序的其他交互。通常在由应用E序所理的一个新的线E中来?/div>
BluetoothServerSocket 对象?BluetoothSocket 对象来工作。要l止诸如 accept()q样?/div>
d调用Ҏ(gu)Q就要从另一个线E中调用 BluetoothServerSocket 对象Q或 BluetoothSocket
对象Q的 close()Ҏ(gu)Q这旉塞会(x)立即q回。注意在 BluetoothServerSocket ?/div>
BluetoothSocket 对象上的所有方法都是线E安全的?/div>
CZ
以下是一个被化的接收q接h的服务端lgQ?/div>
 public class AcceptThread extends Thread{
 private BluetoothServerSocket mServerSocket;
 public AcceptThread(){
 BluetoothServerSocket tmp = null;
 try {
 tmp = mController.getmAdapter()
.listenUsingRfcommWithServiceRecord("BluetoothServer", 
UUID.fromString(getPackageName()));
 } catch (IOException e) {
 e.printStackTrace();
 }
 mServerSocket = tmp;
 }
 @Override
 public void run() {
 super.run();
 BluetoothSocket socket = null;
 //不断监听直到q回q接或者发生异?/div>
 while (true){
 try {
 //启连接请求,q是一个阻塞方法,必须攑֜子线E?/div>
 socket = mServerSocket.accept();
 } catch (IOException e) {
 e.printStackTrace();
 }
 //建立了连?/div>
 if(socket!=null){
 //理q接(在一个独立的U程里进?
 manageConnectedSocket(socket);
 try {
 mServerSocket.close();//关闭q接
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
 }
 /**
 * 取消正在监听的接?/div>
 */
 public void cancel(){
 try {
 mServerSocket.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 public void manageConnectedSocket(BluetoothSocket socket){
 }
在这个例子中Q只希望有一个呼入连接,因此q接一旦被接收Qƈ获取了一?/div>
BluetoothSocket 对象Q应用程序就?x)把获得?BluetoothSocket 对象发送给一个独立的U?/div>
E,然后关闭 BluetoothServerSocket 对象q中断@环?/div>
注意Q在 accept()Ҏ(gu)q回 BluetoothSocket 对象Ӟ套接字已l是被连接的Q因?/div>
你不应该再调用像客户端那栯?connect()Ҏ(gu)了?/div>
应用E序中的 manageConnectedSocket()Ҏ(gu)是一个自定义Ҏ(gu)Q它?x)初始化用于传?/div>
数据的线E?/div>
通常Q一旦你监听完成呼入q接Q就应该关闭 BluetoothServerSocket 对象。在q个C?/div>
例中Qclose()Ҏ(gu)是在获得 BluetoothSocket 对象之后被调用的。你可能q想要提供一?/div>
公共Ҏ(gu)Q以便在你的U程中能够关闭你惌l止监听的服务套接字事g中的U有
BluetoothSocket 对象?/div>
作ؓ(f)q接的客L(fng)
Z初始化一个与q程讑֤Q持有打开的服务套接字的设备)的连接,首先必须获取?/div>
代表q程讑֤?BluetoothDevice 对象。然后?BluetoothDevice 对象来获取一?/div>
BluetoothSocket 对象Qƈ初始化该q接?/div>
以下是一个基本的q接q程Q?/div>
1. 通过调用 BluetoothDevice ?createRfcommSocketToServiceRecord(UUID)Ҏ(gu)Q?/div>
获得一?BluetoothSocket 对象。这个方法会(x)初始化一个连接到 BluetoothDevice 对象?/div>
BluetoothSocket ?????l?q?????UUID ???????????开
BluetoothServerSocket 对象时所使用?UUID 相匹配。在你的应用E序中简单的使用编
码进行比对,如果匚wQ服务端和客L(fng)代码可以应用这?BluetoothSocket 对象了?/div>
通过调用 connect()Ҏ(gu)来初始化q接。在q个调用中,Z扑ֈ匚w?UUIDQ系l会(x)
在远E的讑֤上执行一?SDP 查询。如果查询成功,q且q程讑֤接收了该q接hQ那?/div>
它会(x)在连接期间共享?RFCOMM 通道Qƈ?connect()Ҏ(gu)?x)返回。这个方法是一个阻?/div>
调用。如果因为某些原因,q接p|或连接超Ӟ大约?12 U之后)Q就?x)抛Z个异常?/div>
因ؓ(f) connect()Ҏ(gu)是阻塞调用,q个q接q程始终应该在独立与?Activity U程?/div>
外的U程中被执行?/div>
注意Q在调用 connect()Ҏ(gu)Ӟ应该始终保讑֤没有正在执行讑֤发现操作。如?/div>
是在发现操作的过E中Q那么连接尝试会(x)明显的变慢,q且更像是要p|的样子?/div>
CZ
以下是初始化蓝牙q接U程的一个基本的例子Q?/div>
 public class ConnectThread extends Thread{
 private BluetoothDevice mDevice;
 private BluetoothSocket mSocket;
 public ConnectThread(BluetoothDevice device){
 BluetoothSocket temp = null;
 mDevice = device;
 try {
 temp = 
mDevice.createRfcommSocketToServiceRecord(UUID.fromString(getPackageName()));
 } catch (IOException e) {
 e.printStackTrace();
 }
 mSocket = temp;
 }
 @Override
 public void run() {
 super.run();
 //取消搜烦因ؓ(f)搜烦?x)让q接变慢
 mController.getmAdapter().cancelDiscovery();
 try {
 //通过 socket q接讑֤Q这是一个阻塞操作,知道q接成功或发生异?/div>
 mSocket.connect();
 } catch (IOException e) {
 //无法q接Q关?socket q且退?/div>
 try {
 mSocket.close();
 } catch (IOException e1) {
 e1.printStackTrace();
 }
 }
 //理q接(在独立的U程)
 // manageConnectedSocket(mmSocket);
 }
 /**
 * 取消正在q行的链接,关闭 socket
 */
 public void cancel() {
 try {
 mSocket.close();
 } catch (IOException e) { }
 }
 }
在徏立连接之前要调用 cancelDiscovery()Ҏ(gu)。在q接之前应该始终调用q个Ҏ(gu)Q?/div>
q且不用实际的检查蓝牙发现处理是否正在运行也是安全的Q如果想要检查,调用
isDiscovering()Ҏ(gu)Q?/div>
manageConnectedSocket()Ҏ(gu)是一个应用程序中自定义的Ҏ(gu)Q它?x)初始化传输数?/div>
的线E?/div>
当用完 BluetoothSocket 对象Ӟ要始l调?close()Ҏ(gu)来进行清理工作。这样做
?x)立卛_闭被q接的套接字Qƈ清理所有的内部资源?/div>
好了Q这文章就到这里。大家仔l理解体?x)。下面给出源码的下蝲地址
客户端:(x)http://download.csdn.net/detail/small_lee/9453107
服务端:(x)http://download.csdn.net/detail/small_lee/9453105

 

------分隔U?---------------------------
?!-- //底部模板 -->