I was following the code in this thread/post: Enable bluetooth tethering android programmatically (and subsequently, this post: How to check Bluetooth tethering status programmatically in Android ), and I encountered a roadblock. I'm using anirudh reddy's code. When I invoke the line

setTetheringOn.invoke(instance,true);

I get a NullPointerException. Here's the LogCat stack trace:

12-21 13:11:16.655: W/System.err(12738): java.lang.reflect.InvocationTargetException
12-21 13:11:16.655: W/System.err(12738):    at java.lang.reflect.Method.invoke(Native Method)
12-21 13:11:16.655: W/System.err(12738):    at java.lang.reflect.Method.invoke(Method.java:372)
12-21 13:11:16.655: W/System.err(12738):    at com.myname.android.bluetoothtetheringwidget.BluetoothTetheringActivity.turnBluetoothTetheringOn(BluetoothTetheringActivity.java:50)
12-21 13:11:16.655: W/System.err(12738):    at com.myname.android.bluetoothtetheringwidget.BluetoothTetheringActivity.onCreate(BluetoothTetheringActivity.java:27)
12-21 13:11:16.655: W/System.err(12738):    at android.app.Activity.performCreate(Activity.java:5933)
12-21 13:11:16.655: W/System.err(12738):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
12-21 13:11:16.655: W/System.err(12738):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
12-21 13:11:16.655: W/System.err(12738):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
12-21 13:11:16.656: W/System.err(12738):    at android.app.ActivityThread.access$800(ActivityThread.java:144)
12-21 13:11:16.656: W/System.err(12738):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
12-21 13:11:16.656: W/System.err(12738):    at android.os.Handler.dispatchMessage(Handler.java:102)
12-21 13:11:16.656: W/System.err(12738):    at android.os.Looper.loop(Looper.java:135)
12-21 13:11:16.656: W/System.err(12738):    at android.app.ActivityThread.main(ActivityThread.java:5221)
12-21 13:11:16.656: W/System.err(12738):    at java.lang.reflect.Method.invoke(Native Method)
12-21 13:11:16.656: W/System.err(12738):    at java.lang.reflect.Method.invoke(Method.java:372)
12-21 13:11:16.656: W/System.err(12738):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
12-21 13:11:16.656: W/System.err(12738):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
12-21 13:11:16.656: W/System.err(12738): Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void android.bluetooth.IBluetoothPan.setBluetoothTethering(boolean)' on a null object reference
12-21 13:11:16.656: W/System.err(12738):    at android.bluetooth.BluetoothPan.setBluetoothTethering(BluetoothPan.java:337)
12-21 13:11:16.656: W/System.err(12738):    ... 17 more

In my BluetoothTetheringActivity, my onCreate method calls turnBluetoothTetheringOn method.

Moving forward, I went into debug mode (I'm using Eclipse Luna), and discovered something interesting when I got into android.bluetooth.BluetoothPan.setBluetoothTethering method: the class variable mPanService was null. This is odd because the code explicitly uses the reference to mPanService. Here's the code in android.bluetooth.BluetoothPan.setBluetoothTethering:

public void setBluetoothTethering(boolean value) {
    if (DBG) log("setBluetoothTethering(" + value + ")");
    try {
        mPanService.setBluetoothTethering(value);
    } catch (RemoteException e) {
        Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
    }
}

I'm not certain how up-to-date this code is, but a site called grepcode.com has a page of BluetoothPan's code: android.bluetooth.BluetoothPan. In this code, mPanService is called mService.

How can I ensure the BluetoothPan's class variable mPanService is referencing an actual object before I try to invoke setBluetoothTethering?

I may not be asking the correct question, so any constructive criticism on rewording my question would be appreciated.

1

There are 1 answers

0
wei chen On

Based on Android source code: http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/bluetooth/BluetoothPan.java http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java

It is suggested to get Pan Proxy by

getProfileProxy@BluetoothAdapter
public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,int profile)

And pass your ServiceListener as parameter to receive following event:

(1)onServiceConnected

(2)onServiceDisconnected

When you are notified when onServiceConnected, mPanService will be set, or else, mPanServer will be null. And you can do your preferred action during onServiceConnected and onServiceDisconnected.

But notest that, there is defect in current Android source code. BluetoothPan will set mPanService as null prior to callback to your serviceListener when onServiceDisconnected is called, so it is possible that mPanService is null when you have done above items.