博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 4.4.2上与BLE 蓝牙锁设备的通讯
阅读量:4646 次
发布时间:2019-06-09

本文共 32919 字,大约阅读时间需要 109 分钟。

Android从4.3(Api level 18)开始支持BLE的开发,本文记录了Android 4.4.2设备与BLE设备通讯的流程。

权限需求:

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

步骤:

1.获取蓝牙服务
BluetoothManager btManager= (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
2.获取蓝牙设备管理器(适配器)
BluetoothAdapter mBluetoothAdapter = btManager.getAdapter();
3.判断设备是否支持BLE蓝牙通讯,支持则判断蓝牙是否已开启,未开启蓝牙的设置开启。
if (mBluetoothAdapter != null && (!mBluetoothAdapter.isEnabled())){
mBluetoothAdapter.enable();//打开蓝牙
}
4.扫描当前附近的蓝牙BLE设备(这个操作比较耗电,要适时地停止)
5.停止设备扫描
6.与指定BLE设备建立Gatt连接
7.在连接成功后,设置扫描BLE设备支持的service和characteristic,并设置。这里需要注意,需要开启通知的,需要设置相应描述符。
8.读写操作
9.断开Gatt连接
10.关闭Gatt连接

在开发过程中,遇到的主要问题是onCharacteristicWrite失败回调,这个可能跟低功耗蓝牙外设有关,需要断开并关闭Gatt连接重新建立

 下面是主要参考代码

package com.rollup.bluetoothlock;import java.lang.ref.WeakReference;import java.util.ArrayList;import java.util.List;import java.util.Timer;import java.util.TimerTask;import java.util.UUID;import com.android.peephole.MyApplication;import com.rollup.bluetoothlock.MyLog;import com.rollup.bluetoothlock.Utils;import com.rollup.bluetoothlock.Value;import android.R.integer;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothAdapter.LeScanCallback;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothGatt;import android.bluetooth.BluetoothGattCallback;import android.bluetooth.BluetoothGattCharacteristic;import android.bluetooth.BluetoothGattDescriptor;import android.bluetooth.BluetoothGattService;import android.bluetooth.BluetoothManager;import android.bluetooth.BluetoothProfile;import android.content.Context;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.os.Handler;import android.os.Message;import android.widget.EditText;import android.widget.Toast;public class BleManager {    private static final String TAG = "BleManager";    public static final int ERROR_NO_ERROR = 0;//成功    public static final int ERROR_BTDEVICE_EXC_FAIL = 1;// 蓝牙锁端执行错误    public static final int ERROR_PSD_ERROR = 2; // 钥匙错误    public static final int ERROR_CONNECT_FAIL = 3;    public static final int ERROR_DEFAULT = 4;    public static final int ERROR_NOT_FOUND_DEVICE = 5;// 未扫描到指定编码的锁    public static final int ERROR_HAVE_CONNECTED = 6;//上次连接未执行完毕    public static final int ERROR_NO_DEVICE = 7;//设备没有初始化    public static final int ERROR_CREATE_FAIL = 8;    private static final int STOP_LESCAN = 1;    private final int OVER_TIMER = 60 * 1000;// 扫描超时时间    private Context mContext = null;    private BluetoothAdapter mBluetoothAdapter = null;    private BluetoothManager mBluetoothManager = null;    public BluetoothDevice mBluetoothDevice = null;    private BluetoothGatt mBluetoothGatt;    private static boolean isScanning = false;    private BluetoothGattCharacteristic writeCharacteristic = null;    private static boolean isConnectToDevice = false;    private String btName = null;    private String psd = null;    private boolean hasExcuteOpenDoor = false;// 开门命令已执行    private byte[] devceKey;    private static boolean haveRetry = false;    private static BleManager instance = null;    private MyHandler mHandler = null;    public static long lastOpendoorTime = 0;    private OnBleScanOpenDoorCallback openDoorCallback = null;    public interface OnBleScanOpenDoorCallback {        public void openDoorSuc();        public void openDoorFail(int error);    }    private BleManager(Context context, String btName, String psd) {        this.mContext = context;        initBluetooth();        if (mBluetoothManager == null) {            MyLog.e(TAG, "Unable to initialize BluetoothManager.");            return;        }        this.btName = btName;        this.psd = psd;        devceKey = new byte[16];    }    public static BleManager getInstance(String btName, String psd) {        if (instance == null) {            instance = new BleManager(MyApplication.getMyApplication(), btName,                    psd);        } else {            instance.setBTinfo(btName, psd);        }        return instance;    }    private void setBTinfo(String name, String psd) {        this.btName = name;        this.psd = psd;    }    private void initBluetooth() {        mHandler = new MyHandler(this);        mBluetoothManager = (BluetoothManager) mContext                .getSystemService(Context.BLUETOOTH_SERVICE);        if (mBluetoothManager != null) {            mBluetoothAdapter = mBluetoothManager.getAdapter();            if (mBluetoothAdapter != null) {                if (!mBluetoothAdapter.isEnabled()) {                    mBluetoothAdapter.enable(); // 打开蓝牙                }            }        }    }        /**     * 是否空闲可用     * @return     */    public static boolean isFree(){        return (!isConnectToDevice)&&(!isScanning);    }    public void startLeScan(boolean autoConnect) {        if (mBluetoothAdapter == null) {            return;        }        if (btName == null || btName.length() == 0) {            return;        }        if (isScanning) {            return;        }        isScanning = true;        if (autoConnect) {            mBluetoothAdapter.startLeScan(mLeScanCallback2);        } else {            mBluetoothAdapter.startLeScan(mLeScanCallback); // 此mLeScanCallback为回调函数        }        mHandler.sendEmptyMessageDelayed(STOP_LESCAN, OVER_TIMER); // 这个搜索30秒,如果搜索不到则停止搜索    }    private void stopLeScan() {        if (mHandler != null && mHandler.hasMessages(STOP_LESCAN)) {            mHandler.removeMessages(STOP_LESCAN);        }        if (mBluetoothAdapter == null) {            return;        }        if (!isScanning) {            return;        }        mBluetoothAdapter.stopLeScan(mLeScanCallback);        mBluetoothAdapter.stopLeScan(mLeScanCallback2);        isScanning = false;    }    private LeScanCallback mLeScanCallback = new LeScanCallback() {        @Override        public void onLeScan(BluetoothDevice device, int arg1, byte[] arg2) {            MyLog.i(TAG, "onLeScan() DeviceName------>" + device.getName()); // 在这里可通过device这个对象来获取到搜索到的ble设备名称和一些相关信息            if (device.getAddress() != null) {                if (device.getName().toLowerCase().replace("_", "")                        .contentEquals(btName.toLowerCase().replace(" ", ""))) {                    mBluetoothDevice = device;                    stopLeScan();                }            }        }    };    private LeScanCallback mLeScanCallback2 = new LeScanCallback() {        @Override        public void onLeScan(BluetoothDevice device, int arg1, byte[] arg2) {            MyLog.i(TAG, "onLeScan() DeviceName------>" + device.getName()); // 在这里可通过device这个对象来获取到搜索到的ble设备名称和一些相关信息            if (device.getAddress() != null) {                if (device.getName().toLowerCase().replace("_", "")                        .contentEquals(btName.toLowerCase().replace(" ", ""))) {                    mBluetoothDevice = device;                    stopLeScan();                    connect();                }            }        }    };    private static class MyHandler extends Handler {        WeakReference
wf = null; public MyHandler(BleManager manager) { // TODO Auto-generated constructor stub wf = new WeakReference
(manager); } @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub switch (msg.what) { case STOP_LESCAN: MyLog.i(TAG, "MyHandler handleMessage STOP_LESCAN"); if (wf.get()!=null){ wf.get().stopLeScan(); } MyLog.i(TAG, "release(), Scan time is up"); break; } } } public int connect() { if (mBluetoothDevice == null) { MyLog.i(TAG, "BluetoothDevice is null."); return ERROR_NO_DEVICE; } if(isConnectToDevice){ MyLog.i(TAG, "Have connected to device"); return ERROR_HAVE_CONNECTED; } isConnectToDevice = true; hasExcuteOpenDoor = false; // 两个设备通过BLE通信,首先需要建立GATT连接。这里我们讲的是Android设备作为client端,连接GATT Server mBluetoothGatt = mBluetoothDevice.connectGatt(mContext, false, mGattCallback); // mGattCallback为回调接口 if (mBluetoothGatt != null) { if (mBluetoothGatt.connect()) { MyLog.d(TAG, "Connect succeed."); return ERROR_NO_ERROR; } else { MyLog.d(TAG, "Connect fail."); return ERROR_CONNECT_FAIL; } } else { MyLog.d(TAG, "BluetoothGatt null."); return ERROR_CREATE_FAIL; } } private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (newState == BluetoothProfile.STATE_CONNECTED) { isConnectToDevice = true; gatt.discoverServices(); // 执行到这里其实蓝牙已经连接成功了 MyLog.i(TAG, "Connected to GATT server."); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { if (!hasExcuteOpenDoor) { disconnect(); retryUnlock(); if (!haveRetry) { //已失败重试过 if (openDoorCallback != null) { openDoorCallback.openDoorFail(ERROR_CONNECT_FAIL); } } } else { MyLog.i(TAG, "BluetoothProfile.STATE_DISCONNECTED hasExcuteOpenDoor=TRUE"); haveRetry = false; disconnect(); } MyLog.i(TAG, "BluetoothProfile.STATE_DISCONNECTED --release()"); } } public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { MyLog.i(TAG, "onServicesDiscovered"); List
services = gatt.getServices(); for (int i = 0; i < services.size(); i++) { MyLog.i(TAG, "[Service " + i + "] uuid:" + services.get(i).getUuid()); if (services.get(i).getUuid().equals(Value.uuid)) { List
characteristics = services .get(i).getCharacteristics(); for (int j = 0; j < characteristics.size(); j++) { MyLog.i(TAG, "[Characteristic]" + characteristics.get(j).getUuid()); if (characteristics.get(j).getUuid() .equals(Value.CHARACTERISTIC_READ)) { boolean res = mBluetoothGatt .setCharacteristicNotification( characteristics.get(j), true); // 打开通知描述 for (BluetoothGattDescriptor descriptor : characteristics .get(j).getDescriptors()) { descriptor .setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); gatt.writeDescriptor(descriptor); MyLog.i(TAG, "Characteristic set notification is Success!"); } MyLog.i(TAG, "onServicesDiscovered setCharacteristicNotification result=" + res); break; } } characteristics = null; } } for (int i = 0; i < services.size(); i++) { MyLog.i(TAG, "[Service " + i + "] uuid:" + services.get(i).getUuid()); if (services.get(i).getUuid().equals(Value.uuid)) { List
characteristics = services .get(i).getCharacteristics(); for (int j = 0; j < characteristics.size(); j++) { MyLog.i(TAG, "[Characteristic]" + characteristics.get(j).getUuid()); if (characteristics.get(j).getUuid() .equals(Value.CHARACTERISTIC_WRITE)) { writeCharacteristic = characteristics.get(j); final int charaProp = characteristics.get(j) .getProperties(); // 如果该char可写 if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) { byte[] value = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; characteristics.get(j).setValue(value); writeCharacteristic .setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); mBluetoothGatt .writeCharacteristic(characteristics .get(j)); value = null; } break; } } characteristics = null; } } services = null; } else { MyLog.i(TAG, "onServicesDiscovered status------>" + status); } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { MyLog.i(TAG, "onCharacteristicRead------>" + Utils.bytesToHexString(characteristic.getValue())); } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { MyLog.i(TAG, "onCharacteristicChanged------>" + Utils.bytesToHexString(characteristic.getValue())); MyLog.i(TAG, "UUID------>" + characteristic.getUuid().toString()); if (Value.CHARACTERISTIC_READ.equals(characteristic.getUuid())) { byte[] value = characteristic.getValue(); if ((value[0] & 0xFF) == 0x81) { for (int i = 0; i < 16; i++) { devceKey[i] = value[i + 1]; } // MyLog.i(TAG, "加密秘钥为:"+Utils.bytesToHexString(devceKey)); if (writeCharacteristic != null) { byte[] cmd = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (psd.length() == 8) { int j = 0; for (int i = 0; i < 4; i++) { cmd[5 + i] = (byte) (((((Integer.valueOf(psd .charAt(j)) - 48) << 4) & (0xF0)) + ((Integer .valueOf(psd.charAt(j + 1)) - 48) & 0x0F)) & 0xFF); MyLog.i(TAG, "cmd" + (9 + i) + "=" + cmd[9 + i]); j = j + 2; } } byte[] cmd_encrypt = Utils.enCode(devceKey, cmd); if (cmd_encrypt != null) { byte[] request = new byte[17]; request[0] = 0x03; for (int i = 1; i < (cmd_encrypt.length < request.length ? cmd_encrypt.length : request.length); i++) { request[i] = cmd_encrypt[i - 1]; } writeCharacteristic.setValue(request); writeCharacteristic .setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); // MyLog.i(TAG, // "发送开锁命令:"+Utils.bytesToHexString(request)); mBluetoothGatt .writeCharacteristic(writeCharacteristic); request = null; } cmd_encrypt = null; cmd = null; } } else if ((value[0] & 0xFF) == 0x83) { byte[] res = new byte[16]; for (int i = 0; i < 16; i++) { res[i] = value[i + 1]; } // MyLog.i(TAG, "解密秘钥为:"+Utils.bytesToHexString(devceKey)); // MyLog.i(TAG, "待解密数据为:"+Utils.bytesToHexString(res)); byte[] decode_res = Utils.deCode(devceKey, res); hasExcuteOpenDoor = true; if (decode_res != null) { MyLog.i(TAG, "获取到蓝牙开锁返回数据:" + Utils.bytesToHexString(decode_res)); if ((decode_res[0] & 0xFF) == 0x01) { if ((decode_res[1] & 0xFF) == 0x00) { MyLog.i(TAG, "开锁成功"); if (openDoorCallback != null) { openDoorCallback.openDoorSuc(); } lastOpendoorTime = System.currentTimeMillis(); } else if ((decode_res[1] & 0xFF) == 0x01) { MyLog.i(TAG, "开锁失败:命令执行失败"); if (openDoorCallback != null) { openDoorCallback .openDoorFail(ERROR_BTDEVICE_EXC_FAIL); } } else if ((decode_res[1] & 0xFF) == 0x02) { MyLog.i(TAG, "开锁失败:密钥解密失败,无效用户密钥"); if (openDoorCallback != null) { openDoorCallback .openDoorFail(ERROR_PSD_ERROR); } } else { MyLog.e(TAG, "开锁返回异常"); if (openDoorCallback != null) { openDoorCallback .openDoorFail(ERROR_DEFAULT); } } new Timer().schedule(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub sendEndCmd(); } }, 500); } else { MyLog.e(TAG, "开锁返回动作标志位异常,此时锁还会再次返回其他数据"); if (openDoorCallback != null) { openDoorCallback.openDoorFail(ERROR_DEFAULT); } } } else { MyLog.e(TAG, "蓝牙开锁数据获取失败"); if (openDoorCallback != null) { openDoorCallback.openDoorFail(ERROR_DEFAULT); }// disconnect(true); } decode_res = null; res = null; } else { MyLog.e(TAG, " value[0] = " + value[0] + " ===release() 11111111");// disconnect(true); } value = null; } } // 接受Characteristic被写的通知,收到蓝牙模块的数据后会触发onCharacteristicWrite @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { MyLog.i(TAG, "onCharacteristicWrite status = " + status + ",onCharacteristicWrite------>" + Utils.bytesToHexString(characteristic.getValue())); if (status != 0) {// disconnect(true); } } }; private void sendEndCmd() { if (writeCharacteristic != null) { byte[] cmd = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; byte[] cmd_encrypt = Utils.enCode(devceKey, cmd); if (cmd_encrypt != null) { byte[] request = new byte[17]; request[0] = 0x08; for (int i = 1; i < (cmd_encrypt.length < request.length ? cmd_encrypt.length : request.length); i++) { request[i] = cmd_encrypt[i - 1]; } writeCharacteristic.setValue(request); writeCharacteristic .setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); mBluetoothGatt.writeCharacteristic(writeCharacteristic); request = null; } cmd = null; cmd_encrypt = null; } // release(); } private void retryUnlock() { if (!haveRetry) { haveRetry = true; connect(); } else { haveRetry = false; MyLog.i(TAG, "retryUnlock haveRetry"); } } public void setOpenDoorCallback(OnBleScanOpenDoorCallback callback) { openDoorCallback = callback; } public synchronized void disconnect() { MyLog.i(TAG, "disconnect"); if (mBluetoothGatt != null) { mBluetoothGatt.disconnect(); mBluetoothGatt.close(); mBluetoothGatt = null; } isConnectToDevice = false; }}
View Code
package com.example.common;import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;public class Utils {     /** Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串。       * @param src byte[] data       * @return hex string       */         public static String bytesToHexString(byte[] src){          StringBuilder stringBuilder = new StringBuilder("");          if (src == null || src.length <= 0) {              return null;          }          for (int i = 0; i < src.length; i++) {              int v = src[i] & 0xFF;              String hv = Integer.toHexString(v);              if (hv.length() < 2) {                  stringBuilder.append(0);              }              stringBuilder.append(hv);          }          return stringBuilder.toString();      }      /**      * Convert hex string to byte[]      * @param hexString the hex string      * @return byte[]      */      public static byte[] hexStringToBytes(String hexString) {          if (hexString == null || hexString.equals("")) {              return null;          }          hexString = hexString.toUpperCase();          int length = hexString.length() / 2;          char[] hexChars = hexString.toCharArray();          byte[] d = new byte[length];          for (int i = 0; i < length; i++) {              int pos = i * 2;              d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));          }          return d;      }          /**      * Convert char to byte      * @param c char      * @return byte      */       private static byte charToByte(char c) {          return (byte) "0123456789ABCDEF".indexOf(c);      }      //将指定byte数组以16进制的形式打印到控制台      public static void printHexString( byte[] b) {           for (int i = 0; i < b.length; i++) {            String hex = Integer.toHexString(b[i] & 0xFF);            if (hex.length() == 1) {              hex = '0' + hex;            }            System.out.print(hex.toUpperCase() );          }             }          /**     * 真正的加密过程     * 1.通过密钥得到一个密钥专用的对象SecretKeySpec     * 2.Cipher 加密算法,加密模式和填充方式三部分或指定加密算 (可以只用写算法然后用默认的其他方式)Cipher.getInstance("AES");     * @param key     * @param src     * @return     * @throws Exception     */    public static byte[] enCode(byte[] key, byte[] src) {        try {            SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");            Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");             cipher.init(Cipher.ENCRYPT_MODE, skeySpec);            byte[] encrypted = cipher.doFinal(src);            return encrypted;        } catch (Exception e) {            // TODO: handle exception            e.printStackTrace();            return null;        }            }         /**     * 解密     * @param view     */    public static byte[] deCode(byte[] key, byte[] src){         try {            //获取AESkey            SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");            Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding"); //AES/ECB/ZeroBytePadding            cipher.init(Cipher.DECRYPT_MODE, skeySpec);            byte[] decrypted = cipher.doFinal(src);            byte[] result;            if (decrypted.length<16){                result = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};                for (int i=0; i
View Code
package com.example.common;import java.util.UUID;public class Value {    public static final String BLE_LOCK_SP_NAME = "BleLockConfig";    public static final String KEY_BLE_LOCK_ID = "kEY_BLE_LOCK_ID";    public static final String KEY_BLE_LOCK_KEY = "KEY_BLE_LOCK_KEY";        public final static UUID uuid = UUID.fromString("0000ff12-0000-1000-8000-00805f9b34fb");    public final static UUID CHARACTERISTIC_WRITE = UUID.fromString("0000ff01-0000-1000-8000-00805f9b34fb");//主机BLE发送给BLE模块数据使用    public final static UUID CHARACTERISTIC_READ = UUID.fromString("0000ff04-0000-1000-8000-00805f9b34fb");//BLE模块发送给主机BLE数据使用,NOTIFY功能发送,前提是双方连接上后,需要主机BLE主动打开BLE模块的UUID=0XFF04(NOTIFY)功能。}
View Code
package com.example.bluetoothdemo;import com.example.common.BleManager;import com.example.common.Utils;import com.example.common.BleManager.OnBleScanOpenDoorCallback;import android.app.Activity;import android.app.ProgressDialog;import android.content.Context;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.view.inputmethod.InputMethodManager;import android.widget.Button;import android.widget.EditText;import android.widget.RelativeLayout;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener, OnBleScanOpenDoorCallback{        private final String TAG = "MainActivity";    private final String KEY_BLE_LOCK_ID = "kEY_BLE_LOCK_ID";    private final String KEY_BLE_LOCK_KEY = "KEY_BLE_LOCK_KEY";        private BleManager mBleManager = null;        private RelativeLayout relativeLayout = null;    private EditText idEditText = null;    private EditText psdEditText = null;    private Button scanButton = null;    private Button connectButton = null;    private ProgressDialog progressDialog = null;        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        getWindow().requestFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);                relativeLayout = (RelativeLayout) findViewById(R.id.relativelayout);        scanButton = (Button) findViewById(R.id.button_scan);            connectButton = (Button) findViewById(R.id.button_connect);        idEditText = (EditText) findViewById(R.id.edittext_lock_id);        psdEditText = (EditText) findViewById(R.id.edittext_psd);        progressDialog = new ProgressDialog(this);        progressDialog.setMessage(getString(R.string.waiting));                SharedPreferences sp = getPreferences(MODE_PRIVATE);        String bleName = sp.getString(KEY_BLE_LOCK_ID, "ZY121711240013");        String blePsd = sp.getString(KEY_BLE_LOCK_KEY, "12345678");        idEditText.setText(bleName);        psdEditText.setText(blePsd);                relativeLayout.setOnClickListener(this);        scanButton.setOnClickListener(this);                connectButton.setOnClickListener(this);                mBleManager = BleManager.getInstance(bleName, blePsd);  //这个this是一个上下文,只要在上面的BleManager工具类定义一个有参数就好        mBleManager.setOpenDoorCallback(this);    }        @Override    protected void onResume() {        // TODO Auto-generated method stub        super.onResume();    }        @Override    protected void onPause() {        // TODO Auto-generated method stub        super.onPause();        SharedPreferences sp = getPreferences(MODE_PRIVATE);        Editor editable = sp.edit();        editable.putString(KEY_BLE_LOCK_ID, idEditText.getText().toString().trim());        editable.putString(KEY_BLE_LOCK_KEY, psdEditText.getText().toString().trim());        editable.commit();    }    @Override    public void onClick(View v) {        // TODO Auto-generated method stub        switch (v.getId()) {        case R.id.button_scan:            break;        case R.id.relativelayout:            InputMethodManager m = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);            m .hideSoftInputFromWindow(relativeLayout.getWindowToken(), 0);//比如EditView            break;        case R.id.button_connect:            progressDialog.show();            int res = mBleManager.connect();                        if (res == BleManager.ERROR_NO_ERROR){            }else if (res == BleManager.ERROR_HAVE_CONNECTED){                //已经连接不能再次连                progressDialog.dismiss();            }else{                mBleManager.startLeScan(true);            }            break;                default:                        break;        }    }    @Override    protected void onDestroy() {        // TODO Auto-generated method stub                if (mBleManager != null){            mBleManager.setOpenDoorCallback(null);            mBleManager.disconnect();            mBleManager = null;        }        super.onDestroy();    }    @Override    public void openDoorSuc() {        // TODO Auto-generated method stub        runOnUiThread(new Runnable() {                        @Override            public void run() {                // TODO Auto-generated method stub                if (progressDialog.isShowing()){                    progressDialog.dismiss();                }                Toast.makeText(MainActivity.this, getString(R.string.open_door_suc), Toast.LENGTH_LONG).show();            }        });            }    @Override    public void openDoorFail(final int error) {        // TODO Auto-generated method stub        runOnUiThread(new Runnable() {                        @Override            public void run() {                // TODO Auto-generated method stub                if (progressDialog.isShowing()){                    progressDialog.dismiss();                }                int resId  = R.string.error_default;                if (error==BleManager.ERROR_BTDEVICE_EXC_FAIL){                    resId = R.string.error_btdevice_exc_fail;                }else if (error == BleManager.ERROR_CONNECT_FAIL){                    resId = R.string.error_not_connect;                }else if (error == BleManager.ERROR_PSD_ERROR){                    resId = R.string.error_psd_error;                }else if (error == BleManager.ERROR_NOT_FOUND_DEVICE){                    resId = R.string.error_device_not_found;                }                Toast.makeText(MainActivity.this, resId, Toast.LENGTH_LONG).show();            }        });            }}
View Code

 

转载于:https://www.cnblogs.com/suxiaoqi/p/8023588.html

你可能感兴趣的文章
Linux的学习:
查看>>
JavaScript中的原型继承原理
查看>>
Python logger模块
查看>>
jquery控制css的display(控制元素的显示与隐藏)
查看>>
关于python做人工智能的一个网页(很牛逼)
查看>>
判断控件的CGRect是否重合,获取控件的最大XY值
查看>>
POJ-1128 Frame Stacking
查看>>
浏览器调试淘宝首页看到有趣的招聘信息
查看>>
ASP.NET Identity “角色-权限”管理 4
查看>>
[转][译]ASP.NET MVC 4 移动特性
查看>>
SOC CPU
查看>>
get_result --perl
查看>>
163镜像地址
查看>>
ehcache memcache redis 三大缓存男高音
查看>>
eclipse 快捷键Open Implementation 直接退出
查看>>
minix中管道文件和设备文件的读写
查看>>
JAXB - Annotations, Annotations for Enums: XmlEnum, XmlEnumValue
查看>>
context 插图
查看>>
文件管理器中不支持的wma歌曲也显示可以播放的音乐图标
查看>>
Java基础学习-流程控制语句
查看>>