Android和BLE模塊連接通信


首先,進行一下科普:

1.BLE(Bluetooth Low Energy),藍牙4.0核心profile,主要特點是快速搜索,快速連接,超低功耗保持連接和數據傳輸,缺點:數據傳輸速率低,由於其具有低功耗特點,故而經常用在可穿戴設備之中。Android4.3才開始支持BLE api

2.關於BLE數據傳輸:

a.profile可以理解為一種規范,一個標准的通信協議,其存在於手機中,藍牙組織規定了一些標准的profile:HID OVER GATT ,防丟器等,每個profile中包含了多個service。

b.service 可以理解為一個服務,在BLE從機中有多個服務,電量信息,系統服務信息等,每一個service中包含了多個characteristic特征值,每一個具體的characteristic特征值才是BLE通信的主題。

舉個例子吧:從機當前的電量是80%,從機會借由電量的characteristic特征值將這個信息儲存於從機的profile中,主機可以通過該characteristic來讀取80%這個數據。

c.characteristic特征值:BLE主機從機通信均是通過characteristic進行,可以將其理解為一個標簽,通過該標簽可以讀取或寫入相關信息。

d. UUID(統一標識碼):service和characteristic均需要這個唯一的UUID進行標識

/****************************************************************************************/

科普結束,首先上效果圖:



 這個就是實現后的效果,我用的BLE模塊是:MicrodunioBT4.0

 

 

/*********************************************************分隔符********************************************************************************/

BLE設備和Android應用進行通信,首先要做的就是讓Android應用找到BLE設備(代碼分析部分,只對關鍵點進行注釋)

 

package com.TANK.temperature.BT;

import java.util.List;

import com.TANK.temperature.R;
import com.TANK.temperature.BT.BluetoothLeClass.OnDataAvailableListener;
import com.TANK.temperature.BT.BluetoothLeClass.OnServiceDiscoverListener;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Typeface;
import android.net.wifi.WifiConfiguration.Status;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class DeviceScanActivity extends Activity {
    private final static String TAG = DeviceScanActivity.class.getSimpleName();
    private final static String UUID_KEY_DATA = "0000fff6-0000-1000-8000-00805f9b34fb";
    private Handler mHandler;
    private static final long SCAN_PERIOD = 10000;

    /** 搜索BLE終端 */
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothLeClass mBLE;
    private boolean mScanning;
    private BluetoothDevice BTtoLink = null;
    private String BTtoFind = "Microduino";

    private TextView BT_find, BT_info, BT_link;//三個textview分別表示:設備是否找到,BLE模塊傳輸的信息,連接狀態
    private String S_BT_info = "null", info = "111";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.temperature);
        mHandler = new Handler();

        BT_find = (TextView) findViewById(R.id.BT_find);
        BT_info = (TextView) findViewById(R.id.BT_info);
        BT_link = (TextView) findViewById(R.id.BT_link);
          
        Typeface typeface = Typeface.createFromAsset(getAssets(),
                "fonts/maozedong.ttf");//設置顯示字體
        BT_find.setTypeface(typeface);
        BT_info.setTypeface(typeface);
        BT_link.setTypeface(typeface);

        BT_find.setText("查找中");
        BT_info.setText("null");
        BT_link.setText("未連接");

        if (!getPackageManager().hasSystemFeature(   //判斷主機是否支BLE牙設備
                PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, "BLE is not supported", Toast.LENGTH_SHORT)
                    .show();
            finish();

        }
        final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);//獲得Android設備中的bluetoothmanager
        mBluetoothAdapter = bluetoothManager.getAdapter();//獲得bluetoothadapter
        if (mBluetoothAdapter == null) {
            Toast.makeText(this, "Bluetooth not supported", Toast.LENGTH_SHORT)
                    .show();
            finish();
            return;
        }
        mBluetoothAdapter.enable(); //強制使能Bluetoothadapter,打開Android設備藍牙
        mBLE = new BluetoothLeClass(this); //BLuetoothLeClass類
        if (!mBLE.initialize()) {
            Log.e(TAG, "Unable to initialize Bluetooth");
            finish();

        }

        // 發現BLE終端的Service時回調
        mBLE.setOnServiceDiscoverListener(mOnServiceDiscover);

        // 收到BLE終端數據交互的事件
        mBLE.setOnDataAvailableListener(mOnDataAvailable);

    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        scanLeDevice(true);//搜索BLE設備
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        scanLeDevice(false);
        mBLE.disconnect();
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        mBLE.close();
    }

    private void scanLeDevice(final boolean enable) {
        // TODO Auto-generated method stub
        if (enable) {

            mHandler.postDelayed(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);

                }
            }, SCAN_PERIOD);//在搜索時間內,關閉搜索標志,不對搜索回調函數進行響應
            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);

        } else {

            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);

        }

    }

    /**
     * 搜索到BLE終端服務的事件
     */
    private BluetoothLeClass.OnServiceDiscoverListener mOnServiceDiscover = new OnServiceDiscoverListener() {

        @Override
        public void onServiceDiscover(BluetoothGatt gatt) {

            displayGattServices(mBLE.getSupportedGattService());
        }

    };

    /**
     * 收到BLE終端數據交互的事件
     */
    private BluetoothLeClass.OnDataAvailableListener mOnDataAvailable = new OnDataAvailableListener() {

        /**
         * BLE終端數據寫入的事件
         */
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS)
                Log.e(TAG,
                        "onCharRead "
                                + gatt.getDevice().getName()
                                + " read "
                                + characteristic.getUuid().toString()
                                + " -> "
                                + Utils.bytesToHexString(characteristic
                                        .getValue()));

        }

        /**
         * 對BLE終端讀取數據
         */
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt,
                BluetoothGattCharacteristic characteristic) {
            info = new String(characteristic.getValue());//對得到的byte數組進行解碼,構造新的string
            Log.e(TAG, "onCharWrite " + gatt.getDevice().getName() + " write "
                    + characteristic.getUuid().toString() + " -> " + info);
            if (!S_BT_info.equals(info)) {//判斷讀取的數據是否發生變化,如果變化,更新UI
                DeviceScanActivity.this.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        BT_link.setText("已連接");
                        StringBuilder sb = new StringBuilder();//詳情參見:http://blog.csdn.net/rmn190/article/details/1492013
                        sb.append(info);
                        sb.append("度");
                        BT_info.setText(sb.toString());
                        sb = null;

                    }
                });

            }

        }
    };

    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {//搜索回調函數:
        String BT_name = null;

        @Override
        public void onLeScan(final BluetoothDevice device, int rssi,
                byte[] scanRecord) {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    BT_name = device.getName();
                    if (BT_name.equals(BTtoFind)) { //如果是要找的設備,更新UI上信息,設置搜索標志,停止響應搜索回調函數,連接BLE設備
                        /** 連接事件 */
                        BT_find.setText("已找到設備!");
                        mScanning = false;
                        mBluetoothAdapter.stopLeScan(mLeScanCallback);
                        mBLE.connect(device.getAddress());

                    }

                }
            });

        }
    };

    private void displayGattServices(BluetoothGattService bluetoothGattService) {

        if (bluetoothGattService == null)
            return;

        // -----Service的字段信息-----//
        int type = bluetoothGattService.getType();
        Log.e(TAG, "-->service type:" + Utils.getServiceType(type));
        Log.e(TAG, "-->includedServices size:"
                + bluetoothGattService.getIncludedServices().size());
        Log.e(TAG, "-->service uuid:" + bluetoothGattService.getUuid());

        // -----Characteristics的字段信息-----//
        List<BluetoothGattCharacteristic> gattCharacteristics = bluetoothGattService
                .getCharacteristics();
        for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
            Log.e(TAG, "---->char uuid:" + gattCharacteristic.getUuid());

            int permission = gattCharacteristic.getPermissions();
            Log.e(TAG,
                    "---->char permission:"
                            + Utils.getCharPermission(permission));

            int property = gattCharacteristic.getProperties();
            Log.e(TAG, "---->char property:" + Utils.getCharPropertie(property));

            byte[] data = gattCharacteristic.getValue();
            if (data != null && data.length > 0) {
                Log.e(TAG, "---->char value:" + new String(data));
            }

            // UUID_KEY_DATA是可以跟藍牙模塊串口通信的Characteristic
            if (gattCharacteristic.getUuid().toString().equals(UUID_KEY_DATA)) {
                // 測試讀取當前Characteristic數據,會觸發mOnDataAvailable.onCharacteristicRead()
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mBLE.readCharacteristic(gattCharacteristic);
                    }
                }, 500);

                // 接受Characteristic被寫的通知,收到藍牙模塊的數據后會觸發mOnDataAvailable.onCharacteristicWrite()
                mBLE.setCharacteristicNotification(gattCharacteristic, true);
                // 設置數據內容
                gattCharacteristic.setValue("send data->");
                // 往藍牙模塊寫入數據
                mBLE.writeCharacteristic(gattCharacteristic);
            }

            // -----Descriptors的字段信息-----//
            List<BluetoothGattDescriptor> gattDescriptors = gattCharacteristic
                    .getDescriptors();
            for (BluetoothGattDescriptor gattDescriptor : gattDescriptors) {
                Log.e(TAG, "-------->desc uuid:" + gattDescriptor.getUuid());
                int descPermission = gattDescriptor.getPermissions();
                Log.e(TAG,
                        "-------->desc permission:"
                                + Utils.getDescPermission(descPermission));

                byte[] desData = gattDescriptor.getValue();
                if (desData != null && desData.length > 0) {
                    Log.e(TAG, "-------->desc value:" + new String(desData));
                }
            }

        }

    }

}

 

 

  

  

package com.TANK.temperature.BT;


import java.util.UUID;



import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.util.Log;

public class BluetoothLeClass{
    private final static String TAG = BluetoothLeClass.class.getSimpleName();

    private BluetoothManager mBluetoothManager;
    private BluetoothAdapter mBluetoothAdapter;
    private String mBluetoothDeviceAddress;
    private BluetoothGatt mBluetoothGatt;

    public interface OnConnectListener {
        public void onConnect(BluetoothGatt gatt);
    }
    public interface OnDisconnectListener {
        public void onDisconnect(BluetoothGatt gatt);
    }
    public interface OnServiceDiscoverListener {
        public void onServiceDiscover(BluetoothGatt gatt);
    }
    public interface OnDataAvailableListener {
         public void onCharacteristicRead(BluetoothGatt gatt,
                    BluetoothGattCharacteristic characteristic,
                    int status);
         public void onCharacteristicWrite(BluetoothGatt gatt,
                    BluetoothGattCharacteristic characteristic);
    }
    
    private OnConnectListener mOnConnectListener;
    private OnDisconnectListener mOnDisconnectListener;
    private OnServiceDiscoverListener mOnServiceDiscoverListener;
    private OnDataAvailableListener mOnDataAvailableListener;
    private Context mContext;
    public void setOnConnectListener(OnConnectListener l){
        mOnConnectListener = l;
    }
    public void setOnDisconnectListener(OnDisconnectListener l){
        mOnDisconnectListener = l;
    }
    public void setOnServiceDiscoverListener(OnServiceDiscoverListener l){
        mOnServiceDiscoverListener = l;
    }
    public void setOnDataAvailableListener(OnDataAvailableListener l){
        mOnDataAvailableListener = l;
    }
    
    public BluetoothLeClass(Context c){
        mContext = c;
    }
    
    // Implements callback methods for GATT events that the app cares about.  For example,
    // connection change and services discovered.
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                if(mOnConnectListener!=null)
                    mOnConnectListener.onConnect(gatt);
                Log.i(TAG, "Connected to GATT server.");
                // Attempts to discover services after successful connection.
                Log.i(TAG, "Attempting to start service discovery:" +
                        mBluetoothGatt.discoverServices());

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                if(mOnDisconnectListener!=null)
                    mOnDisconnectListener.onDisconnect(gatt);
                Log.i(TAG, "Disconnected from GATT server.");
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS && mOnServiceDiscoverListener!=null) {
                    mOnServiceDiscoverListener.onServiceDiscover(gatt);
            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {
            if (mOnDataAvailableListener!=null)
                mOnDataAvailableListener.onCharacteristicRead(gatt, characteristic, status);
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            if (mOnDataAvailableListener!=null)
                mOnDataAvailableListener.onCharacteristicWrite(gatt, characteristic);
        }
    };

    /**
     * Initializes a reference to the local Bluetooth adapter.
     *
     * @return Return true if the initialization is successful.
     */
    public boolean initialize() {
        // For API level 18 and above, get a reference to BluetoothAdapter through
        // BluetoothManager.
        if (mBluetoothManager == null) {
            mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
            if (mBluetoothManager == null) {
                Log.e(TAG, "Unable to initialize BluetoothManager.");
                return false;
            }
        }

        mBluetoothAdapter = mBluetoothManager.getAdapter();
        if (mBluetoothAdapter == null) {
            Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
            return false;
        }

        return true;
    }

    /**
     * Connects to the GATT server hosted on the Bluetooth LE device.
     *
     * @param address The device address of the destination device.
     *
     * @return Return true if the connection is initiated successfully. The connection result
     *         is reported asynchronously through the
     *         {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
     *         callback.
     */
    public boolean connect(final String address) {
        if (mBluetoothAdapter == null || address == null) {
            Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
            return false;
        }

        // Previously connected device.  Try to reconnect.
        if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
                && mBluetoothGatt != null) {
            Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
            if (mBluetoothGatt.connect()) {
                return true;
            } else {
                return false;
            }
        }

        final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            Log.w(TAG, "Device not found.  Unable to connect.");
            return false;
        }
        // We want to directly connect to the device, so we are setting the autoConnect
        // parameter to false.
        mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback);
        Log.d(TAG, "Trying to create a new connection.");
        mBluetoothDeviceAddress = address;
        return true;
    }

    /**
     * Disconnects an existing connection or cancel a pending connection. The disconnection result
     * is reported asynchronously through the
     * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
     * callback.
     */
    public void disconnect() {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        mBluetoothGatt.disconnect();
    }

    /**
     * After using a given BLE device, the app must call this method to ensure resources are
     * released properly.
     */
    public void close() {
        if (mBluetoothGatt == null) {
            return;
        }
        mBluetoothGatt.close();
        mBluetoothGatt = null;
    }

    /**
     * Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported
     * asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
     * callback.
     *
     * @param characteristic The characteristic to read from.
     */
    public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        mBluetoothGatt.readCharacteristic(characteristic);
    }

    /**
     * Enables or disables notification on a give characteristic.
     *
     * @param characteristic Characteristic to act on.
     * @param enabled If true, enable notification.  False otherwise.
     */
    public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,//便於更新數據
                                              boolean enabled) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
    }

    public void writeCharacteristic(BluetoothGattCharacteristic characteristic){
         mBluetoothGatt.writeCharacteristic(characteristic);
    }
    /**
     * Retrieves a list of supported GATT services on the connected device. This should be
     * invoked only after {@code BluetoothGatt#discoverServices()} completes successfully.
     *
     * @return A {@code List} of supported services.
     */
    public BluetoothGattService getSupportedGattService() {//根據service的UUID來獲取service
        if (mBluetoothGatt == null) return null;

        return mBluetoothGatt.getService(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb"));
    }
}

 

public class Utils {

    private static HashMap<Integer, String> serviceTypes = new HashMap();
    static {
        // Sample Services.
        serviceTypes.put(BluetoothGattService.SERVICE_TYPE_PRIMARY, "PRIMARY");
        serviceTypes.put(BluetoothGattService.SERVICE_TYPE_SECONDARY, "SECONDARY");
    }
    
    public static String getServiceType(int type){
        return serviceTypes.get(type);
    }
    

    //-------------------------------------------    
    private static HashMap<Integer, String> charPermissions = new HashMap();
    static {
        charPermissions.put(0, "UNKNOW");
        charPermissions.put(BluetoothGattCharacteristic.PERMISSION_READ, "READ");
        charPermissions.put(BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED, "READ_ENCRYPTED");
        charPermissions.put(BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED_MITM, "READ_ENCRYPTED_MITM");
        charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE, "WRITE");
        charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE_ENCRYPTED, "WRITE_ENCRYPTED");
        charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE_ENCRYPTED_MITM, "WRITE_ENCRYPTED_MITM");
        charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE_SIGNED, "WRITE_SIGNED");
        charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE_SIGNED_MITM, "WRITE_SIGNED_MITM");    
    }
    
    public static String getCharPermission(int permission){
        return getHashMapValue(charPermissions,permission);
    }
    //-------------------------------------------    
    private static HashMap<Integer, String> charProperties = new HashMap();
    static {
        
        charProperties.put(BluetoothGattCharacteristic.PROPERTY_BROADCAST, "BROADCAST");
        charProperties.put(BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS, "EXTENDED_PROPS");
        charProperties.put(BluetoothGattCharacteristic.PROPERTY_INDICATE, "INDICATE");
        charProperties.put(BluetoothGattCharacteristic.PROPERTY_NOTIFY, "NOTIFY");
        charProperties.put(BluetoothGattCharacteristic.PROPERTY_READ, "READ");
        charProperties.put(BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE, "SIGNED_WRITE");
        charProperties.put(BluetoothGattCharacteristic.PROPERTY_WRITE, "WRITE");
        charProperties.put(BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE, "WRITE_NO_RESPONSE");
    }
    
    public static String getCharPropertie(int property){
        return getHashMapValue(charProperties,property);
    }
    
    //--------------------------------------------------------------------------
    private static HashMap<Integer, String> descPermissions = new HashMap();
    static {
        descPermissions.put(0, "UNKNOW");
        descPermissions.put(BluetoothGattDescriptor.PERMISSION_READ, "READ");
        descPermissions.put(BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED, "READ_ENCRYPTED");
        descPermissions.put(BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED_MITM, "READ_ENCRYPTED_MITM");
        descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE, "WRITE");
        descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED, "WRITE_ENCRYPTED");
        descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED_MITM, "WRITE_ENCRYPTED_MITM");
        descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE_SIGNED, "WRITE_SIGNED");
        descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE_SIGNED_MITM, "WRITE_SIGNED_MITM");
    }
    
    public static String getDescPermission(int property){
        return getHashMapValue(descPermissions,property);
    }
    
    //這段代碼沒看明白,歡迎大神指教
    private static String getHashMapValue(HashMap<Integer, String> hashMap,int number){
        String result =hashMap.get(number);
        if(TextUtils.isEmpty(result)){
            List<Integer> numbers = getElement(number);
            result="";
            for(int i=0;i<numbers.size();i++){
                result+=hashMap.get(numbers.get(i))+"|";
            }
        }
        return result;
    }

    /**
     * 位運算結果的反推函數10 -> 2 | 8;
     */
    static private List<Integer> getElement(int number){
        List<Integer> result = new ArrayList<Integer>();
        for (int i = 0; i < 32; i++){
            int b = 1 << i;
            if ((number & b) > 0) 
                result.add(b);
        }
        
        return result;
    }
    
    
    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();  
    }  
}

 

  





  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM