1

私は、Bluetooth ディスカバリをかなり多用するアプリに取り組んでいます (詳細はこちら)。このアプリの性質上、BT を常にオンにしておいて、一部のブロードキャスト デバイスから BT 名が変更されるのを待っています。私のデバイスは常に充電されているので、電力使用量は問題ではありません。

BT がオンになっていて、範囲内にデバイスがある場合でも、特定の時間にアプリが「スレッドを失い」、BT で何も検出されないことがわかりました。手動で、デバイスの BT をオフにしてからオンにすることでこれを解決できます。それは再び動作します。だから私はこれをコードでやりたかったのです。メッセージをハンドラーに送信するタイムアウトタイマー全体があります。

        bluetoothHandler = new Handler() {
        @Override
        public void  handleMessage(Message msg) {
            if (!btAdapter.isDiscovering())
            {
                btAdapter.disable();
                btAdapter.enable();
                btAdapter.startDiscovery();
                // some other stuff
            }

さて、このコードは「disable」行でヌルポインタ例外で時々クラッシュするようです

ACRA の情報は次のとおりです。

"java.lang.NullPointerException
    at android.os.Parcel.readException(Parcel.java:1328)
    at android.os.Parcel.readException(Parcel.java:1276)
    at android.bluetooth.IBluetooth$Stub$Proxy.disable(IBluetooth.java:604)
    at android.bluetooth.BluetoothAdapter.disable(BluetoothAdapter.java:562)
    at com.myapp.stuff.MainActivity$8.handleMessage(MainActivity.java:574)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3687)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)

ご覧のとおり、btAdapter が実際に null であることは意味がありません。そうしないと、前の行 (「if」) でクラッシュしたことになります。コードが再入可能であると仮定しても、btAdapter を null にすることはありません。私のコードはいつでも - OnCreate に設定して永遠にそのままにしておくので、どうすれば null になりますか?

NullPointerException が有効化/無効化されたコードを実行しているという投稿を見た人が何人かいます。また、Intents を使用して Bluetooth を開始/停止することを提案しています。これはここではオプションではありません。ユーザーの介入はありません。特別なアプリが機能するためには、BT が自動的に実行されている必要があります (正しく実行されていない場合は修正されます)。

NullPointerException の周りに try/catch を配置できないと仮定しています (それは偽物ですが) - Bluetooth の内部構造について十分に知っている人はいますか?

4

3 に答える 3

0

何がうまくいかなかったのかよくわかりませんが、私の修正はかなり単純でばかげていました。

btAdapter の 1 つの値を残す代わりに、使用する前に毎回チェックし、例外を試行/キャッチします (ただし、これは REAL ヌル ポインターをキャプチャしないと想定しています)。

したがって、無効にするたびに(クラッシュしていました)、これを行います

                btAdapter = BluetoothAdapter.getDefaultAdapter();
                if (null == btAdapter)
                {
                    Log.e(LOG_TAG,"Bluetooth adapter is NULL!!!");
                    return;
                }
                try {
                    btAdapter.disable();
                }
                catch (Exception e) {
                    //don't do anything
                }
于 2012-06-18T10:26:36.383 に答える
0

disableメソッド内で発生しています。ファイルBluetoothAdapter.javaのAndroidソースコードの読み取り、562行目は、この問題の原因を理解するのに役立ちます。

于 2012-05-30T20:12:33.177 に答える
0

たとえば assertNotNull( btAdapter ) のように、handleMessage 関数の最初の行にアサーションを配置する必要があると思います。 Assertのドキュメントは次のとおりです。少なくともそのようにして、btAdapter が実際には null ではないことが確実にわかります。

これで実際に問題が解決するわけではありませんが、問題はアサーションが役立つことを思い出させてくれます。

于 2012-05-30T21:41:09.253 に答える