zoukankan      html  css  js  c++  java
  • Android 蓝牙

     

    前言
             欢迎大家我分享和推荐好用的代码段~~
    声明
             欢迎转载,但请保留文章原始出处:
             CSDN:
    http://www.csdn.net
             雨季o莫忧离:http://blog.csdn.net/luckkof

    正文

     

    蓝牙是一种支持设备短距离传输数据的无线技术。android在2.0以后提供了这方面的支持。 
    从查找蓝牙设备到能够相互通信要经过几个基本步骤(本机做为服务器): 
    1.设置权限 
    在manifest中配置 

     

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

    2.启动蓝牙 
    首先要查看本机是否支持蓝牙,获取BluetoothAdapter蓝牙适配器对象 

     

    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(mBluetoothAdapter == null){
            //表明此手机不支持蓝牙
            return;
    }
    if(!mBluetoothAdapter.isEnabled()){	//蓝牙未开启,则开启蓝牙
    			Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    			startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
    }
    //......
    public void onActivityResult(int requestCode, int resultCode, Intent data){
           if(requestCode == REQUEST_ENABLE_BT){
                  if(requestCode == RESULT_OK){
                       //蓝牙已经开启 
                  }
           }
    }

    3。发现蓝牙设备 
    这里可以细分为几个方面 
    (1)使本机蓝牙处于可见(即处于易被搜索到状态),便于其他设备发现本机蓝牙 

    //使本机蓝牙在300秒内可被搜索
    private void ensureDiscoverable() {
            if (mBluetoothAdapter.getScanMode() !=
                BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                startActivity(discoverableIntent);
            }
    }
    

    (2)查找已经配对的蓝牙设备,即以前已经配对过的设备 

    		Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    		if (pairedDevices.size() > 0) {
    			findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
    			for (BluetoothDevice device : pairedDevices) {
    				//device.getName() +" "+ device.getAddress());
    			}
    		} else {
    			mPairedDevicesArrayAdapter.add("没有找到已匹对的设备");
    		}
    

    (3)通过mBluetoothAdapter.startDiscovery();搜索设备,要获得此搜索的结果需要注册 
    一个BroadcastReceiver来获取。先注册再获取信息,然后处理 

    //注册,当一个设备被发现时调用onReceive
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    		this.registerReceiver(mReceiver, filter);
    
    //当搜索结束后调用onReceive
    filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    		this.registerReceiver(mReceiver, filter);
    //.......
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    		@Override
    		public void onReceive(Context context, Intent intent) {
    			String action = intent.getAction();
    			if(BluetoothDevice.ACTION_FOUND.equals(action)){
    				 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    	              // 已经配对的则跳过
    	             if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
    	                  mNewDevicesArrayAdapter.add(device.getName() + "
    " + device.getAddress());  //保存设备地址与名字
    	             }
    			}else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {  //搜索结束
                    if (mNewDevicesArrayAdapter.getCount() == 0) {
                        mNewDevicesArrayAdapter.add("没有搜索到设备");
                    }
    			}
    
    		}
    };
    

    4.建立连接 
    查找到设备 后,则需要建立本机与其他设备之间的连接。 
    一般用本机搜索其他蓝牙设备时,本机可以作为一个服务端,接收其他设备的连接。 
    启动一个服务器端的线程,死循环等待客户端的连接,这与ServerSocket极为相似。 
    这个线程在准备连接之前启动 

    //UUID可以看做一个端口号
    private static final UUID MY_UUID =
            UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
       //像一个服务器一样时刻监听是否有连接建立
        private class AcceptThread extends Thread{
        	private BluetoothServerSocket serverSocket;
        	
        	public AcceptThread(boolean secure){
        		BluetoothServerSocket temp = null;
        		try {
    	    		temp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(
    	    					NAME_INSECURE, MY_UUID);
        		} catch (IOException e) {
    				  Log.e("app", "listen() failed", e);
    			}
        		serverSocket = temp;
        	}
        	
        	public void run(){
        		BluetoothSocket socket=null;
        		while(true){
        			try {
    					socket = serverSocket.accept();
    				} catch (IOException e) {
    					 Log.e("app", "accept() failed", e);
    	                 break;
    				}
        		}
        		if(socket!=null){
        			//此时可以新建一个数据交换线程,把此socket传进去
        		}
        	}
        	
        	//取消监听
        	public void cancel(){	
    	        try {
    	            serverSocket.close();
    	        } catch (IOException e) {
    	            Log.e("app", "Socket Type" + socketType + "close() of server failed", e);
    	        }
        	}
    
    }

    搜索到设备后可以获取设备的地址,通过此地址获取一个BluetoothDeviced对象,可以看做客户端,通过此对象device.createRfcommSocketToServiceRecord(MY_UUID);同一个UUID可与服务器建立连接获取另一个socket对象,由此服务端与客户端各有一个socket对象,此时 
    他们可以互相交换数据了。 
    创立客户端socket可建立线程 

        //另一个设备去连接本机,相当于客户端
        private class ConnectThread extends Thread{
        	private BluetoothSocket socket;
        	private BluetoothDevice device;
        	public ConnectThread(BluetoothDevice device,boolean secure){
        		this.device = device;
        		BluetoothSocket tmp = null;
        		try {
    				tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
    			} catch (IOException e) {
    				 Log.e("app", "create() failed", e);
    			}
        	}
        	
        	public void run(){
        		mBluetoothAdapter.cancelDiscovery();	//取消设备查找
        		try {
    				socket.connect();
    			} catch (IOException e) {
    				try {
    					socket.close();
    				} catch (IOException e1) {
    					 Log.e("app", "unable to close() "+
    	                            " socket during connection failure", e1);
    				}
    				connetionFailed();	//连接失败
    				return;
    			}
    	        //此时可以新建一个数据交换线程,把此socket传进去
        	}
        	
        	  public void cancel() {
                  try {
                      socket.close();
                  } catch (IOException e) {
                      Log.e("app", "close() of connect  socket failed", e);
                  }
              }
        }
    

    5.建立数据通信线程,进行读取数据 

    //建立连接后,进行数据通信的线程
        private class ConnectedThread extends Thread{
        	private BluetoothSocket socket;
        	private InputStream inStream;
        	private OutputStream outStream;
        	
        	public ConnectedThread(BluetoothSocket socket){
        		
        		this.socket = socket;
        		try {
        			//获得输入输出流
    				inStream = socket.getInputStream();
    				outStream = socket.getOutputStream();
    			} catch (IOException e) {
    				Log.e("app", "temp sockets not created", e);
    			}
        	}
        	
        	public void run(){
        		byte[] buff = new byte[1024];
        		int len=0;
        		//读数据需不断监听,写不需要
        		while(true){
        			try {
    					len = inStream.read(buff);
    					//把读取到的数据发送给UI进行显示
    					Message msg = handler.obtainMessage(BluetoothChat.MESSAGE_READ,
    							len, -1, buff);
    					msg.sendToTarget();
    				} catch (IOException e) {
    					Log.e("app", "disconnected", e);
                        connectionLost();	//失去连接
                        start();	//重新启动服务器
                        break;
    				}
        		}
        	}
        	
        	
        	public void write(byte[] buffer) {
                try {
                    outStream.write(buffer);
    
                    // Share the sent message back to the UI Activity
                    handler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
                            .sendToTarget();
                } catch (IOException e) {
                    Log.e("app", "Exception during write", e);
                }
            }
    
            public void cancel() {
                try {
                    socket.close();
                } catch (IOException e) {
                    Log.e("app", "close() of connect socket failed", e);
                }
            }
        }
    



  • 相关阅读:
    关于响应式布局
    HTML5 学习笔记--------》HTML5概要与新增标签!
    jQuery学习笔记:attr()与prop()的区别
    关于php语言的使用!
    MYSQL的常用命令和增删改查语句和数据类型!
    html5 和css3的小知识!
    应收单
    Spring Boot 启动过程及 自定义 Listener等组件
    23. Spring Boot JPA BaseDao 配置 文章
    22. SpringBoot 集成 Mybatis
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3157378.html
Copyright © 2011-2022 走看看