Android 蓝牙开发小结与探讨

来源:互联网 发布:少数民族人脸数据库 编辑:程序博客网 时间:2024/06/08 18:23

加入权限

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

一、本机蓝牙

1 得到本机蓝牙适配器

 BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  mBluetoothAdapter.getName();//得到蓝牙名称(设备名称)  mBluetoothAdapter.getAddress();//得到本机蓝牙地址  mBluetoothAdapter.getBondedDevices();//得到已配对的蓝牙集合(Set集合)  mBluetoothAdapter.setName(name);//待验证:设置蓝牙名称,短时间有效,过段时间恢复为设备名称 ?  mBluetoothAdapter.getRemoteDevice(mInfo.getmAddress());//通过地址得到远程蓝牙设备

2 打开蓝牙

 mBluetoothAdapter.isEnabled();//判断蓝牙是否已经打开 mBluetoothAdapter.enable();//打开蓝牙,无提示框 Intent enabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);// startActivity(enabler);//打开蓝牙,有提示框 Intent enablerTime = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); enablerTime.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//设置持续时间(最多300秒),默认120秒 con.startActivity(enablerTime);// 蓝牙可被其它设备发现

二、搜索蓝牙

1 注册蓝牙广播

//注册广播 IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_FOUND);  //filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); registerReceiver(mReceiver, filter); //广播接收者 private BroadcastReceiver mReceiver=new BroadcastReceiver(){    @Override    public void onReceive(Context context, Intent intent) {        String action=intent.getAction();        if (BluetoothDevice.ACTION_FOUND.equals(action)) {            mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);            if(mDevice.getBondState()!=BluetoothDevice.BOND_BONDED){                //设备配对状态,BOND_BONDED为已配对            }           }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {        }    } }   //注销广播 unregisterReceiver(mReceiver);

2 搜索

mBluetoothAdapter.cancelDiscovery();//待验证:有的手机如魅族会在此方法后发送ACTION_DISCOVERY_FINISHED广播,有的手机不会如小米。?     mBluetoothAdapter.startDiscovery(); //一轮搜索时间为12s

三、蓝牙配对

反射技术

Method creMethod = BluetoothDevice.class.getMethod("createBond"); boolean peidui=(Boolean) creMethod.invoke(mBluetoothAdapter.getRemoteDevice(mInfo.getmAddress()));//此方法后会有弹出框确认是否配对,待解决:怎么用代码判断配对成功或失败????

我的解决办法,开个10s的线程去检测蓝牙配对状态:

new Thread(new Runnable() {    @Override    public void run() {        int i=0;        while(i<GameForPartyUtils.PAIR_TIME){            if(mBluetoothAdapter.getRemoteDevice(mInfo.getmAddress()).getBondState()==BluetoothDevice.BOND_BONDED){                mhandler.sendEmptyMessage(0);//配对成功                break;            }            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            i++;            }        if(i==GameForPartyUtils.PAIR_TIME){            mhandler.sendEmptyMessage(1);//配对失败        }                        } }).start();

四、蓝牙连接

蓝牙连接是通过BluetoothSocket建立连接,服务器端(BluetoothServerSocket)和客户端(BluetoothSocket)需指定同样的UUID,才能建立连接,因为建立连接的方法会阻塞线程,所以服务器端和客户端都应启动新线程连接。

1 服务器端:

public class ServerThread extends Thread{    public static final String PROTOCOL_SCHEME_RFCOMM = "btspp";    private BluetoothSocket socket = null;        private final BluetoothServerSocket mserverSocket;    private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();    private Context con;    private Handler mHandler;    private boolean mAcceptFlag=true;    public ServerThread(Context con,Handler h){        this.con=con;        this.mHandler=h;        BluetoothServerSocket tmp = null; //使用一个临时对象代替,因为mserverSocket定义为final,必须定义为final,才能连接多个客户端        try {            tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,                    UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));        } catch (IOException e) {            e.printStackTrace();        }           mserverSocket=tmp;    }    @Override    public void run() {        while(mAcceptFlag){            try {                socket = mserverSocket.accept();//阻塞操作,等待连接                String deviceName=socket.getRemoteDevice().getName();连接成功后,得到连接设备的名称                ReadThread mreadThread = new ReadThread(con,socket,mHandler,deviceName);                mreadThread.start();//接收客户端的数据                Thread.sleep(1000);            } catch (IOException e) {                e.printStackTrace();            }catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

待解决:怎么判断客户端已从服务端断开???
2 客户端

public class ClientThread extends Thread{    private final BluetoothSocket mSocket;    private BluetoothDevice mDevice;    private Context mCon;    private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();    private Handler mHandler;    public ClientThread(Context con,BluetoothDevice device,Handler h){        this.mDevice=device;        this.mCon=con;        this.mHandler=h;        BluetoothSocket tmp= null;        try {            tmp = mDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));        } catch (IOException e) {            e.printStackTrace();        }        mSocket=tmp;    }    public BluetoothSocket getmSocket() {        return mSocket;    }    @Override    public void run() {        mBluetoothAdapter.cancelDiscovery();//有利于提高连接性能        try {            mSocket.connect();//阻塞操作,连接服务器            mHandler.sendEmptyMessage(0);        }catch (IOException e){            e.printStackTrace();            mHandler.sendEmptyMessage(1);            Log.i("server", "连接服务端异常!断开连接重新试一试");        }     }}

五、通信

public class ReadThread extends Thread{    private BluetoothSocket mSocket;    private Handler mHandler;    private String mDeviceName;    private boolean mReadFlag=true;    public ReadThread(){}    public ReadThread(Context con, BluetoothSocket socket,Handler h,String name) {        this.mSocket=socket;        this.mHandler=h;        this.mDeviceName=name;    }    @Override    public void run() {        byte[] buffer = new byte[1024];        int bytes;        InputStream mmInStream = null;        try {            mmInStream = mSocket.getInputStream();        } catch (IOException e1) {            e1.printStackTrace();        }           while (mReadFlag) {            try {                // Read from the InputStream                if( (bytes = mmInStream.read(buffer)) > 0 ){                    byte[] buf_data = new byte[bytes];                    for(int i=0; i<bytes; i++){                        buf_data[i] = buffer[i];                    }                    String s = new String(buf_data);                    Message msg = new Message();                    msg.obj=mDeviceName+": "+s;                    msg.what=GameForPartyUtils.HANDLER_DEVICE_OUTINFO;                    mHandler.sendMessage(msg);                    Log.i("server", "output="+s);                }            } catch (IOException e) {                e.printStackTrace();                break;            }        }        try {            mmInStream.close();        } catch (IOException e1) {            e1.printStackTrace();        }    }    public boolean ismReadFlag() {        return mReadFlag;    }    public void setmReadFlag(boolean mReadFlag) {        this.mReadFlag = mReadFlag;    }}
0 0
原创粉丝点击