Andorid Studio加入蓝牙

269 阅读1分钟

一.Manifest加入权限

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

二.蓝牙控制

public class BlueToothController {
    private BluetoothAdapter mAapter;

    public BlueToothController() {
        mAapter = BluetoothAdapter.getDefaultAdapter();
    }

    public BluetoothAdapter getAdapter() {
        return mAapter;
    }
    /**
     * 打开蓝牙
     * @param activity
     * @param requestCode
     */
    public void turnOnBlueTooth(Activity activity, int requestCode) {
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        activity.startActivityForResult(intent, requestCode);
//        mAdapter.enable();
    }

    /**
     * 打开蓝牙可见性
     * @param context
     */
    public void enableVisibly(Context context) {
        Intent discoverableIntent = new
                Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
        context.startActivity(discoverableIntent);
    }

    /**
     * 查找设备
     */
    public void findDevice() {
        assert (mAapter != null);
        mAapter.startDiscovery();
    }

    /**
     * 获取绑定设备
     * @return
     */
    public List<BluetoothDevice> getBondedDeviceList() {
        return new ArrayList<> (mAapter.getBondedDevices());
    }
}

三.客户端

public class ConnectThread extends Thread {
    private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);
    /** 客户端socket*/
    private final BluetoothSocket mmSoket;
    /** 要连接的设备*/
    private final BluetoothDevice mmDevice;
    private BluetoothAdapter mBluetoothAdapter;
    /** 主线程通信的Handler*/
    private final Handler mHandler;
    /** 发送和接收数据的处理类*/
    private ConnectedThread mConnectedThread;



    public ConnectThread(BluetoothDevice device, BluetoothAdapter bluetoothAdapter, Handler mUIhandler) {
        mmDevice = device;
        mBluetoothAdapter = bluetoothAdapter;
        mHandler = mUIhandler;

        BluetoothSocket tmp = null;
        try {
            // 创建客户端Socket
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            e.printStackTrace();
        }

        mmSoket = tmp;
    }

    @Override
    public void run() {
        super.run();
        // 关闭正在发现设备.(如果此时又在查找设备,又在发送数据,会有冲突,影响传输效率)
        mBluetoothAdapter.cancelDiscovery();

        try {
            // 连接服务器
            mmSoket.connect();
        } catch (IOException e) {
            // 连接异常就关闭
            try {
                mmSoket.close();
            } catch (IOException e1) {
            }
            return;
        }

        manageConnectedSocket(mmSoket);
    }

    private void manageConnectedSocket(BluetoothSocket mmSoket) {
        // 通知主线程连接上了服务端socket,更新UI
        mHandler.sendEmptyMessage(Constant.MSG_CONNECTED_TO_SERVER);
        // 新建一个线程进行通讯,不然会发现线程堵塞
        mConnectedThread = new ConnectedThread(mmSoket,mHandler);
        mConnectedThread.start();
    }

    /**
     * 关闭当前客户端
     */
    public void cancel() {
        try {
            mmSoket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送数据
     * @param data
     */
    public void sendData(byte[] data) {
        if(mConnectedThread != null) {
            mConnectedThread.write(data);
        }
    }
}

四.接收端

public class AcceptThread extends Thread {
    private static final String NAME = "BlueToothClass";
    private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);

    private final BluetoothServerSocket mmServerSocket;
    private final BluetoothAdapter mBluetoothAdapter;
    private final Handler mHandler;
    private ConnectedThread mConnectedThread;

    public AcceptThread(BluetoothAdapter adapter, Handler handler) {
        mBluetoothAdapter = adapter;
        mHandler = handler;
        BluetoothServerSocket tmp = null;
        try {
            tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) { }
        mmServerSocket = tmp;
    }

    public void run() {
        BluetoothSocket socket = null;
        while (true) {
            try {
                mHandler.sendEmptyMessage(Constant.MSG_START_LISTENING);
                socket = mmServerSocket.accept();
            } catch (IOException e) {
                mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR, e));
                break;
            }
            if (socket != null) {
                manageConnectedSocket(socket);
                try {
                    mmServerSocket.close();
                    mHandler.sendEmptyMessage(Constant.MSG_FINISH_LISTENING);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }

    private void manageConnectedSocket(BluetoothSocket socket) {
        //只支持同时处理一个连接
        if( mConnectedThread != null) {
            mConnectedThread.cancel();
        }
        mHandler.sendEmptyMessage(Constant.MSG_GOT_A_CLINET);
        mConnectedThread = new ConnectedThread(socket, mHandler);
        mConnectedThread.start();
    }

    public void cancel() {
        try {
            mmServerSocket.close();
            mHandler.sendEmptyMessage(Constant.MSG_FINISH_LISTENING);
        } catch (IOException e) { }
    }

    public void sendData(byte[] data) {
        if( mConnectedThread!=null){
            mConnectedThread.write(data);
        }
    }
}

五.执行

public class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
    private final Handler mHandler;

    public ConnectedThread(BluetoothSocket socket, Handler handler) {
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
        mHandler = handler;
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }


    public void run() {
        byte[] buffer = new byte[1024];
        int bytes;

        //一直读数据
        while (true) {
            try {

                // Read from the InputStream
                bytes = mmInStream.read(buffer);
                // Send the obtained bytes to the UI activity
                if( bytes >0) {
                    Message message = mHandler.obtainMessage(Constant.MSG_GOT_DATA, new String(buffer, 0, bytes, "utf-8"));
                    mHandler.sendMessage(message);
                }
                Log.d("GOTMSG", "message size" + bytes);
            } catch (IOException e) {
                mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR, e));
                break;
            }
        }
    }

    //发送数据
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) { }
    }

    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}

六.设备控制

public class DeviceAdapter extends BaseAdapter {
    private Context mContext;
    private List<BluetoothDevice> mDate;

    public DeviceAdapter(List<BluetoothDevice> Date, Context context){
        mDate = Date;
        mContext = context;

    }
    @Override
    public int getCount() {
        return mDate.size();
    }

    @Override
    public Object getItem(int position) {
        return mDate.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if(convertView==null){
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.deviceadapter_layout,null);
            viewHolder.textView1 = (TextView)convertView.findViewById(R.id.textview1);
            viewHolder.textView2 = (TextView)convertView.findViewById(R.id.textview2);
            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder) convertView.getTag();
        }
        //获取蓝牙设备
        BluetoothDevice bluetoothDevice = (BluetoothDevice) getItem(position);
        viewHolder.textView1.setText("Name="+bluetoothDevice.getName());
        viewHolder.textView2.setText("Address"+bluetoothDevice.getAddress());
        return convertView;
    }
    public class ViewHolder{
        public TextView textView1;
        public  TextView textView2;

    }
    public void refresh(List<BluetoothDevice> data){
        mDate = data;
        notifyDataSetChanged();
    }
}
public class Constant {
    public static final String CONNECTTION_UUID = "00001101-0000-1000-8000-00805F9B34FB";

    /**
     * 开始监听
     */

    public static final int MSG_START_LISTENING = 1;

    /**
     * 结束监听
     */
    public static final int MSG_FINISH_LISTENING = 2;

    /**
     * 有客户端连接
     */
    public static final int MSG_GOT_A_CLINET = 3;

    /**
     * 连接到服务器
     */
    public static final int MSG_CONNECTED_TO_SERVER = 4;

    /**
     * 获取到数据
     */
    public static final int MSG_GOT_DATA = 5;

    /**
     * 出错
     */
    public static final int MSG_ERROR = -1;
}

七.运行截图

Screenshot_2021-12-13-20-47-45-241_com.example.my.jpg

Screenshot_2021-12-13-20-48-13-576_com.example.my.jpg

八.源码

gitee.com/xie-junlong…