无法在 Android 上初始化 UART 服务

Cannot initialize UART service on Android

我正在开发使用 UART 的传感器的移动应用程序。 official github page 中的示例工作完美,但从中提取的代码不起作用。我唯一改变的是设备搜索,但此代码与 Polar H7 设备完美配合(仅发现设备名称和设备地址并发送到下一个 activity)。在这个 activity 上,我正在尝试连接到 UART 设备,这里是代码:

public class UartRecordingActivity extends AppCompatActivity {

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

    // BLE stuff
    public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
    public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";


    //private BleService bleService;

    private String deviceName;
    private String deviceAddress;

    //private BleServicesAdapter gattServiceAdapter;

    private boolean isConnected = false;



    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;
    private static final int UART_PROFILE_DISCONNECTED = 21;
    private static final int STATE_OFF = 10;
    private int mState = UART_PROFILE_DISCONNECTED;

    private UartService mService = null;
    private BluetoothDevice mDevice = null;
    private BluetoothAdapter mBtAdapter = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recording_uart);

        Log.i(TAG, "onCreate");

        final Intent intent = getIntent();
        deviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
        deviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);

        final Intent gattServiceIntent = new Intent(this, UartService.class);
        bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);

    }

    @Override
    protected void onStart() {
        super.onStart();

        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
        service_init();

        mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceAddress);
        mService.connect(deviceAddress);
    }

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

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

    //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 = null;
        }
    };


    @Override
    public boolean onOptionsItemSelected(MenuItem menuItem) {
        if (menuItem.getItemId() == android.R.id.home) {
            Intent intent = new Intent(this, HomeActivity.class);
            startActivity(intent);
        }
        return super.onOptionsItemSelected(menuItem);}

private final BroadcastReceiver UARTStatusChangeReceiver = new BroadcastReceiver() {
    @Override
    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, "UART_CONNECT_MSG");

                    mState = UART_PROFILE_CONNECTED;
                }
            });
        }

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

            runOnUiThread(new Runnable() {
                public void run() {
                    String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
                    Log.d(TAG, "UART_DISCONNECT_MSG");
                    mState = UART_PROFILE_DISCONNECTED;
                    mService.close();
                }
            });
        }

        //*********************//
        if (action.equals(UartService.ACTION_GATT_SERVICES_DISCOVERED)) {
            mService.enableTXNotification();
        }
        //*********************//
        if (action.equals(UartService.ACTION_DATA_AVAILABLE)) {
            Log.i("data","received");
            final byte[] txValue = intent.getByteArrayExtra(UartService.EXTRA_DATA);
            //handle data
        }
        //*********************//
        if (action.equals(UartService.DEVICE_DOES_NOT_SUPPORT_UART)) {
        }

    }
};




    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;
    }
}

错误是由这一行引起的(mService causing NullPointerException):

mService.connect(deviceAddress);

OnServiceConnected 方法保证您已通过绑定连接到服务。在 OnStart 回调中你有 NullPointer,因为当你调用 bindService 时,它​​需要一点时间来建立连接。把你的代码写成这样:

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();
    }
    mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceAddress);
    mService.connect(deviceAddress);
}