Android蓝牙串口通信的用法(一)

2018-06-05  本文已影响0人  未丑

一. 蓝牙权限


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

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

二.配对

代码走起~~ 会顺带加些常用的知识点。简书这个贴代码,格式都没了,将就的看吧,需要的时候自己再检查括号啥的,毕竟时间很紧张。

1.发起请求:

BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();

 if(mAdapter!=null && mAdapter.isEnabled()){

   try {   

          // pair before connect   

          BluetoothDevice Vdevice = mAdapter.getRemoteDevice(BTMAC);

           if (Vdevice.getBondState() == BluetoothDevice.BOND_NONE) {   

                       Method creMethod = BluetoothDevice.class.getMethod("createBond");   

                       Log.e(TAG, "START pair");   

                     creMethod.invoke(Vdevice);   

           } else {

                    Log.e(TAG, "paired!");

           } 

       } catch (Exception e) {   

        // TODO: handle exception   

              e.printStackTrace();   

         }

}else{

         //;

 }

2.如果需要固定码直接配对,可以使用方法:(此段代码在下面完整的广播例子中有)

if(action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) //再次得到的action,会等于PAIRING_REQUEST

        { 

            BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

            Log.e(TAG, action); 

            if(btDevice.getAddress().equals(BTMAC))  //btDevice.getName().contains("HC-05")

            { 

                try { 

                    //1.确认配对 

                    ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true); 

                    //2.终止有序广播 

                    Log.i(TAG, "isOrderedBroadcast:"+isOrderedBroadcast()+",isInitialStickyBroadcast:"+isInitialStickyBroadcast()); 

                    abortBroadcast();//如果没有将广播终止,则会出现一个一闪而过的配对框。 

                    //3.调用setPin方法进行配对... 

                    boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, BTPIN); 

                } catch (Exception e) { 

                    // TODO Auto-generated catch block 

                    e.printStackTrace(); 

                } 

            }else{ 

                Log.e(TAG, "NOT THE BT U WANT"); 

            }

3.以上用到将相关方法封装的一个类,ClsUtils。也是参考网上的“轮子”,感谢热心分享的技术大牛。

public class ClsUtils

{   

    /** 

    * 与设备配对 参考源码:platform/packages/apps/Settings.git 

    * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java 

    */   

    static public boolean createBond(Class btClass, BluetoothDevice btDevice)   

    throws Exception   

    {   

        Method createBondMethod = btClass.getMethod("createBond");   

        Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);   

        return returnValue.booleanValue();   

    }   

    static public boolean removeBond(Class btClass, BluetoothDevice btDevice)   

            throws Exception   

    {   

        Method removeBondMethod = btClass.getMethod("removeBond");   

        Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);   

        return returnValue.booleanValue();   

    }   

    static public boolean setPin(Class btClass, BluetoothDevice btDevice,   

            String str) throws Exception   

    {   

        try   

        {   

            Method removeBondMethod = btClass.getDeclaredMethod("setPin",   

                    new Class[]   

                    {byte[].class});   

            Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,   

                    new Object[]   

                    {str.getBytes()});   

            Log.e("returnValue", "" + returnValue);   

        }   

        catch (SecurityException e)   

        {   

            // throw new RuntimeException(e.getMessage());   

            e.printStackTrace();   

        }   

        catch (IllegalArgumentException e)   

        {   

            // throw new RuntimeException(e.getMessage());   

            e.printStackTrace();   

        }   

        catch (Exception e)   

        {   

            // TODO Auto-generated catch block   

            e.printStackTrace();   

        }   

        return true;   

    }   

    // 取消用户输入   

    static public boolean cancelPairingUserInput(Class btClass,   

            BluetoothDevice device)  throws Exception   

    {   

        Method createBondMethod = btClass.getMethod("cancelPairingUserInput");   

//        cancelBondProcess(btClass, device); 

        Boolean returnValue = (Boolean) createBondMethod.invoke(device);   

        return returnValue.booleanValue();   

    }   

    // 取消配对   

    static public boolean cancelBondProcess(Class btClass,   

            BluetoothDevice device)   

    throws Exception   

    {   

        Method createBondMethod = btClass.getMethod("cancelBondProcess");   

        Boolean returnValue = (Boolean) createBondMethod.invoke(device);   

        return returnValue.booleanValue();   

    } 

    //确认配对 

    static public void setPairingConfirmation(Class btClass,BluetoothDevice device,boolean isConfirm)throws Exception 

    { 

        Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation",boolean.class); 

        setPairingConfirmation.invoke(device,isConfirm); 

    } 

    /** 

    * 

    * @param clsShow 

    */   

    static public void printAllInform(Class clsShow)   

    {   

        try   

        {   

            // 取得所有方法   

            Method[] hideMethod = clsShow.getMethods();   

            int i = 0;   

            for (; i < hideMethod.length; i++)   

            {   

                Log.e("method name", hideMethod[i].getName() + ";and the i is:"   

                        + i);   

            } 

            // 取得所有常量   

            Field[] allFields = clsShow.getFields();   

            for (i = 0; i < allFields.length; i++)   

            {   

                Log.e("Field name", allFields[i].getName());   

            } 

        }   

        catch (SecurityException e)   

        {   

            // throw new RuntimeException(e.getMessage());   

            e.printStackTrace();   

        }   

        catch (IllegalArgumentException e)   

        {   

            // throw new RuntimeException(e.getMessage());   

            e.printStackTrace();   

        }   

        catch (Exception e)   

        {   

            // TODO Auto-generated catch block   

            e.printStackTrace();   

        }   

    }   

4.配对的相关广播,查询配对状态,根据这些时机插入需要处理的事件,

顺便把广播的使用方式贴出来:

filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);

filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);

//filter.addAction(Intent.ACTION_POWER_CONNECTED);

//filter.addAction(Intent.ACTION_POWER_DISCONNECTED);

filter.addAction("android.bluetooth.device.action.PAIRING_REQUEST");

//filter.addAction("android.bluetooth.device.action.FOUND");

filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);

//filter.addAction("android.bluetooth.adapter.action.STATE_CHANGED");

registerReceiver(myReceiver, filter);

private BroadcastReceiver myReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if(action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)){

        Log.d(TAG, "ACTION_USB_DEVICE_ATTACHED");//这个广播是当Android系统作为host插入USB设备的时候发出的

}else if(action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)){

        Log.d(TAG, "ACTION_USB_DEVICE_DETACHED");//拔出USB设备

}else if(action.equals(Intent.ACTION_POWER_CONNECTED)){

        Log.d(TAG, "ACTION_POWER_CONNECTED");

}else if(action.equals(Intent.ACTION_POWER_DISCONNECTED)){

        Log.d(TAG, "ACTION_POWER_DISCONNECTED");

}else if(action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) //再次得到的action,会等于PAIRING_REQUEST 

        { 

            BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

            Log.e(TAG, action); 

            if(btDevice.getAddress().equals(BTMAC))  //btDevice.getName().contains("HC-05")

            { 

                try { 

                    //1.确认配对 

                    ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true); 

                    //2.终止有序广播 

                    Log.i(TAG, "isOrderedBroadcast:"+isOrderedBroadcast()+",isInitialStickyBroadcast:"+isInitialStickyBroadcast()); 

                    abortBroadcast();//如果没有将广播终止,则会出现一个一闪而过的配对框。 

                    //3.调用setPin方法进行配对... 

                    boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, BTPIN); 

                } catch (Exception e) { 

                    // TODO Auto-generated catch block 

                    e.printStackTrace(); 

                } 

            }else{ 

                Log.e(TAG, "NOT THE BT U WANT"); 

            }

        }else if(action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {

            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

            //String name = device.getName();

            //Log.d("aaa", "device name: " + name);

            int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);

            switch (state) {

                case BluetoothDevice.BOND_NONE:

                    Log.d(TAG, "BOND_NONE 删除配对");

                    break;

                case BluetoothDevice.BOND_BONDING:

                    Log.d(TAG, "BOND_BONDING 正在配对");

                    break;

                case BluetoothDevice.BOND_BONDED:

                    Log.d(TAG, "BOND_BONDED 配对成功");

                    break;

            }

        }else if(action.equals("android.bluetooth.adapter.action.STATE_CHANGED")){

        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,

            BluetoothAdapter.ERROR);

    switch (state) {

        case BluetoothAdapter.STATE_OFF:

            //Log.d("aaa", "STATE_OFF 手机蓝牙关闭");

            break;

        case BluetoothAdapter.STATE_TURNING_OFF:

            //Log.d("aaa", "STATE_TURNING_OFF 手机蓝牙正在关闭");

            break;

        case BluetoothAdapter.STATE_ON:

            //Log.d(TAG, "STATE_ON"+s);

         break;

        case BluetoothAdapter.STATE_TURNING_ON:

            //Log.d("aaa", "STATE_TURNING_ON 手机蓝牙正在开启");

            break;

    }

        }else{

Log.d(TAG, action);

}

}

};

5.解配对方法:

try {

      // pair before connect   

          BluetoothDevice Vdevice = mAdapter2.getRemoteDevice(BTMAC);

      if (Vdevice.getBondState() == BluetoothDevice.BOND_BONDED) {   

              Method creMethod = BluetoothDevice.class.getMethod("removeBond");   

          Log.e(TAG, "removeBond");   

          creMethod.invoke(Vdevice);   

      } else {

      Log.e(TAG, "un paired");

      } 

    } catch (Exception e) {   

        // TODO: handle exception   

        e.printStackTrace();   

    }

三.连接

private int connect(String mac) {//这个返回int状态只是因为个人项目需要,可以自行修改

    Log.e("wwww", "start, was connect()? "+isConnection);

    if (!this.isConnection ) {

       mBluetoothDevice=mBluetoothAdapter.getRemoteDevice(mac);

        try {

        // 固定的UUID     串口通信profile

            final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";   

            UUID uuid = UUID.fromString(SPP_UUID);

        mBluetoothSocket = this.mBluetoothDevice.createRfcommSocketToServiceRecord(uuid);

        mBluetoothSocket.connect();

            outputStream = mBluetoothSocket.getOutputStream();

            inputStream = mBluetoothSocket.getInputStream();

            SocketReadThread rt = new SocketReadThread();//这个用来等待接收对方的数据

            rt.setLocalSocket(inputStream, 1);

            Thread thread = new Thread(rt);

               thread.start();

            this.isConnection = true;

        } catch (Exception e) {

            System.out.println("1" + e);

            return -1;

        }

        Log.e("www", "连接成功!");

        return 0;

    } else {

        return 0;

    }

}

接收线程:

public class SocketReadThread implements Runnable

    {

    InputStream input;

    int inum = 1;//预留

        public void setLocalSocket(InputStream is, int num )

        {

        input = is;

        inum = num;

        }

        public void run()

        {

try {

            DataInputStream dis = new DataInputStream(input);

            byte[] bytes = new byte[1024];//1k

                int readnum=0;

            while ((readnum=dis.read(bytes)) != -1) {//阻塞

                 printHexString(TAG,bytes);//前面的文章有讲过这个方法

             }

} catch (IOException e) {

Log.d(TAG, "read duankai");

// TODO Auto-generated catch block

e.printStackTrace();

}

}   

}

四.发送数据

private boolean send(byte[] sendData) {//这个返回也是因为当时项目需要

    if (this.isConnection) {

        try {

            //byte[] data = sendData.getBytes();//"GBK"

            outputStream.write(sendData, 0, sendData.length);

            outputStream.flush();

            Log.e("com send", "send-flush");

        } catch (IOException e) {

        Log.e("com send", "send-", e);

        return false;

        }

        return true;

    } else {

    Log.e("com send", "not connection");

    return false;

    }

}

五.关闭资源

这些不使用的时候,没关闭也是很耗资源的,不能忘记哈

private void closeBtconnect() {

// TODO Auto-generated method stub

    try {

            if(outputStream!=null){

            outputStream.close();

            outputStream=null;

            }

            if(inputStream!=null){

            inputStream.close();

            inputStream=null;

            }

            if(mBluetoothSocket!=null){

            mBluetoothSocket.close();

            mBluetoothSocket=null;

            }

} catch (Exception e) {

// TODO: handle exception

}

        this.isConnection = false;

}

几个主要的功能API使用大概如此。就是这个后台不适合代码编排,简书需要改进才是。

上一篇 下一篇

猜你喜欢

热点阅读