

<http://qiita.com/anzai_k/items/131373caa0a6294efdd4>

上記のサイトを参考にBLE Peripheralアプリを作成しました。  
しかし、CentralからReadRequestが来ると下記のエラーを出力してサービスをクリアしてしまいます。調べても解決できなかったため質問させていただきます。

[code]

    W/BluetoothGattServer: Unhandled exception in callback
    
    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothGattServer.sendResponse(android.bluetooth.BluetoothDevice, int, int, int, byte[])' on a null object reference
    
[/code]


CC BY-SA 3.0
2017-02-10T07:44:47.953
32559
2017-02-10T08:59:51.343
2017-02-10T08:25:22.160
19110
20604
question
android
Android BluetoothLE Pripheral


作成されているアプリのコードが記載されていないため、参考にされているサイトのコードからの推測です。

## まずは直接の原因から

以下のAPIをコールしようとして`java.lang.NullPointerException`が発生しています。

> android.bluetooth.BluetoothGattServer.sendResponse

## 原因の理由を考える

ReadRequestが来た時ということなので以下のコードで発生しているのでしょう。

[code]

    //セントラル（クライアント）からReadRequestが来ると呼ばれる
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice device, int requestId, 
        int offset, BluetoothGattCharacteristic characteristic) {
    (略)
        bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
    (略)
    }
    
[/code]

つまり`bluetoothGattServer`が`null`であることが原因です。  
次に`bluetoothGattServer`を見ていきます。  
すると以下のコンストラクタで代入されていることがわかります。

[code]

    //BLE
    private BluetoothGattServer bluetoothGattServer;
    public BLEServer(BluetoothGattServer gattServer) {
        this.bluetoothGattServer = gattServer;
    }
    
[/code]

おそらくコンストラクタに渡されている`gattServer`が`null`なのだと考えられます。  
次にこの`BELServer`をインスタンス化しているところを探します。  
すると以下の処理で`BLEServer`をインスタンス化しているようです。

[code]

    //GattServerを取得
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    private BluetoothGattServer getGattServer(Context context, BluetoothManager manager) {
        return manager.openGattServer(context, new BLEServer(gattServer));
    }
    
[/code]

ここで渡されている`gattServer`を探します。宣言はメンバ変数ですね。

[code]

    private BluetoothGattServer gattServer;
    
[/code]

ここで`gattSever`に代入しているみたいです。

[code]

    //アドバタイズを開始
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public void startAdvertise(Context context) {
    
        //BLE各種を取得
        BluetoothManager manager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter adapter = manager.getAdapter();
        advertiser = getAdvertiser(adapter);
        gattServer = getGattServer(context, manager);
    (略)
    }
    
[/code]

ここまで調べておかしいことに気づいてください。  
`gattServer`に代入するために呼び出しているメソッドが先ほど`BLEServer`をインスタンス化しようとしていた`getGattServer`メソッドになっています。  
つまり`getGattServer`メソッドを呼び出している段階では、`gattServer`はインスタンス化されていません。（=null）  
そのため`BLEServer`のコンストラクタに渡されている`gattServer`は`null`になっていると考えられます。

あとはご自身のコードをデバッグしてみて実際にどこが`null`なのかを調査してみてください。


CC BY-SA 3.0
2017-02-10T08:59:51.343
32561
2017-02-10T08:59:51.343
20272
32559
answer