How to read/receive data using bluetooth? - java

I'm trying to make an app that can send and receive data via bluetooth from arduino. The part where i send the data is fairly simple so I've managed to get it right. I got stuck at receiving data.
My program has 2 layouts. First there is a layout with a CONNECT button and some buttons that change the layout. This is the code:
Public class MainActivity extends AppCompatActivity {
ImageButton test, manual,connect;
Button back;
private BluetoothAdapter mbluetoothAdapter;
protected AlertDialog.Builder builder;
ConnectThread mBluetooth = new ConnectThread();
String mBluetoothName = "";
String mBluetoothAdress = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Context context = this;
//final LayoutInflater factory = getLayoutInflater();
//final View textEntryView = factory.inflate(R.layout.activity_main);
builder = new AlertDialog.Builder(this);
mbluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
connect = (ImageButton) findViewById(R.id.connect);
test = (ImageButton) findViewById(R.id.test);
manual = (ImageButton) findViewById(R.id.manual);
test.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context,SecondActivity.class );
context.startActivity(intent);
}
});
manual.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context,SecondActivity.class );
context.startActivity(intent);
}
});
connect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mbluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBtIntent);
} else {
if (!mBluetooth.mBluetoothAddress.equals("")) {//if another connection is already exits then close it first
stopAllActivities();
} else {
try {
Intent serverIntent = new Intent(MainActivity.this, DeviceListActivity.class);
startActivityForResult(serverIntent, Helper.REQUEST_CONNECT_DEVICE);
} catch (Exception e) {
showToast(getString(R.string.errorOccured) + ": " + e.getMessage());
e.printStackTrace();
}
}
}
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case Helper.REQUEST_CONNECT_DEVICE:
if (resultCode == Activity.RESULT_OK) {
mBluetoothName = data.getExtras().getString(Helper.EXTRA_BLUETOOTH_NAME);
mBluetoothAdress = data.getExtras().getString(Helper.EXTRA_BLUETOOTH_ADDRESS);
// setBluetoothInfo();
showToast(R.string.connectedDevice + mBluetoothName);
if (!mBluetoothAdress.equals("")) {
if (!mBluetooth.connect(mBluetoothAdress)){
}
}
}
break;
}
}
The SecondActivity contains the main purpose of this app: To send and receive data. This is how it looks like:
public class SecondActivity extends AppCompatActivity {
final Context context = this;
Button back;
ImageButton btnup, btndown, btnright, btnleft;
ConnectThread mBluetooth = new ConnectThread();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnup = (ImageButton) findViewById(R.id.btnup);
btndown = (ImageButton) findViewById(R.id.btndown);
btnleft = (ImageButton) findViewById(R.id.btnleft);
btnright = (ImageButton) findViewById(R.id.btnright);
final TextView direction = (TextView) findViewById(R.id.text_direction);
final TextView steering = (TextView) findViewById(R.id.steering_direction);
final TextView speed = (TextView) findViewById(R.id.speed);
final TextView battery = (TextView) findViewById(R.id.batery);
final Chronometer chronometer = (Chronometer) findViewById(R.id.chronometer);
btndown.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mBluetooth.write("2");
direction.setText(R.string.Backwards);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
mBluetooth.write("x");
direction.setText(R.string.blank);
}
return false;
}
});
Note: I didnt post the whole code because i have more buttons with the exact same code as the one above.
For the Bluetooth connection i have 2 separate classes one called ConnectThread:
public class ConnectThread {
BluetoothAdapter mBluetoothAdapter = null;
BluetoothSocket mSocket = null;
OutputStream mOutStream = null;
InputStream mInStream=null;
String mBluetoothAddress = "";
public boolean connect(String bluetoothAddress) {
if (!mBluetoothAddress.equals(bluetoothAddress) && !mBluetoothAddress.equals("")) {
close();
}
mBluetoothAddress = bluetoothAddress;
if (mBluetoothAdapter == null) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
if (mBluetoothAdapter == null) {
return false;
}
if (!mBluetoothAdapter.isEnabled()) {
return false;
}
try {
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mBluetoothAddress);
if (mSocket == null) {
mSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
mSocket.connect();
}
} catch (IOException e) {
mSocket = null;
e.printStackTrace();
return false;
}
try {
mOutStream = mSocket.getOutputStream();
} catch (IOException e) {
mOutStream = null;
e.printStackTrace();
return false;
}
return true;
}
public boolean check() {
if (mBluetoothAdapter == null) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
if (mBluetoothAdapter == null) {
return false;
}
if (!mBluetoothAdapter.isEnabled()) {
return false;
}
if (!mSocket.isConnected()) {
return false;
}
return true;
}
public boolean close() {
try {
if (mOutStream != null) {
mOutStream.close();
}
if (mSocket != null) {
mSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
mOutStream = null;
mSocket = null;
return true;
}
public boolean write(String strData) {
byte[] buffer = strData.getBytes();
try {
if (mOutStream != null && mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
mOutStream.write(buffer);
}
else {
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
}
And the other one DeviceListActivity:
public class DeviceListActivity extends Activity {
private BluetoothAdapter mBtAdapter;
private ArrayAdapter<String> mPairedDevicesArrayAdapter;
private ArrayAdapter<String> mNewDevicesArrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the window
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.device_list);
// Set result CANCELED incase the user backs out
setResult(Activity.RESULT_CANCELED);
// Initialize the button to perform device discovery
Button scanButton = (Button) findViewById(R.id.button_scan);
scanButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (mBtAdapter == null)
return;
doDiscovery();
v.setVisibility(View.GONE);
}
});
// Initialize array adapters. One for already paired devices and
// one for newly discovered devices
mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
// Find and set up the ListView for paired devices
ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
pairedListView.setAdapter(mPairedDevicesArrayAdapter);
pairedListView.setOnItemClickListener(mDeviceClickListener);
// Find and set up the ListView for newly discovered devices
ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
newDevicesListView.setOnItemClickListener(mDeviceClickListener);
// Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
// Get the local Bluetooth adapter
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBtAdapter == null) {
mPairedDevicesArrayAdapter.add("DUMMY\n00:00:00:00:00:00");
return;
}
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (BluetoothDevice device : pairedDevices) {
mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
String noDevices = getResources().getText(R.string.none_paired).toString();
mPairedDevicesArrayAdapter.add(noDevices);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
// Make sure we're not doing discovery anymore
if (mBtAdapter != null)
mBtAdapter.cancelDiscovery();
// Unregister broadcast listeners
this.unregisterReceiver(mReceiver);
}
/**
* Start device discover with the BluetoothAdapter
*/
private void doDiscovery() {
if (mBtAdapter == null)
return;
// Indicate scanning in the title
setProgressBarIndeterminateVisibility(true);
setTitle(R.string.scanning);
// Turn on sub-title for new devices
findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
// If we're already discovering, stop it
if (mBtAdapter.isDiscovering()) {
mBtAdapter.cancelDiscovery();
}
// Request discover from BluetoothAdapter
mBtAdapter.startDiscovery();
}
// The on-click listener for all devices in the ListViews
private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
if (mBtAdapter != null) {
// Cancel discovery because it's costly and we're about to connect
mBtAdapter.cancelDiscovery();
}
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) v).getText().toString();
String name = info.substring(0, info.length() - 18);
String address = info.substring(info.length() - 17);
// Create the result Intent and include the MAC address
Intent intent = new Intent();
intent.putExtra(Helper.EXTRA_BLUETOOTH_ADDRESS, address);
intent.putExtra(Helper.EXTRA_BLUETOOTH_NAME, name);
// Set result and finish this Activity
setResult(Activity.RESULT_OK, intent);
finish();
}
};
// The BroadcastReceiver that listens for discovered devices and
// changes the title when discovery is finished
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
for (int i = 0; i < mNewDevicesArrayAdapter.getCount(); i++) {
if (mNewDevicesArrayAdapter.getItem(i).equals(device.getName() + "\n" + device.getAddress())) {
return;
}
}
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setProgressBarIndeterminateVisibility(false);
setTitle(R.string.select_device);
if (mNewDevicesArrayAdapter.getCount() == 0) {
String noDevices = getResources().getText(R.string.none_found).toString();
mNewDevicesArrayAdapter.add(noDevices);
}
}
}
};
}
I want to update two TextView with the data i receive from arduino. The data would look something like #first_data,second_data* where # is the start of data series and * the end. I would appreciate if you can help me with some advice/code how to do that. I am pretty new to java and I still dont fully understand how everything works.

Once you get the Bluetooth socket you could use its stream to read/write the content.
...
m_Input = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
m_Output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
...
// reading from stream
m_Input.read(buffer, readBytes, 1) ;
you could use
m_Input.available()
to check if is any data available into stream. Otherwise the read method will block until you will read the number of bytes you specified as third argument.
int readBytes=0;
while(readBytes < expectedBytes){
timeout = 0;
while((m_Input.available()) == 0 && timeout < ReadTimeout) {
timeout+=250;
// throws interrupted exception
Thread.sleep(250);// let control to other threads
}
if(timeout >= ReadTimeout){
// throw new timeout exception
}
if (m_Input.read(buffer, readBytes, 1) == -1) {
// throw stream/socket closed
}
readBytes++;
}
Ad for writing use write method
...
//writting to stream
m_Output.write(buffer,..);

Related

Send bluetooth message via Android Studio

I'm trying to send a message via bluetooth in Android Studio. I've googled but I cannot find the answer. I want to send a message to a connected device.
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private ImageView bluetoothOnImageView;
private ImageView bluetoothOffImageView;
private TextView bluetoothOnOffTextView;
private BluetoothAdapter bluetoothAdapter;
private ListView listView;
private EditText messageEditText;
private ArrayList<String> deviceList = new ArrayList<String>();
private ArrayList<BluetoothDevice> deviceListBluetooth = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bluetoothOnImageView = findViewById(R.id.bluetoothOnImageView);
bluetoothOffImageView = findViewById(R.id.bluetoothOffImageView);
bluetoothOnOffTextView = findViewById(R.id.bluetoothOnOffTextView);
listView = findViewById(R.id.listView);
messageEditText = findViewById(R.id.messageEditText);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.startDiscovery();
checkBluetooth();
Toast.makeText(this, "Scanning devices...", Toast.LENGTH_SHORT).show();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
IntentFilter filterChange = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(receiverChange, filter);
listView.setOnItemClickListener(MainActivity.this);
}
private final BroadcastReceiver receiverChange = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 3 Cases
// 1: Bonded already
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
Log.d("BroadcastReceiver", "BOND_BONDED");
Toast.makeText(MainActivity.this, "Already connected to this device.", Toast.LENGTH_SHORT).show();
}
// 2: Creating a bond
if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
Log.d("BroadcastReceiver", "BOND_BONDING");
}
// 3: Breaking a bond
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
Log.d("BroadcastReceiver", "BOND_NONE");
Toast.makeText(MainActivity.this, "Broke connection to this device.", Toast.LENGTH_SHORT).show();
}
}
}
};
public void bluetoothSearchOnClick(View view) {
Toast.makeText(this, "Rescanning devices...", Toast.LENGTH_SHORT).show();
// Reset devices
deviceList.clear();
deviceListBluetooth.clear();
bluetoothAdapter.startDiscovery();
checkBluetooth();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
}
#Override
protected void onDestroy() {
unregisterReceiver(receiver);
unregisterReceiver(receiverChange);
super.onDestroy();
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String newDevice = device.getName() + "\n" + device.getAddress();
boolean duplicate = false;
// No duplicate devices
for (int i = 0; i < deviceList.size(); i++) {
if (newDevice.equals(deviceList.get(i))) {
duplicate = true;
}
}
if (!duplicate) {
deviceList.add(newDevice);
deviceListBluetooth.add(device);
}
Log.i("BT", device.getName() + "\n" + device.getAddress());
listView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, deviceList));
}
}
};
public void bluetoothOnOnClick(View view) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.disable();
// Wait x milliseconds
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
checkBluetooth();
}
}, 500);
}
public void bluetoothOffOnClick(View view) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.enable();
// Wait x milliseconds
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
checkBluetooth();
}
}, 500);
}
private void checkBluetooth() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
// Device does not support Bluetooth
Toast.makeText(this, "This device does not support Bluetooth", Toast.LENGTH_SHORT).show();
} else if (!bluetoothAdapter.isEnabled()) {
// Bluetooth is not enabled :)
bluetoothOnImageView.setVisibility(View.GONE);
bluetoothOffImageView.setVisibility(View.VISIBLE);
bluetoothOnOffTextView.setText("OFF");
bluetoothOnOffTextView.setTextColor(Color.RED);
} else {
// Bluetooth is enabled
bluetoothOffImageView.setVisibility(View.GONE);
bluetoothOnImageView.setVisibility(View.VISIBLE);
bluetoothOnOffTextView.setText("ON");
bluetoothOnOffTextView.setTextColor(Color.GREEN);
}
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
checkBluetooth();
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bluetoothAdapter.cancelDiscovery();
Log.d("Bluetooth Adapter", "onItemClick: You Clicked on a device.");
String[] device = deviceList.get(position).split("\n");
String deviceName = device[0];
// Bond
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
Log.d("Bluetooth Adapter", "Trying to pair with " + deviceName);
deviceListBluetooth.get(position).createBond();
}
}
public void sendButtonOnClick(View view) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Send message
}
}
In the method sendButtonOnClick(View view) is where I want to send the message. You can find this method at the bottom of the code.
Can anyone help me?
this is not so simple as you think (packing up messaging feature into one method). you need to connect to BluetoothSocket obtained from BluetoothDevice using createRfcommSocketToServiceRecord and knowing "messaging" UUID (you can list them with getUuids() method). after proper socket connection you can obtain input and output streams (getInputStream and getOutputStream), from which you can read and write bytes converting to text if you want. found pretty good sample in HERE, which is using separated Threads for Bluetooth communication making whole feature async and not hanging main/UI thread

Android Bluetooth sends msg when breakpoint added, but not if program doesn't pause

I have the following code that talks to a C# program on a computer. When I add a breakpoint before the outputStream.write(bytes) code, it works fine when I restart the program. If I just let the program run, it doesn't send the message. I am thinking it has something to do with timing, but I have tried everything I can think of to make sure the BT is connected before it sends the message.
The message is being sent on a button click.
Here are the 2 classes:
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static BluetoothAdapter mBluetoothAdapter;
public static BluetoothDevice mBluetoothDevice;
private String scannedContents;
private Button scanBtn;
private TextView formatTxt, contentTxt;
public static int mState = 0;
private ConnectThread btThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Bottom Right Buttons
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(this);
//Setup BT
if (savedInstanceState == null) {
mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
if (mBluetoothAdapter != null) {
if (mBluetoothAdapter.isEnabled()) {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
if (device.getAddress().equalsIgnoreCase("00:1a:7d:da:71:11")) {
mBluetoothDevice = device;
ConnectThread btThread = new ConnectThread(mBluetoothDevice);
btThread.run();
}
}
} else
showErrorText(R.string.bt_not_paired);
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, Constants.REQUEST_ENABLE_BT);
}
} else {
showErrorText(R.string.bt_not_supported);
}
}
//Scanning Button Code
scanBtn = (Button) findViewById(R.id.scan_button);
formatTxt = (TextView) findViewById(R.id.scan_format);
contentTxt = (TextView) findViewById(R.id.scan_content);
scanBtn.setOnClickListener(this);
}
public void onClick(View v) {
//respond to clicks
if (v.getId() == R.id.scan_button) {
//scan
IntentIntegrator scanIntegrator = new IntentIntegrator(this);
scanIntegrator.initiateScan();
} else if (v.getId() == R.id.fab) {
btThread.write(scannedContents.getBytes());
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case Constants.REQUEST_ENABLE_BT:
if (resultCode == RESULT_OK) {
//TODO
} else {
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
case Constants.REQUEST_SCANNED_DATA:
//Scanner Code
IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (scanningResult.getContents() != null) {
//we have a result
String scanContent = scanningResult.getContents();
String scanFormat = scanningResult.getFormatName();
//TODO Do something with data
this.scannedContents = scanContent;
formatTxt.setText("FORMAT: " + scanFormat);
contentTxt.setText("CONTENT: " + scanContent);
} else {
Toast toast = Toast.makeText(getApplicationContext(), "No scan data received!", Toast.LENGTH_SHORT);
toast.show();
}
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
#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) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void showErrorText(int messageId) {
TextView view = (TextView) findViewById(R.id.error_textview);
view.setText(getString(messageId));
}
public final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
//TODO
}
};
}
ConnectThread.java
public class ConnectThread extends Thread {
final BluetoothSocket mmSocket;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket
// because mmSocket is final.
BluetoothSocket tmp = null;
try {
// Get a BluetoothSocket to connect with the given BluetoothDevice.
// MY_UUID is the app's UUID string, also used in the server code.
UUID uuid = UUID.fromString("F814E012-48FE-44F4-AF94-9D9C4CF7495A");
tmp = device.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
Log.e(TAG, "Socket's create() method failed", e);
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it otherwise slows down the connection.
MainActivity.mBluetoothAdapter.cancelDiscovery();
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and return.
try {
mmSocket.close();
} catch (IOException closeException) {
Log.e(TAG, "Could not close the client socket", closeException);
}
return;
}
// The connection attempt succeeded. Perform work associated with
// the connection in a separate thread.
MainActivity.mState = 1;
}
public void write(byte[] bytes) {
try {
OutputStream outputStream = mmSocket.getOutputStream();
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
// Closes the client socket and causes the thread to finish.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the client socket", e);
}
}
}
Ok. This was me not understanding threads. The issue was I was using thread.run() instead of thread.start().

Android Studio - Sending a Bluetooth PIN automatically

I am looking at the following code by Lorensius W. L. T
I have seen other posts about sending a PIN automatically (e.g. 1234) to the device when it pairs so that there is no user prompt. I can't figure it out how to add their code fragments to get it to work.
How is the following code modified to achieve this?
/**
* Device list.
*
* #author Lorensius W. L. T <lorenz#londatiga.net>
*
*/
public class DeviceListActivity extends Activity {
private ListView mListView;
private DeviceListAdapter mAdapter;
private ArrayList<BluetoothDevice> mDeviceList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_paired_devices);
mDeviceList = getIntent().getExtras().getParcelableArrayList("device.list");
mListView = (ListView) findViewById(R.id.lv_paired);
mAdapter = new DeviceListAdapter(this);
mAdapter.setData(mDeviceList);
mAdapter.setListener(new DeviceListAdapter.OnPairButtonClickListener() {
#Override
public void onPairButtonClick(int position) {
BluetoothDevice device = mDeviceList.get(position);
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
unpairDevice(device);
} else {
showToast("Pairing...");
pairDevice(device);
}
}
});
mListView.setAdapter(mAdapter);
registerReceiver(mPairReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
}
#Override
public void onDestroy() {
unregisterReceiver(mPairReceiver);
super.onDestroy();
}
private void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
private void pairDevice(BluetoothDevice device) {
try {
Method method = device.getClass().getMethod("createBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void unpairDevice(BluetoothDevice device) {
try {
Method method = device.getClass().getMethod("removeBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
showToast("Paired");
} else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
showToast("Unpaired");
}
mAdapter.notifyDataSetChanged();
}
}
};
}

Android Bluetooth connection error

I'm developing a bluetooth app to control an Arduino board, but now I made some mistakes: when I try to make a connection from my phone, it displays an AlertDialog (it is OK) and a lot of Toasts (they're called from onSensorChanged).
The BT module connected to the board is OK (tested with other apps), so the problem is Java: I can't make a connection to my BT module. Unfortunately, Android Studio doesn't give me any logcat or errors.
This is my code:
/* imports... */
public class MainActivity extends AppCompatActivity implements SensorEventListener {
/* Bluetooth */
private static final int REQUEST_ENABLE_BT = 1;
private String selectedDevice = "";
static final UUID defaultUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //This SPP UUID should work for most devices.
//private boolean isConnected = false;
BluetoothAdapter bluetoothAdapter;
BluetoothSocket bluetoothSocket;
/* Is in full screen = ? */
private boolean FullScreenState = true;
/* Views */
private SeekBar steeringWheel;
private SeekBar forwardsSpeed;
private SeekBar backwardsSpeed;
private Toolbar toolbar;
/* Dialogs */
AlertDialog.Builder errorDialog;
AlertDialog.Builder listDialog;
ProgressDialog progressDialog;
/* Accelerometer managers */
Sensor accelerometer;
SensorManager sensorManager;
float Y = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
(...)
/* Views */
steeringWheel = (SeekBar) findViewById(R.id.Steering_wheel);
forwardsSpeed = (SeekBar) findViewById(R.id.Forwards_speed);
backwardsSpeed = (SeekBar) findViewById(R.id.Backwards_speed);
/* listDialogs */
listDialog = new AlertDialog.Builder(this);
listDialog.setCancelable(true);
listDialog.setTitle(R.string.app_name);
//listDialog.setMessage("Select a device:");
listDialog.setIcon(R.drawable.launcher_icon);
//listDialog.setView(devicesListView);
listDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
/* errorDialog */
errorDialog = new AlertDialog.Builder(this);
errorDialog.setCancelable(false);
errorDialog.setTitle(R.string.app_name);
errorDialog.setIcon(R.drawable.error_material);
errorDialog.setPositiveButton("I got it", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
/* Set the full screen and keep the screen always on... */
/* Accelerometer initializer... */
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
...
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
...
if (id == R.id.toolbar_connect) {
initializeBT();
return true;
} else if (id == R.id.toolbar_settings) {
/* Settings activity. Coming soon. */
return true;
} else if (id == R.id.toolbar_disconnect) {
if (bluetoothSocket != null) {
try {
bluetoothSocket.close();
} catch (IOException e) {
errorDialog.setMessage("Disconnection error!");
errorDialog.show();
}
}
return true;
}
...
}
#Override
public void onSensorChanged(SensorEvent event) {
/* Get the axes */
Y = event.values[1];
/* Set the steering wheel position */
steeringWheel.setProgress((int)Y + 10);
send(String.valueOf(steeringWheel.getProgress()));
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
...
}
private class connect extends AsyncTask<Void, Void, Void> {
private boolean connectionSuccess = false;
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(MainActivity.this, "Connecting...", "Creating bluetooth connection");
}
#Override
protected Void doInBackground(Void... devices) {
try {
if (bluetoothSocket == null) {
//if ((bluetoothSocket == null) || (!isConnected)) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice arduino = bluetoothAdapter.getRemoteDevice(selectedDevice);
bluetoothSocket = arduino.createInsecureRfcommSocketToServiceRecord(defaultUUID);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
bluetoothSocket.connect();
connectionSuccess = true;
}
} catch (IOException e) {
connectionSuccess = false;
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (!connectionSuccess) {
errorDialog.setMessage("Connection error!");
errorDialog.show();
bluetoothSocket = null;
} else {
Toast.makeText(getApplicationContext(), "Successfully connected", Toast.LENGTH_LONG).show();
//isConnected = true;
}
progressDialog.dismiss();
}
}
void initializeBT() {
/* Check for Bluetooth support */
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
errorDialog.setMessage("Unfortunately, Bluetooth connection isn't supported on your device.");
errorDialog.show();
} else if (!bluetoothAdapter.isEnabled()) {
/* Bluetooth disables -> enable it */
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
devicesPrompt();
}
}
void devicesPrompt() {
//final ArrayList<String> devicesList = new ArrayList()<String>;
Set<BluetoothDevice> pairedDevices;
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for(BluetoothDevice bluetoothDevice : pairedDevices) {
/* Get the device's name and the address */
//devicesList.add(bt.getName() + "\n" + bt.getAddress());
adapter.add(bluetoothDevice.getName() + "\n" + bluetoothDevice.getAddress());
}
} else {
Toast.makeText(getApplicationContext(), "No paired Bluetooth devices found!", Toast.LENGTH_LONG).show();
}
listDialog.setAdapter(adapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Log.d("RoverBluetooth!!", String.valueOf(which));
//;
String info = adapter.getItem(which);
selectedDevice = info.substring(info.length() - 17);
new connect().execute();
dialog.dismiss();
}
});
listDialog.show();
}
public void send(String message) {
message = message + "/r";
if (bluetoothSocket != null) {
try {
bluetoothSocket.getOutputStream().write(message.getBytes());
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Error during sending", Toast.LENGTH_SHORT).show();
Log.d("RoverBluetooth errors", e.toString());
}
}
}
public void buttonsActions(View view) {
int viewId = view.getId();
if (viewId == R.id.Forwards_button) { //ON
send(String.valueOf(forwardsSpeed.getProgress() + 1000));
} else if (viewId == R.id.Stop_button) { //OFF
send("21");
} else if (viewId == R.id.Backwards_button) { //Backwards
send(String.valueOf(backwardsSpeed.getProgress() + 1500));
} else if (viewId == R.id.Light_ON) { //Light ON
send("22");
} else if (viewId == R.id.Light_OFF) { //Light OFF
send("23");
}
}
}
I already wrote a class to make a bluetooth connection between Android and Arduino. I suppose you're using a HC-06 (or -05 ?). My code is on github:
https://github.com/omaflak/Bluetooth-Android
I also wrote a tutorial on my blog, you may want to take a look at it:
https://causeyourestuck.io/2015/12/14/communication-between-android-and-hc-06-module/
Good luck!

How to transfer data via Bluetooth from two different activities?

I tried to send data from my app to my Arduino board to make the led light.
The problem is that if I send from my main activity it works but if I send it from a second activity (HolopickerColor), it doesn't work and I don't get any errors.
Thanks for your anwsers.
MainActivity :
public class MainActivity extends AppCompatActivity{
private Button mPairedBtn;
Button on, find;
public BluetoothAdapter BA;
private ProgressDialog mProgressDlg;
// public ConnectedThread mConnectedThread;
private ArrayList<BluetoothDevice> mDeviceList = new ArrayList<BluetoothDevice>();
private DrawerLayout mDrawerLayout;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
Button btnOn, btnOff;
// SPP UUID service
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// MAC-address of Bluetooth module (you must edit this line)
private static String address ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
on = (Button) findViewById(R.id.btn_enable);
find = (Button) findViewById(R.id.btn_scan);
mPairedBtn = (Button) findViewById(R.id.btn_view_paired);
BA = BluetoothAdapter.getDefaultAdapter();
mProgressDlg = new ProgressDialog(this);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
actionBar.setDisplayHomeAsUpEnabled(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
Toast.makeText(MainActivity.this, menuItem.getTitle(), Toast.LENGTH_LONG).show();
switch (menuItem.getItemId()) {
case R.id.nav_item_colorlight:
Intent color = new Intent(MainActivity.this, HolopickerColor.class);
// color.putExtra("color", ConnectedThread.getInstance());
startActivity(color);
break;
case R.id.nav_item_effectlight:
Intent light = new Intent(MainActivity.this, LightEffect.class);
startActivity(light);
break;
case R.id.nav_item_music:
Intent music = new Intent(MainActivity.this, Music.class);
startActivity(music);
break;
case R.id.nav_item_about:
Intent about = new Intent(MainActivity.this, About.class);
startActivity(about);
break;
}
return true;
}
});
mProgressDlg.setMessage("Scanning...");
mProgressDlg.setCancelable(false);
mProgressDlg.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
BA.cancelDiscovery();
}
});
if (BA == null) {
showUnsupported();
} else {
mPairedBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Set<BluetoothDevice> pairedDevices = BA.getBondedDevices();
if (pairedDevices == null || pairedDevices.size() == 0) {
showToast("No Paired Devices Found");
} else {
ArrayList<BluetoothDevice> list = new ArrayList<BluetoothDevice>();
list.addAll(pairedDevices);
Intent intent = new Intent(MainActivity.this, DeviceListActivity.class);
intent.putParcelableArrayListExtra("device.list", list);
startActivity(intent);
}
}
});
find.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
BA.startDiscovery();
}
});
on.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (BA.isEnabled()) {
BA.disable();
showDisabled();
try
{
btSocket.close();
} catch (IOException e2)
{
//insert code to deal with this
}
} else {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1000);
}
}
});
if (BA.isEnabled()) {
showEnabled();
} else {
showDisabled();
}
}
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);
btnOn = (Button) findViewById(R.id.btnOn);
btnOff = (Button) findViewById(R.id.btnOff);
// Set up onClick listeners for buttons to send 1 or 0 to turn on/off LED
btnOff.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
/* r = 255;
g = 15;
b = 50;
mConnectedThread.write("r"+Integer.toString(r)+"\n"); // Send "0" via Bluetooth
mConnectedThread.write("g"+Integer.toString(g)+"\n");
mConnectedThread.write("b"+Integer.toString(b)+"\n");*/
ConnectedThread.getInstance().write("1");
Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show();
}
});
btnOn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//cathode nen 1 la off, o la on
ConnectedThread.getInstance().write("0"); // Send "1" via Bluetooth //gui nhan ne
Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show();
}
});
//Get MAC address from DeviceListActivity via intent
// Intent intent = getIntent();
//Get the MAC address from the DeviceListActivty via EXTRA
//address = intent.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// MAC-address of Bluetooth module (you must edit this line)
address = "30:14:10:09:07:86";
//create device and set the MAC address
BluetoothDevice device = BA.getRemoteDevice(address);
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show();
}
// Establish the Bluetooth socket connection.
try
{
btSocket.connect();
} catch (IOException e) {
try
{
btSocket.close();
} catch (IOException e2)
{
//insert code to deal with this
}
}
ConnectedThread.createInstance(btSocket);
ConnectedThread.getInstance().start();
//I send a character when resuming.beginning transmission to check device is connected
//If it is not an exception will be thrown in the write method and finish() will be called
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
return device.createRfcommSocketToServiceRecord(MY_UUID);
//creates secure outgoing connecetion with BT device using UUID
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch (id) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
public void onPause() {
if (BA != null) {
if (BA.isDiscovering()) {
BA.cancelDiscovery();
}
}
try
{
//Don't leave Bluetooth sockets open when leaving activity
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
super.onPause();
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
private void showEnabled() {
Toast.makeText(getApplicationContext(), "on", Toast.LENGTH_LONG).show();
on.setText("Disable");
on.setEnabled(true);
mPairedBtn.setEnabled(true);
find.setEnabled(true);
}
private void showDisabled() {
Toast.makeText(getApplicationContext(), "off", Toast.LENGTH_LONG).show();
on.setText("Enable");
on.setEnabled(true);
mPairedBtn.setEnabled(false);
find.setEnabled(false);
}
private void showUnsupported() {
Toast.makeText(getApplicationContext(), "Bluetooth is unsupported by this device", Toast.LENGTH_LONG).show();
on.setText("Enable");
on.setEnabled(false);
mPairedBtn.setEnabled(false);
find.setEnabled(false);
}
private void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothAdapter.STATE_ON) {
showToast("Enabled");
showEnabled();
}
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
mDeviceList = new ArrayList<BluetoothDevice>();
mProgressDlg.show();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
mProgressDlg.dismiss();
Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class);
newIntent.putParcelableArrayListExtra("device.list", mDeviceList);
startActivity(newIntent);
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device);
showToast("Found device " + device.getName());
}
}
};
Second activity :
public class HolopickerColor extends AppCompatActivity implements ColorPicker.OnColorChangedListener {
private TextView text;
com.larswerkman.holocolorpicker.ColorPicker picker;
SVBar svBar ;
Button test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_holopicker_color);
picker = (ColorPicker) findViewById(R.id.picker);
svBar = (SVBar) findViewById(R.id.svbar);
text = (TextView) findViewById(R.id.color1);
picker.addSVBar(svBar);
picker.getColor();
picker.setOnColorChangedListener(this);
picker.setShowOldCenterColor(false);// Tat mau cu
test = (Button)findViewById(R.id.test);
test.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ConnectedThread.getInstance().write("r255\n");
Toast.makeText(getBaseContext(),"yes",Toast.LENGTH_LONG).show();
}
});
//ConnectedThread.getInstance().start();
}
public void onColorChanged(int color) {
// TODO Auto-generated method stub
text.setTextColor(color);//hien mau len chu
if (ConnectedThread.getInstance() != null) {
int r = (color >> 16) & 0xFF;//xuat kieu mau ra thanh chu
int g = (color >> 8) & 0xFF;
int b = (color >> 0) & 0xFF;
// mTcpClient.sendMessage(Integer.toHexString(picker.getColor()));
ConnectedThread.getInstance().write("r255");//gui ko nhan ne
Here is the ConnectedThread :
class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final OutputStream mmOutStream; // cai nay e can implement Serializable nua
private static ConnectedThread instance = null;
private ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmOutStream = tmpOut;
}
public static void createInstance(BluetoothSocket socket) {
if (instance == null) {
instance = new ConnectedThread(socket);
}
}
public static ConnectedThread getInstance() {
return instance;
}
//write method
public void write(String input) {
byte[] msgBuffer = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(msgBuffer); //write bytes over BT connection via outstream
} catch (IOException e) {
cancel();
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
The problem is that you are creating your ConnectedThread singleton instance using a BluetoothSocket, and then you close that same socket in the onPause method of your activity. So basically, after onPause has been called, the ConnectedThread instance cannot send anything anymore. Instead of this you should have ConnectedThread manage the socket, i.e. keep a reference to it and then close it when you no longer need it or have detected a problem.
By the way, each time you call write on ConnectedThread after the socket is closed, your cancel method is called. You would have been able to easily detect the problem if you were not silencing exceptions in this method. This is why you should never have an empty catch block.

Categories