BLE与棒棒糖相连,但未与牛轧糖相连

时间:2018-08-24 15:23:49

标签: android bluetooth-lowenergy

我是android开发的新手,正在开发一个通过Uart服务将数据传输/接收到BLE模块的应用程序。

使用智能手机android 5.x.x,该应用程序可以正常运行,它可以与硬件连接并接收/传输数据。

使用智能手机android 7.x.x,该应用无法连接。 在下面,您可以看到MainActivity.java的代码段:

private final BroadcastReceiver UARTStatusChangeReceiver = new BroadcastReceiver() {

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

        final Intent mIntent = intent;
        //*********************//
        if (action.equals(UartService.ACTION_GATT_CONNECTED)) {
            runOnUiThread(new Runnable() {
                public void run() {
                    Log.d(TAG, "HW_CONNECT_MSG");

                    DisconnectButton.setEnabled(true);
                    DeviceInfo.setText("Device Information:");
                    DeviceName.setText(mDevice.getName() + " - Connected");
                    mState = UART_PROFILE_CONNECTED;

                    isConnected = true;

                    if(isConnected) {

                        //Serial protocol to send command on MCU
                        Connectcmd[0] = (byte) STX;
                        Connectcmd[1] = (byte) 0x02;
                        Connectcmd[2] = (byte) 0x43;      // 'C';
                        Connectcmd[3] = (byte) 0x54;      // 'T'
                        Connectcmd[4] = (byte) ETX;

                        try {
                            //send data to UART service
                            SendData(Connectcmd);
                            sleep(500);  // wait 500ms to send data

                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                        new Handler().postDelayed(mUpdateTimeTask, 2000);
                    }
                    else
                    {
                        isConnected = false;
                    }
                }
            });
        }

似乎在发送数据时,GATT操作尚未完成。由于action.equals(UartService.DEVICE_DOES_NOT_SUPPORT_BLE_UART),智能手机显示消息“设备不支持通过BLE的UART。正在断开连接...”。

如果我删除if(isConnected)... else ...语句,则具有Android 7.x.x的智能手机也将连接。 我的问题是怎么回事,该如何解决?

我的目标是通过BLE向硬件发送命令,以便在连接MCU时,蜂鸣器发出声音。

感谢您的帮助。

编辑

下面您可以找到整个MainActivity:

    public class MainActivity extends Activity implements RadioGroup.OnCheckedChangeListener {

    public static final String TAG = "DEBUG ";

    public static final String DEV_NAME_FILTER = "";

    private static final int REQUEST_SELECT_DEVICE = 1;
    private static final int REQUEST_ENABLE_BT = 2;
    private static final int UART_PROFILE_READY = 10;
    private static final int UART_PROFILE_CONNECTED = 20;
    public static final int UART_PROFILE_DISCONNECTED = 21;
    private static final int STATE_OFF = 10;

    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;

    TextView mRemoteRssiVal;
    RadioGroup mRg;
    private int mState = UART_PROFILE_DISCONNECTED;
    private static UartService mService = null;
    private static BluetoothDevice mDevice = null;
    private BluetoothAdapter mBtAdapter = null;
    private ListView messageListView;
    private ArrayAdapter<String> listAdapter;
    private Button SelectButton, DisconnectButton;
    private EditText edtMessage;
    private static Context context;
    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient client;

    private static TextView DeviceInfo;
    private static TextView DeviceName;
    private static TextView Manufacturer;

    public static boolean isConnected;
    public static boolean isSetting;
    public static boolean isReading;
    public static boolean isManual;
    public static boolean isFunctional;
    public static boolean isBootloader;


    public static byte[] SettingValues;
    public static byte[] ReadingValues;

    public static byte[] ManualValues;
    public static byte[] FunctionalValues;
    private static byte[] Connectcmd = new byte[5];

    public static int STX = 0x3E;  // '>'
    public static int ETX = 0x23;  // '#'

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DeviceInfo = (TextView) findViewById(R.id.deviceInfo);
        DeviceName = (TextView) findViewById(R.id.deviceName);
        Manufacturer= (TextView) findViewById(R.id.manufacturer);

        isConnected = false;
        isSetting = false;
        isReading = false;
        isManual = false;
        isFunctional = false;
        isBootloader = false;

        context = this;

        //Enable location
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // Android M Permission check
            if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("This app needs location access");
                builder.setMessage("Please grant location access so this app can detect beacons.");
                builder.setPositiveButton(android.R.string.ok, null);
                builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    @TargetApi(Build.VERSION_CODES.M)
                    public void onDismiss(DialogInterface dialog) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
                    }
                });
                builder.show();
            }
        }



        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBtAdapter == null) {
            Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
        SelectButton = (Button) findViewById(R.id.button);
        DisconnectButton = (Button) findViewById(R.id.disconnect);

        DisconnectButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                //Serial protocol to send command on MCU
                Connectcmd[0] = (byte) STX;
                Connectcmd[1] = (byte) 0x02;
                Connectcmd[2] = (byte) 0x44;      // 'D';
                Connectcmd[3] = (byte) 0x43;      // 'C'
                Connectcmd[4] = (byte) ETX;

                try {
                    //send data to Banner service
                    SendData(Connectcmd);
                    sleep(500);  // Wait 500ms to send data    
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    MainActivity.disconnected();
                    setContentView(R.layout.activity_main);
                    finish();
                } catch (Exception e) {
                    Log.e(TAG, "Disconnect error");
                }
            }
        });

        // Handle Select device button
        SelectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!mBtAdapter.isEnabled()) {
                    Log.i(TAG, "onClick - BT not enabled yet");
                    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
                } else {
                    if (SelectButton.getText().equals("SELECT CELU")) {

                        //Connect button pressed, open DeviceListActivity class, with popup windows that scan for devices
                        Log.i(TAG, "Push button CONNECT");
                        Intent newIntent = new Intent(context, DeviceListActivity.class);
                        ((Activity) context).startActivityForResult(newIntent, MainActivity.REQUEST_SELECT_DEVICE);
                    } else {
                        //Disconnect button pressed
                        disconnected();
                    }
                }
            }
        });

        // Set initial UI state

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
    }

    //UART service connected/disconnected
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder rawBinder) {
            mService = ((UartService.LocalBinder) rawBinder).getService();
            Log.d(TAG, "onServiceConnected mService= " + mService);
            if (!mService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }

        }

        public void onServiceDisconnected(ComponentName classname) {
            ////     mService.disconnect(mDevice);
            mService = null;
        }
    };

    private Handler mHandler = new Handler() {
        @Override

        //Handler events that received from UART service 
        public void handleMessage(Message msg) {

        }
    };

    private final BroadcastReceiver UARTStatusChangeReceiver = new BroadcastReceiver() {

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

            final Intent mIntent = intent;
            //*********************//
            if (action.equals(UartService.ACTION_GATT_CONNECTED)) {
                runOnUiThread(new Runnable() {
                    public void run() {
                        String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
                        Log.d(TAG, "CELU_CONNECT_MSG");
                        //btnConnectDisconnect.setText("Disconnect");
                        //edtMessage.setEnabled(true);
                        DisconnectButton.setEnabled(true);

                        DeviceInfo.setText("Device Information:");
                        DeviceName.setText(mDevice.getName() + " - Connected");
                        mState = UART_PROFILE_CONNECTED;

                        isConnected = true;

                        //IF COMMENTED THE APP CONNECTS!!!!!!!!!!!!!!!!!!
                        //ELSE IF NOT COMMENTED THE APP NEVER CONNECTS
                        /*if(isConnected) {

                            //Serial protocol to send command on MCU
                            Connectcmd[0] = (byte) STX;
                            Connectcmd[1] = (byte) 0x02;
                            Connectcmd[2] = (byte) 0x43;      // 'C';
                            Connectcmd[3] = (byte) 0x54;      // 'T'
                            Connectcmd[4] = (byte) ETX;

                            try {
                                //send data to UART service
                                SendData(Connectcmd);
                                sleep(500);  // Wait 500ms to send data

                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                            new Handler().postDelayed(mUpdateTimeTask, 2000);
                        }
                        else
                        {
                            isConnected = false;
                        }*/
                        new Handler().postDelayed(mUpdateTimeTask, 2000);

                    }
                });
            }

            //*********************//
            if (action.equals(UartService.ACTION_GATT_DISCONNECTED)) {
                runOnUiThread(new Runnable() {
                    public void run() {
                        Log.d(TAG, "HW_DISCONNECT_MSG");
                        DisconnectButton.setEnabled(false);
                        DeviceName.setText("Not Connected");

                        mState = UART_PROFILE_DISCONNECTED;
                        mService.close();
                        //setUiState();

                    }
                });
            }


            //Enable notifivcation on UART service//

            if (action.equals(UartService.ACTION_GATT_SERVICES_DISCOVERED)) {
                mService.enableTXNotification();
            }

            //*********************//
            if (action.equals(UartService.ACTION_DATA_AVAILABLE)) {

                final byte[] txValue = intent.getByteArrayExtra(UartService.EXTRA_DATA);

                try {
                        ParsingPacket(txValue);

                } catch (Exception e) {
                    Log.e(TAG, e.toString());
                }
            }



            //*********************//
            if (action.equals(UartService.DEVICE_DOES_NOT_SUPPORT_BLE_UART)) {
                showMessage("Device doesn't support UART over BLE Celu . Disconnecting");
                mService.disconnect();
            }


        }
    };


    private static void ParsingPacket(byte[] packet) throws Exception {

        if (packet.length == 0) {
            // received empty packet 
            isConnected = false;
            isSetting = false;
            isReading = false;
            isManual = false;
            isFunctional = false;
            isBootloader = false;
        }


        if(isSetting){

            isSetting = false;

            SettingValues = packet.clone();

            String text = new String(SettingValues, "UTF-8");
            Log.d(TAG, text);
        }

        if(isReading){

            ReadingValues= packet;

            ReadActivity.updateMeasure(ReadingValues);
            //ReadActivity.addData(packet);

            //String text = new String(ReadingValues, "UTF-8");

            Log.d("Length ", String.format("%02d", (int) ReadingValues.length));

            for(int i=0; i<ReadingValues.length; i++) {
                String text = String.format("%02x", (int) ReadingValues[i]);
                Log.d(TAG, text);
            }
        }

        if(isManual){

            isManual = false;

            ManualValues = packet.clone();

            String text = new String(ManualValues, "UTF-8");
            Log.d(TAG, text);
        }

        if(isFunctional){

            isFunctional = false;

            FunctionalValues = packet.clone();

            String text = new String(FunctionalValues, "UTF-8");
            Log.d(TAG, text);
        }

        if(isBootloader){

            isBootloader = false;

            // do samething
        }

    }

    private Runnable mUpdateTimeTask = new Runnable() {
        public void run() {
            if(DeviceName.getText()!="Not Connected") {
                Intent connectedIntent = new Intent(getApplicationContext(), MenuActivity.class); //new Intent("com.antertech.mybleapplication.MenuActivity");
                startActivity(connectedIntent);
            }
        }
    };

    private void service_init() {
        Intent bindIntent = new Intent(this, UartService.class);
        bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);

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

    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_BLE_UART);
        return intentFilter;
    }

    @Override
    public void onStart() {
        super.onStart();// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
        client.connect();
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        AppIndex.AppIndexApi.start(client, getIndexApiAction());
    }

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

        try {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(UARTStatusChangeReceiver);
        } catch (Exception ignore) {
            Log.e(TAG, ignore.toString());
        }
        unbindService(mServiceConnection);
        mService.stopSelf();
        mService = null;

    }

    @Override
    protected void onStop() {
        Log.d(TAG, "onStop");
        super.onStop();// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
        AppIndex.AppIndexApi.end(client, getIndexApiAction());
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client.disconnect();
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause");
        super.onPause();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, "onRestart");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
        if (!mBtAdapter.isEnabled()) {
            Log.i(TAG, "onResume - BT not enabled yet");
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        }

    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {

            case REQUEST_SELECT_DEVICE:
                //When the DeviceListActivity return, with the selected device address

                if (resultCode == Activity.RESULT_OK && data != null) {
                    String deviceAddress = data.getStringExtra(BluetoothDevice.EXTRA_DEVICE);
                    mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceAddress);

                    Log.d(TAG, "... onActivityResultdevice.address==" + mDevice + " mserviceValue " + mService);
                    mService.connect(deviceAddress);
                    //setContentView(R.layout.activity_setting);
                    ((TextView) findViewById(R.id.deviceName)).setText(mDevice.getName() + " - Connecting...");
                                    }
                break;
            case REQUEST_ENABLE_BT:
                // When the request to enable Bluetooth returns

                if (resultCode == Activity.RESULT_OK) {
                    Toast.makeText(this, "Bluetooth has turned on ", Toast.LENGTH_SHORT).show();

                } else {
                    // User did not enable Bluetooth or an error occurred
                    Log.d(TAG, "BT not enabled");
                    Toast.makeText(this, "Problem in BT Turning ON ", Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
            default:
                Log.e(TAG, "wrong request code");
                break;
        }
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {

    }

    public static void SendData(byte[] text) {
        mService.writeRXCharacteristic(text);
        Log.i(TAG, "Message send to Target");
    }


    public static void disconnected() {
        if (mDevice != null) {
            mService.disconnect();
            Log.i(TAG, "Push Button DISCONNECT");
        }
    }


    private void showMessage(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onBackPressed() {
        if (mState == UART_PROFILE_CONNECTED) {
            Intent startMain = new Intent(Intent.ACTION_MAIN);
            startMain.addCategory(Intent.CATEGORY_HOME);
            startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(startMain);
            showMessage("CELU TPE running in background.\n             Disconnect to exit");
        } else {
            new AlertDialog.Builder(this)
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .setTitle(R.string.popup_title)
                    .setMessage(R.string.popup_message)
                    .setPositiveButton(R.string.popup_yes, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    })
                    .setNegativeButton(R.string.popup_no, null)
                    .show();
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[],
                                           int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_COARSE_LOCATION: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "coarse location permission granted");
                } else {
                    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("Functionality limited");
                    builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
                    builder.setPositiveButton(android.R.string.ok, null);
                    builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                        @Override
                        public void onDismiss(DialogInterface dialog) {
                        }
                    });
                    builder.show();
                }
                return;
            }
        }
    }


    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    public Action getIndexApiAction() {
        Thing object = new Thing.Builder()
                .setName("Main Page") // TODO: Define a title for the content shown.
                // TODO: Make sure this auto-generated URL is correct.
                .setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
                .build();
        return new Action.Builder(Action.TYPE_VIEW)
                .setObject(object)
                .setActionStatus(Action.STATUS_TYPE_COMPLETED)
                .build();
    }
}

0 个答案:

没有答案