Android 蓝牙监听,BLE蓝牙和经典蓝牙合成的蓝牙监听案例

1、Android 蓝牙有两个两种,一种是BLE蓝牙,另外一种是经典蓝牙。

BLE蓝牙连接与通讯使用的是 BluetoothKit 框架,BluetoothKit 框架源码地址与说明:

https://gitee.com/www163/Android-BluetoothKit

BluetoothKit 的弊端经典蓝牙连接失败

所以经典蓝牙,自己写了连接和通讯方式。

对于通讯来讲,分为服务端BtServer与客户端BtClient,一般是安装app方为服务端,主要是本身的蓝牙mac是固定,所以作为服务器端,被连接方为客户端。

对BLE的连接与通讯,大家可以看 BluetoothKit 框架详细说明,这里就不累赘。

下面主要是介绍经典蓝牙的连接和通讯。

ps:在蓝牙连接通讯时,前提先要配对才能正常通讯。

最下面有项目源码下载。

 

在经典蓝牙连接时,经常出现“run: read failed, socket might closed or timeout, read ret: -1”

主要原因是UUID的错误。

非手机终端的UUID:00001101-0000-1000-8000-00805f9B34FB

手机终端的UUID:00001105-0000-1000-8000-00805f9b34fb

 

 

1、AndroidManifest.xml 清单设置蓝牙权限

 <uses-feature
        android:name="android.hardware.bluetooth_le"
        android:required="true" />

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

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

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

2、蓝牙通讯BtBase 基类:

package com.inuker.bluetooth;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Environment;
import android.util.Log;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.UUID;

public class BtBase {

    //00001101-0000-1000-8000-00805F9B34FB  -  00001101-0000-1000-8000-00805f9b34fb
    //00001106-0000-1000-8000-00805F9B34FB  -  00001105-0000-1000-8000-00805f9b34fb
    //00001105-0000-1000-8000-00805f9B34FB  -  00001105-0000-1000-8000-00805f9b34fb
    //非手机终端的UUID
    public static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9B34FB");
    //手机终端的UUID
    public static final UUID MOB_UUID = UUID.fromString("00001105-0000-1000-8000-00805f9B34FB");
    private static final String FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/bluetooth/";
    private static final int FLAG_MSG = 0;  //消息标记
    private static final int FLAG_FILE = 1; //文件标记

    private BluetoothSocket mSocket;
    private DataOutputStream mOut;
    private Listener mListener;
    public boolean isRead;
    public boolean isSending;

    BtBase(Listener listener) {
        mListener = listener;
    }

    /**
     * 循环读取对方数据(若没有数据,则阻塞等待)
     */
    void loopRead(BluetoothSocket socket) {
        mSocket = socket;
        try {
            Log.i("test","---------loopRead111--------");
            if (!mSocket.isConnected())
                mSocket.connect();
            Log.i("test","---------loopRead2222--------");
            notifyUI(Listener.CONNECTED, mSocket.getRemoteDevice());
            mOut = new DataOutputStream(mSocket.getOutputStream());
            DataInputStream in = new DataInputStream(mSocket.getInputStream());
            isRead = true;
            while (isRead) { //死循环读取
                Log.i("Test","------------------server in.readInt="+in.readInt());
                switch (in.readInt()) {
                    case FLAG_MSG: //读取短消息
                        String msg = in.readUTF();
                        notifyUI(Listener.MSG, "接收短消息:" + msg);
                        break;
                    case FLAG_FILE: //读取文件
                        Util.mkdirs(FILE_PATH);
                        String fileName = in.readUTF(); //文件名
                        long fileLen = in.readLong(); //文件长度
                        // 读取文件内容
                        long len = 0;
                        int r;
                        byte[] b = new byte[4 * 1024];
                        FileOutputStream out = new FileOutputStream(FILE_PATH + fileName);
                        notifyUI(Listener.MSG, "正在接收文件(" + fileName + "),请稍后...");
                        while ((r = in.read(b)) != -1) {
                            out.write(b, 0, r);
                            len += r;
                            if (len >= fileLen)
                                break;
                        }
                        notifyUI(Listener.MSG, "文件接收完成(存放在:" + FILE_PATH + ")");
                        break;
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
            Log.i("Test","-------------BtBase close-----------------");
            close();
        }
    }

    void loopRead2(BluetoothSocket socket) {
        mSocket = socket;
        try {
            Log.i("test","---------loopRead111--------");
            if (!mSocket.isConnected())
                mSocket.connect();
            Log.i("test","---------loopRead2222--------");
            notifyUI(Listener.CONNECTED, mSocket.getRemoteDevice());


        } catch (Throwable e) {
            e.printStackTrace();
            Log.i("Test","-------------BtBase close-----------------");
            close();
        }
    }

    /**
     * 循环读取对方数据(若没有数据,则阻塞等待)
     */
    void loopReadMsg() {

        try {

//            notifyUI(Listener.CONNECTED, mSocket.getRemoteDevice());
            Log.i("Test","-----------BtBase-loopReadMsg2---------");
//            mOut = new DataOutputStream(mSocket.getOutputStream());
            DataInputStream in = new DataInputStream(mSocket.getInputStream());
            isRead = true;
            Log.i("Test","-----------BtBase-loopReadMsg3---------");
            while (isRead) { //死循环读取
                String msg = in.readUTF();
                Log.i("Test","-----------BtBase-loopReadMsg4---------");
                notifyUI(Listener.MSG, "接收短消息:" + msg);

            }
        } catch (Throwable e) {
            e.printStackTrace();
            close();
        }
    }


    /**
     * 发送短消息
     */
    public void sendMsg2(String msg) {
        Log.i("Test","-----------sendMsg3----2-----");
        if (checkSend()) return;
        isSending = true;
        Log.i("Test","-----------sendMsg3----3-----");
        try {
            Log.i("Test","----------sendMsg2--mSocket="+mSocket);
            OutputStream out = mSocket.getOutputStream();
            Log.i("Test","----------sendMsg2--out="+out);
            mOut = new DataOutputStream(out);
            mOut.writeInt(FLAG_MSG); //消息标记
            mOut.writeUTF(msg);
            mOut.flush();
            notifyUI(Listener.MSG, "发送短消息:" + msg);
        } catch (Throwable e) {
            e.printStackTrace();
//            close();
        }
        isSending = false;
    }

    /**
     * 发送短消息
     */
    public void sendMsg(String msg) {
        Log.i("Test","-----------sendMsg3----2-----");
        if (checkSend()) return;
        isSending = true;
        Log.i("Test","-----------sendMsg3----3-----");
        try {

            mOut = new DataOutputStream(mSocket.getOutputStream());
            mOut.writeInt(FLAG_MSG); //消息标记
            mOut.writeUTF(msg);
            mOut.flush();
            notifyUI(Listener.MSG, "发送短消息:" + msg);
        } catch (Throwable e) {
            e.printStackTrace();
//            close();
        }
        isSending = false;
    }


    /**
     * 发送文件
     */
    public void sendFile(final String filePath) {
        if (checkSend()) return;
        isSending = true;
        Util.EXECUTOR.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    FileInputStream in = new FileInputStream(filePath);
                    File file = new File(filePath);
                    mOut.writeInt(FLAG_FILE); //文件标记
                    mOut.writeUTF(file.getName()); //文件名
                    mOut.writeLong(file.length()); //文件长度
                    int r;
                    byte[] b = new byte[4 * 1024];
                    notifyUI(Listener.MSG, "正在发送文件(" + filePath + "),请稍后...");
                    while ((r = in.read(b)) != -1)
                        mOut.write(b, 0, r);
                    mOut.flush();
                    notifyUI(Listener.MSG, "文件发送完成.");
                } catch (Throwable e) {
                    close();
                }
                isSending = false;
            }
        });
    }

    /**
     * 释放监听引用(例如释放对Activity引用,避免内存泄漏)
     */
    public void unListener() {
        mListener = null;
    }

    /**
     * 关闭Socket连接
     */
    public void close() {
        try {
            Log.i("Test","---------关闭Socket连接-----------");
            isRead = false;
            if(mSocket!=null){
                mSocket.close();
                notifyUI(Listener.DISCONNECTED, null);
            }
//            notifyUI(Listener.DISCONNECTED, null);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    /**
     * 当前设备与指定设备是否连接
     */
    public boolean isConnected(BluetoothDevice dev) {
        boolean connected = (mSocket != null && mSocket.isConnected());
        if (dev == null)
            return connected;
        return connected && mSocket.getRemoteDevice().equals(dev);
    }

    // ============================================通知UI===========================================================
    public boolean checkSend() {
        if (isSending) {
            MyApplication.toast("正在发送其它数据,请稍后再发...", 0);
            return true;
        }
        return false;
    }

    public void notifyUI(final int state, final Object obj) {
        MyApplication.runUi(new Runnable() {
            @Override
            public void run() {
                try {
                    if (mListener != null)
                        mListener.socketNotify(state, obj);
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public interface Listener {
        int DISCONNECTED = 0;
        int CONNECTED = 1;
        int MSG = 2;

        void socketNotify(int state, Object obj);
    }

}

3、服务器端BtServer 代码:

package com.inuker.bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

import java.lang.reflect.Method;
import java.util.UUID;

public class BtServer extends BtBase{

    private static final String TAG = BtServer.class.getSimpleName();
    private BluetoothServerSocket mSSocket;
    private BluetoothSocket socket;

    BtServer(Listener listener) {
        super(listener);
//        listen();
    }

    /**
     * 监听客户端发起的连接
     */
    public void listen() {
        try {
//            Method listenMethod = btClass.getMethod("listenUsingRfcommOn", new Class[]{int.class});

            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
//            mSSocket = adapter.listenUsingRfcommWithServiceRecord(TAG, SPP_UUID); //加密传输,Android强制执行配对,弹窗显示配对码
            mSSocket = adapter.listenUsingInsecureRfcommWithServiceRecord(TAG, MOB_UUID); //明文传输(不安全),无需配对
            // 开启子线程
            Util.EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                         socket = mSSocket.accept(); // 监听连接
//                        mSSocket.close(); // 关闭监听,只连接一个设备
                        loopRead(socket); // 循环读取
                    } catch (Throwable e) {
                        close();
                    }
                }
            });
        } catch (Throwable e) {
            close();
        }
    }

    public void listen(UUID uuid) {
        try {
//            Method listenMethod = btClass.getMethod("listenUsingRfcommOn", new Class[]{int.class});
            Log.i("Test","--------------------uuid="+uuid);
            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
//            mSSocket = adapter.listenUsingRfcommWithServiceRecord(TAG, SPP_UUID); //加密传输,Android强制执行配对,弹窗显示配对码
            mSSocket = adapter.listenUsingInsecureRfcommWithServiceRecord(TAG, uuid); //明文传输(不安全),无需配对
            // 开启子线程
            Util.EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                         socket = mSSocket.accept(); // 监听连接
//                        mSSocket.close(); // 关闭监听,只连接一个设备
                        loopRead(socket); // 循环读取
                    } catch (Throwable e) {
                        close();
                    }
                }
            });
        } catch (Throwable e) {
            close();
        }
    }

    @Override
    public void close() {
        super.close();
        try {
            if(socket!=null){
                socket.close();
            }

            if(mSSocket!=null){
                mSSocket.close();
            }

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

}

4、客户端BtClient 代码:

package com.inuker.bluetooth;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.ParcelUuid;
import android.util.Log;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;

public class BtClient extends BtBase {

    private  BluetoothSocket mSocket;
    boolean flag = false;

    BtClient(Listener listener) {
        super(listener);
    }

    /**
     * 与远端设备建立长连接
     *
     * @param dev 远端设备
     */
    public void connect(BluetoothDevice dev) {
        close();
        try {

//             final BluetoothSocket socket = dev.createRfcommSocketToServiceRecord(SPP_UUID); //加密传输,Android系统强制配对,弹窗显示配对码
            final BluetoothSocket socket = dev.createInsecureRfcommSocketToServiceRecord(SPP_UUID); //明文传输(不安全),无需配对
            Log.i("Test","------------------socket="+socket);
            // 开启子线程
            Util.EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    Log.i("Test","-----------connect-------");
                    loopRead(socket); //循环读取

                }
            });
        } catch (Throwable e) {
            Log.i("Test","-------------BtClient close-----------------");
            close();
        }
    }


    public void connect2(BluetoothDevice dev,UUID uuid) {
        close();
        try {

//            ParcelUuid[] parcel = dev.getUuids();
//            UUID uuid = parcel[0].getUuid();
//             final BluetoothSocket socket = dev.createRfcommSocketToServiceRecord(SPP_UUID); //加密传输,Android系统强制配对,弹窗显示配对码
            final BluetoothSocket socket = dev.createInsecureRfcommSocketToServiceRecord(uuid); //明文传输(不安全),无需配对
            Log.i("Test","------------------socket="+socket);
            // 开启子线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        boolean isCon = socket.isConnected();
                        Log.i("Test","------------------isCon="+isCon);
                        socket.connect();
                        loopRead2(socket); //循环读取


                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }).start();

        } catch (Throwable e) {
            Log.i("Test","-------------BtClient close-----------------");
            close();
        }
    }



    public void connect3(BluetoothDevice dev) {
        close();
        try {

//            ParcelUuid[] parcel = dev.getUuids();
//            UUID uuid = parcel[0].getUuid();
//             final BluetoothSocket socket = dev.createRfcommSocketToServiceRecord(SPP_UUID); //加密传输,Android系统强制配对,弹窗显示配对码
            final BluetoothSocket socket = dev.createInsecureRfcommSocketToServiceRecord(SPP_UUID); //明文传输(不安全),无需配对
            Log.i("Test","------------------socket="+socket);
            // 开启子线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        boolean isCon = socket.isConnected();
                        Log.i("Test","------------------isCon="+isCon);
                        socket.connect();
                        loopRead2(socket); //循环读取


                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }).start();

        } catch (Throwable e) {
            Log.i("Test","-------------BtClient close-----------------");
            close();
        }
    }



    public void loopReadMsg(BluetoothDevice dev) {
//        close();
        try {
            Log.i("Test","-----------loopReadMsg1---------");
//             final BluetoothSocket socket = dev.createRfcommSocketToServiceRecord(SPP_UUID); //加密传输,Android系统强制配对,弹窗显示配对码
//            final BluetoothSocket socket = dev.createInsecureRfcommSocketToServiceRecord(SPP_UUID); //明文传输(不安全),无需配对
            // 开启子线程
            Util.EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    Log.i("Test","-----------loopReadMsg2---------");
                    loopReadMsg(); //循环读取
                }
            });
        } catch (Throwable e) {
            e.printStackTrace();
            Log.i("Test","-----------loopReadMsg3---------ex="+e.getMessage());
            close();
        }
    }


    public void clientSendMsg(String msg) {
        Log.i("Test","-----------sendMsg3----2-----");
        if (checkSend()) return;
        isSending = true;
        Log.i("Test","-----------sendMsg3----3-----");
        try {

            Log.i("Test","----------sendMsg2--mSocket="+mSocket);
            OutputStream out = mSocket.getOutputStream();
            Log.i("Test","----------sendMsg2--out="+out);
            DataOutputStream mOut = new DataOutputStream(out);
            mOut.writeInt(Listener.MSG); //消息标记
            mOut.writeUTF(msg);
            mOut.flush();
            notifyUI(Listener.MSG, "发送短消息:" + msg);
        } catch (Throwable e) {
            e.printStackTrace();
//            close();
        }
        isSending = false;
    }




}

5、Activity 中调用案例:

package com.inuker.bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.inuker.bluetooth.library.connect.listener.BluetoothStateListener;
import com.inuker.bluetooth.library.search.SearchResult;
import com.inuker.bluetooth.library.utils.BluetoothLog;
import com.inuker.bluetooth.view.PullRefreshListView;
import com.inuker.bluetooth.view.PullToRefreshFrameLayout;

import java.io.File;
import java.util.ArrayList;
import java.util.UUID;


public class CommonFragment extends Fragment implements BtBase.Listener, BtReceiver.Listener, BtDevAdapter.Listener{

    private TextView mTips;
    private EditText mInputMsg;
    private EditText mInputFile;
    private TextView mLogs;
    private BtReceiver mBtReceiver;
    private  BtDevAdapter mBtDevAdapter;
    private  BtClient mClient;

    private View view;
    private Context context;

    private Button scanBtn,sendMsgBtn,sendFileBtn,listenTerBtn,listenMobBtn;
    private BluetoothDevice remoteDev;
    private boolean isLoop = true;
    private BtServer mServer;
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    private boolean isListen = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_common, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        view = getView();
        context = view.getContext();
        mBtDevAdapter = new BtDevAdapter(this);
        mClient = new BtClient(this);
        mServer = new BtServer(this);

        listenTerBtn = view.findViewById(R.id.listen_ter);
        listenMobBtn = view.findViewById(R.id.listen_mob);


        RecyclerView rv = view.findViewById(R.id.rv_bt);
        rv.setLayoutManager(new LinearLayoutManager(context));
        rv.setAdapter(mBtDevAdapter);
        mTips = view.findViewById(R.id.tv_tips);
        mInputMsg = view.findViewById(R.id.input_msg);
        mInputFile = view.findViewById(R.id.input_file);
        mLogs = view.findViewById(R.id.tv_log);

        scanBtn = view.findViewById(R.id.button2);
        sendMsgBtn = view.findViewById(R.id.btn_sendMsg);
        sendFileBtn = view.findViewById(R.id.btn_sendFile);
        mBtReceiver = new BtReceiver(context, this);//注册蓝牙广播
        BluetoothAdapter.getDefaultAdapter().startDiscovery();


        scanBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                reScan();
            }
        });

        sendMsgBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String txt = sendMsgBtn.getText().toString();
                Log.i("Test","-----is="+"发送信息".equals(txt));
                if("发送信息".equals(txt)){
//                    handler3.sendEmptyMessage(0);
                    mLogs.setText("");
                        sendMsgBtn.setText("关闭");
//                        sendMsg11();
//                        isLoop = true;
//
                    loopSendMsg();


                }else{
//                        isLoop = false;
//                        sendMsgBtn.setText("发送信息");
                    handler3.sendEmptyMessage(1);
                }

            }
        });

        sendFileBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendFile();
            }
        });

        listenTerBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mServer.close();
                mServer.listen(BtBase.SPP_UUID);
                isListen = true;
            }
        });

        listenMobBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mServer.close();
                mServer.listen(BtBase.MOB_UUID);
                isListen = true;
            }
        });


    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        context.unregisterReceiver(mBtReceiver);
        mClient.unListener();
        mClient.close();

        mServer.unListener();
        mServer.close();
    }


    @Override
    public void socketNotify(int state, Object obj) {
//        if (isDestroyed())
//            return;
        String msg = null;
        switch (state) {
            case BtBase.Listener.CONNECTED:
                BluetoothDevice dev = (BluetoothDevice) obj;
                msg = String.format("与%s(%s)连接成功", dev.getName(), dev.getAddress());
                remoteDev = dev;
                mTips.setText(msg);
                break;
            case BtBase.Listener.DISCONNECTED:
                msg = "连接断开";
                mTips.setText(msg);
                break;
            case BtBase.Listener.MSG:
                msg = String.format("\n%s", obj);
                mLogs.append(msg);

                break;
        }
        MyApplication.toast(msg, 0);
    }

    @Override
    public void onItemClick(BluetoothDevice dev) {

        mServer.close();
        mBluetoothAdapter.cancelDiscovery();

        Log.i("Test","------name="+dev.getName()+","+dev.getAddress());
        if (mClient.isConnected(dev)) {
            remoteDev = dev;
            MyApplication.toast("已经连接了", 0);
            return;
        }

        int state = dev.getBondState();
        if(state != BluetoothDevice.BOND_BONDED){
            boolean isPair = BluetoothUtils.pair(dev.getAddress(),"");
//
            Log.i("Test","-------------------isPair="+isPair);
            MyApplication.toast("请先配对蓝牙", 0);
            reScan();
            return;
        }

        ParcelUuid[] parcel = dev.getUuids();

        boolean isContain = isContainUUID(dev);
        if(isContain){
            mServer.listen(BtBase.SPP_UUID);
            mClient.connect2(dev,BtBase.SPP_UUID);
        }else{
            mServer.listen(BtBase.MOB_UUID);
            mClient.connect2(dev,BtBase.MOB_UUID);

        }

        MyApplication.toast("正在连接...", 0);
        mTips.setText("正在连接...");
    }

    @Override
    public void foundDev(BluetoothDevice dev) {
        mBtDevAdapter.add(dev);
    }


    // 重新扫描
    public void reScan() {
        mBtDevAdapter.reScan();
    }

    //发送信息
    public void sendMsg2() {
        if (mClient.isConnected(null)) {
            String msg = mInputMsg.getText().toString();
            if (TextUtils.isEmpty(msg))
                MyApplication.toast("消息不能空", 0);
            else
                mClient.sendMsg(msg);
        } else
            MyApplication.toast("没有连接", 0);
    }

    public void sendMsgByClient() {

            mClient.sendMsg("发送成功");

    }


    //发送信息
    public void loopReadMsg() {
        if (mClient.isConnected(null)) {
            String msg = "发送成功......";
            mClient.loopReadMsg();

        } else
            MyApplication.toast("没有连接", 0);
    }


    public void sendMsg() {
        Log.i("Test","-----------sendMsg1---------");
        if(remoteDev == null){
            MyApplication.toast("请选连接蓝牙", 0);
            return;
        }
        Log.i("Test","-----------sendMsg2---------");
        if (!mClient.isConnected(remoteDev)) {
            MyApplication.toast("请选连接蓝牙", 0);
            return;
        }
        Log.i("Test","-----------sendMsg3---------");
        mClient.loopReadMsg(remoteDev);
    }


    //发送文件
    public void sendFile() {
        if (mClient.isConnected(null)) {
            String filePath = mInputFile.getText().toString();
            if (TextUtils.isEmpty(filePath) || !new File(filePath).isFile())
                MyApplication.toast("文件无效", 0);
            else
                mClient.sendFile(filePath);
        } else
            MyApplication.toast("没有连接", 0);
    }

    private void loopRead(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (isLoop){
//                    sendMsg3();
                    loopReadMsg();
                }
            }
        }).start();
    }

    private Handler handler = new Handler(){

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            String txt = sendMsgBtn.getText().toString();
            if("发送信息".equals(txt)){
//                    loopRead();
//                loopRead();
                if (mClient.isConnected(null)) {
//                    String msg = "发送成功......";
                    sendMsgBtn.setText("关闭");
                    mClient.loopReadMsg();

                    isLoop = true;

                } else
                    MyApplication.toast("没有连接", 0);

            }else{
                isLoop = false;
                sendMsgBtn.setText("发送信息");
            }

        }
    };


    public void serverSendMsg() {
        if (mServer.isConnected(null)) {
//            String msg = mInputMsg.getText().toString();
//            if (TextUtils.isEmpty(msg))
//                MyApplication.toast("消息不能空", 0);
//            else
                mServer.sendMsg("测试。。。。");
        } else
            MyApplication.toast("没有连接", 0);
    }

    private boolean isContainUUID(BluetoothDevice dev){
        ParcelUuid[] pars = dev.getUuids();
        for(ParcelUuid p : pars){
            UUID u = p.getUuid();
            if(BtBase.SPP_UUID.equals(u)){
                return true;
            }
        }
        return false;
    }


    private Handler handler3 = new Handler(){

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
//                    sendMsgBtn.setText("关闭");
                    sendMsgByClient();
                    isLoop = true;
                    break;
                case 1:
                    isLoop = false;
                    sendMsgBtn.setText("发送信息");
                    break;
            }

        }
    };


    private void loopSendMsg(){
        new Thread(new Runnable() {
            @Override
            public void run() {

                while(isLoop){
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    handler3.sendEmptyMessage(0);

                }
            }
        }).start();
    }
}

6、效果如下:

Android 蓝牙监听,BLE蓝牙和经典蓝牙合成的蓝牙监听案例

 

 Android 蓝牙监听,BLE蓝牙和经典蓝牙合成的蓝牙监听案例

 

 XT300 是打印机终端:

Android 蓝牙监听,BLE蓝牙和经典蓝牙合成的蓝牙监听案例

 

 K5为手机蓝牙连接如下:

Android 蓝牙监听,BLE蓝牙和经典蓝牙合成的蓝牙监听案例

 

7、项目源码:

https://github.com/hongchuanfeng/Android-Bluetooth-Demo

 

Android 蓝牙监听,BLE蓝牙和经典蓝牙合成的蓝牙监听案例

上一篇:为什么hashmap以2的倍数作为桶的长度,同时以2作为扩容倍数


下一篇:Java面试必问之Hashmap底层实现原理(JDK1.8)