2017-07-30 41 views
0

此代碼是藍牙服務,但在連接線程調用時我得到NullPointerException,我不知道如何從藍牙服務接收數據以更新UI (處理消息)。如何創建一個在後臺運行的藍牙服務並保存數據庫中的接收數據

我想這個服務在後臺運行,並將接收到的數據保存在數據庫中。我是初學者,無法解決它。

BluetoothService.java

public class BluetoothService extends Service{ 

private Handler myHandler = null; 
private int state; 

BluetoothDevice myDevice; 

ConnectThread connectThread; 
ConnectedThread connectedThread; 
private final IBinder mIBinder = new LocalBinder(); 
BluetoothAdapter mBluetoothAdapter; 

/*public BluetoothService(Handler handler, BluetoothDevice device) { 
    state = Constants.STATE_NONE; 
    myHandler = handler; 
    myDevice = device; 
}*/ 

@Override 
public void onCreate() 
{ 
    super.onCreate(); 
} 

@Override 
public int onStartCommand(Intent intent, int flag, int startId) { 
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
    if (mBluetoothAdapter != null) { 
     myDevice = (BluetoothDevice) intent.getExtras().get(Constants.EXTRA_DEVICE); 
     String deviceName = myDevice.getName(); 
     String macAddress = myDevice.getAddress(); 
     if (macAddress != null && macAddress.length() > 0) { 
      connect(myDevice); 
     } else { 
      stopSelf(); 

     } 

    } 
    return START_STICKY; 
} 

public void onDestroy() 
{ 
    if(myHandler != null) 
    { 
     myHandler = null; 
    } 
} 

    public IBinder onBind(Intent intent) 
{ 
    return mIBinder; 
} 

public class LocalBinder extends Binder 
{ 
    public BluetoothService getInstance() 
    { 
     return BluetoothService.this; 
    } 
} 

public void setHandler(Handler handler) 
{ 
    myHandler = handler; 
} 



public synchronized void connect(BluetoothDevice myDevice) { 
    Log.d(Constants.TAG, "Connecting to: " + myDevice.getName() + " - " + myDevice.getAddress()); 
    // Start the thread to connect with the given device 

    setState(Constants.STATE_CONNECTING); 
    connectThread = new ConnectThread(myDevice); 
    connectThread.start(); 
} 



public synchronized void stop() { 
    cancelConnectThread(); 
    cancelConnectedThread(); 
    setState(Constants.STATE_NONE); 
} 

private synchronized void setState(int state) { 
    Log.d(Constants.TAG, "setState() " + this.state + " -> " + state); 
    this.state = state; 
    // Give the new state to the Handler so the UI Activity can update 
    myHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); 
} 

public synchronized int getState() { 
    return state; 
} 


public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) { 
    Log.d(Constants.TAG, "connected to: " + device.getName()); 

    cancelConnectThread(); 
    // Start the thread to manage the connection and perform transmissions 
    connectedThread = new ConnectedThread(socket); 
    connectedThread.start(); 

    setState(Constants.STATE_CONNECTED); 
} 

/** 
* Indicate that the connection attempt failed and notify the UI Activity. 
*/ 
private void connectionFailed() { 
    Log.e(Constants.TAG, "Connection Failed"); 
    // Send a failure item_message back to the Activity 
    Message msg = myHandler.obtainMessage(Constants.MESSAGE_SNACKBAR); 
    Bundle bundle = new Bundle(); 
    bundle.putString(Constants.SNACKBAR, "Unable to connect"); 
    msg.setData(bundle); 
    myHandler.sendMessage(msg); 
    setState(Constants.STATE_ERROR); 
    cancelConnectThread(); 
} 

/** 
* Indicate that the connection was lost and notify the UI Activity. 
*/ 
private void connectionLost() { 
    Log.e(Constants.TAG, "Connection Lost"); 
    // Send a failure item_message back to the Activity 
    Message msg = myHandler.obtainMessage(Constants.MESSAGE_SNACKBAR); 
    Bundle bundle = new Bundle(); 
    bundle.putString(Constants.SNACKBAR, "Cconnection was lost"); 
    msg.setData(bundle); 
    myHandler.sendMessage(msg); 
    setState(Constants.STATE_ERROR); 
    cancelConnectedThread(); 
} 

private void cancelConnectThread() { 
    // Cancel the thread that completed the connection 
    if (connectThread != null) { 
     connectThread.cancel(); 
     connectThread = null; 
    } 
} 

private void cancelConnectedThread() { 
    // Cancel any thread currently running a connection 
    if (connectedThread != null) { 
     connectedThread.cancel(); 
     connectedThread = null; 
    } 
} 

public void write(byte[] out) { 
    // Create temporary object 
    ConnectedThread r; 
    // Synchronize a copy of the ConnectedThread 
    synchronized (this) { 
     if (state != Constants.STATE_CONNECTED) { 
      Log.e(Constants.TAG, "Trying to send but not connected"); 
      return; 
     } 
     r = connectedThread; 
    } 

    // Perform the write unsynchronized 
    r.write(out); 
} 

private class ConnectThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final BluetoothDevice mmDevice; 

    public ConnectThread(BluetoothDevice device) { 
     // Use a temporary object that is later assigned to mmSocket, 
     // because mmSocket is final 
     BluetoothSocket tmp = null; 
     mmDevice = device; 

     // Get a BluetoothSocket to connect with the given BluetoothDevice 
     try { 
      // MY_UUID is the app's UUID string, also used by the server code 
      UUID uuid = Constants.myUUID; 
      tmp = device.createRfcommSocketToServiceRecord(uuid); 
     } catch (IOException e) { 
      Log.e(Constants.TAG, "Create RFcomm socket failed", e); 
     } 
     mmSocket = tmp; 
    } 

    public void run() { 
     try { 
      // Connect the device through the socket. This will block 
      // until it succeeds or throws an exception 
      mmSocket.connect(); 
     } catch (IOException connectException) { 
      // Unable to connect; close the socket and get out 
      Log.e(Constants.TAG, "Unable to connect", connectException); 
      try { 
       mmSocket.close(); 
      } catch (IOException closeException) { 
       Log.e(Constants.TAG, "Unable to close() socket during connection failure", closeException); 
      } 
      connectionFailed(); 
      return; 
     } 

     synchronized (BluetoothService.this) { 
      connectThread = null; 
     } 

     // Do work to manage the connection (in a separate thread) 
     connected(mmSocket, mmDevice); 
    } 

    /** Will cancel an in-progress connection, and close the socket */ 
    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(Constants.TAG, "Close() socket failed", e); 
     } 
    } 
} 


public class ConnectedThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final InputStream mmInStream; 
    private final OutputStream mmOutStream; 

    public ConnectedThread(BluetoothSocket socket) { 
     mmSocket = socket; 
     InputStream tmpIn = null; 
     OutputStream tmpOut = null; 

     // Get the input and output streams, using temp objects because 
     // member streams are final 
     try { 
      tmpIn = socket.getInputStream(); 
      tmpOut = socket.getOutputStream(); 
     } catch (IOException e) { 
      Log.e(Constants.TAG, "Temp sockets not created", e); 
     } 

     mmInStream = tmpIn; 
     mmOutStream = tmpOut; 
    } 

    public void run() { 
     Log.i(Constants.TAG, "Begin connectedThread"); 
     byte[] buffer = new byte[1024]; // buffer store for the stream 
     int bytes; // bytes returned from read() 

     StringBuilder readMessage = new StringBuilder(); 

     // Keep listening to the InputStream until an exception occurs 
     while (true) { 
      try { 

       bytes = mmInStream.read(buffer); 
       String read = new String(buffer, 0, bytes); 
       readMessage.append(read); 

       if (read.contains("\n")) { 

        myHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, readMessage.toString()).sendToTarget(); 
        readMessage.setLength(0); 
       } 

      } catch (Exception e) { 

       Log.e(Constants.TAG, "Connection Lost", e); 
       connectionLost(); 
       break; 
      } 
     } 
    } 

    /* Call this from the main activity to send data to the remote device */ 
    public void write(byte[] bytes) { 
     try { 
      mmOutStream.write(bytes); 
      myHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, bytes).sendToTarget(); 
     } catch (IOException e) { 
      Log.e(Constants.TAG, "Exception during write", e); 
     } 
    } 

    /* Call this from the main activity to shutdown the connection */ 
    /** Will cancel an in-progress connection, and close the socket */ 
    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(Constants.TAG, "close() of connect socket failed", e);} 
    } 
} 


} 

Main.java

public class Main extends AppCompatActivity { 
BluetoothDevice device; 
static BluetoothService bluetoothService; 
static TextView T2; 
Button button; 
static ImageView UVBorder; 
static ImageView TempBorder; 
static ImageView UVStatus; 
static ImageView TempStatus; 
ImageView UVChart; 
ImageView TempChart; 
static TextView UVValue; 
static TextView TempValue; 
TextView UVLable; 
TextView TempLable; 

static int SAFE_STATUS=R.drawable.ok; 
static int NEED_CARE_STATUS=R.drawable.need_care; 
static int AT_RISK_STATUS=R.drawable.alert; 
//ProgressDialog progressDlg; 
//private static ArrayAdapter<String> mConversationArrayAdapter; 
//private ListView mConversationView; 
private int time_interval = 2000; 
private long oldCurrentTimeMillis; 
static String username; 
private Toolbar toolbar; 
private NavigationView navigationView; 
private DrawerLayout drawerLayout; 
static PulsatorLayout mPulsator1; 
static PulsatorLayout mPulsator2; 
private BluetoothService mService = null; 

private boolean mIsBound; 
myHandler handler; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main_view); 

    UVStatus=(ImageView) findViewById(R.id.uv_stat); 
    TempStatus=(ImageView) findViewById(R.id.temp_stat); 



    toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 


    User CurrentUser = UserHolder.getInstance().getUser(); 

    device = getIntent().getExtras().getParcelable(Constants.EXTRA_DEVICE); 

    myHandler handler = new myHandler(Main.this); 
    ///bluetoothService = new BluetoothService(handler, device); 
    Intent intent=new Intent(this.getBaseContext(), BluetoothService.class); 
    intent.putExtra(Constants.EXTRA_DEVICE, device); 
    startService(intent); 
    doBindService(); 

} 

private ServiceConnection mConnection = new ServiceConnection() { 
    @Override 
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) 
    { 
     mService = ((BluetoothService.LocalBinder)iBinder).getInstance(); 
     mService.setHandler(handler); 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName componentName) 
    { 
     mService = null; 
    } 
}; 

private void doBindService() 
{ 
    // Establish a connection with the service. We use an explicit 
    // class name because we want a specific service implementation that 
    // we know will be running in our own process (and thus won't be 
    // supporting component replacement by other applications). 
    bindService(new Intent(this, 
      BluetoothService.class), mConnection, Context.BIND_AUTO_CREATE); 
    mIsBound = true; 
} 

private void doUnbindService() 
{ 
    if (mIsBound) 
    { 
     // Detach our existing connection. 
     unbindService(mConnection); 
     mIsBound = false; 
    } 
} 

@Override 
protected void onDestroy() 
{ 
    super.onDestroy(); 
    doUnbindService(); 
} 



@Override protected void onStart() { 
    super.onStart(); 
    IntentFilter filter = new IntentFilter(); 
    filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 
    registerReceiver(mReceiver, filter); 

    // bluetoothService.connect(); 


} 

@Override protected void onStop() { 
    super.onStop(); 

    if (bluetoothService != null) { 
     bluetoothService.stop(); 
     Log.d(Constants.TAG, "Stopping"); 
    } 

    unregisterReceiver(mReceiver); 
} 


private static class myHandler extends Handler { 
    private final WeakReference<Main> mActivity; 

    public myHandler(Main activity) { 
     mActivity = new WeakReference<Main>(activity); 
    } 

    // @Override 
    public void handleMessage(Message msg) { 

     final Main activity = mActivity.get(); 

     switch (msg.what) { 

      case Constants.MESSAGE_READ: 
       Packet packet=new Packet(); 
       User CurrentUser = UserHolder.getInstance().getUser(); 
       String username=CurrentUser.getUsername(); 
       packet.setUserName(username); 

       int site_id=CurrentUser.getSite().getId(); 
       packet.setSiteId(site_id); 

       String readMessage = (String) msg.obj; 
       // mConversationArrayAdapter.add(readMessage); 
       Log.e("msg",readMessage); 
       //run a asynctask 


       break; 
     } 
    } 


} 

} 
@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 

    int id = item.getItemId(); 

    return super.onOptionsItemSelected(item); 
}} 
+0

普萊斯e增加你的'NullPointerException'堆棧跟蹤 –

回答

0

我希望你從下面的鏈接找到答案:

Example link

+0

歡迎您訪問解決方案的鏈接,但請確保您的答案在沒有它的情況下很有用:[在鏈接周圍添加上下文](http://meta.stackexchange.com/a/8259)所以你的同行用戶會有一些想法是什麼,爲什麼它在那裏,然後引用你鏈接到的頁面最相關的部分,以防目標頁面不可用。 [僅僅是一個鏈接的答案可能會被刪除](http://stackoverflow.com/help/deleted-answers)。 – mrun

相關問題