• Android 蓝牙


    首先需要添加权限

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

    Android中的蓝牙是通过BluetoothAdapter来操作的,

    //先获取BlueToothAdapter的实例
    BluetoothAdapter blueToothAdapter=BluetoothAdapter.getDefaultAdapter();

    打开蓝牙,断开蓝牙

    //判断蓝牙是否打开
            if (!bluetoothAdapter.isEnabled()) {
                //第一种 调用enable()直接打开
                bluetoothAdapter.enable();
                //断开蓝牙
                bluetoothAdapter.disable();
                Toast.makeText(this, "蓝牙功能已开启", Toast.LENGTH_SHORT).show();
    
            }

    设置蓝牙可见性,能被周围设备扫描到

    if (bluetoothAdapter.getScanMode() !=
                    BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                //设置最多可见时间为300秒
                discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                startActivity(discoverableIntent);
            }

    蓝牙的搜索功能

      blueToothAdapter.startDiscovery();

    当搜索到设备后系统会以广播的形式接收,自定义一个广播

    class BluetoothReceiver extends BroadcastReceiver {
    
            @Override
            public void onReceive(Context context, Intent intent) {
    
                if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
                    Log.e(getPackageName(), "找到新设备了");
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                }
            }
        }

    注册广播

    //注册广播
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
    registerReceiver(new BluetoothReceiver(), intentFilter);

    注意 ,如果你的代码将运行在(Build.VERSION.SDK_INT >= 23)的设备上,需要获取设备的定位权限才能进行蓝牙搜索功能,并在代码中动态的申请权限.

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

    动态申请权限

    private void requestPermission() {
            if (Build.VERSION.SDK_INT >= 23) {
                int checkAccessFinePermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
                if (checkAccessFinePermission != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                            REQUEST_PERMISSION_ACCESS_LOCATION);
                    Log.e(getPackageName(), "没有权限,请求权限");
                    return;
                }
                Log.e(getPackageName(), "已有定位权限");
                //这里可以开始搜索操作
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
            switch (requestCode) {
                case REQUEST_PERMISSION_ACCESS_LOCATION: {
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
                        Log.e(getPackageName(), "开启权限permission granted!");
                        //这里可以开始搜索操作
                    } else {
                        Log.e(getPackageName(), "没有定位权限,请先开启!");
                    }
                }
            }
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }

    蓝牙的配对,调用BluetoothDevice的createBondde()方法,如果我们想监听配对的这个过程,那么我们可以为广播接收器再注册一个action。

                            try {
                                Method method = null;
                                method = BluetoothDevice.class.getMethod("createBond");
                                Log.e(getPackageName(), "开始配对");
                                method.invoke(device);
                                flag = true;
                            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                                Log.e(getPackageName(), "配对失败");
                                e.printStackTrace();
                            }

    如果想监听配对过程,可以通过广播的形式,在注册一个action

    //绑定状态发生变化
    intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);

    广播接收器中

    if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    switch (device.getBondState()) {
                        case BluetoothDevice.BOND_NONE:
                            Log.e(getPackageName(), "取消配对");
                            break;
                        case BluetoothDevice.BOND_BONDING:
                            Log.e(getPackageName(), "配对中");
                            break;
                        case BluetoothDevice.BOND_BONDED:
                            Log.e(getPackageName(), "配对成功");
                            break;
                    }
    }

    配对设配发送数据

    发送数据分为客户端和服务端,通过Socket来进行消息交互

    服务端

    new Thread(new Runnable() {
                @Override
                public void run() {
                    InputStream is = null;
                    try {
                        BluetoothServerSocket serverSocket = blueToothAdapter.listenUsingRfcommWithServiceRecord("serverSocket", uuid);
                        mHandler.sendEmptyMessage(startService);
                        BluetoothSocket accept = serverSocket.accept();
                        is = accept.getInputStream();
    
                        byte[] bytes = new byte[1024];
                        int length = is.read(bytes);
    
                        Message msg = new Message();
                        msg.what = getMessageOk;
                        msg.obj = new String(bytes, 0, length);
                        mHandler.sendMessage(msg);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

    客户端

    new Thread(new Runnable() {
                @Override
                public void run() {
                    OutputStream os = null;
                    try {
                        BluetoothSocket socket = strArr.get(i).createRfcommSocketToServiceRecord(uuid);
                        socket.connect();
                        os = socket.getOutputStream();
                        os.write("testMessage".getBytes());
                        os.flush();
                        mHandler.sendEmptyMessage(sendOver);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();

    可以看到无论是服务端还是客户端,都需要新起一个子线程来操作。那么服务端和客户端是怎么识别对方的呢,那么就需要用到UUID了,只有当服务端和客户端的UUID相同的时候才能够建立连接。

    private static final UUID uuid = UUID.fromString(Constants.CONNECTTION_UUID);
    public static final String CONNECTTION_UUID = "fa87c0d0-afac-11de-8a39-0800200c9a66";
  • 相关阅读:
    蓝翔杯子校内赛练习代码
    [蓝桥杯][算法训练VIP]猴子分苹果
    系统设计部分代码
    坐标离散化
    蒟蒻吃药计划-治疗系列 #round 1 机器分配+挖地雷
    蒟蒻吃药计划
    F小蒟蒻教你卡常
    最长不下降子序列
    最大子段和(DP)
    luogu P1216 (USACO1.5) Number Triangles
  • 原文地址:https://www.cnblogs.com/conglingkaishi/p/10082235.html
Copyright © 2020-2023  润新知