蓝牙通信

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();
        }
    }
}

 效果图:

posted @ 2016-06-11 13:31  ts-android  阅读(366)  评论(0编辑  收藏  举报