2016-09-21 2 views
-1

Androidに新しく、Bluetoothデータを複数の異なるアクティビティに配信するアプリを開発しました。私は発見を実行し、デバイスにユーザに提示するConnectActivityを持っており、ユーザがthisのディスカッションの誰かが示唆するようにデバイスを選択すると、BluetoothServiceが開始されます。LocalBroadcastManager.getInstance()を呼び出そうとしたときのNPE sendBroadcast()

BluetoothServiceはサービスを拡張し、最終的にはInputStreamでブロックするために使用されるバックグラウンドスレッドを開始し、データが利用可能な場合(startService()経由でポーリングする)

ここはアクティビティです。受信機を定義します。

protected void onCreate(Bundle savedInstanceState) { 
... 
    IntentFilter dataFilter = new IntentFilter(BluetoothService.INCOMING_DATA); 
    registerReceiver(mDataReceiver, dataFilter); 

    // Start the service with an intent identifying the context ("this" is an Activity, 
    // which inherits from Context) and the recipient. 
    Intent i = new Intent(this, BluetoothService.class); 
    i.putExtra(BluetoothService.COMMAND, "MY_COMMAND"); // Add the command as payload to the intent. 
    if(D) 
     Log.d(TAG, "Starting service."); 
    startService(i); 
} 

そして、最後に、ボタンの押しに接続します:ここで

private void connect(){ 
    if(D) 
     Log.d(TAG, "Connecting to device " + (mBluetoothDevices.get(mSelectedPos).toString()) + " at position " + mSelectedPos); 

    final ProgressDialog dialog = new ProgressDialog(this); 
    dialog.setTitle("Connecting"); 
    dialog.setMessage("Please wait..."); 
    dialog.show(); 

    if(D) 
     Log.d(TAG, "Attempting to connect."); 
    mBluetoothService.connect(mBluetoothDevices.get(mSelectedPos), dialog); 

は私のサービスです。

public class ConnectActivity extends AppCompatActivity { 
... 
    // My test receiver just to see if things are working. 
    private BroadcastReceiver mDataReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     if(D) 
      Log.d(TAG, "Broadcast received."); 
    } 
}; 

は、サービスのonCreate()を開始します

public class BluetoothService extends Service { 
... 
    public void connect (BluetoothDevice device, ProgressDialog dialog){ 
    .... 
    // Start the thread to connect to the device 
    mConnectThread = new ConnectThread(device, dialog, this); 
    mConnectThread.start(); 
} 

ConnectThreadはsucces sfullyと私の問題がある場合、これがあるので、私はそれのすべてを含めています、それが入ってくるようacitvityに戻ってデータを送信するために意図されConnectedThreadを開始:私の問題は、それがライン上にある

public class ConnectedThread extends Thread { 
    private BluetoothSocket mmSocket; 
    private final String mmMYNAME = "ConnectedThread"; 
    private final InputStream mmInStream; 
    private final OutputStream mmOutStream; 
    private final Context mmContext; 


    public ConnectedThread(BluetoothSocket socket, Context context) { 
     mmSocket = socket; 
     mmContext = context; 

     InputStream tryIn = null; 
     OutputStream tryOut = null; 

     // Get the BluetoothSocket input and output streams 
     try { 
      tryIn = mmSocket.getInputStream(); 
      tryOut = mmSocket.getOutputStream(); 
     } catch (IOException e) { 
      Log.e(TAG, mmMYNAME + " could not create streams.", e); 
     } 

     mmInStream = tryIn; 
     mmOutStream = tryOut; 
     mConnectedThreadEnabled = true; 
    } 

    @Override 
    public void run() 
    { 
     Thread.currentThread().setName(mmMYNAME); 
     Intent i = new Intent(INCOMING_DATA); 

     while(mConnectedThreadEnabled) { 
      SystemClock.sleep(1000); 
      if(D) 
       Log.d(TAG, "ConnectedThread is running."); 

      LocalBroadcastManager.getInstance(mmContext).sendBroadcast(i); //KABOOM 
     } 
     if(D) 
      Log.d(TAG, "Stopping ConnectedThread."); 

    } 

    public void cancel() { 
     if(D) 
      Log.d(TAG,"Canceling ConnectedThread."); 

     try { 
      if(D) 
       Log.d(TAG,"Shutting down existing socket."); 
      mConnectedThreadEnabled = false; 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "close() of connect socket failed", e); 
     } 
    } 

} 

LocalBroadcastManager.getInstance(mmContext).sendBroadcast(i); //KABOOM 

Iは、受信しています:

java.lang.NullPointerExceptionが:NULLオブジェクト参照 に ')android.content.Context android.content.Context.getApplicationContext(' 仮想メソッドを呼び出す試みandroid.content.ContextWrapper.getApplicationContext(ContextWrapper.java:107) android.support.v4.content.LocalBroadcastManager.getInstance(LocalBroadcastManager.java:102) (com.company.me.app.BluetoothService)$ ConnectedThread.run (BluetoothService.java:255)

mmContextと私の両方が適切に作成されたように見えることをデバッグが示しているので、問題が何であるかはっきりしていません。

+1

スレッドが実行されている間、サービスが破損している可能性があります。 'ConnectedThread'を' context'の代わりに 'context.getApplicationContext()'に保持させてください。 – CommonsWare

+0

デバッガによれば、コンテキストはnullではないようです。緊急時にOSによって明示的に停止または再要求されるまで、サービスポイントは固執していませんか?ところで、私はあなたの本にリンクするつもりでした。サービスの概要として使ったからです。 :)素晴らしい本。 – sje

+0

"緊急時にOSによって明示的に停止または再要求されるまで、サービスポイントは守られていませんか?" - 'startService()'によって開始されたサービスは 'stopService()'/'stopSelf()'まで実行されるか、サービスがクラッシュするか、プロセスが終了します。しかし、私はあなたのコードをすべて知っているわけではないので、このサービスをどれくらいの期間保っているか分かりません。親切な言葉をありがとう! – CommonsWare

答えて

0

これはmBluetoothService = new BluetoothService()を実行します。

自分でコンポーネントのインスタンスを作成します。この行を取り除く。書き換えるmBluetoothServiceニーズを使用している何でも:

  • サービス自体であっても、又は

  • 利用サービスバインディング(例えば、活動はその後、供給Binderのメソッドを呼び出すとbindService()、)、または

  • はおろか、サービス自体のインスタンスを作成し、サービスへの直接参照を持つようにしようと活動を避けるために、他のいくつかのパターンを使用し

+0

私は初期の接続を開始するためのコマンドパターンとパブリックメソッドを使って、デフォルトの "Bluetoothデバイスをポーリングする"だけをサポートするようにサービスを設計しました。サービスの明示的なインスタンス化を行わずにコマンドパターン(またはバインディング)を通して_all_ビヘイビアをサポートする必要があります。どうもありがとう。 – sje

関連する問題