Android低功耗藍牙

花了半個多月,寫Android BLE,看了github上很多源碼。

 


import android.annotation.SuppressLint;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
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.Intent;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import android.app.Activity;

import btlescan.ui.control.DeviceControlActivity;


//creator by zhangkun on 2018-12-1
@SuppressLint("NewApi")
public class PkeService extends Service {

    private final static String TAG = PkeService.class.getSimpleName();

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

    BluetoothGattService linkLossService_pke;
    BluetoothGattCharacteristic alertLevel_pke;
    private int mConnectionState = STATE_DISCONNECTED;

    private static final int STATE_DISCONNECTED = 0;
    private static final int STATE_CONNECTING = 1;
    private static final int STATE_CONNECTED = 2;


    public final static String ACTION_GATT_CONNECTED = "com.choicemmed.bledemo.ACTION_GATT_CONNECTED";
    public final static String ACTION_GATT_DISCONNECTED = "com.choicemmed.bledemo.ACTION_GATT_DISCONNECTED";
    public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.choicemmed.bledemo.ACTION_GATT_SERVICES_DISCOVERED";
    public final static String ACTION_DATA_AVAILABLE = "com.choicemmed.bledemo.ACTION_DATA_AVAILABLE";
    public final static String EXTRA_DATA = "com.choicemmed.bledemo.EXTRA_DATA";

    public static String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";

    //zhangkun add 2018-11-15
    public SharedPreferences pkeUserSettings = null;
    private String PkeMacAddr = "";
    private boolean mScanning;
    private static BluetoothDevice PkeDevice;
    private int PkeRssiQualified = 0;
    // 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) {
            String intentAction;
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                intentAction = ACTION_GATT_CONNECTED;
                mConnectionState = STATE_CONNECTED;
        //        broadcastUpdate(intentAction);
                Log.i(TAG, "Connected to GATT server.");
                // Attempts to discover services after successful connection.
        //        Log.i(TAG, "Attempting to start service discovery:"
        //                + mBluetoothGatt.discoverServices());

                Log.e("onConnec中中中", "連接成功:");
                gatt.discoverServices();//必須有,可以讓onServicesDiscovered顯示所有Services

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                intentAction = ACTION_GATT_DISCONNECTED;
                mConnectionState = STATE_DISCONNECTED;
                Log.i(TAG, "Disconnected from GATT server.");
            //    broadcastUpdate(intentAction);
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
        //        broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
                List<BluetoothGattService> list = mBluetoothGatt.getServices();
                for (BluetoothGattService bluetoothGattService:list){
                    String str = bluetoothGattService.getUuid().toString();
                    Log.e("onServicesDisc中中中", " :" + str);
                    List<BluetoothGattCharacteristic> gattCharacteristics = bluetoothGattService
                            .getCharacteristics();
                    for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                        Log.e("onServicesDisc中中中", " :" + gattCharacteristic.getUuid());
                        if("0000ffe1-0000-1000-8000-00805f9b34fb".equals(gattCharacteristic.getUuid().toString())){
                            linkLossService_pke=bluetoothGattService;
                            alertLevel_pke=gattCharacteristic;
                            Log.e("daole",alertLevel_pke.getUuid().toString());
                        }
                    }

                }
                enableNotification(true,gatt,alertLevel_pke);//必須要有,否則接收不到數據
            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic, int status) {
            Log.d(TAG, "onCharacteristicRead:" +status);
            Log.e("onCharacteristicRead中", "數據接收了哦"+bytesToHexString(characteristic.getValue()));
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt,
                                          BluetoothGattCharacteristic characteristic, int status) {
            System.out.println("--------write success----- status:" + status);
            Log.e("onCharacteristicWrite中", "數據發送了哦");
            Log.e("onCharacteristicWrite中", bytesToHexString(characteristic.getValue()));
            if(status == BluetoothGatt.GATT_SUCCESS){//寫入成功
                Log.e("onCharacteristicWrite中", "寫入成功");
                //              tx_display.append("寫入成功");
            }else if (status == BluetoothGatt.GATT_FAILURE){
                Log.e("onCharacteristicWrite中", "寫入失敗");
            }else if (status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED){
                Log.e("onCharacteristicWrite中", "沒權限");
            }
        };

        /*
         * when connected successfully will callback this method
         * this method can dealwith send password or data analyze
         *
         * */
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            Log.e("CharacteristicChanged中", "數據接收了哦"+bytesToHexString(characteristic.getValue()));
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt,
                                      BluetoothGattDescriptor descriptor, int status) {
            UUID uuid = descriptor.getCharacteristic().getUuid();
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            System.out.println("rssi = " + rssi);
        }
    };

    private void broadcastUpdate(final String action) {
        final Intent intent = new Intent(action);
        sendBroadcast(intent);
    }

    private void broadcastUpdate(final String action,
                                 final BluetoothGattCharacteristic characteristic) {
        final Intent intent = new Intent(action);

        byte[] heartRate = characteristic.getValue();
        String s = DeviceControlActivity.byte2HexStr(heartRate);
        String data = DeviceControlActivity.print10(s);
        if (data != null ) {
            intent.putExtra(EXTRA_DATA, data);
        }
        sendBroadcast(intent);
    }
    public class LocalBinder extends Binder {
        public PkeService getService() {
            return PkeService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        // After using a given device, you should make sure that
        // BluetoothGatt.close() is called
        // such that resources are cleaned up properly. In this particular
        // example, close() is
        // invoked when the UI is disconnected from the Service.
        close();
        return super.onUnbind(intent);
    }

    private final IBinder mBinder = new LocalBinder();

    /**
     * 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) 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;
        }else
        {
            ReadPkeStatus();

        }

        return true;
    }

    public void closePke()
    {
        timerPke.cancel();
        mBluetoothGatt.close();
    }

    /**
     * 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, final BluetoothDevice device ) {
        if (mBluetoothAdapter == null || address == null) {
            Log.w(TAG,
                    "BluetoothAdapter not initialized or unspecified address.");
            return false;
        }

        if (device == null) {
            Log.d(TAG, "沒有設備");
            return false;
        }
        // We want to directly connect to the device, so we are setting the
        // autoConnect
        // parameter to false.
        mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
        Log.d(TAG, "Trying to create a new connection.");
        mBluetoothDeviceAddress = address;
        mConnectionState = STATE_CONNECTING;
        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;
    }

    public void wirteCharacteristic(BluetoothGattCharacteristic characteristic) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        mBluetoothGatt.writeCharacteristic(characteristic);

    }

    /**
     * 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) {
        Log.d(TAG, "readCharacteristic: "+characteristic.getProperties());
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.d(TAG, "BluetoothAdapter爲空");
            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.d(TAG, "BluetoothAdapter爲空");
            return;
        }
        mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID
                .fromString(CLIENT_CHARACTERISTIC_CONFIG));
        if (descriptor != null) {
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mBluetoothGatt.writeDescriptor(descriptor);
        }
    }

    /**
     * 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 List<BluetoothGattService> getSupportedGattServices() {
        if (mBluetoothGatt == null)
            return null;

        return mBluetoothGatt.getServices();
    }

    /**
     * Read the RSSI for a connected remote device.
     * */
    public boolean getRssiVal() {
        if (mBluetoothGatt == null)
            return false;

        return mBluetoothGatt.readRemoteRssi();
    }


    //  Bluetooth PKE scan device callback function by Zhangkun on 2018-11-26
    private final BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
            Log.e("LeScanCallback-onLeScan", " "+device.toString()+ "rssi:"+rssi);
            if(device.toString().contains(PkeMacAddr))
            {
                //    Log.e("LeScanCallback-onLeScan", " "+device.toString()+ rssi + "uuids "+ device.getUuids().toString());
                if(rssi > -90)
                {
                    Log.e(" pke onLeScan","rssi > 90");
                    PkeRssiQualified++;
                    PkeDevice = device;
                }
/*
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        updateItemCount(rssi);
                    }
                });             */
            }

        }
    };
    //update rssi TextView by ZhangKun 2018-11-26
    private void updateItemCount(final int count) {
        /*
        mTvRssiShow.setText(
                getString(
                        R.string.formatter_db,
                        String.valueOf(count)));
        */
    }

    public void ReadPkeStatus()
    {
        //
        pkeUserSettings = getSharedPreferences("PkeSetting", 0);
        PkeMacAddr = pkeUserSettings.getString("MacAddr",null);
        Log.e("ReadPkeStatus", "pkeUserSettings...  addr="+ PkeMacAddr);
        if(PkeMacAddr != null)
        {
            boolean pkeSwitch = pkeUserSettings.getBoolean("pkeSwitch", false);
            Log.e("ReadPkeStatus", "pkeSwitch "+ pkeSwitch);
            if(pkeSwitch == true)
            {
                //auto open door of car
                //1. start scan bluetooth
                mBluetoothAdapter.startLeScan(mLeScanCallback);
                mScanning = true;
                //2. check rssi > -90 then stop bluetooth scan,and try connect
                timerPke.schedule(timerTaskPke,200,1000);//延時1s,每隔500毫秒執行一次run方法

                Log.e("ReadPkeStatus", "Start scan...");
                boolean pkeUnlock = pkeUserSettings.getBoolean("pkeUnlock", false);
                boolean pkeLock = pkeUserSettings.getBoolean("pkeLock", false);
            }
        }
    }

    public static final String bytesToHexString(byte[] bArray) {
        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }


    private void enableNotification(boolean enable, BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        if (gatt == null || characteristic == null)
            return; //這一步必須要有 否則收不到通知 gatt.setCharacteristicNotification(characteristic, enable); BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUIDUtils.CCC); if (enable) { clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); } else { clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); } //準備數據 BleWriteData bData = new BleWriteData(); bData.write_type = BleWriteData.DESCRIP_WRITE;//數據種類 bData.object = clientConfig; //將數據加入隊列 mWriteQueue.add(bData); }
        //這一步必須要有 否則收不到通知 gatt.setCharacteristicNotification(characteristic, enable); BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUIDUtils.CCC); if (enable) { clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); } else { clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); } //準備數據 BleWriteData bData = new BleWriteData(); bData.write_type = BleWriteData.DESCRIP_WRITE;//數據種類 bData.object = clientConfig; //將數據加入隊列 mWriteQueue.add(bData);
        gatt.setCharacteristicNotification(characteristic, enable);
    }

    /**
     * 向藍牙發送數據
     */
    public void dataSend(){
        alertLevel_pke.setValue(getCmd80_new((byte)0x00));
        boolean status = mBluetoothGatt.writeCharacteristic(alertLevel_pke);
        try{
            Thread.sleep(200);
        }catch (Exception e){}
        alertLevel_pke.setValue("xxxxxx");
        mBluetoothGatt.writeCharacteristic(alertLevel_pke);
        Log.e("dataSend", status+"");
    }



    Timer timerPke = new Timer();
    TimerTask timerTaskPke = new TimerTask() {
        @Override
        public void run() {
            Message message = new Message();
            message.what = 1;
            handlerPke.sendMessage(message);
        }
    };
    Handler handlerPke = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){
                //do something
                if(mScanning)
                {
                    //the status is Scanning,check rssi > 90
                    //signal over 3 times
                    if(PkeRssiQualified > 3)
                    {
                        //Stop Scan and Connect PKE
                        mScanning = false;
                        mBluetoothAdapter.stopLeScan(mLeScanCallback);
                        connect(PkeMacAddr, PkeDevice);
                    }

                }else
                {
                    if(mConnectionState == STATE_CONNECTED)
                    {
                        dataSend();
                    }else
                    {
                        if(!mScanning)
                        {
                            mBluetoothAdapter.startLeScan(mLeScanCallback);     //start scan
                            PkeRssiQualified = 0;
                        }

                    }
                }


                Log.e("readCharacteristic", "handleMessage");
            }
            super.handleMessage(msg);
        }
    };


}

 

調用部分:

Intent gattServiceIntentPke = new Intent(this, PkeService.class);
        boolean bll = bindService(gattServiceIntentPke, mServiceConnectionPkeService,
                BIND_AUTO_CREATE);
        if (bll) {
            System.out.println("---------------");
        } else {
            System.out.println("===============");
        }

    private final ServiceConnection mServiceConnectionPkeService = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName,
                                       IBinder service) {
            mPkeService = ((PkeService.LocalBinder) service).getService();
            if (!mPkeService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }
            // Automatically connects to the device upon successful start-up
            // initialization.
            //mBluetoothLeService.connect(mDeviceAddress);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mPkeService.closePke();
            mPkeService = null;
        }
    };

 

 

設備掃描並將藍牙Mac地址存儲到本地,

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="xxxxxx.BindBluethothDevice2">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".BindBluetoothDevice">

        <LinearLayout
            android:id="@+id/BigLine"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@mipmap/bluebackground"
            android:orientation="vertical"
            app:layout_constraintBottom_toBottomOf="parent">

            <LinearLayout
                android:id="@+id/firstLineLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="top"
                android:orientation="horizontal">


                <ImageView
                    android:id="@+id/imageViewBcak"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@mipmap/title_back" />

                <TextView
                    android:id="@+id/textView45"
                    android:layout_width="wrap_content"
                    android:layout_height="44dp"
                    android:layout_weight="1"
                    android:text="藍牙硬件設備號"
                    android:textColor="@color/white"
                    tools:layout_width="wrap_content" />

                <TextView
                    android:id="@+id/mtvCommit"
                    android:layout_width="wrap_content"
                    android:layout_height="44dp"
                    android:layout_weight="1"
                    android:text="提交"
                    android:textColor="@color/white" />

            </LinearLayout>

            <LinearLayout
                android:id="@+id/secondLine"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:orientation="vertical"
                android:visibility="visible">

                <LinearLayout
                    android:id="@+id/second2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:visibility="visible">

                    <TextView
                        android:id="@+id/textView85"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="藍牙硬件號"
                        android:textColor="@color/white"
                        android:visibility="visible" />

                    <EditText
                        android:id="@+id/editTextUUID"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:ems="10"
                        android:inputType="textPersonName"
                        android:text="Name"
                        android:textColor="@color/white"
                        tools:text="請手輸或掃碼輸入硬件設備號" />

                    <ImageView
                        android:id="@+id/imageViewScan"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        app:srcCompat="@android:drawable/btn_star" />
                </LinearLayout>

            </LinearLayout>

            <LinearLayout
                android:id="@+id/infoContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:orientation="vertical">

                <View
                    android:id="@+id/lowersep"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#000000" />

                <TextView
                    android:id="@+id/tvItemCount"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="formatter_item_count"
                    android:textColor="@color/color2" />
            </LinearLayout>

            <LinearLayout
                android:id="@+id/listContainer"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_above="@id/infoContainer"
                android:layout_alignParentTop="true"
                android:orientation="vertical">

                <ListView
                    android:id="@+id/bluetoothListView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
            </LinearLayout>

        </LinearLayout>

    </android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class BindBluethothDevice2 extends AppCompatActivity  implements AdapterView.OnItemClickListener {
    //打開Preferences,名稱爲setting,如果存在則打開它,否則創建新的Preferences
    public SharedPreferences pkeUserSettings = null;
    @BindView(R.id.tvItemCount)
    protected TextView mTvItemCount;
    @BindView(R.id.mtvCommit)
    public TextView tvCommit;
    @BindView(R.id.editTextUUID)
    public EditText editInput;
    @BindView(R.id.bluetoothListView)
    public ListView mlstView;
    private final static String TAG = BindBluethothDevice2.class.getSimpleName();
    private BluetoothManager mBluetoothManager;
    private BluetoothAdapter mBluetoothAdapter;
    private String mBluetoothDeviceAddress;
    public final static int REQUEST_ENABLE_BT = 2001;

    List<HashMap<String,String>> data = new ArrayList<>();
    SimpleAdapter simpleAdapter;

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Log.e("onItemClick", data.get(position).get("text1") +"  "+ data.get(position).get("text2"));
        mBluetoothDeviceAddress = data.get(position).get("text2");
        editInput.setText(mBluetoothDeviceAddress);
    }

    //  Bluetooth PKE scan device callback function by Zhangkun on 2018-12-3
    private final BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
        //    Log.e("LeScanCallback-onLeScan", " "+device.toString()+ "rssi:"+rssi);

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    updateItemCount(rssi);

                    HashMap<String,String> map = new HashMap<>();
                    map.put("text1", device.getName());
                    map.put("text2", device.getAddress());
                    if(data.contains(map))
                    {
                        for(HashMap mhash : data)
                        {
                            if(mhash.equals(map))
                            {
                                //
                            }
                        }
                    }else
                    {
                        if(device.getName().isEmpty() || device.getAddress().isEmpty())
                        {
                            //do nothing
                        }else
                        {
                            data.add(map);
                        }
                    }

                }
            });
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bind_bluethoth_device2);
        ButterKnife.bind(this);
        pkeUserSettings = getSharedPreferences("PkeSetting", 0);
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        //判斷是否支持藍牙
        if (mBluetoothAdapter == null) {
            //不支持
            //    Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
            finish();
            return;
        }else
        {
            //打開藍牙
            if (!mBluetoothAdapter.isEnabled()) {//判斷是否已經打開
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        }
        simpleAdapter = new SimpleAdapter(BindBluethothDevice2.this,
                data,
                android.R.layout.simple_list_item_2, new String[]{"text1","text2"},
                new int[]{android.R.id.text1,android.R.id.text2});
        mlstView.setAdapter(simpleAdapter);
        mlstView.setOnItemClickListener(this);

    }
    //update rssi TextView by ZhangKun 2018-11-26
    private void updateItemCount(final int count) {
        mTvItemCount.setText(
                getString(
                        R.string.formatter_db,
                        String.valueOf(count)));
    }
    @Override
    protected void onResume()
    {
        super.onResume();
        mBluetoothAdapter.startLeScan(mLeScanCallback);
        Log.e(TAG, "onResume+ startLeScan");
    }

    @Override
    protected void onPause() {
        super.onPause();
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }

    @OnClick({R.id.infoContainer,R.id.tvItemCount, R.id.listContainer,
            R.id.imageViewBcak, R.id.mtvCommit})
    public  void OnClick(View v)
    {
        switch (v.getId())
        {
            case R.id.imageViewBcak:
                this.finish();
                break;
            case R.id.mtvCommit:
                SharedPreferences.Editor editor = pkeUserSettings.edit();
                Log.e("PkeMacAddr",  editInput.getText().toString());
                editor.putString("MacAddr", editInput.getText().toString());
                editor.commit();
                Toast.makeText(getApplicationContext(),"commit...",Toast.LENGTH_SHORT).show();
                try{Thread.sleep(500);}catch (Exception e){}
                this.finish();
                default:
                break;
        }
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章