android 蓝牙不弹框

2017-06-24 18:41:53 songmingzhan 阅读数 5797

在一般的android开发中我们一般弹出一些提示信息,例如 已打开蓝牙,wifi之类的提示,我们都是会选择Toast进行弹出。今天我们的客户提出们应用弹出提示太小,用户不注意的情况下,容易被忽略掉,要弹出的宽度填充整个屏幕,首先想到是不是需要自定义Toast,经过自己的一番研究后,发现不需要自定Toast,用现有的Toast就可以轻松实现了。
public void showToast(Context conext,String str){
if(mToast ==null){
Log.i(“showToast”,”showToast…….”);
mToast = Toast.makeText(conext, null, Toast.LENGTH_SHORT);
mToast.setGravity(Gravity.CENTER, 0, 0);
LinearLayout toastView = (LinearLayout)mToast.getView();
WindowManager wm = (WindowManager)conext.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
tv=new TextView(this);
toastView.setBackgroundResource(R.mipmap.bg);
tv.setTextSize(40);
toastView.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(0, 0, 0, 180);
tv.setLayoutParams(params);
mToast.setView(toastView);
toastView.addView(tv);
}
tv.setText(str);
mToast.show();
}
就可以实现下面的效果。
这里写图片描述

2017-01-04 15:56:55 zrf1335348191 阅读数 9082

本文已授权微信公众号  fanfan程序媛 上独家发布

刚好最近项目需求需要到这方面的知识,才发现这个有些欠缺,完善一下,记录下来,方便以后查阅

转载请注明出处

Android蓝牙配对弹出框过程分析


根据远程蓝牙设备(remote devices)的要求,手机端发起与远程蓝牙设备Bluetooth remote Device的配对有两种情况
第一种配对时需要pin码(pin request event)即有配对请求pairing request :所对应的action为 : BluetoothDevice.ACTION_PAIRING_REQUEST。

 根据远程设备所携带的type信息判断是否可以获取到pairingkey
     type值通过BluetoothDevice.EXTRA_PAIRING_VARIANT获取到

int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                    BluetoothDevice.ERROR);


     pairingkey通过BluetoothDevice.EXTRA_PAIRING_KEY获取到

 int pairingKey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY,
                        BluetoothDevice.ERROR);



如果type(int型数值)属于以下3种类型:
  • BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION(数值为2,远程设备为手机/scp860时为该类型),需要用户确认
  • BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY(数值为4),以前的一种配对方式,用在蓝牙2.1配对过程中,需要在本机(local device)输入显示在远程设备上的秘钥                passkey: enter the passkey displayed on remote device
  • BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN(数值为5),蓝牙2.0配对过程中,在本机输入显示在远程设备上的pin码:
     enter the PIN displayed on remote device
则表示远程设备(remote device)本身携带有配对码pairingkey,可以通过BluetoothDevice.EXTRA_PAIRING_KEY获取到配对码

如果type不属于以上3种类型,则表示远程设备不会携带pairingkey配对码,必须要用户自己手动输入:The user will be prompted to enter a pin or an app will enter a pin for user

第二种不需要pin码(create bond)没有配对请求(对应的设备有scp960,蓝牙耳机等),此时远程设备不需要鉴权,可以直接使用(just works)
所对应的action为:BluetoothDevice.ACTION_BOND_STATE_CHANGED

监听action的类为BluetoothPairingRequest.java,配对弹窗为BluetoothPairingDialog.java。字段信息存在于BluetoothDevice.java中


总结来说如果不以action为区分的话,配对分为三种情况

  • 直接配对连接不需要鉴权(just works):这种情况相当于手机发起配对时不需要请求远程设备,即不需要远程设备的认可
  • passkey/pin enter需要一方输入型:这种情况配对时会请求远程设备,然后远程设备会提供一个passk/pin码但不会通过代码的形式通知给用户,用户需要去查看远程设备显示的配对码并输入该pairingkey配对码(属于蓝牙2.0和2.1时的处理)
  • passkey/pin confirmmation无需输入密码只需确认型:这种情况配对时也会请求远程设备,远程会提供一个配对码并且通知给用户,此时代码中可以获取到pairingkey配对码,严格来说是用户需要查看远程设备上显示的配对码与当前手机上显示的配对码是否一致,进行比较(compare)确认后配对,所以属于确认型,对应于上述type的第一种类型
2017-04-17 11:07:53 yi412 阅读数 8694

近期项目中需要连接蓝牙设备,起初只是设置蓝牙列表界面让用户点击然后输入默认PIN码,后来改需求了 = = ,要求自动连接指定设备并不需要用户手动输入PIN码,作为Android 小白的我是拒绝的,但是拒绝有什么用~

首先说一下之后会用到的关于蓝牙方面的东西:

  • 断开蓝牙已配对的设备
  • 搜索附近蓝牙设备
  • 拦截用户交互页面,使用代码输入
  • 由于在最后连接的时候使用的是设备的SDK所以在这里就不介绍了

1.断开已配对设备

最后在项目中发现没有用。这里就先记录一下。

    //得到配对的设备列表,清除已配对的设备
    public void removePairDevice() {
        if (mBluetoothAdapter != null) {
            //mBluetoothAdapter初始化方式 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            //这个就是获取已配对蓝牙列表的方法
            Set<BluetoothDevice> bondedDevices = mBluetoothAdapter.getBondedDevices();
            for (BluetoothDevice device : bondedDevices) {
                //这里可以通过device.getName()  device.getAddress()来判断是否是自己需要断开的设备
                unpairDevice(device);
            }
        }
    }

    //反射来调用BluetoothDevice.removeBond取消设备的配对
    private void unpairDevice(BluetoothDevice device) {
        try {
            Method m = device.getClass().getMethod("removeBond", (Class[]) null);
            m.invoke(device, (Object[]) null);
        } catch (Exception e) {
            Log.e("mate", e.getMessage());
        }
    }

2.搜索附近蓝牙

首先我们需要注册两个广播,第一个为正在搜索时的,第二个为搜索完成的。

        // Register for broadcasts when a device is discovered
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        this.registerReceiver(mFindBlueToothReceiver, filter);
        // Register for broadcasts when discovery has finished
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(mFindBlueToothReceiver, filter);

        //需要时开始搜索
        if (mBluetoothAdapter.isDiscovering()) {
                    mBluetoothAdapter.cancelDiscovery();
         }
        mBluetoothAdapter.startDiscovery();

然后对广播进行处理。这里要说明一下ClsUtils.createBond()这个方法如果连接设备SDK中有配对的方法,建议把这个方法去掉,我这里是去掉的,加上的话偶尔会Toast出无法配对。

 private final BroadcastReceiver mFindBlueToothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                //TODO 开始搜索
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             //   if (device.getBondState() != BluetoothDevice.BOND_BONDED) {//判断蓝牙状态,是否是已配对
                    //TODO 可以在这判断名字 如果搜索结束后没有,再到已配对中寻找
                    String BTName[] = device.getName().split("-");
                    if (BTName[0].equals("xxx")) {
                          //在这连接设备 一般需要蓝牙地址 device.getAddress();
                          try {
                              ClsUtils.createBond(device.getClass(), device);
                          } catch (Exception e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                          }
                    }
              //  }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                //TODO 搜索结束
                Toast.makeText(context, "搜索结束",Toast.LENGTH_SHORT).show();
            }
        }
    };

这里在Activity结束时记得取消注册和取消搜索

unregisterReceiver(mFindBlueToothReceiver);
 if (mBluetoothAdapter != null) {
         mBluetoothAdapter.cancelDiscovery();
 }

3.拦截用户交互页面

通过广播可以监听到输入PIN码的那个页面将要弹出

       <receiver android:name=".BluetoothConnectActivityReceiver" >
            <intent-filter android:priority="1000">
                <action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
            </intent-filter>
        </receiver>

广播中需要做的事情,注意一定要调用abortBroadcast(),不然交互页面还是会出现一下然后消失。就是这个方法找了一天(╯‵□′)╯︵┴─┴。。。

public class BluetoothConnectActivityReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
            BluetoothDevice mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            try {
                //(三星)4.3版本测试手机还是会弹出用户交互页面(闪一下),如果不注释掉下面这句页面不会取消但可以配对成功。(中兴,魅族4(Flyme 6))5.1版本手机两中情况下都正常
                //ClsUtils.setPairingConfirmation(mBluetoothDevice.getClass(), mBluetoothDevice, true);
                abortBroadcast();//如果没有将广播终止,则会出现一个一闪而过的配对框。
                //3.调用setPin方法进行配对...
                boolean ret = ClsUtils.setPin(mBluetoothDevice.getClass(), mBluetoothDevice, "你需要设置的PIN码");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

然后只要在搜索到自己需要的设备后连接进行操作就可以了!!!一定要记得加权限~

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

在Android6.0之后还需要一个模糊定位的权限

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

最后把ClsUtils类奉上,网上有很多的。

/**************** 蓝牙配对函数 ***************/

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.bluetooth.BluetoothDevice;
import android.util.Log;

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();
    }

    /**
     * 与设备解除配对 参考源码:platform/packages/apps/Settings.git
     * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
     */
    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<? extends BluetoothDevice> 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();
        }
    }
}

文章最后提供两篇促使我写这篇文章的背后资源╮( ̄▽ ̄)╭。
Markdown新手指南
Android蓝牙自动配对Demo,亲测好使!!!

第一次写文章,不知道会是什么效果,我的第一次就这么出去了o(〃'▽'〃)o。

2019-11-27 16:51:49 qq_38950819 阅读数 494

目录

 

前言

一、相关概念介绍

二、实战开发

三、项目演示

四、Demo案例源码地址


前言

之前的几篇文章,主要介绍了经典蓝牙开发相关的知识,今天我们就来看看低功耗蓝牙的开发。如果小伙伴们对之前的文章感兴趣兴趣,也可以看看,欢迎提出不足或者建议。

【Android】蓝牙开发——经典蓝牙(附Demo源码)

【Android】蓝牙开发——经典蓝牙配对介绍(通过手机系统蓝牙演示)

【Android】蓝牙开发—— 经典蓝牙配对介绍(Java代码实现演示)附Demo源码

一、相关概念介绍

BLE,全称 Bluetooth Low Energy,即低功耗蓝牙。BLE关键术语和概念,可以查看官网介绍:

https://developer.android.google.cn/guide/topics/connectivity/bluetooth-le

首先,我们需要知道,BLE设备有以下几个方面的东西:

1、一个BLE设备包含多个服务,这些服务通过UUID来区分。

2、一个服务包含1个或多个特征,这些特征也是通过UUID来区分。

3、一个特征包含一个Value和多个描述符,一个描述符包含一个Value,

其次,我们来看一看Android中BLE相关的对象:

1、BluetoothDevice :蓝牙设备

2、BluetoothGatt:建立的连接

3、BluetoothGattCallback:连接回调

3、BluetoothGattService:服务

4、BluetoothGattCharacteristic:服务的特征

5、BluetoothGattDescriptor:特征的描述

了解了这些之后,我们开始进入BLE开发阶段。

二、实战开发

注意:BLE是在Android 4.3(API 18)以后引入的,所以要进行BLE开发,必须在Android 4.3以上版本的机子上。

1、添加相关权限

(1)蓝牙权限

<!-- 应用使用蓝牙的权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!--启动设备发现或操作蓝牙设置的权限-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

(2)位置权限(BLE与经典蓝牙相比,还需要位置权限,如果没有,有的机型是扫描不到设备的,注意Android6.0以后还需要动态申请位置权限)

<!--位置权限-->
<!--Android 10以上系统,需要ACCESS_FINE_LOCATION-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--Android 9以及以下系统,需要ACCESS_FINE_LOCATION-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

2、使用蓝牙之前,首先要检查当前手机是否支持BLE蓝牙。如果支持BLE蓝牙,检查手机蓝牙是否已开启。如果没有开启,则需要先打开蓝牙。打开手机蓝牙,有两种方式,一种是直接enable()打开,另外一种是提示用户打开,推荐第二种方式。

 /**
     * 检测手机是否支持4.0蓝牙
     * @param context  上下文
     * @return true--支持4.0  false--不支持4.0
     */
    private boolean checkBle(Context context){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {  //API 18 Android 4.3
            bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
            if(bluetoothManager == null){
                return false;
            }
            bluetooth4Adapter = bluetoothManager.getAdapter();  //BLUETOOTH权限
            if(bluetooth4Adapter == null){
                return false;
            }else{
                Log.d(TAG,"该设备支持蓝牙4.0");
                return true;
            }
        }else{
            return false;
        }
    }
/**
     * 获取蓝牙状态
     */
    public boolean isEnable(){
        if(bluetooth4Adapter == null){
            return false;
        }
        return bluetooth4Adapter.isEnabled();
    }

    /**
     * 打开蓝牙
     * @param isFast  true 直接打开蓝牙  false 提示用户打开
     */
    public void openBluetooth(Context context,boolean isFast){
        if(!isEnable()){
            if(isFast){
                Log.d(TAG,"直接打开手机蓝牙");
                bluetooth4Adapter.enable();  //BLUETOOTH_ADMIN权限
            }else{
                Log.d(TAG,"提示用户去打开手机蓝牙");
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                context.startActivity(enableBtIntent);
            }
        }else{
            Log.d(TAG,"手机蓝牙状态已开");
        }
    }

3、系统蓝牙已打开,则可以开启扫描设备。需要注意的是,扫描设备是耗时的操作,一旦扫描结束,就要及时停止扫描。

////////////////////////////////////  扫描设备  ///////////////////////////////////////////////
    //扫描设备回调
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice bluetoothDevice, int rssi, byte[] bytes) {
            //在onLeScan()回调中尽量做少的操作,可以将扫描到的设备扔到另一个线程中处理
            if(bluetoothDevice == null)
                return;

            if(bluetoothDevice.getName() != null){
                Log.d(TAG,bluetoothDevice.getName() + "-->" + bluetoothDevice.getAddress());
            }else{
                Log.d(TAG,"null" + "-->" + bluetoothDevice.getAddress());
            }
            BLEDevice bleDevice = new BLEDevice(bluetoothDevice,rssi);
            if(onDeviceSearchListener != null){
                onDeviceSearchListener.onDeviceFound(bleDevice);  //扫描到设备回调
            }
        }
    };

    /**
     * 设置时间段 扫描设备
     * @param onDeviceSearchListener  设备扫描监听
     * @param scanTime  扫描时间
     */
    public void startDiscoveryDevice(OnDeviceSearchListener onDeviceSearchListener,long scanTime){
        if(bluetooth4Adapter == null){
            Log.e(TAG,"startDiscoveryDevice-->bluetooth4Adapter == null");
            return;
        }

        this.onDeviceSearchListener = onDeviceSearchListener;
        if(onDeviceSearchListener != null){
            onDeviceSearchListener.onDiscoveryStart();  //开始扫描回调
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            Log.d(TAG,"开始扫描设备");
            bluetooth4Adapter.startLeScan(leScanCallback);

        }else{
            return;
        }

        //设定最长扫描时间
        mHandler.postDelayed(stopScanRunnable,scanTime);
    }

    private Runnable stopScanRunnable = new Runnable() {
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void run() {
            if(onDeviceSearchListener != null){
                onDeviceSearchListener.onDiscoveryOutTime();  //扫描超时回调
            }
            //scanTime之后还没有扫描到设备,就停止扫描。
            stopDiscoveryDevice();
        }
    };

4、扫描到目标设备之后,开始建立连接,这里注意,连接之前一定要关闭扫描,否则会影响连接。BLE与经典蓝牙不同,经典蓝牙一旦建立连接,就可以进行数据通讯,而BLE建立连接之后,还需要发现系统服务,获取特定服务及读写特征。

(1)建立连接 & 发现系统服务

/////////////////////////////////////  执行连接  //////////////////////////////////////////////
    //连接/通讯结果回调
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        @Override
        public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
            super.onPhyUpdate(gatt, txPhy, rxPhy, status);
        }

        @Override
        public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
            super.onPhyRead(gatt, txPhy, rxPhy, status);
        }

        //连接状态回调-连接成功/断开连接
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            Log.d(TAG,"status:" + status);
            Log.d(TAG,"newState:" + newState);

            switch(status){
                case BluetoothGatt.GATT_SUCCESS:
                    Log.w(TAG,"BluetoothGatt.GATT_SUCCESS");
                    break;
                case BluetoothGatt.GATT_FAILURE:
                    Log.w(TAG,"BluetoothGatt.GATT_FAILURE");
                    break;
                case BluetoothGatt.GATT_CONNECTION_CONGESTED:
                    Log.w(TAG,"BluetoothGatt.GATT_CONNECTION_CONGESTED");
                    break;
                case BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION:
                    Log.w(TAG,"BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION");
                    break;
                case BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION:
                    Log.w(TAG,"BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION");
                    break;
                case BluetoothGatt.GATT_INVALID_OFFSET:
                    Log.w(TAG,"BluetoothGatt.GATT_INVALID_OFFSET");
                    break;
                case BluetoothGatt.GATT_READ_NOT_PERMITTED:
                    Log.w(TAG,"BluetoothGatt.GATT_READ_NOT_PERMITTED");
                    break;
                case BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED:
                    Log.w(TAG,"BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED");
                    break;
            }

            BluetoothDevice bluetoothDevice = gatt.getDevice();
            Log.d(TAG,"连接的设备:" + bluetoothDevice.getName() + "  " + bluetoothDevice.getAddress());

            isConnectIng = false;
            //移除连接超时
            mHandler.removeCallbacks(connectOutTimeRunnable);

            if(newState == BluetoothGatt.STATE_CONNECTED){
                Log.w(TAG,"连接成功");
                //连接成功去发现服务
                gatt.discoverServices();
                //设置发现服务超时时间
                mHandler.postDelayed(serviceDiscoverOutTimeRunnable,MAX_CONNECT_TIME);

                if(onBleConnectListener != null){
                    onBleConnectListener.onConnectSuccess(gatt,bluetoothDevice,status);   //连接成功回调
                }
            }else if(newState == BluetoothGatt.STATE_DISCONNECTED) {
                //清空系统缓存
                ClsUtils.refreshDeviceCache(gatt);
                Log.e(TAG, "断开连接status:" + status);
                gatt.close();  //断开连接释放连接

                if(status == 133){
                    //无法连接
                    if(onBleConnectListener != null){
                        onBleConnectListener.onConnectFailure(gatt,bluetoothDevice,"连接异常!",status);  //133连接异常 异常断开
                        Log.e(TAG,"连接失败status:" + status + "  " + bluetoothDevice.getAddress());
                    }
                }else if(status == 62){
                    //成功连接没有发现服务断开
                    if(onBleConnectListener != null){
                        onBleConnectListener.onConnectFailure(gatt,bluetoothDevice,"连接成功服务未发现断开!",status); //62没有发现服务 异常断开
                        Log.e(TAG,"连接成功服务未发现断开status:" + status);
                    }

                }else if(status == 0){
                    if(onBleConnectListener != null){
                        onBleConnectListener.onDisConnectSuccess(gatt,bluetoothDevice,status); //0正常断开 回调
                    }
                }else if(status == 8){
                    //因为距离远或者电池无法供电断开连接
                    // 已经成功发现服务
                    if(onBleConnectListener != null){
                        onBleConnectListener.onDisConnectSuccess(gatt,bluetoothDevice,status); //8断电断开  回调
                    }
                }else if(status == 34){
                    if(onBleConnectListener != null){
                        onBleConnectListener.onDisConnectSuccess(gatt,bluetoothDevice,status); //34断开
                    }
                }else {
                    //其它断开连接
                    if(onBleConnectListener != null){
                        onBleConnectListener.onDisConnectSuccess(gatt,bluetoothDevice,status); //其它断开
                    }
                }
            }else if(newState == BluetoothGatt.STATE_CONNECTING){
                Log.d(TAG,"正在连接...");
                if(onBleConnectListener != null){
                    onBleConnectListener.onConnecting(gatt,bluetoothDevice);  //正在连接回调
                }
            }else if(newState == BluetoothGatt.STATE_DISCONNECTING){
                Log.d(TAG,"正在断开...");
                if(onBleConnectListener != null){
                    onBleConnectListener.onDisConnecting(gatt,bluetoothDevice); //正在断开回调
                }
            }
        }

        //发现服务
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            //移除发现服务超时
            mHandler.removeCallbacks(serviceDiscoverOutTimeRunnable);
            Log.d(TAG,"移除发现服务超时");

            Log.d(TAG,"发现服务");

            //获取特定服务及特征
            if(setupService(gatt,serviceUUID,readUUID,writeUUID)){
                if(onBleConnectListener != null){
                    onBleConnectListener.onServiceDiscoverySucceed(gatt,gatt.getDevice(),status);  //成功发现服务回调
                }
            }else{
                if(onBleConnectListener != null){
                    onBleConnectListener.onServiceDiscoveryFailed(gatt,gatt.getDevice(),"获取服务特征异常");  //发现服务失败回调
                }
            }
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            Log.d(TAG,"读status: " + status);
        }

        //向蓝牙设备写入数据结果回调
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);

            if(characteristic.getValue() == null){
                Log.e(TAG,"characteristic.getValue() == null");
                return;
            }
            //将收到的字节数组转换成十六进制字符串
            String msg = TypeConversion.bytes2HexString(characteristic.getValue(),characteristic.getValue().length);
            if(status == BluetoothGatt.GATT_SUCCESS){
                //写入成功
                Log.w(TAG,"写入成功:" + msg);
                if(onBleConnectListener != null){
                    onBleConnectListener.onWriteSuccess(gatt,gatt.getDevice(),characteristic.getValue());  //写入成功回调
                }

            }else if(status == BluetoothGatt.GATT_FAILURE){
                //写入失败
                Log.e(TAG,"写入失败:" + msg);
                if(onBleConnectListener != null){
                    onBleConnectListener.onWriteFailure(gatt,gatt.getDevice(),characteristic.getValue(),"写入失败");  //写入失败回调
                }
            }else if(status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED){
                //没有权限
                Log.e(TAG,"没有权限!");
            }
        }

        //读取蓝牙设备发出来的数据回调
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);

            //接收数据
            byte[] bytes = characteristic.getValue();
            Log.w("TAG","收到数据str:" + TypeConversion.bytes2HexString(bytes,bytes.length));
            if(onBleConnectListener != null){
                onBleConnectListener.onReceiveMessage(gatt,gatt.getDevice(),characteristic,characteristic.getValue());  //接收数据回调
            }
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorRead(gatt, descriptor, status);
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);
        }

        @Override
        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
            super.onReliableWriteCompleted(gatt, status);
            Log.d(TAG,"onReliableWriteCompleted");
        }
        
        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            super.onReadRemoteRssi(gatt, rssi, status);
            if(status == BluetoothGatt.GATT_SUCCESS){
                Log.w(TAG,"读取RSSI值成功,RSSI值:" + rssi + ",status" + status);
                if(onBleConnectListener != null){
                    onBleConnectListener.onReadRssi(gatt,rssi,status);  //成功读取连接的信号强度回调
                }
            }else if(status == BluetoothGatt.GATT_FAILURE){
                Log.w(TAG,"读取RSSI值失败,status:" + status);
            }
        }

        //修改MTU值结果回调
        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            super.onMtuChanged(gatt, mtu, status);
            ///设置mtu值,即bluetoothGatt.requestMtu()时触发,提示该操作是否成功
            if(status == BluetoothGatt.GATT_SUCCESS){  //设置MTU成功  
                //MTU默认取的是23,当收到 onMtuChanged 后,会根据传递的值修改MTU,注意由于传输用掉3字节,因此传递的值需要减3。
                //mtu - 3
                Log.w(TAG,"设置MTU成功,新的MTU值:" + (mtu-3) + ",status" + status);
                if(onBleConnectListener != null){
                    onBleConnectListener.onMTUSetSuccess("设置后新的MTU值 = " + (mtu-3) + "   status = " + status,mtu - 3);  //MTU设置成功
                }

            }else if(status == BluetoothGatt.GATT_FAILURE){  //设置MTU失败  
                Log.e(TAG,"设置MTU值失败:" + (mtu-3) + ",status" + status);
                if(onBleConnectListener != null){
                    onBleConnectListener.onMTUSetFailure("设置MTU值失败:" + (mtu-3) + "   status:" + status);  //MTU设置失败
                }
            }

        }
    };

    /**
     * 通过蓝牙设备连接
     * @param context  上下文
     * @param bluetoothDevice  蓝牙设备
     * @param outTime          连接超时时间
     * @param onBleConnectListener  蓝牙连接监听者
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public BluetoothGatt connectBleDevice(Context context, BluetoothDevice bluetoothDevice, long outTime,OnBleConnectListener onBleConnectListener){
        if(bluetoothDevice == null){
            Log.e(TAG,"addBLEConnectDevice-->bluetoothDevice == null");
            return null;
        }

        this.onBleConnectListener = onBleConnectListener;

        this.curConnDevice = bluetoothDevice;
        Log.d(TAG,"开始准备连接:" + bluetoothDevice.getName() + "-->" + bluetoothDevice.getAddress());
        //出现 BluetoothGatt.android.os.DeadObjectException 蓝牙没有打开
        try{
            mBluetoothGatt = bluetoothDevice.connectGatt(context,false,bluetoothGattCallback);
            mBluetoothGatt.connect();

        }catch(Exception e){
            Log.e(TAG,"e:" + e.getMessage());
        }

        mHandler.postDelayed(connectOutTimeRunnable,outTime);

        return mBluetoothGatt;
    }

    //连接超时
    private Runnable connectOutTimeRunnable = new Runnable() {
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void run() {
            if(mBluetoothGatt == null){
                Log.e(TAG,"connectOuttimeRunnable-->mBluetoothGatt == null");
                return;
            }

            isConnectIng = false;
            mBluetoothGatt.disconnect();

            //连接超时当作连接失败回调
            if(onBleConnectListener != null){
                onBleConnectListener.onConnectFailure(mBluetoothGatt,curConnDevice,"连接超时!",-1);  //连接失败回调
            }
        }
    };

    //发现服务超时
    private Runnable serviceDiscoverOutTimeRunnable = new Runnable() {
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void run() {
            if(mBluetoothGatt == null){
                Log.e(TAG,"connectOuttimeRunnable-->mBluetoothGatt == null");
                return;
            }

            isConnectIng = false;
            mBluetoothGatt.disconnect();

            //发现服务超时当作连接失败回调
            if(onBleConnectListener != null){
                onBleConnectListener.onConnectFailure(mBluetoothGatt,curConnDevice,"发现服务超时!",-1);  //连接失败回调
            }
        }
    };

(2)发现系统服务之后,还需要获取特定服务及读写特征才能进行数据通讯。一般,读特征是用来读取蓝牙设备发出来的数据,写特征是向蓝牙设备写入数据,其中,读特征一定要设置打开通知,否则接收不到消息。

/**
     * 获取特定服务及特征
     * 1个serviceUUID -- 1个readUUID -- 1个writeUUID
     * @param bluetoothGatt
     * @param serviceUUID
     * @param readUUID
     * @param writeUUID
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    private boolean setupService(BluetoothGatt bluetoothGatt,String serviceUUID,String readUUID,String writeUUID) {
        if (bluetoothGatt == null) {
            Log.e(TAG, "setupService()-->bluetoothGatt == null");
            return false;
        }

        if(serviceUUID == null){
            Log.e(TAG, "setupService()-->serviceUUID == null");
            return false;
        }

        for (BluetoothGattService service : bluetoothGatt.getServices()) {
//            Log.d(TAG, "service = " + service.getUuid().toString());
            if (service.getUuid().toString().equals(serviceUUID)) {
                bluetoothGattService = service;
            }
        }
        //通过上面方法获取bluetoothGattService
//        bluetoothGattService = bleManager.getBluetoothGattService(bluetoothGatt,ConsData.MY_BLUETOOTH4_UUID);
        if (bluetoothGattService == null) {
            Log.e(TAG, "setupService()-->bluetoothGattService == null");
            return false;
        }
        Log.d(TAG, "setupService()-->bluetoothGattService = " + bluetoothGattService.toString());

        if(readUUID == null || writeUUID == null){
            Log.e(TAG, "setupService()-->readUUID == null || writeUUID == null");
            return false;
        }

        for (BluetoothGattCharacteristic characteristic : bluetoothGattService.getCharacteristics()) {
            if (characteristic.getUuid().toString().equals(readUUID)) {  //读特征
                readCharacteristic = characteristic;
            } else if (characteristic.getUuid().toString().equals(writeUUID)) {  //写特征
                writeCharacteristic = characteristic;
            }
        }
        if (readCharacteristic == null) {
            Log.e(TAG, "setupService()-->readCharacteristic == null");
            return false;
        }
        if (writeCharacteristic == null) {
            Log.e(TAG, "setupService()-->writeCharacteristic == null");
            return false;
        }
        //打开读通知
        enableNotification(true, bluetoothGatt, readCharacteristic);

        //重点中重点,需要重新设置
        List<BluetoothGattDescriptor> descriptors = writeCharacteristic.getDescriptors();
        for (BluetoothGattDescriptor descriptor : descriptors) {
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            bluetoothGatt.writeDescriptor(descriptor);
        }

        //延迟2s,保证所有通知都能及时打开
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {

            }
        }, 2000);

        return true;

    }

    /////////////////////////////////////////  打开通知  //////////////////////////////////////////

    /**
     * 设置读特征接收通知
     * @param enable  为true打开通知
     * @param gatt    连接
     * @param characteristic  特征
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void enableNotification(boolean enable, BluetoothGatt gatt, BluetoothGattCharacteristic characteristic){
        if(gatt == null){
            Log.e(TAG,"enableNotification-->gatt == null");
            return;
        }
        if(characteristic == null){
            Log.e(TAG,"enableNotification-->characteristic == null");
            return;
        }
        //这一步必须要有,否则接收不到通知
        gatt.setCharacteristicNotification(characteristic,enable);
    }

5、数据通讯

(1)发送数据

mBluetoothGatt.writeCharacteristic()方法的返回值,并不能真正的表示数据是否发送成功,而是通过BluetoothGattCallback回调方法onCharacteristicWrite()来判断数据是否已成功写入底层。

 //向蓝牙设备写入数据结果回调
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);

            if(characteristic.getValue() == null){
                Log.e(TAG,"characteristic.getValue() == null");
                return;
            }
            //将收到的字节数组转换成十六进制字符串
            String msg = TypeConversion.bytes2HexString(characteristic.getValue(),characteristic.getValue().length);
            if(status == BluetoothGatt.GATT_SUCCESS){
                //写入成功
                Log.w(TAG,"写入成功:" + msg);
                if(onBleConnectListener != null){
                    onBleConnectListener.onWriteSuccess(gatt,gatt.getDevice(),characteristic.getValue());  //写入成功回调
                }

            }else if(status == BluetoothGatt.GATT_FAILURE){
                //写入失败
                Log.e(TAG,"写入失败:" + msg);
                if(onBleConnectListener != null){
                    onBleConnectListener.onWriteFailure(gatt,gatt.getDevice(),characteristic.getValue(),"写入失败");  //写入失败回调
                }
            }else if(status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED){
                //没有权限
                Log.e(TAG,"没有权限!");
            }
        }

 

///////////////////////////////////  发送数据  ///////////////////////////////////////////////

    /**
     * 发送消息  byte[]数组
     * @param msg  消息
     * @return  true  false
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public boolean sendMessage( byte[] msg){
        if(writeCharacteristic == null){
            Log.e(TAG,"sendMessage(byte[])-->writeGattCharacteristic == null");
            return false;
        }

        if(mBluetoothGatt == null){
            Log.e(TAG,"sendMessage(byte[])-->mBluetoothGatt == null");
            return false;
        }

        boolean  b = writeCharacteristic.setValue(msg);
        Log.d(TAG, "写特征设置值结果:" + b);
        return mBluetoothGatt.writeCharacteristic(writeCharacteristic);
    }

(2)接收数据

接收的数据是直接通过BluetoothGattCallback回调方法onCharacteristicChanged()来获取的。

//读取蓝牙设备发出来的数据回调
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);

            //接收数据
            byte[] bytes = characteristic.getValue();
            Log.w("TAG","收到数据str:" + TypeConversion.bytes2HexString(bytes,bytes.length));
            if(onBleConnectListener != null){
                onBleConnectListener.onReceiveMessage(gatt,gatt.getDevice(),characteristic,characteristic.getValue());  //接收数据回调
            }
        }

6、断开连接

BLE通讯结束之后,需要及时断开连接,并且在断开连接的回调处释放资源。否则会导致下一次执行连接操作时,导致133异常。所以,一般连接出现133异常,都是因为断开后及时释放资源。

断开连接的结果是在BluetoothGattCallback回调方法onConnectionStateChange()来获取的。(可查看上面建立连接处的代码)

 ///////////////////////////////////  断开连接  ///////////////////////////////////////////////
    /**
     * 断开连接
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void disConnectDevice(){
        if(mBluetoothGatt == null){
            Log.e(TAG,"disConnectDevice-->bluetoothGatt == null");
            return;
        }

        //系统断开
        mBluetoothGatt.disconnect();
    }

三、项目演示

(1)扫描目标设备(BLEyqy),点击“连接”按钮, 会在“搜索”按钮下方显示连接结果 。

BLE扫描连接

(2)手机给目标设备发送数据成功之后,蓝牙设备把接收到的数据再回发送给手机。

BLE发送接收数据

(3)断开连接。点击“断开”按钮, 会在“搜索”按钮下方显示断开结果 。

BLE断开连接

四、Demo案例源码地址

码云:https://gitee.com/lilium_foliage/Android-Bluetooth-Low-Energy

CSDN:https://download.csdn.net/download/qq_38950819/12001139

 

 

2014-06-17 15:43:42 proud2005 阅读数 1889

http://my.oschina.net/billowworld/blog/62975

android版的蓝牙 与血压计通讯的项目,遇到最大的难题就是自动配对.

上网查资料说是用反射createBond()和setPin(),但测试时进行配对还是会出现提示,但配对是成功了

我就开始查找怎么关闭这个蓝牙配对提示框,后面还是伟大的android源码帮助了我。

在源码 BluetoothDevice 类中还有两个隐藏方法

cancelBondProcess()和cancelPairingUserInput()

这两个方法一个是取消配对进程一个是取消用户输入

下面是自动配对的代码

Mainfest,xml注册

 

1 <receiver android:name=".BluetoothConnectActivityReceiver" >
2     <intent-filter>
3         <action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
4     </intent-filter>
5 </receiver>

自己在收到广播时处理并将预先输入的密码设置进去

 

01 public class BluetoothConnectActivityReceiver extends BroadcastReceiver
02 {
03  
04     String strPsw = "0";
05  
06     @Override
07     public void onReceive(Context context, Intent intent)
08     {
09         // TODO Auto-generated method stub
10         if (intent.getAction().equals(
11                 "android.bluetooth.device.action.PAIRING_REQUEST"))
12         {
13             BluetoothDevice btDevice = intent
14                     .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
15  
16             // byte[] pinBytes = BluetoothDevice.convertPinToBytes("1234");
17             // device.setPin(pinBytes);
18             Log.i("tag11111""ddd");
19             try
20             {
21                 ClsUtils.setPin(btDevice.getClass(), btDevice, strPsw); // 手机和蓝牙采集器配对
22                 ClsUtils.createBond(btDevice.getClass(), btDevice);
23                 ClsUtils.cancelPairingUserInput(btDevice.getClass(), btDevice);
24             }
25             catch (Exception e)
26             {
27                 // TODO Auto-generated catch block
28                 e.printStackTrace();
29             }
30         }
31  
32  
33     }
34 }

 

001 <b>/************************************ 蓝牙配对函数 * **************/
002 import java.lang.reflect.Field;
003 import java.lang.reflect.Method;
004  
005 import android.bluetooth.BluetoothDevice;
006 import android.util.Log;
007 public class ClsUtils
008 {
009  
010     /**
011      * 与设备配对 参考源码:platform/packages/apps/Settings.git
012      * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
013      */
014     static public boolean createBond(Class btClass, BluetoothDevice btDevice)
015             throws Exception
016     {
017         Method createBondMethod = btClass.getMethod("createBond");
018         Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
019         return returnValue.booleanValue();
020     }
021  
022     /**
023      * 与设备解除配对 参考源码:platform/packages/apps/Settings.git
024      * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
025      */
026     static public boolean removeBond(Class btClass, BluetoothDevice btDevice)
027             throws Exception
028     {
029         Method removeBondMethod = btClass.getMethod("removeBond");
030         Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
031         return returnValue.booleanValue();
032     }
033  
034     static public boolean setPin(Class btClass, BluetoothDevice btDevice,
035             String str) throws Exception
036     {
037         try
038         {
039             Method removeBondMethod = btClass.getDeclaredMethod("setPin",
040                     new Class[]
041                     {byte[].class});
042             Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,
043                     new Object[]
044                     {str.getBytes()});
045             Log.e("returnValue""" + returnValue);
046         }
047         catch (SecurityException e)
048         {
049             // throw new RuntimeException(e.getMessage());
050             e.printStackTrace();
051         }
052         catch (IllegalArgumentException e)
053         {
054             // throw new RuntimeException(e.getMessage());
055             e.printStackTrace();
056         }
057         catch (Exception e)
058         {
059             // TODO Auto-generated catch block
060             e.printStackTrace();
061         }
062         return true;
063  
064     }
065  
066     // 取消用户输入
067     static public boolean cancelPairingUserInput(Class btClass,
068             BluetoothDevice device)
069  
070     throws Exception
071     {
072         Method createBondMethod = btClass.getMethod("cancelPairingUserInput");
073         // cancelBondProcess()
074         Boolean returnValue = (Boolean) createBondMethod.invoke(device);
075         return returnValue.booleanValue();
076     }
077  
078     // 取消配对
079     static public boolean cancelBondProcess(Class btClass,
080             BluetoothDevice device)
081  
082     throws Exception
083     {
084         Method createBondMethod = btClass.getMethod("cancelBondProcess");
085         Boolean returnValue = (Boolean) createBondMethod.invoke(device);
086         return returnValue.booleanValue();
087     }
088  
089     /**
090      *
091      * @param clsShow
092      */
093     static public void printAllInform(Class clsShow)
094     {
095         try
096         {
097             // 取得所有方法
098             Method[] hideMethod = clsShow.getMethods();
099             int i = 0;
100             for (; i < hideMethod.length; i++)
101             {
102                 Log.e("method name", hideMethod[i].getName() + ";and the i is:"
103                         + i);
104             }
105             // 取得所有常量
106             Field[] allFields = clsShow.getFields();
107             for (i = 0; i < allFields.length; i++)
108             {
109                 Log.e("Field name", allFields[i].getName());
110             }
111         }
112         catch (SecurityException e)
113         {
114             // throw new RuntimeException(e.getMessage());
115             e.printStackTrace();
116         }
117         catch (IllegalArgumentException e)
118         {
119             // throw new RuntimeException(e.getMessage());
120             e.printStackTrace();
121         }
122         catch (Exception e)
123         {
124             // TODO Auto-generated catch block
125             e.printStackTrace();
126         }
127     }
128 }</b>

 执行时直接使用:

 

01 <b>public static boolean pair(String strAddr, String strPsw)
02     {
03         boolean result = false;
04         BluetoothAdapter bluetoothAdapter = BluetoothAdapter
05                 .getDefaultAdapter();
06  
07         bluetoothAdapter.cancelDiscovery();
08  
09         if (!bluetoothAdapter.isEnabled())
10         {
11             bluetoothAdapter.enable();
12         }
13  
14         if (!BluetoothAdapter.checkBluetoothAddress(strAddr))
15         // 检查蓝牙地址是否有效
16  
17