Bluetooth Gatt Low Energy无法正常工作

时间:2015-10-13 08:56:50

标签: android bluetooth gatt

我正在使用Gatt协议向北欧设备发送一些数据,如果我从onCreate内部调用函数初始化,则控件返回onServiceConnected,但是如果我从onClick内部调用函数初始化,则控件不会来对于回调函数onServiceConnecdted,我无法找到原因。如果有人在此之前遇到过这样的问题,请详细说明这个问题。

package com.evobi.bisoft.io;
import java.io.OutputStream;
import java.util.UUID;
import com.evobi.bisoft.BaseActivity;
import com.evobi.bisoft.R;
import com.evobi.bisoft.io.bluetooth.SettingsActivity;
import com.evobi.bisoft.io.bluetooth.UartService;
import android.app.ActionBar;
import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

/**
 * 
 * @author Sreekanth
 * Sends remote data to the bibox over bluetooth. 
 * The remote contains an up,down,left,right. A slider, a keypad.
 * Protocol - For any key press send  'B' first then the associated key value.
 *          - For any slider movement 'S' first then the associated slider value.
 * 
 */
public class BlueToothRemoteActivity extends BaseActivity {
    //Arrow control buttons...
    Button mRightArrowBtn,mLeftArrowBtn,mUpArrowBtn,mDownArrowBtn;
    //KeyPad buttons declared...
    Button mKeyPad0Btn,mKeyPad1Btn,mKeyPad2Btn,mKeyPad3Btn,mKeyPad4Btn,mKeyPad5Btn,mKeyPad6Btn,mKeyPad7Btn,mKeyPad8Btn,mKeyPad9Btn,mKeyPadSBtn,mKeyPadEBtn;
    //
    SeekBar  mBtSliderSeekBar;
    TextView mBtSliderSeekBarTv;

    private String mDeviceMACAddress;
    private byte[] mSendArray;
    // Bluetooth Stuff
    private BluetoothAdapter mBluetoothAdapter          =   null;
    private static final int MAX_ALLOWED_PAIRED_DEVICES =   3;
    private static  UUID SPP_UUID                       =   UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private OutputStream mOutStream                     =   null;
    private Handler mHandler;
    private Toast mFailToast ;  

    private boolean mConnectStatus                      =   false;
    private boolean mConnectionStatus2                  =   false;
    private static final int REQUEST_ENABLE_BT          =   2;

    private static final int REQUEST_CONNECT_DEVICE     =   1;
    private String mDeviceAddress                       =   null;

    private boolean mIsInitialized;

    private ProgressDialog mProgressDialog;

    private UartService mService                =   null;
    private boolean mIsConnected;
    private byte[] mCurrentData                 =   null;

    private String mDeviceBtAddress;



    private static final int UART_PROFILE_DISCONNECTED  = 21;
    private static final int UART_PROFILE_CONNECTED     = 20;
    private int mState = UART_PROFILE_DISCONNECTED;


    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        switch (requestCode) {
        case REQUEST_CONNECT_DEVICE:
            // When DeviceListActivity returns with a device to connect
            if (resultCode == Activity.RESULT_OK) {
                // Get the device MAC address
                this.mDeviceAddress = data.getExtras().getString(SettingsActivity.EXTRA_DEVICE_ADDRESS);
                // Connect to device with specified MAC address

            } else {
                // Failure retrieving MAC address
                Toast.makeText(this, R.string.macFailed, Toast.LENGTH_SHORT).show();
            }
            break;
        case REQUEST_ENABLE_BT:
            // When the request to enable Bluetooth returns
            if (resultCode == Activity.RESULT_OK) {

            } else {
                // User did not enable Bluetooth or an error occured
                // Toast.makeText(this, R.string.bt_not_enabled_leaving,
                // Toast.LENGTH_SHORT).show();
                this.finish();
            }
        }
    }

    @Override
    protected void onStop(){


        super.onStop();
    }

    @Override
     protected void onCreate(final Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            this.getActionBar().setIcon(R.drawable.ic_bt_remote);
            this.getActionBar().setTitle("Bluetooth Remote");

            getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); 
            getActionBar().setCustomView(R.layout.actionbar_bt_remote);

            this.setContentView(R.layout.layout_bt_remote);

            this.mIsConnected   =   false;

            this.mIsInitialized =   false;

            byte[] sliderData       =   new byte[2];
            sliderData[0]           =   (byte) 'B';
            sliderData[1]           =   (byte) 'R';

            mCurrentData            =   sliderData;

            //Navigation arrow buttons initialisation..
            mRightArrowBtn  =   (Button) findViewById(R.id.id_bt_remote_right_button);
            mLeftArrowBtn   =   (Button) findViewById(R.id.id_bt_remote_left_button);
            mDownArrowBtn   =   (Button) findViewById(R.id.id_bt_remote_down_button);
            mUpArrowBtn     =   (Button) findViewById(R.id.id_bt_remote_up_button);

            //KeyPad Buttons initialisation...
            mKeyPad0Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_0);
            mKeyPad1Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_1);
            mKeyPad2Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_2);
            mKeyPad3Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_3);
            mKeyPad4Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_4);
            mKeyPad5Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_5); 
            mKeyPad6Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_6);
            mKeyPad7Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_7);
            mKeyPad8Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_8);
            mKeyPad9Btn     =   (Button) findViewById(R.id.id_bt_remote_keypad_9);
            mKeyPadSBtn     =   (Button) findViewById(R.id.id_bt_remote_keypad_s);
            mKeyPadEBtn     =   (Button) findViewById(R.id.id_bt_remote_keypad_e); 

            //SeekBar intialised...
            mBtSliderSeekBar            =   (SeekBar)findViewById(R.id.id_bt_remote_seek_bar);
            mBtSliderSeekBarTv          =   (TextView)findViewById(R.id.id_seek_bar_progress_tv);


            //SeekBar definition...
            mBtSliderSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                    byte[] sliderData       =   new byte[2];
                    sliderData[0]           =   (byte) 'S';
                    sliderData[1]           =   (byte) seekBar.getProgress();
                    mCurrentData            =   sliderData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);               
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onProgressChanged(SeekBar seekBar, int progress,
                        boolean fromUser) {
                    //Let the textview show the seekbar progress..
                    mBtSliderSeekBarTv.setText(String.valueOf(progress));

                }
            });

            //Arrow buttons...
            mRightArrowBtn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] rightArrowData       =   new byte[2];
                    rightArrowData[0]           =   (byte) 'B';
                    rightArrowData[1]           =   (byte) 'r';
                    mCurrentData                =   rightArrowData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);


                }
            });

            mLeftArrowBtn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] leftArrowData        =   new byte[2];
                    leftArrowData[0]            =   (byte) 'B';
                    leftArrowData[1]            =   (byte) 'l';
                    mCurrentData                =   leftArrowData;


                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);

                }
            });

            mDownArrowBtn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    byte[] downArrowData        =   new byte[2];
                    downArrowData[0]            =   (byte) 'B';
                    downArrowData[1]            =   (byte) 'd';

                    mCurrentData                =   downArrowData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);
                }
            });
            mUpArrowBtn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    byte[] upArrowData      =   new byte[2];
                    upArrowData[0]          =   (byte) 'B';
                    upArrowData[1]          =   (byte) 'u';

                    mCurrentData            =   upArrowData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);
                }
            });


            //KeyPad Buttons...
            mKeyPad0Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '0';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);
                }
            });

            mKeyPad1Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {   

                    initializeConnection();

                    do{

                    }while(!mIsInitialized);

                    mIsConnected            =   mService.connect(mDeviceBtAddress);

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '1';

                    mCurrentData            =   keyPadData;


                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    boolean writeStatus =   mService.writeRXCharacteristic(mCurrentData);

                    do{

                    }while(!writeStatus);

                    try {
                        LocalBroadcastManager.getInstance(v.getContext()).unregisterReceiver(UARTStatusChangeReceiver);
                    } catch (Exception ignore) {
                        Log.e("TAG", ignore.toString());
                    } 

                    Intent bindIntent   =   new Intent(getApplicationContext(), UartService.class);
                    boolean isBound     =   getApplicationContext().bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);

                    if(isBound)
                        getApplicationContext().unbindService(mServiceConnection);

                    if(mService!=null)
                        mService.stopSelf();
                    mService= null;
                }
            });

            mKeyPad2Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '2';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);
                }
            });

            mKeyPad3Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '3';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);
                }
            });

            mKeyPad4Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '4';

                    mCurrentData            =   keyPadData; 

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);
                }
            });

            mKeyPad5Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '5';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);
                }
            });


            mKeyPad6Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '6';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);
                }
            });

            mKeyPad7Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '7';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);
                }
            });

            mKeyPad8Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '8';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);

                }
            });

            mKeyPad9Btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) '9';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);

                }
            });

            mKeyPadSBtn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) 'S';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);

                }
            });

            mKeyPadEBtn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    byte[] keyPadData       =   new byte[2];
                    keyPadData[0]           =   (byte) 'B';
                    keyPadData[1]           =   (byte) 'E';

                    mCurrentData            =   keyPadData;

                    do{
                        //Wait till initialization is over.
                    }while(!mIsConnected);

                    //Now initialization is over.
                    mService.writeRXCharacteristic(mCurrentData);



                }
            });

            initializeConnection();
     }

    /*
     * Gets the mac id of the saved device...
     * 
     * @return macId
     *              returns the mac id of the saved device.
     *              if no device saved, returns null.
     */
    private String getSavedDeviceMadId(){
        SharedPreferences pref  =   PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        String macId            =   pref.getString("BL", "bl");
        if(!macId.equals("bl"))
            return macId;
        else
            return null;
    }

    /**
     * Saves the saved device mac id to mDeviceMACid, if not found shows a toast message.
     * Sets the bluetooth adapter to mBluetoothAdapter, if not success, then sets shows a toast.
     */
    private void initializeConnection(){

        //If some device has been saved...
        String macId    =   getSavedDeviceMadId();
        if(macId != null){

//          mProgressDialog = ProgressDialog.show(this, "Connecting...",
//                  "Please wait while initializing the connection.", true);
//          mProgressDialog.show();

            service_init();

            //Save mac id to the mDeviceMacAddress...
            this.mDeviceMACAddress         =   getSavedDeviceMadId();

            this.mBluetoothAdapter         =   BluetoothAdapter.getDefaultAdapter();

            if (this.mBluetoothAdapter == null) {
                Toast.makeText(this, R.string.no_bt_device, Toast.LENGTH_LONG).show();
                this.finish();
                return;
            }

        }else{
            //No device saved...
            showToast(getString(R.string.save_device_message), true);
        }
    }
    @Override
    public void onBackPressed(){

        super.onBackPressed();
        Log.d("TAG", "onBackPressed");

        try {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(UARTStatusChangeReceiver);
        } catch (Exception ignore) {
            Log.e("TAG", ignore.toString());
        } 

        Intent bindIntent   =   new Intent(getApplicationContext(), UartService.class);
        boolean isBound     =   getApplicationContext().bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);

        if(isBound)
            getApplicationContext().unbindService(mServiceConnection);

        if(mService!=null)
            mService.stopSelf();
        mService= null;

    }

    @Override
    public void onDestroy() {
         super.onDestroy();
        Log.d("TAG", "onDestroy()");

        try {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(UARTStatusChangeReceiver);
        } catch (Exception ignore) {
            Log.e("TAG", ignore.toString());
        } 

        Intent bindIntent   =   new Intent(getApplicationContext(), UartService.class);
        boolean isBound     =   getApplicationContext().bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);

        if(isBound)
            getApplicationContext().unbindService(mServiceConnection);

        if(mService!=null)
            mService.stopSelf();
        mService= null;
    }

     /**
     * Initializes the service.
     */
    private void service_init() {
        Intent bindIntent = new Intent(this, UartService.class);
        getApplicationContext().bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);

        LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(UARTStatusChangeReceiver, makeGattUpdateIntentFilter());
    }

    /**
     * Updates the gatt intent filter.
     */
    private static IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(UartService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(UartService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(UartService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(UartService.ACTION_DATA_AVAILABLE);
        intentFilter.addAction(UartService.DEVICE_DOES_NOT_SUPPORT_UART);
        return intentFilter;
    }

    private final BroadcastReceiver UARTStatusChangeReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

           /**
            * If connected, then set the state.
            */
            if (action.equals(UartService.ACTION_GATT_CONNECTED)) {
                 runOnUiThread(new Runnable() {
                     public void run() {
                         mState = UART_PROFILE_CONNECTED;
                     }
                 });
            }


            /**
             * If disconnected then set the state accordingly.
             */
            if (action.equals(UartService.ACTION_GATT_DISCONNECTED)) {
                 runOnUiThread(new Runnable() {
                     public void run() {
                             Log.d("TAG", "UART_DISCONNECT_MSG");
                             mState = UART_PROFILE_DISCONNECTED;
                             if(mService!=null)
                             mService.close();


                     }
                 });
            }

            if (action.equals(UartService.ACTION_GATT_SERVICES_DISCOVERED)) {
                 if(mService.getBluetoothGatt()!=null)
                     mService.enableTXNotification();
                 Log.d("tag", "action gatt services discovered");
            }
          //*********************//
            if (action.equals(UartService.ACTION_DATA_AVAILABLE)) {
              Log.d("tag", "action data available");

             }
           //*********************//
            if (action.equals(UartService.DEVICE_DOES_NOT_SUPPORT_UART)){
                Log.d("tag", "device dont support uart");
            }            
        }
    };

    //UART service connected/disconnected
    private ServiceConnection mServiceConnection = new ServiceConnection() {

        boolean isBound;
        boolean isWriteStatus;
        public void onServiceConnected(ComponentName className, IBinder rawBinder) {

//              mProgressDialog.dismiss();
                mService = ((UartService.LocalBinder) rawBinder).getService();

                final SharedPreferences pre =   PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                //Get the device mac address...
                mDeviceBtAddress            =   pre.getString("BL", "");

                Log.d("TAG", "onServiceConnected mService= " + mService);
                if (!mService.initialize()) {
                    Log.e("TAG", "Unable to initialize Bluetooth");
                    finish();
                }                            

                mIsConnected    =   mService.connect(mDeviceBtAddress);

                mIsInitialized  =   true;
         }

        public void onServiceDisconnected(ComponentName classname) {
                mService = null;
        }
    };
}

0 个答案:

没有答案