添加权限:

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

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

  • 客户端

开启蓝牙:

/**

 * 打开蓝牙设备

 */

void openBT(){

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (mBluetoothAdapter!= null){

if (!mBluetoothAdapter.isEnabled()){

mBluetoothAdapter.enable();

Log.d("qfopenBT","打开蓝牙成功");

}

}

}

搜索蓝牙:

/**

 * 搜索蓝牙设备

 * @param view

 */

@OnClick(R.id.btSearch)

public void startSearch(View view){

if(mBluetoothAdapter!= null &&mBluetoothAdapter.isEnabled()){

if (!mBluetoothAdapter.isDiscovering()){

mBluetoothAdapter.startDiscovery();

}

}

}

开启搜索是异步操作,发现设备后会发送广播,所以要定义广播接收者

在接收到广播后,获取广播里的蓝牙数据

private class BTBroadCastRevextends BroadcastReceiver{

@Override

public void onReceive(Context context,Intent intent) {

String strAction = intent.getAction();

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

BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

mArrDevice.add(device);

mAdapter.notifyDataSetChanged();

}

else if(strAction.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){

Log.d("qfonReceive","搜索完成");

}

}

}

//注册广播接收者

myReceive = newBTBroadCastRev();

IntentFilter ifFind = new IntentFilter(BluetoothDevice.ACTION_FOUND);

this.registerReceiver(myReceive,ifFind);

IntentFilter ifFinishFind = newIntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

this.registerReceiver(myReceive,ifFinishFind);

连接蓝牙,并开启发送数据线程:

/**

 * 点击item,连接对应的蓝牙设备

 */

protected void connectBT() {

mLvDevice.setOnItemClickListener(newAdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent,View view, int position, longid) {

MyClientTask task = newMyClientTask();

task.execute(mArrDevice.get(position));

}

});

}

class MyClientTask extends AsyncTask<BluetoothDevice,Void,Void>{

@Override

protected VoiddoInBackground(BluetoothDevice... devices) {

BluetoothDevice device = devices[0];

try {

//使用安全连接,服务端也要一样使用安全连接,UUID也要跟服务器的监听UUID一致

BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);

socket.connect();

Log.d("qfdoInBackground_client","连接成功,开始发送数据");

byte[] btMsg =new String("Hello").getBytes();

socket.getOutputStream().write(btMsg,0,btMsg.length);

} catch(Exception e) {

e.printStackTrace();

}

return null;

}

}

uuid可以通过uuidgen生成,生成结果类似以下结构:

5D3D5E52-338A-47B8-9F10-27ADF89E204E

  • 服务端

开启蓝牙,跟客户端一样

启动服务线程

new RevTask().execute();

class RevTask extendsAsyncTask<Void,Void,String>{

@Override

protected void onPostExecute(String s) {

super.onPostExecute(s);

tvMsg.setText(s);

}

@Override

protected StringdoInBackground(Void... params) {

try {

Log.d("qfdoInBackground","开始监听");

//要跟客户端uuid一致

BluetoothServerSocket sevSocket =mBluetoothAdapter.listenUsingRfcommWithServiceRecord("blue_service",MY_UUID_SECURE);

BluetoothSocket socket = sevSocket.accept();

if(socket != null){

Log.d("qfdoInBackground","连接成功");

InputStream stream = socket.getInputStream();

byte[] btRead =new byte[1024];

int iLength = stream.read(btRead);

Log.d("qfdoInBackground","读取数据成功"+iLength);

String strMsg =new String(btRead,"utf-8");

Log.d("qfdoInBackground",strMsg);

return strMsg;

}

else{

Log.d("qfdoInBackground","失败");

}

} catch (IOException e) {

e.printStackTrace();

Log.d("qfdoInBackground","异常");

}

return null;

}

}

上述代码没有实现配对,对应经典蓝牙通信,最好先进行配对再连接,已经配对的蓝牙设备可以直接通过adapter获取到

//得到所有已经配对的蓝牙适配器对象
Set<BluetoothDevice> devices = adapter.getBondedDevices();
            

没有配对的蓝牙设备,可以在扫描设备的广播通知中判断:

if

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

点击设备连接时,判断是否已经配对,如果已经配对,直接连接,如果没有配对,先配对:

  1. if (btDev.getBondState() == BluetoothDevice.BOND_NONE) {
  2. //利用反射方法调用BluetoothDevice.createBond(BluetoothDevice remoteDevice);
  3. Method createBondMethod = BluetoothDevice.class
  4. .getMethod("createBond");
  5. Log.d("BlueToothTestActivity", "开始配对");
  6. returnValue = (Boolean) createBondMethod.invoke(btDev);
  7. }else if(btDev.getBondState() == BluetoothDevice.BOND_BONDED){
  8. connect(btDev);
  9. }

配对结果也会通过广播传递结果信息:

  1. // 注册Receiver来获取蓝牙设备相关的结果
  2. IntentFilter intent = new IntentFilter();
  3. intent.addAction(BluetoothDevice.ACTION_FOUND);// 用BroadcastReceiver来取得搜索结果
  4. intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
  5. intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
  6. intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
  7. registerReceiver(searchDevices, intent);
  1. if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){
  2. device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  3. switch (device.getBondState()) {
  4. case BluetoothDevice.BOND_BONDING:
  5. Log.d("BlueToothTestActivity", "正在配对......");
  6. break;
  7. case BluetoothDevice.BOND_BONDED:
  8. Log.d("BlueToothTestActivity", "完成配对");
  9. connect(device);//连接设备
  10. break;
  11. case BluetoothDevice.BOND_NONE:
  12. Log.d("BlueToothTestActivity", "取消配对");
  13. default:
  14. break;
  15. }

最新文章

  1. Intellij IDEA 13.1.3 打开多个窗口项目
  2. interview que
  3. 清北暑假模拟day1 艳阳天
  4. setImageResource和setBackgroundResource的區別
  5. HTML5定稿一周年,你必须要重新认识HTML5了
  6. Java中ThreadLocal的深入理解
  7. [itint5]下一个排列
  8. IntelliJ IDEA Subversion的使用方式
  9. JS于,子类调用父类的函数
  10. Thread thread2 = new Thread()
  11. java动态加载配置文件
  12. gawk的用法
  13. android AlarmManager讲解
  14. 用css实现正方形div
  15. Acdream1201 SuSu&#39;s Power
  16. NPOI颜色对照表
  17. 剑指Offer 39. 平衡二叉树 (二叉树)
  18. type的解释
  19. linux 进程 ctrl-c,ctrl-z,ctrl-d
  20. centOSmini安装教程

热门文章

  1. Oracle中PL/SQL的执行部分和各种流程控制
  2. 使用&quot;关键词&quot;来整理自己的知识库
  3. AngularJS Best Practices: resource
  4. js判断手机 横屏模式
  5. Jquery 定时器 倒计时
  6. Leetcode: Bomb Enemy
  7. jquery 选择器(name,属性,元素)大全
  8. 编写ros串口节点,使用官方serial包
  9. eBox(stm32) 之中断结构
  10. python for MSSQLserver