0

This code is a Bluetooth service, but I get NullPointerException when connect thread calls and I don't know how to receive data from Bluetooth service to update UI (handle message).

I want that this service runs in background and save received data in the database. I am a beginner and can not solve it.

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);
}}
BJ_213
  • 73
  • 2
  • 9

1 Answers1

-1

I hope you will find answer from below link:

Example link

Akash
  • 1
  • 5
  • 2
    A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](http://meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted](http://stackoverflow.com/help/deleted-answers). – mrun Oct 06 '17 at 11:56