Android蓝牙通讯/蓝牙聊天之基本操作的实现

 

     本系列的文章主要介绍Android设备基于蓝牙通讯实现实时聊天,文章系列主要包括两个部分: Android蓝牙的基本操作,Android蓝牙的聊天实现。

 

     本博客资源免费下载:

蓝牙工具:

蓝牙畅聊:

 

    大家可以先直观有效的感受一下该应用下的蓝牙基本操作的实现:

android 用户聊天功能 安卓聊天功能实现_android 用户聊天功能

android 用户聊天功能 安卓聊天功能实现_android_02

 

    从上面的图中可以看出,这边针对蓝牙的基本操作实现主要有: 打开蓝牙,关闭蓝牙, 列出设备已连接过的蓝牙设备,扫描设备周边可连接的蓝牙设备, 设置当前设备可被检测状态。

    那么,下面就这五个基本操作进行讲解:

 

1. 权限设定:

    设备蓝牙的操作是需要一些基本的权限添加的:

 

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

    在这需要说明的是,自android6.0以后,有两个改动需要注意:

 

        1. 对于搜索周边蓝牙的操作的权限需要添加一个获取设备模糊地理位置的权限:

 

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

         2. 针对一些权限需要用户手动去确认添加,比如上面说道的获取设备模糊地理位置的权限:

 

 

private void checkBluetoothPermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            //校验是否已具有模糊定位权限
            if (ContextCompat.checkSelfPermission(MainActivity.this,
                    Manifest.permission.ACCESS_COARSE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                        1);
            } else {
                //具有权限
            }
        } else {
            //系统不高于6.0直接执行
        }
    }

 

 

 

2. 打开蓝牙:

 

public void openBT(View view){

        if (!BA.isEnabled()) {
            Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(turnOn, 1);
            Toast.makeText(getApplicationContext(),"Turned on"
                    ,Toast.LENGTH_LONG).show();
        }
        else{
            Toast.makeText(getApplicationContext(),"Already on",
                    Toast.LENGTH_LONG).show();
        }
    }

 

    其中:

 

private BluetoothAdapter BA;
BA = BluetoothAdapter.getDefaultAdapter();

   

以上便是对设备蓝牙状态的获取与打开操作。

 

3. 关闭蓝牙:

 

public void closeBT(View view){
        BA.disable();
        Toast.makeText(getApplicationContext(),"Turned off" ,
                Toast.LENGTH_LONG).show();
    }

 

 

 

4. 列举设备已连接过的所有设备:

 

 

public void showcennected(View view){
        discover_list.clear();
        connected_list.clear();
        pairedDevices = BA.getBondedDevices();
        for(BluetoothDevice bt : pairedDevices)
            connected_list.add(bt.getName() + "\n" + bt.getAddress());
        Toast.makeText(getApplicationContext(),"Showing Paired Devices",
                Toast.LENGTH_SHORT).show();

        final ArrayAdapter adapter1 = new ArrayAdapter
                (this,android.R.layout.simple_list_item_1, connected_list);
        LV1.setAdapter(adapter1);
        ifconnected = true;
    }

 

    由代码可以看出,首先我们获取的所有已连接过的设备都在添加到connected_list下:

 

connected_list.add(bt.getName() + "\n" + bt.getAddress());

 

然后通过ListView控件全部展示出来:

 

 

private ListView LV1;
...

LV1.setAdapter(adapter1);

 

 

 

5. 扫描周边设备:

 

BA.startDiscovery();

private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("find","进入查找");
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // 已经配对的则跳过
                Log.i("find","查找设备");
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    Log.i("find","添加设备");
                    discover_list.add(device.getName() + "\n" + device.getAddress());
                }
            }
            else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {  //搜索结束
                if (discover_list == null) {
                    Log.i("find","没有查找到设备");
                }
                Log.i("find","显示设备");
                for(int i=0; i < discover_list.size();i++){
                    Log.i("BTlist","111");
                }
//                Log.i("list",discover_list);
                final ArrayAdapter adapter1 = new ArrayAdapter
                        (MasterChat1.this,android.R.layout.simple_list_item_1, discover_list);
                LV1.setAdapter(adapter1);
//            		   }
                pd.dismiss(); //关闭ProgressDialog
            }
        }
    };

    上面的重构的函数便是获取到经过扫面获取到的设备,并且添加到ListView下去显示。

6. 蓝牙连接的实现:

 

 

private void connectBT(){

        if(BA.isDiscovering()){
            BA.cancelDiscovery();
        }
        BluetoothDevice btDev = BA.getRemoteDevice(connectBTaddress);
        connectState = btDev.getBondState();

        switch (connectState){
            //正在配对情况
            case BluetoothDevice.BOND_BONDING:
                Toast.makeText(getApplicationContext(),"Be Bonding",
                        Toast.LENGTH_LONG).show();
                // 未配对情况
            case BluetoothDevice.BOND_NONE:
                // 配对
                try {
                    Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
                    createBondMethod.invoke(btDev);
                    PsText.setText("您当前选中的设备为:"+ ConnectBTname);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            // 已经配对情况
            case BluetoothDevice.BOND_BONDED:
                try {
                    // 连接
                    PsText.setText("您当前选中的设备为:"+ ConnectBTname);
                    final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
                    UUID uuid = UUID.fromString(SPP_UUID);
                    BluetoothSocket socket = btDev.createRfcommSocketToServiceRecord(uuid);
                    socket.connect();
                    PsText.setText("您当前选中的设备为:"+ ConnectBTname);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    可以看出,这边对蓝牙的连接有两种情况,一种是之前有连接过却没有执行过forget操作的设备,还有一种是直接执行连接。

 

 

7. 最后就是设置设备是可被扫描状态的设定:

public void BeVisable(View view){

        Intent getVisible = new Intent(BluetoothAdapter.
                ACTION_REQUEST_DISCOVERABLE);
        startActivityForResult(getVisible, 0);

 

    因为其实大部分设备默认的是蓝牙没法被扫描到的,这里提供的方法是设置设备蓝牙可被其他设备扫描到。但是默认只有120秒。

    这里只是针对蓝牙的一些基本操作所做的指导,如果想更深入的学习,可参见下一篇:
蓝牙通讯/蓝牙聊天的实现(二):蓝牙通讯之实时聊天实现