蓝牙通信
public class MainActivity extends Activity implements OnClickListener { private Button startBluetooth; private Button searchBluetooth; private Button visibleBluetooth; /** * 本机蓝牙设备,为空代表本机没有蓝牙功能 */ private BluetoothAdapter bluetoothAdapter=BluetoothAdapter.getDefaultAdapter(); //开启蓝牙的请求编码 private int REQUEST_ENABLE=1; /** * 装已经配对过的设备集合 */ private List<BluetoothDevice> devices=new ArrayList<BluetoothDevice>(); //装匹配过的与搜索到的设备的名称与地址 private ArrayList<Device> bluetoothDevices = new ArrayList<Device>(); private ListView listView; //ListView的适配器 private MyBluetoothAdapter adapter; //服务端对象 private BluetoothServerSocket bluetoothServerSocket; //连接部分需要的对象 private BluetoothSocket socket;//连接这个对象 private BluetoothSocket clientSocket;//客服端对象(也就是通过上面这个对象获取的它的客服对象,再通过IO流就可以通信了) //通信需要的UUID 相当于port 手机与手机蓝牙通信使用这个 private final UUID MY_UUID = java.util.UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private String NAME;//本机名字 private String address;//本机地址 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startBluetooth = (Button) findViewById(R.id.btn_startBluetooth); searchBluetooth = (Button) findViewById(R.id.btn_search); visibleBluetooth = (Button) findViewById(R.id.btn_visible); listView=(ListView) findViewById(R.id.listView);//显示蓝牙设备的 startBluetooth.setOnClickListener(this);//开启蓝牙单击事件 searchBluetooth.setOnClickListener(this);//搜索附近的蓝牙设备 visibleBluetooth.setOnClickListener(this);//设置蓝牙的可见性 IntentFilter filter=new IntentFilter(BluetoothDevice.ACTION_FOUND);//接收找到设备的广播 registerReceiver(discoveryBroad, filter);//注册广播 //适配器 adapter=new MyBluetoothAdapter(this, bluetoothDevices); //获取本机名字和地址 NAME=bluetoothAdapter.getName(); address=bluetoothAdapter.getAddress(); //开启服务等待连接 startServer(); //ListView单击事件,也就是主动去连接点击的对象 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { buildConnect(position); } }); listView.setAdapter(adapter); } /** * 蓝牙广播接收器 */ //注册接收扫描到设备的广播 private BroadcastReceiver discoveryBroad=new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(BluetoothDevice.ACTION_FOUND.equals(action)){ System.out.println("接收到来自系统找到蓝牙设备发送的广播"); Toast.makeText(getApplicationContext(), "接收到来自系统找到蓝牙设备发送的广播", 0).show(); //获取找到的设备 BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //地址叫:MAC地址 System.out.println("找到的设备名字:"+device.getName()+",地址:"+device.getAddress()); // 如果该设备已经被添加过,则跳过 if (!devices.contains(device)) { //设备数组获得新的设备信息并更新adapter bluetoothDevices.add(new Device(device.getName(), device.getAddress(),device.getBondState())); //添加新的设备到设备Arraylist devices.add(device); adapter.notifyDataSetChanged(); } } } }; @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_startBluetooth://开启蓝牙,查询已经匹配好的设备 if(bluetoothAdapter!=null){ System.out.println("当前设备 有蓝牙接口"); if(!bluetoothAdapter.isEnabled()){//如果蓝牙没有打开就跳转到开启蓝牙的界面 Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);//请求开启蓝牙 startActivityForResult(intent, REQUEST_ENABLE); } }else{ System.out.println("当前设备 没有蓝牙功能"); return; } break; case R.id.btn_search://搜索能够配对的设备 if(bluetoothAdapter.isEnabled()){ if(devices.size()==0){//如果没有已经配对的就再获取一次 queryBondedDevice(); } //当扫描到开启了蓝牙的设备时会自动发出一条广播,所以需要注册广播来接收扫描到的设备信息 bluetoothAdapter.startDiscovery();//开始扫描,在另一个线程运行的,耗时12S }else{ Toast.makeText(this, "请先打开蓝牙", 0).show(); } break; case R.id.btn_visible://设置蓝牙的可见性 if(bluetoothAdapter.isEnabled()){ //请求可见性的Intent Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); //额外的可见性时间的设置,如果请求超过300S会被覆盖为300S (默认为120S) discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent);//android系统自带的活动 }else{ Toast.makeText(this, "请先打开蓝牙", 0).show(); } break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //如果请求码等于开启蓝牙且蓝牙开启成功 if(requestCode==REQUEST_ENABLE && resultCode==RESULT_OK){ System.out.println("用户选择了打开蓝牙"); queryBondedDevice();//查询已经匹配好的设备 }else{ System.out.println("用户退出了开启蓝牙的操作"); } } /** * 查询已经配对过的蓝牙设备 * 获取了本机蓝牙名字和地址 */ private void queryBondedDevice() { Set<BluetoothDevice> pairedDevices=bluetoothAdapter.getBondedDevices();//查询已经匹配好的设备 if(pairedDevices.size()>0){ //将已经匹配过的放到集合中 for (BluetoothDevice i : pairedDevices) { bluetoothDevices.add(new Device(i.getName(), i.getAddress(),i.getBondState())); devices.add(i);//将第一次搜索到的放入集合 adapter.notifyDataSetChanged(); } } } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(discoveryBroad);//取消广播的注册 } /** * 开启服务端 */ private void startServer() { if (!bluetoothAdapter.isEnabled()){//蓝牙没有打开 bluetoothAdapter.enable();//避免没有开蓝牙创建服务端失败 } //开启子线程等待连接 new Thread(new Runnable() { @Override public void run() { try { bluetoothServerSocket = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME,MY_UUID); while (true) { System.out.println("服务端在等待客服端的连接"); //等待客户端接入 clientSocket = bluetoothServerSocket.accept();//bluetoothServerSocket不为空 if (clientSocket != null) { //连接后需要进行的操作IO ServiceUtils service=new ServiceUtils(clientSocket); System.out.println("服务端这边---->客服端连接成功"); System.out.println("客服端读取到的数据:"+service.readerData()); clientSocket.close();//操作完关闭连接的对象 } } } catch (IOException e) { e.printStackTrace(); System.out.println("服务端创建失败"); } } }).start(); } /** * 点击ListView列表主动去建立连接 自己充当 客服端 */ private void buildConnect(int position) { //通过点击的对象的蓝牙地址获取对象 final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(bluetoothDevices.get(position).getAddress()); boolean result = false; try { //先进行配对 //如果没有配对 if (device.getBondState() == BluetoothDevice.BOND_NONE) { Method createBondMethod = null; createBondMethod = BluetoothDevice.class.getMethod("createBond"); Toast.makeText(getApplicationContext(), "开始配对", 0).show(); result = (Boolean) createBondMethod.invoke(device); } //如果已经配对好了 if (device.getBondState() == BluetoothDevice.BOND_BONDED) { if(result){ bluetoothDevices.get(position).setBondState(BluetoothDevice.BOND_BONDED); adapter.notifyDataSetChanged(); } //获得客户端Socket socket= device.createRfcommSocketToServiceRecord(MY_UUID); //如果正在搜索,要先取消. if (bluetoothAdapter.isDiscovering()) { bluetoothAdapter.cancelDiscovery(); } //蓝牙客户端发数据第4步,开始连接 new Thread(new Runnable() { @Override public void run() { try { //先停止扫描,以防止之后的连接被阻塞 bluetoothAdapter.cancelDiscovery(); System.out.println("客服端:正在准备连接中...."); socket.connect(); System.out.println("连接成功"); //连接后的操作 在另外的类中去执行 ClientUtils client=new ClientUtils(socket); client.writerData(); System.out.println("写数据成功"); } catch (IOException e) { e.printStackTrace(); runOnUiThread(new Runnable() { public void run() { Toast.makeText(getApplicationContext(), "客服端连接失败", 0).show(); } }); }finally{ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }).start(); } }catch(Exception e){ Toast.makeText(getApplicationContext(), "配对失败", 0).show(); } } }
适配器代码:
public class MyBluetoothAdapter extends BaseAdapter{ private Context context; private ArrayList<Device> devices; public MyBluetoothAdapter(Context context,ArrayList<Device> devices) { this.context = context; this.devices = devices; } @Override public int getCount() { return devices.size(); } @Override public Object getItem(int position) { return devices.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView==null){ convertView=LayoutInflater.from(context).inflate(R.layout.list_item_layout, null); holder=new ViewHolder(); holder.tv_name=(TextView) convertView.findViewById(R.id.tv_name); holder.tv_address=(TextView) convertView.findViewById(R.id.tv_address); holder.tv_bondState=(TextView) convertView.findViewById(R.id.tv_bondState); convertView.setTag(holder); }else{ holder=(ViewHolder) convertView.getTag(); } holder.tv_name.setText(devices.get(position).getName()); holder.tv_address.setText(devices.get(position).getAddress()); if(devices.get(position).getBondState()==BluetoothDevice.BOND_BONDED){ holder.tv_bondState.setText("已配对"); }else{ holder.tv_bondState.setText("没有配对"); } return convertView; } class ViewHolder{ private TextView tv_name; private TextView tv_address; private TextView tv_bondState; } }
蓝牙信息的实体类:
/** 蓝牙设备的信息包装类 */ public class Device { private String name; private String address; private int bondState; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getBondState() { return bondState; } public void setBondState(int bondState) { this.bondState = bondState; } public Device(String name, String address, int bondState) { super(); this.name = name; this.address = address; this.bondState = bondState; } public Device() { super(); } @Override public String toString() { return "Device [name=" + name + ", address=" + address + ", 配对状态=" + bondState + "]"; } }
public class ServiceUtils{ //读写socket private BluetoothSocket socket; private BufferedReader br; private BufferedWriter bw; public ServiceUtils(BluetoothSocket socket) { super(); this.socket = socket; try { br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8")); bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"utf-8")); } catch (IOException e) { e.printStackTrace(); } } public String readerData(){ String str = null; try { str=br.readLine(); } catch (IOException e) { e.printStackTrace(); } return str; } }
public class ClientUtils{ //读写socket private BluetoothSocket socket; private BufferedReader br; private BufferedWriter bw; public ClientUtils(BluetoothSocket socket) { super(); this.socket = socket; try { br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8")); bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"utf-8")); } catch (IOException e) { e.printStackTrace(); } } public String readerData(){ String str = null; try { str=br.readLine(); } catch (IOException e) { e.printStackTrace(); } return str; } public void writerData(){ try { bw.write("客服端向服务端发送数据"); bw.newLine(); bw.flush(); } catch (IOException e) { e.printStackTrace(); } } }
效果图: