Related
I'm writing an app and it has a part which, on button click, scans for Bluetooth devices and shows them in a ListView. It works fine, but i need it to show only devices starting with a word in the name, for example: "MyArduino/123", so I need it to look for the "MyArduino/" part in device names and only show those that have it.
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.test.app.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/title"
android:textSize="20sp"
android:textAlignment="center"
android:text="#string/title"
android:gravity="center_horizontal" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/title"
android:text="#string/bt_menu"
android:background="#color/button"
android:onClick="showBt"
android:id="#+id/to_bt_menu"
android:layout_margin="10sp"
tools:ignore="UsingOnClickInXml" />
<Button
android:id="#+id/to_vars_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/title"
android:layout_marginLeft="10sp"
android:layout_marginStart="10sp"
android:layout_toEndOf="#id/to_bt_menu"
android:layout_toRightOf="#id/to_bt_menu"
android:onClick="showVars"
android:text="#string/vars_menu"
android:background="#color/button"
android:layout_margin="10sp"
tools:ignore="UsingOnClickInXml" />
<TextView
android:id="#+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/to_bt_menu"
android:visibility="gone"
android:ellipsize="end"
android:maxLines="1"
android:text="#string/status"
android:textStyle="bold" />
<TextView
android:id="#+id/bluetooth_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/to_bt_menu"
android:visibility="gone"
android:layout_toEndOf="#id/status"
android:layout_toRightOf="#id/status"
android:layout_marginLeft="20sp"
android:layout_marginStart="20sp"
android:ellipsize="end"
android:maxLines="1"
android:text="#string/bluetooth_status" />
<Button
android:id="#+id/scan"
android:layout_width="150sp"
android:layout_height="wrap_content"
android:layout_below="#id/bluetooth_status"
android:layout_margin="10sp"
android:visibility="gone"
android:text="#string/bluetooth_on"
android:background="#color/button" />
<Button
android:id="#+id/off"
android:layout_width="150sp"
android:layout_height="wrap_content"
android:layout_below="#id/bluetooth_status"
android:layout_margin="10sp"
android:visibility="gone"
android:layout_toRightOf="#id/scan"
android:layout_toEndOf="#id/scan"
android:background="#color/button"
android:text="#string/bluetooth_off" />
<Button
android:id="#+id/paired_btn"
android:layout_width="150sp"
android:layout_height="wrap_content"
android:layout_below="#id/off"
android:layout_margin="10sp"
android:visibility="gone"
android:text="#string/show_paired_devices"
android:background="#color/button" />
<Button
android:id="#+id/discover"
android:layout_width="150sp"
android:layout_height="wrap_content"
android:layout_below="#id/off"
android:layout_margin="10sp"
android:visibility="gone"
android:layout_toEndOf="#+id/paired_btn"
android:layout_toRightOf="#id/paired_btn"
android:text="#string/discover_new_devices"
android:background="#color/button" />
<ListView
android:id="#+id/devices_list_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/discover"
android:visibility="gone"
android:choiceMode="singleChoice" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20sp"
android:onClick="reqVars"
android:text="#string/req_btn"
android:layout_below="#id/user_edit"
android:visibility="gone"
android:id="#+id/req_btn"
android:layout_margin="10sp"
android:background="#color/button" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/to_vars_menu"
android:layout_margin="10sp"
android:visibility="gone"
android:id="#+id/user_edit"
android:hint="#string/hint_edit"
tools:ignore="TextFields"/>
<Button
android:id="#+id/send_edit_btn"
android:layout_margin="10sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/user_edit"
android:visibility="gone"
android:layout_marginStart="20sp"
android:layout_marginLeft="20sp"
android:layout_marginTop="20sp"
android:layout_toEndOf="#+id/req_btn"
android:layout_toRightOf="#+id/req_btn"
android:onClick="editVar"
android:text="#string/send_edit_btn"
android:background="#color/button" />
<ListView
android:layout_below="#id/req_btn"
android:visibility="gone"
android:id="#+id/vars"
android:choiceMode="singleChoice"
android:listSelector="#color/list"
android:layout_width="300sp"
android:layout_height="wrap_content" />
</RelativeLayout>
MainActivity:
package com.test.app;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private final String TAG = MainActivity.class.getSimpleName();
private static final UUID BT_MODULE_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // "random" unique identifier
// #defines for identifying shared types between calling functions
private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names
public final static int MESSAGE_READ = 2; // used in bluetooth handler to identify message update
private final static int CONNECTING_STATUS = 3; // used in bluetooth handler to identify message status
// GUI Components
private TextView mBluetoothStatus;
private Button mScanBtn;
private Button mOffBtn;
private Button mListPairedDevicesBtn;
private Button mDiscoverBtn;
private ListView mDevicesListView;
private TextView mStatus;
private EditText mUserEdit;
private Button mReqBtn;
private Button mSendEdit;
private ListView mVars;
private String mSelecVar;
private String mMessage;
private BluetoothAdapter mBTAdapter;
private Set<BluetoothDevice> mPairedDevices;
private ArrayList<BluetoothDevice> mBTDevices;
private ArrayAdapter<String> mBTArrayAdapter;
private Handler mHandler; // Our main handler that will receive callback notifications
private ConnectedThread mConnectedThread; // bluetooth background worker thread to send and receive data
private BluetoothSocket mBTSocket = null; // bi-directional client-to-client data path
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Objects.requireNonNull(getSupportActionBar()).hide();
} else {
getSupportActionBar().hide();
}
setContentView(R.layout.activity_main);
mBluetoothStatus = (TextView)findViewById(R.id.bluetooth_status);
mScanBtn = (Button)findViewById(R.id.scan);
mOffBtn = (Button)findViewById(R.id.off);
mDiscoverBtn = (Button)findViewById(R.id.discover);
mListPairedDevicesBtn = (Button)findViewById(R.id.paired_btn);
mStatus = (TextView)findViewById(R.id.status);
mUserEdit = (EditText)findViewById(R.id.user_edit);
mReqBtn = (Button)findViewById(R.id.req_btn);
mSendEdit = (Button)findViewById(R.id.send_edit_btn);
mVars = (ListView)findViewById(R.id.vars);
mBTArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
mBTDevices = new ArrayList<>();
mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio
mDevicesListView = (ListView)findViewById(R.id.devices_list_view);
assert mDevicesListView != null;
mDevicesListView.setAdapter(mBTArrayAdapter); // assign model to view
mDevicesListView.setOnItemClickListener(mDeviceClickListener);
mVars.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mSelecVar = mVars.getItemAtPosition(position).toString().split(",")[0];
}
});
// Ask for location permission if not already allowed
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
mHandler = new Handler(Looper.getMainLooper()){
#Override
public void handleMessage(Message msg){
if(msg.what == MESSAGE_READ){
String readMessage = null;
try {
readMessage = new String((byte[]) msg.obj, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
mMessage = readMessage;
if (mMessage != null) {
for (int i = 0; i < mMessage.length(); i++) {
if (mMessage.toCharArray()[i] == ';') {
getVars(mMessage);
break;
}
}
}
}
if(msg.what == CONNECTING_STATUS){
if(msg.arg1 == 1) {
mBluetoothStatus.setText("Connected to Device: " + msg.obj);
mConnectedThread.write("list");
} else
mBluetoothStatus.setText("Connection Failed");
}
}
};
if (mBTArrayAdapter == null) {
// Device does not support Bluetooth
mBluetoothStatus.setText("Status: Bluetooth not found");
Toast.makeText(getApplicationContext(),"Bluetooth device not found!",Toast.LENGTH_SHORT).show();
}
else {
mScanBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bluetoothOn();
}
});
mOffBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
bluetoothOff();
}
});
mListPairedDevicesBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
listPairedDevices();
}
});
mDiscoverBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
discover();
}
});
}
}
private void bluetoothOn(){
if (!mBTAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
mBluetoothStatus.setText("Bluetooth enabled");
Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
}
}
// Enter here after user selects "yes" or "no" to enabling radio
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent Data){
// Check which request we're responding to
if (requestCode == REQUEST_ENABLE_BT) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
mBluetoothStatus.setText("Enabled");
}
else
mBluetoothStatus.setText("Disabled");
}
}
private void bluetoothOff(){
mBTAdapter.disable(); // turn off
mBluetoothStatus.setText("Bluetooth disabled");
Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
}
private void discover(){
// Check if the device is already discovering
if(mBTAdapter.isDiscovering()){
mBTAdapter.cancelDiscovery();
Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
}
else{
if(mBTAdapter.isEnabled()) {
mBTArrayAdapter.clear(); // clear items
mBTAdapter.startDiscovery();
Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
}
else{
Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
}
}
}
final BroadcastReceiver blReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// add the name to the list
mBTDevices.add(device);
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
mBTArrayAdapter.notifyDataSetChanged();
}
if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
BluetoothDevice mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (mDevice.getBondState() == BluetoothDevice.BOND_BONDED){
Log.d(TAG, "BroadcastReceiver: BOND_BONDED");
}
if (mDevice.getBondState() == BluetoothDevice.BOND_BONDING){
Log.d(TAG, "BroadcastReceiver: BOND_BONDING");
}
if (mDevice.getBondState() == BluetoothDevice.BOND_NONE){
Log.d(TAG, "BroadcastReceiver: BOND_NONE");
}
}
}
};
private void listPairedDevices(){
mBTArrayAdapter.clear();
mPairedDevices = mBTAdapter.getBondedDevices();
if(mBTAdapter.isEnabled()) {
// put it's one to the adapter
for (BluetoothDevice device : mPairedDevices)
if (device.getName().equals("MyArduino/")){
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
Toast.makeText(getApplicationContext(), "Show Paired Devices", Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
}
private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(!mBTAdapter.isEnabled()) {
Toast.makeText(getBaseContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
return;
}
mBluetoothStatus.setText("Connecting...");
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) view).getText().toString();
final String address = info.substring(info.length() - 17);
final String name = info.substring(0,info.length() - 17);
// Spawn a new thread to avoid blocking the GUI one
new Thread()
{
#Override
public void run() {
boolean fail = false;
BluetoothDevice device = mBTAdapter.getRemoteDevice(address);
try {
mBTSocket = createBluetoothSocket(device);
} catch (IOException e) {
fail = true;
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
}
// Establish the Bluetooth socket connection.
try {
mBTSocket.connect();
} catch (IOException e) {
try {
fail = true;
mBTSocket.close();
mHandler.obtainMessage(CONNECTING_STATUS, -1, -1)
.sendToTarget();
} catch (IOException e2) {
//insert code to deal with this
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
}
}
if(!fail) {
mConnectedThread = new ConnectedThread(mBTSocket, mHandler);
mConnectedThread.start();
mHandler.obtainMessage(CONNECTING_STATUS, 1, -1, name)
.sendToTarget();
}
}
}.start();
}
};
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
try {
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", UUID.class);
return (BluetoothSocket) m.invoke(device, BT_MODULE_UUID);
} catch (Exception e) {
Log.e(TAG, "Could not create Insecure RFComm Connection",e);
}
return device.createRfcommSocketToServiceRecord(BT_MODULE_UUID);
}
public void showBt(View view) {
mBluetoothStatus.setVisibility(View.VISIBLE);
mScanBtn.setVisibility(View.VISIBLE);
mOffBtn.setVisibility(View.VISIBLE);
mDiscoverBtn.setVisibility(View.VISIBLE);
mListPairedDevicesBtn.setVisibility(View.VISIBLE);
mDevicesListView.setVisibility(View.VISIBLE);
mStatus.setVisibility(View.VISIBLE);
mVars.setVisibility(View.GONE);
mUserEdit.setVisibility(View.GONE);
mSendEdit.setVisibility(View.GONE);
mReqBtn.setVisibility(View.GONE);
}
public void showVars(View view) {
mBluetoothStatus.setVisibility(View.GONE);
mScanBtn.setVisibility(View.GONE);
mOffBtn.setVisibility(View.GONE);
mDiscoverBtn.setVisibility(View.GONE);
mListPairedDevicesBtn.setVisibility(View.GONE);
mDevicesListView.setVisibility(View.GONE);
mStatus.setVisibility(View.GONE);
mVars.setVisibility(View.VISIBLE);
mUserEdit.setVisibility(View.VISIBLE);
mSendEdit.setVisibility(View.VISIBLE);
mReqBtn.setVisibility(View.VISIBLE);
}
public void reqVars(View view) {
if (mConnectedThread != null){
mConnectedThread.write("list");
}
}
public void getVars(String string) {
String[] str = string.split(";");
List<String> al;
al = Arrays.asList(str);
ArrayAdapter<String> mVarsArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, al);
mVars.setAdapter(mVarsArrayAdapter);
}
public void editVar(View view) {
if (mConnectedThread != null) {
mConnectedThread.write("edit " + mSelecVar + " " + mUserEdit.getText());
mUserEdit.setText("");
SystemClock.sleep(2000);
mConnectedThread.write("list");
}
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
mBTAdapter.cancelDiscovery();
Log.d(TAG, "onItemClick: You clicked on a device.");
String deviceName = mBTDevices.get(i).getName();
String deviceAddress = mBTDevices.get(i).getAddress();
Log.d(TAG, "onItemClick: deviceName = " + deviceName);
Log.d(TAG, "onItemClick: deviceAddress = " + deviceAddress);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2){
Log.d(TAG, "Trying to pair with " + deviceName);
mBTDevices.get(i).createBond();
}
}
}
ConnectedThread:
package com.test.app;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.SystemClock;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private final Handler mHandler;
public ConnectedThread(BluetoothSocket socket, Handler handler) {
mmSocket = socket;
mHandler = handler;
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) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
#Override
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.available();
if(bytes != 0) {
buffer = new byte[1024];
SystemClock.sleep(100); //pause and wait for rest of data. Adjust this depending on your sending speed.
bytes = mmInStream.available(); // how many bytes are ready to be read?
bytes = mmInStream.read(buffer, 0, bytes); // record how many bytes we actually read
mHandler.obtainMessage(MainActivity.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget(); // Send the obtained bytes to the UI activity
}
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(String input) {
byte[] bytes = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
Right now, the ListView shows all the devices that the Bluetooth founds, and sometimes, even shows them 2 or 3 times in the same list. As you can see in the MainActivity, i tried to make some sort of a filter in line 272 but it just does not work. Thanks
You trying to get device name equals to "MyArduino/" but what you need is actually device name how start with "MyArduino/":
just replace this line in listPairedDevices() on MainActivity:
from : (equals)
if (device.getName().equals("MyArduino/")){
to : (startsWith)
if (device.getName().startsWith("MyArduino/")){
editting the answer
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//before adding the device:
if(device.getName().startsWith("MyArduino/")){
// add the name to the list
mBTDevices.add(device);
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
mBTArrayAdapter.notifyDataSetChanged();
}
}
So, after hours of trial and error, the problem was solved.
I've noticed this line in the errors on crash:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.startsWith(java.lang.String)' on a null object reference
It means that the function was looking for "MyArduino/" in a null object.
So i modified this:
if(device.getName().startsWith("MyArduino/")){
mBTDevices.add(device);
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
mBTArrayAdapter.notifyDataSetChanged();
}
To this:
if (device.getName() != null) {
if (device.getName().contains("MyAdruino/")) {
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
mBTArrayAdapter.notifyDataSetChanged();
}
}
And the problem was solved. It just showed the devices with "MyAdruino/" names and only once. Hope this will help anyone that gets the same problem
Hi i am actually working on app to send command line on the terminal of my Raspberry PI 3.
I wouldlike when i press the button save for example to send the command "ls" to my RPI3.
Acutally, I've got some problem with my object BluetoothconnectionService.
I think I can't send data because my object is not declared on my activity "Accueil" ? `
BluetoothConnectionService.java :
public class BluetoothConnectionService {
private static final String TAG = "BluetoothConnectionServ";
private static final String appName = "MYAPP";
private static final UUID MY_UUID_INSECURE = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");
private final BluetoothAdapter mBluetoothAdapter;
private ConnectedThread mConnectedThread;
private AcceptThread mInsecureAcceptThread;
private ConnectThread mConnectThread;
private BluetoothDevice mmDevice;
private UUID deviceUUID;
ProgressDialog mProgressDialog;
Context mContext;
public BluetoothConnectionService(Context context) {
mContext = context;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
start();
}
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
private BluetoothSocket socket = null;
private InputStream mmInStream;
private String device;
public AcceptThread(){
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try{
tmp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(appName, MY_UUID_INSECURE);
Log.d(TAG, "AcceptThread: Setting up Server using: " + MY_UUID_INSECURE);
}catch (IOException e){
Log.e(TAG, "AcceptThread: IOException: " + e.getMessage() );
}
mmServerSocket = tmp;
}
public void run(){
Log.d(TAG, "run: AcceptThread Running.");
BluetoothSocket socket = null;
try{
// This is a blocking call and will only return on a
// successful connection or an exception
Log.d(TAG, "run: RFCOM server socket start.....");
socket = mmServerSocket.accept();
Log.d(TAG, "run: RFCOM server socket accepted connection.");
}catch (IOException e){
Log.e(TAG, "AcceptThread: IOException: " + e.getMessage() );
}
//talk about this is in the 3rd
if(socket != null){
connected(socket,mmDevice);
}
Log.i(TAG, "END mAcceptThread ");
}
public void cancel() {
Log.d(TAG, "cancel: Canceling AcceptThread.");
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "cancel: Close of AcceptThread ServerSocket failed. " + e.getMessage() );
}
}
}
private class ConnectThread extends Thread {
private BluetoothSocket mmSocket;
public ConnectThread(BluetoothDevice device, UUID uuid) {
Log.d(TAG, "ConnectThread: started.");
mmDevice = device;
deviceUUID = uuid;
}
public void run(){
BluetoothSocket tmp = null;
Log.i(TAG, "RUN mConnectThread ");
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
Log.d(TAG, "ConnectThread: Trying to create InsecureRfcommSocket using UUID: "
+MY_UUID_INSECURE );
tmp = mmDevice.createRfcommSocketToServiceRecord(deviceUUID);
} catch (IOException e) {
Log.e(TAG, "ConnectThread: Could not create InsecureRfcommSocket " + e.getMessage());
}
mmSocket = tmp;
// Always cancel discovery because it will slow down a connection
mBluetoothAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
Log.d(TAG, "run: ConnectThread connected.");
} catch (IOException e) {
// Close the socket
try {
mmSocket.close();
Log.d(TAG, "run: Closed Socket.");
} catch (IOException e1) {
Log.e(TAG, "mConnectThread: run: Unable to close connection in socket " + e1.getMessage());
}
Log.d(TAG, "run: ConnectThread: Could not connect to UUID: " + MY_UUID_INSECURE );
}
//will talk about this in the 3rd video
connected(mmSocket,mmDevice);
}
public void cancel() {
try {
Log.d(TAG, "cancel: Closing Client Socket.");
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "cancel: close() of mmSocket in Connectthread failed. " + e.getMessage());
}
}
}
public synchronized void start() {
Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mInsecureAcceptThread == null) {
mInsecureAcceptThread = new AcceptThread();
mInsecureAcceptThread.start();
}
}
public void startClient(BluetoothDevice device,UUID uuid){
Log.d(TAG, "startClient: Started.");
//initprogress dialog
mProgressDialog = ProgressDialog.show(mContext,"Connecting Bluetooth"
,"Please Wait...",true);
mConnectThread = new ConnectThread(device, uuid);
mConnectThread.start();
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "ConnectedThread: Starting.");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
int error=2;
int i;
//dismiss the progressdialog when connection is established
try{
mProgressDialog.dismiss();
error=1;
}catch (NullPointerException e){
e.printStackTrace();
error=0;
}
try {
tmpIn = mmSocket.getInputStream();
tmpOut = mmSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run(){
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
final String strReceived = new String(buffer,0,bytes);
final String strByteCnt = String.valueOf(bytes) + "bytes received. \n";
// Send the obtained bytes to the UI activity
} catch (IOException e) {
Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage() );
break;
}
}
}
//Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
Log.e(TAG, "write: Error writing to output stream. " + e.getMessage() );
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private void connected(BluetoothSocket mmSocket, BluetoothDevice mmDevice) {
Log.d(TAG, "connected: Starting.");
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
Log.d(TAG, "write: Write Called.");
//perform the write
mConnectedThread.write(out);
}
}
MainActivity.java :`
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
// variables
private static final String TAG = "MainActivity";
private Uri[] mFileUris = new Uri[10];
private static final UUID MY_UUID_INSECURE = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");
public ArrayList<BluetoothDevice> mBTDevices = new ArrayList<>();
public DeviceListAdapter mDeviceListAdapter;
// Bluetooth object
BluetoothAdapter mBluetoothAdapter;
BluetoothConnectionService mBluetoothConnection;
BluetoothDevice mBTDevice;
// variables button
Button btnStartConnection;
Button scan;
// Image button
ImageButton btnONOFF;
// Variables affichages
StringBuilder messages;
ListView lvNewDevices;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Constructor
mBTDevices = new ArrayList<>();
messages = new StringBuilder();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
// list findViewbyID
btnONOFF = (ImageButton) findViewById(R.id.bluetooth_on_off);
scan = (Button) findViewById(R.id.scan);
btnStartConnection = (Button) findViewById(R.id.Connect);
lvNewDevices = (ListView) findViewById(R.id.lvNewDevices);
// divers
registerReceiver(mBroadcastReceiver4, filter);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
lvNewDevices.setOnItemClickListener(MainActivity.this);
// ON/OFF BLUETOOTH
btnONOFF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
enableDisableBT();
}
});
// SCAN
scan.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
btnDiscover();
btnEnableDisable_Discoverable();
}
});
// CONNECTION
btnStartConnection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startConnection();
}
});
}
// 4 BroadcastReceiver
// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver mBroadcastReceiver1 = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (action.equals(mBluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, mBluetoothAdapter.ERROR);
switch(state){
case BluetoothAdapter.STATE_OFF:
Log.d(TAG, "onReceive: STATE OFF");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.d(TAG, "mBroadcastReceiver1: STATE TURNING OFF");
break;
case BluetoothAdapter.STATE_ON:
Log.d(TAG, "mBroadcastReceiver1: STATE ON");
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log.d(TAG, "mBroadcastReceiver1: STATE TURNING ON");
break;
}
}
}
};
private final BroadcastReceiver mBroadcastReceiver2 = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)) {
int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.ERROR);
switch (mode) {
//Device is in Discoverable Mode
case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
Log.d(TAG, "mBroadcastReceiver2: Discoverability Enabled.");
break;
//Device not in discoverable mode
case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
Log.d(TAG, "mBroadcastReceiver2: Discoverability Disabled. Able to receive connections.");
break;
case BluetoothAdapter.SCAN_MODE_NONE:
Log.d(TAG, "mBroadcastReceiver2: Discoverability Disabled. Not able to receive connections.");
break;
case BluetoothAdapter.STATE_CONNECTING:
Log.d(TAG, "mBroadcastReceiver2: Connecting....");
break;
case BluetoothAdapter.STATE_CONNECTED:
Log.d(TAG, "mBroadcastReceiver2: Connected.");
break;
}
}
}
};
private BroadcastReceiver mBroadcastReceiver3 = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.d(TAG, "onReceive: ACTION FOUND.");
if (action.equals(BluetoothDevice.ACTION_FOUND)){
BluetoothDevice device = intent.getParcelableExtra (BluetoothDevice.EXTRA_DEVICE);
mBTDevices.add(device);
Log.d(TAG, "onReceive: " + device.getName() + ": " + device.getAddress());
mDeviceListAdapter = new DeviceListAdapter(context, R.layout.device_adapter_view, mBTDevices);
lvNewDevices.setAdapter(mDeviceListAdapter);
}
}
};
/**
* Broadcast Receiver that detects bond state changes (Pairing status changes)
*/
private final BroadcastReceiver mBroadcastReceiver4 = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
BluetoothDevice mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//3 cases:
//case1: bonded already
if (mDevice.getBondState() == BluetoothDevice.BOND_BONDED){
Log.d(TAG, "BroadcastReceiver: BOND_BONDED.");
//inside BroadcastReceiver4
mBTDevice = mDevice;
}
//case2: creating a bone
if (mDevice.getBondState() == BluetoothDevice.BOND_BONDING) {
Log.d(TAG, "BroadcastReceiver: BOND_BONDING.");
}
//case3: breaking a bond
if (mDevice.getBondState() == BluetoothDevice.BOND_NONE) {
Log.d(TAG, "BroadcastReceiver: BOND_NONE.");
}
}
}
};
//create method for starting connection
public void startConnection(){
startBTConnection(mBTDevice,MY_UUID_INSECURE);
goToAcceuil();
}
public void startBTConnection(BluetoothDevice device, UUID uuid){
Log.d(TAG, "startBTConnection: Initializing RFCOM Bluetooth Connection.");
mBluetoothConnection.startClient(device,uuid);
}
public void enableDisableBT(){
if(mBluetoothAdapter == null){
Log.d(TAG, "enableDisableBT: Does not have BT capabilities.");
}
if(!mBluetoothAdapter.isEnabled()){
Log.d(TAG, "enableDisableBT: enabling BT.");
Intent enableBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBTIntent);
IntentFilter BTIntent = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBroadcastReceiver1, BTIntent);
}
if(mBluetoothAdapter.isEnabled()){
Log.d(TAG, "enableDisableBT: disabling BT.");
mBluetoothAdapter.disable();
IntentFilter BTIntent = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBroadcastReceiver1, BTIntent);
}
}
public void btnEnableDisable_Discoverable() {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
IntentFilter intentFilter = new IntentFilter(mBluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
registerReceiver(mBroadcastReceiver2,intentFilter);
}
public void btnDiscover() {
Log.d(TAG, "btnDiscover: Looking for unpaired devices.");
if(mBluetoothAdapter.isDiscovering()){
mBluetoothAdapter.cancelDiscovery();
Log.d(TAG, "btnDiscover: Canceling discovery.");
//check BT permissions in manifest
checkBTPermissions();
mBluetoothAdapter.startDiscovery();
IntentFilter discoverDevicesIntent = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mBroadcastReceiver3, discoverDevicesIntent);
}
if(!mBluetoothAdapter.isDiscovering()){
//check BT permissions in manifest
checkBTPermissions();
mBluetoothAdapter.startDiscovery();
IntentFilter discoverDevicesIntent = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mBroadcastReceiver3, discoverDevicesIntent);
}
}
/**
* This method is required for all devices running API23+
* Android must programmatically check the permissions for bluetooth. Putting the proper permissions
* in the manifest is not enough.
*
* NOTE: This will only execute on versions > LOLLIPOP because it is not needed otherwise.
*/
private void checkBTPermissions() {
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP){
int permissionCheck = this.checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
permissionCheck += this.checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
if (permissionCheck != 0) {
this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001); //Any number
}
}else{
Log.d(TAG, "checkBTPermissions: No need to check permissions. SDK version < LOLLIPOP.");
}
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//first cancel discovery because its very memory intensive.
mBluetoothAdapter.cancelDiscovery();
Log.d(TAG, "onItemClick: You Clicked on a device.");
String deviceName = mBTDevices.get(i).getName();
String deviceAddress = mBTDevices.get(i).getAddress();
Log.d(TAG, "onItemClick: deviceName = " + deviceName);
Log.d(TAG, "onItemClick: deviceAddress = " + deviceAddress);
//create the bond.
//NOTE: Requires API 17+? I think this is JellyBean
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2){
Log.d(TAG, "Trying to pair with " + deviceName);
mBTDevices.get(i).createBond();
mBTDevice = mBTDevices.get(i);
mBluetoothConnection = new BluetoothConnectionService(MainActivity.this);
}
}
public void goToAcceuil (){
Intent intent = new Intent (this,Accueil.class);
intent.putExtra("DEVICE_NAME", mBTDevice.getName());
intent.putExtra("DEVICE_ADRESS", mBTDevice.getAddress());
intent.putExtra("mBTDevice",mBTDevice);
//intent.putExtra("mBluetoothConnection",mBluetoothConnection);
startActivity(intent);
}
protected void onDestroy() {
Log.d(TAG, "onDestroy: called.");
super.onDestroy();
unregisterReceiver(mBroadcastReceiver1);
unregisterReceiver(mBroadcastReceiver2);
unregisterReceiver(mBroadcastReceiver3);
unregisterReceiver(mBroadcastReceiver4);
}
}
Accueil.java :
public class Accueil extends AppCompatActivity {
// Bluetooth
BluetoothConnectionService mBluetoothConnection;
BluetoothDevice mBTDevice;
// String
String name_device1;
String adress_device1;
String freq_value1;
String item_spin1;
String item_spin;
// Image Button
ImageButton btn_back;
ImageButton btn_accueil;
ImageButton btn_voice;
ImageButton btn_scan;
ImageButton btn_settings;
// Button
Button btn_send_freq;
// Textview
TextView name_device;
TextView adress_device;
// Edit Text
EditText freq_value;
// List
ArrayAdapter<String> adapter;
List<String> list;
// Spinner
Spinner spinner1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_accueil);
// Variables from other activity
name_device1= getIntent().getStringExtra("DEVICE_NAME");
adress_device1=getIntent().getStringExtra("DEVICE_ADRESS");
mBTDevice=getIntent().getExtras().getParcelable("mBTDevice");
//mBluetoothConnection=getIntent().getExtras().getParcelable("mBluetoothConnection");
freq_value1=getIntent().getStringExtra("VALUE_FREQ");
item_spin1=getIntent().getStringExtra("VALUE_SPIN");
// findView by ID
name_device= (TextView) findViewById(R.id.name_device2);
adress_device= (TextView) findViewById(R.id.adress_device2);
btn_back = (ImageButton) findViewById(R.id.back1);
btn_accueil = (ImageButton) findViewById(R.id.accueil1);
btn_voice = (ImageButton) findViewById(R.id.voice1);
btn_scan = (ImageButton) findViewById(R.id.scan1);
btn_settings= (ImageButton) findViewById(R.id.settings1);
btn_send_freq = (Button) findViewById(R.id.send_freq1);
freq_value = (EditText) findViewById(R.id.value_freq1);
spinner1=(Spinner) findViewById(R.id.spinner_freq);
// SetText
name_device.setText(name_device1);
adress_device.setText(adress_device1);
freq_value.setText(freq_value1);
// Spinner
list=new ArrayList<String>();
list.add("MHz");
list.add("GHz");
adapter= new ArrayAdapter<String>(this,R.layout.spinner_item,list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner1.setAdapter(adapter);
btn_send_freq.setOnClickListener(new View.OnClickListener() { // Bouton Save
#Override
public void onClick(View view) {
send_freq();
}
});
btn_back.setOnClickListener(new View.OnClickListener() { // Bouton RETOUR
#Override
public void onClick(View view) {
gotoBack();
}
});
btn_accueil.setOnClickListener(new View.OnClickListener() { // Bouton ACCUEIL
#Override
public void onClick(View view) {
gotoAccueil();
}
});
btn_voice.setOnClickListener(new View.OnClickListener() { // Bouton VOICE
#Override
public void onClick(View view) {
gotoVoice();
}
});
btn_scan.setOnClickListener(new View.OnClickListener() { // Bouton SCAN
#Override
public void onClick(View view) {
gotoScan();
}
});
btn_settings.setOnClickListener(new View.OnClickListener() { // Bouton SETTINGS
#Override
public void onClick(View view) {
gotoSettings();
}
});
}
// Fonction
public void send_freq()
{
byte[] bytesToSend="sudo rm azertyy".getBytes();
mBluetoothConnection.write(bytesToSend);
byte[] NewLine = "\n".getBytes();
mBluetoothConnection.write(NewLine);
}
// Fonctions onglets
public void gotoBack() // Onglet PRECEDENT
{
Intent intent = new Intent (this,MainActivity.class);
startActivity(intent);
}
public void gotoAccueil() // Onglet ACCUEIL
{
Intent intent = new Intent (this,Accueil.class);
// get selected vale and start new activity
item_spin= spinner1.getSelectedItem().toString();
intent.putExtra("DEVICE_NAME", mBTDevice.getName());
intent.putExtra("DEVICE_ADRESS", mBTDevice.getAddress());
intent.putExtra("VALUE_FREQ", freq_value.getText().toString());
intent.putExtra("VALUE_SPIN", item_spin);
intent.putExtra("mBTDevice",mBTDevice);
startActivity(intent);
}
public void gotoVoice() // Onglet VOICE
{
Intent intent = new Intent (this,voice.class);
// get selected vale and start new activity
item_spin= spinner1.getSelectedItem().toString();
intent.putExtra("DEVICE_NAME", mBTDevice.getName());
intent.putExtra("DEVICE_ADRESS", mBTDevice.getAddress());
intent.putExtra("VALUE_FREQ", freq_value.getText().toString());
intent.putExtra("VALUE_SPIN", item_spin);
intent.putExtra("mBTDevice",mBTDevice);
startActivity(intent);
}
public void gotoScan() // Onglet SCAN
{
Intent intent = new Intent (this,Scan.class);
// get selected vale and start new activity
item_spin= spinner1.getSelectedItem().toString();
intent.putExtra("DEVICE_NAME", mBTDevice.getName());
intent.putExtra("DEVICE_ADRESS", mBTDevice.getAddress());
intent.putExtra("VALUE_FREQ", freq_value.getText().toString());
intent.putExtra("VALUE_SPIN", item_spin);
intent.putExtra("mBTDevice",mBTDevice);
startActivity(intent);
}
public void gotoSettings() // Onglet SETTINGS
{
Intent intent = new Intent (this,connection.class);
// get selected vale and start new activity
item_spin= spinner1.getSelectedItem().toString();
intent.putExtra("DEVICE_NAME", mBTDevice.getName());
intent.putExtra("DEVICE_ADRESS", mBTDevice.getAddress());
intent.putExtra("VALUE_FREQ", freq_value.getText().toString());
intent.putExtra("VALUE_SPIN", item_spin);
intent.putExtra("mBTDevice",mBTDevice);
startActivity(intent);
}
}
With this function, I wouldlike to send "ls" on the terminal of my RPI3 :`
public void send_freq()
{
byte[] bytesToSend="ls".getBytes();
mBluetoothConnection.write(bytesToSend);
byte[] NewLine = "\n".getBytes();
mBluetoothConnection.write(NewLine);
}
But I don't understand, I have some error like that :enter image description here
I tried to resolve that with Parcelable, but no sucess... enter image description here
So my code does not work. My app crash all time...
Thanks for any help !
From my understanding you have a button inside your MainActivity.java that opens another Activity (Accueil.java) via an Intent. And in doing so, you are sending an Intent with extras to transfer data between them.
An Intent can only take an object as an extra if it implements the Parcelable interface.
Here you attempted to add BluetoothConnectionService that does not implement Parcelable.
You commented it out because it was giving you the error you showed in the screenshot.
//intent.putExtra("mBluetoothConnection",mBluetoothConnection);
Which means inside of Accueil.java your mBluetoothConnection will be null causing your app to crash.
//mBluetoothConnection=getIntent().getExtras().getParcelable("mBluetoothConnection");
Solutions to this problem would be to either
Find a way to make BluetoothConnectionService implement Parcelable
If possible, re-instantiate BluetoothConnectionService.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
im trying to make Tic-tac-toe game using BT connection.
But when i added code which should show paired devices it crash when i try run app.
It looks like problem with "listView.setOnItemClickListener()".
Game parts worked without problem.
main java:
public class XO extends Activity implements OnItemClickListener {
Button b0,b1,b2,b3,b4,b5,b6,b7,b8,bConnect,bDisconnect,bExit,bClear,bWin,bLoss;
Button[] bArray;
TextView tAlert;
int win = 0,
loss = 0,
cout=0,
msg=0;
boolean mode = false,
wait = false;
ArrayAdapter<String> listAdapter;
ListView listView;
BluetoothAdapter btAdapter;
Set<BluetoothDevice> devicesArray;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
IntentFilter filter;
BroadcastReceiver receiver;
String tag = "debugging";
Handler mHandler = new Handler(){
#Override
public void handleMessage (Message msg)
{
Log.i(tag, "in handler");
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
Toast.makeText(getApplicationContext(), "CONNECT", Toast.LENGTH_SHORT).show();
String s = "successfully connected";
connectedThread.write(s.getBytes());
Log.i(tag, "connected");
break;
case MESSAGE_READ:
byte[] readBuf = (byte[])msg.obj;
String string = new String(readBuf);
Toast.makeText(getApplicationContext(), string, Toast.LENGTH_SHORT).show();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xo);
tAlert = (TextView) findViewById(R.id.tAlert);
b0 = (Button) findViewById(R.id.b0);
b1 = (Button) findViewById(R.id.b1);
b2 = (Button) findViewById(R.id.b2);
b3 = (Button) findViewById(R.id.b3);
b4 = (Button) findViewById(R.id.b4);
b5 = (Button) findViewById(R.id.b5);
b6 = (Button) findViewById(R.id.b6);
b7 = (Button) findViewById(R.id.b7);
b8 = (Button) findViewById(R.id.b8);
bWin = (Button) findViewById(R.id.bWin);
bLoss = (Button) findViewById(R.id.bLoss);
bConnect = (Button) findViewById(R.id.bConnect);
bDisconnect = (Button) findViewById(R.id.bDisconnect);
bExit = (Button) findViewById(R.id.bExit);
bClear = (Button) findViewById(R.id.bClear);
bWin.setText(String.valueOf(win));
bLoss.setText(String.valueOf(loss));
tAlert.setText("By nawiązać połączenie urządzenia muszą być sparowane");
bArray = new Button[]{b0,b1,b2,b3,b4,b5,b6,b7,b8};
bConnect.setOnClickListener(new bConnectListener());
bDisconnect.setOnClickListener(new bDisconnectListener());
bClear.setOnClickListener(new bClearListener());
bExit.setOnClickListener(new bExitListener());
for(Button b : bArray){
b.setOnClickListener(new bListener());
}
init();
if(btAdapter==null){
Toast.makeText(getApplicationContext(), "No bluetooth detected", Toast.LENGTH_SHORT).show();
finish();
}else{
if(!btAdapter.isEnabled()){
turnOnBT();
}
getPairedDevices();
startDiscovery();
}
}
private void startDiscovery() {
btAdapter.cancelDiscovery();
btAdapter.startDiscovery();
}
private void turnOnBT() {
Intent intent =new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private void getPairedDevices() {
devicesArray=btAdapter.getBondedDevices();
if(devicesArray.size()>0){
for(BluetoothDevice device:devicesArray){
pairedDevices.add(device.getName());
}
}
}
public void init() {
listView = (ListView) findViewById(R.id.listView);
listView.setOnItemClickListener(this);
listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 0);
listView.setAdapter(listAdapter);
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devices = new ArrayList<BluetoothDevice>();
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices.add(device);
String s = "";
for(int a=0; a<pairedDevices.size(); a++){
if(device.getName().equals(pairedDevices.get(a))){
s = "(Paired)";
break;
}
}
listAdapter.add(device.getName()+" "+s+" "+"\n"+device.getAddress());
}
else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
}
else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
if(btAdapter.getState() == btAdapter.STATE_OFF){
turnOnBT();
}
}
}
};
registerReceiver(receiver, filter);
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "Bluetooth must be enabled to continue", Toast.LENGTH_SHORT).show();
finish();
}
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3){
if(btAdapter.isDiscovering()){
btAdapter.cancelDiscovery();
}
if (listAdapter.getItem(arg2).contains("Paired")){
BluetoothDevice selectedDevice = devices.get(arg2);
ConnectThread connect = new ConnectThread(selectedDevice);
connect.start();
Log.i(tag, "in click listener");
}else{
Toast.makeText(getApplicationContext(), "device is not paired", Toast.LENGTH_SHORT).show();
}
}
private class ConnectThread extends Thread{
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device){
BluetoothSocket tmp = null;
mmDevice = device;
Log.i(tag, "construct");
try{
tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e){
Log.i(tag, "get socket failed");
}
mmSocket = tmp;
}
public void run(){
btAdapter.cancelDiscovery();
Log.i(tag,"connect-run");
try {
mmSocket.connect();
Log.i(tag, "connect - succeeded");
} catch (IOException connectException) { Log.i(tag, "connect failed");
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
public void cancel(){
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private 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;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer;
int bytes;
while (true) {
try {
buffer = new byte[1024];
bytes = mmInStream.read(buffer);
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
devicelist.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.pwsz.rc.kolkokrzyzyk.XO"
android:background="#ffffff">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Paired Devices"
android:id="#+id/tvPD"
/>
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tvPD"
>
</ListView>
logcat:
05-29 03:28:08.315 4639-4639/com.pwsz.rc.kolkokrzyzyk E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pwsz.rc.kolkokrzyzyk, PID: 4639 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pwsz.rc.kolkokrzyzyk/com.pwsz.rc.kolkokrzyzyk.XO}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2202)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2252)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.pwsz.rc.kolkokrzyzyk.XO.init(XO.java:162)
at com.pwsz.rc.kolkokrzyzyk.XO.onCreate(XO.java:121)
at android.app.Activity.performCreate(Activity.java:5275)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2166)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2252)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
at dalvik.system.NativeStart.main(Native Method)
listView = (ListView) findViewById(R.id.listView);
listView.setOnItemClickListener(this);
It seems that it can't find a view whose id is "listView", so it returns null, you set the content view layout to 'R.layout.activity_xo', but the xml file show above is named devicelist.xml. you should check this.
Well,from the Exception Message.
We can catch the info
Caused by: java.lang.NullPointerException
at com.pwsz.rc.kolkokrzyzyk.XO.init(XO.java:162)
at com.pwsz.rc.kolkokrzyzyk.XO.onCreate(XO.java:121)
yes,the error at your function Init(), and at the line 162.
pleace post complete code about the Main.java(include improt````).
In this way,I can get moew info about the error.
The name of the xml file that contain the 'listview' is 'devicelist.xml'.
But you used
setContentView(R.layout.activity_xo);
There may be no ListView in 'activity_xo' Layout.
I'm making a OBDII Bluetooth Android app and i'm having some issues sending out commands. I've already made a successfully connection between my mobile device and my OBDII adapter, but when I click on another activity, the Bluetooth connection seems to quit?
When you open up the app you'll see a button that says "Connect Device". When you press that, a ListAdapter will show up with paired Bluetooth devices. Then when you have succesfully connected to the device (OBDII Adapter) it will take you to another layout where there is 3 activities that are 3 different powerplatforms for cars. This is where the problem occurs. For now, I just want to be able to read the voltage from the OBDII. But when I click my button getValue inside one of the 3 activities. I get an logcat error. And I think it's because I haven't initiated my BluetoothHandler properly. I have no idea how to do this.
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button b1;
BluetoothAdapter mAdapter;
FragmentHostCallback mHost;
BTHandler btHandler;
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BTHandler.STATE_CONNECTED:
//setContentView(R.layout.activity_connected);
Intent intent = new Intent(MainActivity.this, Connected.class);
startActivity(intent);
Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
Log.v("Log", "Connected");
break;
case BTHandler.STATE_NONE:
Toast.makeText(getApplicationContext(), R.string.title_not_connected, Toast.LENGTH_SHORT).show();
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btHandler = new BTHandler(MainActivity.this, mHandler);
b1 = (Button) findViewById(R.id.connect);
b1.setOnClickListener(this);
mAdapter = BluetoothAdapter.getDefaultAdapter();
//init();
if (mAdapter == null) {
Toast.makeText(getApplicationContext(), R.string.device_not_supported, Toast.LENGTH_LONG).show();
finish();
} else {
if (!mAdapter.isEnabled()) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
}
//BTHandler btHandler = new BTHandler(MainActivity.this, mHandler);
//btHandler.connect("");
}
public void onClick(View v) {
int id = v.getId();
//String voltage = ("ATRV");
switch (id) {
case R.id.connect:
onConnect(); //Operation
Log.v("Log", "Pressed onClick");
break;
/*case R.id.getValue:
btHandler.write(voltage);
Log.v("Log", "getValue" + voltage);
break;*/
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), R.string.enable_bluetooth, Toast.LENGTH_SHORT).show();
finish();
}
}
private void onConnect() {
ArrayList deviceStrs = new ArrayList();
final ArrayList<String> devices = new ArrayList();
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
Set pairedDevices = mAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (Object device : pairedDevices) {
BluetoothDevice bdevice = (BluetoothDevice) device;
deviceStrs.add(bdevice.getName() + "\n" + bdevice.getAddress());
devices.add(bdevice.getAddress());
}
}
// show list
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.select_dialog_singlechoice,
deviceStrs.toArray(new String[deviceStrs.size()]));
alertDialog.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
String deviceAddress = devices.get(position);
btHandler.connect(deviceAddress);
//btHandler.write();
}
});
alertDialog.setTitle("Paired devices");
alertDialog.show();
}
BTHandler:
public class BTHandler {
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
final ArrayList<String> devices = new ArrayList();
private final Handler mHandler;
private BluetoothAdapter mAdapter;
private BluetoothDevice device;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private BluetoothSocket socket;
private String status;
private int mState;
private boolean connectionStatus = false;
public BTHandler(Context context, Handler handler) { // Konstruktor
mAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = handler;
}
public void write(String s) {
mConnectedThread.sendRawCommand(s);
Log.v("write", "write");
}
/*
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
public void connect(String deviceAddress) {
mConnectThread = new ConnectThread(deviceAddress);
mConnectThread.start();
}
private void guiHandler(int what, int arg1, String obj) {
Message msg = mHandler.obtainMessage();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.sendToTarget();
}
private class ConnectThread extends Thread {
BluetoothSocket tmp = null;
private BluetoothSocket mmSocket;
public ConnectThread(String deviceAddress) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
device = mAdapter.getRemoteDevice(deviceAddress);
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
//socket.connect();
//Log.v("connect", "connect");
} catch (IOException e) {
//e.printStackTrace();
//Log.v("exception", "e");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mAdapter.cancelDiscovery();
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes;
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.v("connect", "connect");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
Log.v("close", "close");
} catch (IOException closeException) {
}
guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
return;
}
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private ObdMultiCommand multiCommand;
public ConnectedThread(BluetoothSocket socket) {
connectionStatus = true;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
try {
//RPMCommand engineRpmCommand = new RPMCommand();
//SpeedCommand speedCommand = new SpeedCommand();
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
while (!Thread.currentThread().isInterrupted()) {
//engineRpmCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
//speedCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
voltageCommand.run(socket.getInputStream(), socket.getOutputStream());
// TODO handle commands result
//Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
//Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
Log.v("Log", "Voltage: " + voltageCommand.getFormattedResult());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
OBDcmds();
// Keep listening to the InputStream until an exception occurs
while (connectionStatus) {
sendMultiCommand();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// CALL this to MainActivity
public void sendRawCommand(String command) {
try {
new OdbRawCommand(command);
} catch (Exception e) {
Log.v("sendRawCommand", "e");
}
}
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new TimeoutCommand(100).run(socket.getInputStream(), socket.getOutputStream());
new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN
} catch (Exception e) {
Log.v("OBDcmds", "e");
// handle errors
}
}
/*
// Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
public void sendMultiCommand() {
try {
// RUN some code here
} catch (Exception e) {
}
}
}
}
SPA: One of the power platforms mentioned before.
public class SPA extends AppCompatActivity implements View.OnClickListener {
Button b2;
BTHandler btHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sp);
b2 = (Button) findViewById(R.id.getValue);
b2.setOnClickListener(this);
}
public void onClick(View v) {
int id = v.getId();
String voltage = ("AT RV");
switch (id) {
case R.id.getValue:
btHandler.write(voltage);
Log.v("Log", "getValue" + voltage);
break;
}
}
}
Logcat:
The reason of the error is here:
BTHandler btHandler;
and you are doing this:
btHandler.write(voltage);
but the object is null referenced....
you need to initialize the BTHandler in the oncreate...
or maybe better:
use a service so you can Bind all the activities to that...
PS:
Note that the BTHandler of the MainActivity is not the same as the one declared in the SPA Class... so although that btHandler is constructed and works in MainActivity doesnt mean it will work in other activities/classes
I'm programming a code to open my room's door. But I have an issue.
The TextView.setText does not keep the new String I can see the String changed when the system ask to the user if allow enable Bluetooth textViewBluetooth.setText works, but when the bluetooth is enabled the textViewBluetooth returns to the original String setted on activity_main.xml and I never see it update again even setting text on an special button.
I already debug my code, i can see the setText called in TextView but still have no update string.
I try to add a new TextView but I get the same issue in both TextView.
I comment the bluetoothThread class but the problem persist.
Thanks for your time.
public class MainActivity extends ActionBarActivity {
private static final int REQUEST_ENABLE_BT = 1;
private static final int RESULT_SETTINGS = 1;
private BluetoothAdapter mBTadapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice>pairedDevices;
private BluetoothThread mBluetoothThread = null;
final String deviceAddress = "98:D3:31:20:0B:C9";
String SN = null;
TextView textViewBluetooth;
ImageView imageViewBT;
ImageView imageViewAbrir;
ImageView imageViewCerrar;
boolean NewDevice = false;
ArrayList listNoBondedDevices = new ArrayList();
ArrayAdapter<String> mNewDevicesArrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewBluetooth = (TextView) findViewById(R.id.textView01);
imageViewBT = (ImageView) findViewById(R.id.imageViewBT);
imageViewAbrir = (ImageView) findViewById(R.id.imageViewAbrir);
imageViewCerrar = (ImageView) findViewById(R.id.imageViewCerrar);
mNewDevicesArrayAdapter = new ArrayAdapter<String>
(this,android.R.layout.simple_list_item_1,listNoBondedDevices);
registerReceiver(mReceiver,new IntentFilter(BluetoothDevice.ACTION_FOUND));
mBluetoothThread = new BluetoothThread();
}
#Override
protected void onResume(){
super.onResume();
if(mBTadapter.isEnabled()){
if(!mBluetoothThread.btSocketConnected) {
setContentView(R.layout.activity_main);
tryConnectBTdevice(deviceAddress);
}
}
else {
intentEnableBT();
}
}
void intentEnableBT(){
textViewBluetooth.setText("Encendiendo bluetooth");
Intent intentEnableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intentEnableBT, REQUEST_ENABLE_BT);
}
void tryConnectBTdevice(String address){
if(address != null && address != "00:00:00:00:00:00") {
BluetoothDevice mBTdevice = mBTadapter.getRemoteDevice(address);
if (!mBluetoothThread.btSocketConnected) {
textViewBluetooth.setText("Conectando a\n" + address.toString());
mBluetoothThread.connect(mBTdevice);
}
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode){
case REQUEST_ENABLE_BT:
if(resultCode == Activity.RESULT_OK){
textViewBluetooth.setText("Bluetooth encendido");
tryConnectBTdevice(deviceAddress);
}
else if(resultCode == Activity.RESULT_CANCELED){
textViewBluetooth.setText("No se logró encender Bluetooth");
}
break;
}
}
}
My BluetoothThread:
public class BluetoothThread {
boolean bconnectedthread = false;
boolean bconnectthread = false;
boolean bconnectthreadstart = false;
boolean brun = false;
boolean bconnectedsynchronized = false;
boolean btSocketConnected = false;
private BluetoothAdapter mBluetoothAdapter = null;
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private ConnectedThread mConnectedThread;
private ConnectThread mConnectThread;
public void write(byte[] out) {
ConnectedThread r;
synchronized (this) {
r = mConnectedThread;
}
r.write(out);
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
bconnectthread = true;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.cancelDiscovery();
brun=true;
try {
mmSocket.connect();
btSocketConnected = true;
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
connected(mmSocket);
}
public void cancel() {
try {
mmSocket.close();
btSocketConnected = false;
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public Handler mHandler = null;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
bconnectedthread = true;
Message message;
Handler mHandler;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes; // bytes returned from read()
while (true) {
try {
bytes = mmInStream.read(buffer);
//mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
// .sendToTarget();
} catch (IOException e) {
break;
}
}
}
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
public void disconnectDevice() {
if (mmSocket.isConnected()) {
try {
mmSocket.close();
btSocketConnected = false;
} catch (IOException e) {
}
}
}
}
public synchronized void disconnect(){
mConnectedThread.disconnectDevice();
}
public synchronized void connect(BluetoothDevice device)
{
bconnectthreadstart=true;
mConnectThread = new ConnectThread(device);
mConnectThread.start();
}
public synchronized void connected(BluetoothSocket socket) {
bconnectedsynchronized=true;
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
}
}
My activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.automovil.app.MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageViewBT"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#drawable/bluetooth"
android:onClick="onSyncBT" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/textView01"
android:layout_below="#+id/imageViewBT"
android:layout_centerHorizontal="true"
android:layout_marginTop="39dp"
android:textColor="#00026a"
android:text="Bluetooth"
android:enabled="true"
android:editable="false"
android:clickable="false"
android:autoText="false"
android:autoLink="none" />
</RelativeLayout>
Sorry for my English grammar :\
Thanks a lot for your time again.
Abraham Jaime
You're calling 'setContentView' in onResume. Call that in onCreate.
onActivityResult is called BEFORE onResume, and you're doing your own multithreading here, which can be rough. Especially in this case.
tryConnectBTdevice is called from onActivityResult, which then starts a thread, but 99% of the time you'll probably wind up in in onResume before all of that happens, which means your code calls setContentView again, AND tryConnectBTdevice again.
You're referencing boolean primitives from multiple threads to check for status, which isn't great. Should probably use AtomicBoolean, but that's probably not a huge issue.
What would get a long talk from me if we were working together is eating your IOException's. Error control is very important. Those are being thrown for a reason. Its probably blowing up because you're already connected, which would've tipped you off to the double-call situation.
Simple answer, assuming you're going to ignore all my warnings about exceptions. Don't call setContentView in onResume, and don't call tryConnectBTdevice in onActivityResult, because you're calling it from onResume anyway.
If this is for your room, OK. If you're making a product, I'd strongly advise a rewrite of the threading code.