简体   繁体   中英

Android bluetooth connection fails on the first try

I'm developing two bluetooth apps, both are based on the bluetoothChat sample but one of them is also able to send/receive data from a microcontroller using the USB Accessory mode. These apps run on two different devices, a Nexus 4 and a V301 (a chinese phone). In general everything works fine, the problem is just that on the first try the two devices are not able to make a bluetooth connection. The bluetoothChat app is simply not able to make a connection, the other app (BT+USB) stops and crashes if I try to make a connection. The thing is though, after this crash, everything works fine and I'm able to eventually make a connection from both the two apps. Here are the two android manifest and the error that comes out when the BT+USB app crashes.

The error displayed by the Eclipse console:

06-24 12:40:10.090: W/dalvikvm(5886): threadid=1: thread exiting with uncaught exception (group=0x40a98390)
06-24 12:40:10.110: E/AndroidRuntime(5886): FATAL EXCEPTION: main
06-24 12:40:10.110: E/AndroidRuntime(5886): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { (has extras) }} to activity {com.example.bluetoothx10y/com.example.bluetoothx10y.BluetoothChat}: java.lang.NullPointerException
06-24 12:40:10.110: E/AndroidRuntime(5886):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2988)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3031)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at android.app.ActivityThread.access$1100(ActivityThread.java:126)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1185)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at android.os.Looper.loop(Looper.java:137)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at android.app.ActivityThread.main(ActivityThread.java:4482)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at java.lang.reflect.Method.invokeNative(Native Method)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at java.lang.reflect.Method.invoke(Method.java:511)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at dalvik.system.NativeStart.main(Native Method)
06-24 12:40:10.110: E/AndroidRuntime(5886): Caused by: java.lang.NullPointerException
06-24 12:40:10.110: E/AndroidRuntime(5886):     at com.example.bluetoothx10y.BluetoothChat.onActivityResult(BluetoothChat.java:537)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at android.app.Activity.dispatchActivityResult(Activity.java:4649)
06-24 12:40:10.110: E/AndroidRuntime(5886):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2984)
06-24 12:40:10.110: E/AndroidRuntime(5886):     ... 11 more

The android manifest of the BT+USB app (called bluetoothx10y):

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.bluetoothx10y"
    android:versionCode="1"
    android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="9"
    android:targetSdkVersion="15" />

<uses-feature android:name="android.hardware.usb.accessory"/>
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name="com.example.bluetoothx10y.BluetoothChat"
        android:label="@string/app_name"
        android:screenOrientation="landscape" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter>
           <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"/>
        </intent-filter>

        <meta-data 
            android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
            android:resource="@xml/accessory_filter">
        </meta-data>

    </activity>

    <activity android:name=".DeviceListActivity"
          android:label="@string/app_name"
          android:theme="@android:style/Theme.Dialog"
          android:screenOrientation="landscape" />

</application>
</manifest>

The android manifest of the BT app (called BluetoothChat):

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.BluetoothChat"
     android:versionCode="1"
     android:versionName="1.0">

<uses-sdk
    android:minSdkVersion="6"
    android:targetSdkVersion="9" />

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />

<application android:label="@string/app_name"
             android:icon="@drawable/app_icon" >
    <activity android:name=".BluetoothChat"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".DeviceListActivity"
              android:label="@string/select_device"
              android:theme="@android:style/Theme.Dialog" />
</application>
</manifest>

At line 536 and 537 I have:

mBluetoothAdapter.getRemoteDevice(address); // Attempt to connect to the device      
mChatService.connect(device); 

mChatService is an object of the class responsible for setting up and managing the Bluetooth connection

public synchronized void connect(BluetoothDevice device) {
    if (D) Log.d(TAG, "connect to: " + device);

    // Cancel any thread attempting to make a connection
    if (mState == STATE_CONNECTING) {
        if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
    }

    // Cancel any thread currently running a connection
    if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

    // Start the thread to connect with the given device
    mConnectThread = new ConnectThread(device);
    mConnectThread.start();
    setState(STATE_CONNECTING);
}

Based on your code, the mChatService == null this is what causes the NullPointerException. You should take care about initializing it before usage. If nothing else, use lazy initialization for the field. However, I'd suggest you try to design your code to have as many final fields as possible. Initialize everything you need in the constructor of the object and not try to change their values. Introducing mutable state with mutable (settable) fields will increase the complexity of your code and make it really hard to debug. Especially in multithreaded applications.

Note: for future issues, it is very useful that you learn to read stack traces. This may be a good article to start with http://marxsoftware.blogspot.hu/2010/10/reading-java-stack-traces-few-tips.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM