Android BLE BroadcastReceiver无法在4.4.2上运行

时间:2015-12-07 02:32:59

标签: android android-intent bluetooth bluetooth-lowenergy

我正在开发一个Android应用程序。这就是我所拥有的。

public class DeviceControlActivity extends AppCompatActivity {

    public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
    public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
    private final static String TAG = DeviceControlActivity.class.getSimpleName();
    public static DeviceControlActivity deviceControlActivity = null;

    public TextView mConnectionState;
    private TextView mDataField;
    private String mDeviceName;
    private String mDeviceAddress;
    private ExpandableListView mGattServicesList;
    private BluetoothLeService mBluetoothLeService;
    // Code to manage Service lifecycle. 
    private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.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) {
            mBluetoothLeService = null;
        }
    };
    private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
            new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
    private boolean mConnected = false;
    // Handles various events fired by the Service. 
    // ACTION_GATT_CONNECTED: connected to a GATT server. 
    // ACTION_GATT_DISCONNECTED: disconnected from a GATT server. 
    // ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services. 
    // ACTION_DATA_AVAILABLE: received data from the device.  This can be a result of read 
    //                        or notification operations. 
    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            Log.i(TAG, "IN BROADCASTRECEIVER");
            Log.d(TAG, action);
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                Log.d(TAG, "ACTION_GATT_CONNECTED");
                mConnected = true;
                updateConnectionState(R.string.connected);
                invalidateOptionsMenu();
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                Log.d(TAG, "ACTION_GATT_DISCONNECTED");
                mConnected = false;
                updateConnectionState(R.string.disconnected);
                invalidateOptionsMenu();
                clearUI();
            } else if (!"android.bluetooth.device.action.FOUND".equals(action)) {
                Log.d(TAG, "android.bluetooth.device.action.FOUND");
                if (!"android.bluetooth.adapter.action.DISCOVERY_FINISHED".equals(action)) {
                    Log.d(TAG, "android.bluetooth.device.action.DISCOVERY_FINISHED " + action);
                    Log.d(TAG, "BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action): " + BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action));
                    if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                        Log.d(TAG, "ACTION_DATA_AVAILABLE");
                        String result = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
                        if (result != null) {
                            System.out.println(result);
                        }
                    } else if (BluetoothLeService.ACTION_GATT_HM_RX_TX.equals(action)) {
                        Log.d(TAG, "ACTION_GATT_HM_RX_TX");
                        Toast.makeText(DeviceControlActivity.this, "Serial port aval", Toast.LENGTH_SHORT).show();
                    }
                }
            } else {
                Log.e(TAG, "error: " + action);
            }
        }
    };

    private BluetoothGattCharacteristic mNotifyCharacteristic;
    // If a given GATT characteristic is selected, check for supported features.  This sample 
    // demonstrates 'Read' and 'Notify' features.  See 
    // http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete 
    // list of supported characteristic features. 
    private final ExpandableListView.OnChildClickListener servicesListClickListner =
            new ExpandableListView.OnChildClickListener() {
                @Override
                public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
                                            int childPosition, long id) {
                    Log.d("readCharacteristic", "INSIDE");
                    if (mGattCharacteristics != null) {
                        final BluetoothGattCharacteristic characteristic =
                                mGattCharacteristics.get(groupPosition).get(childPosition);
                        final int charaProp = characteristic.getProperties();
                        if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                            // If there is an active notification on a characteristic, clear 
                            // it first so it doesn't update the data field on the user interface. 
                            if (mNotifyCharacteristic != null) {
                                mBluetoothLeService.setCharacteristicNotification(
                                        mNotifyCharacteristic, false);
                                mNotifyCharacteristic = null;
                            }
                            Log.d("readCharacteristic", "READ");
                            mBluetoothLeService.readCharacteristic(characteristic);
                        }
                        if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                            mNotifyCharacteristic = characteristic;
                            mBluetoothLeService.setCharacteristicNotification(
                                    characteristic, true);
                        }
                        return true;
                    }
                    return false;
                }
            };

    private static IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_HM_RX_TX);
        intentFilter.addAction("android.bluetooth.device.action.ACL_CONNECTED");
        intentFilter.addAction("android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED");
        intentFilter.addAction("android.bluetooth.device.action.ACL_DISCONNECTED");
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_IS_SERVICE_AVAILABLE);
        return intentFilter;
    }

    private void clearUI() {
        mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
        mDataField.setText(R.string.no_data);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gatt_services_characteristics);
        Log.i(TAG, "onCreate");
        final Intent intent = getIntent();
        mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
        mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);

        // Sets up UI references. 
        ((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);
        mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
        mGattServicesList.setOnChildClickListener(servicesListClickListner);
        mConnectionState = (TextView) findViewById(R.id.connection_state);
        mDataField = (TextView) findViewById(R.id.data_value);

        Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
        bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume");
        deviceControlActivity = this;
        registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
        if (mBluetoothLeService != null) {
            final boolean result = mBluetoothLeService.connect(mDeviceAddress);
            Log.d(TAG, "Connect request result=" + result);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
        unregisterReceiver(mGattUpdateReceiver);
        deviceControlActivity = null;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);
        mBluetoothLeService.close();
        mBluetoothLeService = null;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.gatt_services, menu);
        if (mConnected) {
            menu.findItem(R.id.menu_connect).setVisible(false);
            menu.findItem(R.id.menu_disconnect).setVisible(true);
        } else {
            menu.findItem(R.id.menu_connect).setVisible(true);
            menu.findItem(R.id.menu_disconnect).setVisible(false);
        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_connect:
                mBluetoothLeService.connect(mDeviceAddress);
                return true;
            case R.id.menu_disconnect:
                mBluetoothLeService.disconnect();
                return true;
            case android.R.id.home:
                onBackPressed();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void updateConnectionState(final int resourceId) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mConnectionState.setText(resourceId);
            }
        });
    }
}

在BluetoothLeService中,我有:

public static final String ACTION_GATT_HM_RX_TX = "com.example.bluetooth.le.ACTION_GATT_HM_RX_TX";
public static final String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public static final String ACTION_GATT_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public static final String ACTION_GATT_SERVICES_DISCOVERED = "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public static final String ACTION_DATA_AVAILABLE = "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public static final String EXTRA_DATA = "com.example.bluetooth.le.EXTRA_DATA";
public static final String ACTION_GATT_IS_SERVICE_AVAILABLE = "com.example.bluetooth.le.ACTION_GATT_SERVICE_AVAILABLE";

当我的具有API 4.4.4的S3手机正常工作但我的带有API 4.4.2的平板电脑Galaxy Tab 4和带有5.0的S5手机无法正常工作时出现问题。 BroadcastReceiver与S3配合良好,并在BLE设备发送数据时接收数据。对于其他设备,BroadcastReceiver仅在连接到BLE(ACTION_GATT_CONNECTED)时触发一次,但之后没有任何内容。当它与BLE(ACTION_GATT_DISCONNECTED)断开连接时,它会触发另一个。甚至没有Log.i(TAG, "IN BROADCASTRECEIVER");被召唤。 BLE设备是HM-10组件。

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。问题是我的BluetoothLeCallback没有正确实现。一旦我重新实现了i,它现在适用于18岁及以上的所有Android版本。

干杯。