0
votes

I wanted to start with the basics of bluetooth connection and make a simple app capable of scanning, pairing and connecting.

I'm struggling with the last concept, i followed a lot of tutorials but I couldn't make it. I don't know if you can help me but here is my code.

ublic class MainActivity extends Activity {

private final String TAG = "Debugging";
private final static int REQUEST_CODE_ENABLE_BLUETOOTH = 0;
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

BluetoothAdapter btAdapter;
ArrayList<String> arrayListpaired;
ArrayAdapter<String> listAdapter,adapter;
ListView listView,listViewPaired;
Set<BluetoothDevice> deviceArray;
ArrayList<String> pairedDevices;
IntentFilter filter;
BroadcastReceiver receiver;
BluetoothDevice bdDevice;
ArrayList<BluetoothDevice> arrayListBluetoothDevices = null;
ArrayList<BluetoothDevice> arrayListPairedBluetoothDevices;
ListItemClicked listItemClicked;
ListItemClickedonPaired listItemClickedonPaired;
String tag = "debugging";

Handler mHandler= new Handler() {

    public void handleMessage(Message msg){
        super.handleMessage(msg);
        switch(msg.what){
            case SUCCESS_CONNECT:

                ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
                Toast.makeText(getApplicationContext(),"Connect",Toast.LENGTH_LONG).show();

                String s= "Succesfully connected";
                connectedThread.write(s.getBytes());
                Log.i(tag, "connected");
                break;

            case MESSAGE_READ:
                byte[] readbuff=(byte[])msg.obj;
                String  string= readbuff.toString();
                Toast.makeText(getApplicationContext(), string,Toast.LENGTH_SHORT).show();
                break;

        }
    }
};




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

    btAdapter = BluetoothAdapter.getDefaultAdapter();

    arrayListBluetoothDevices = new ArrayList<BluetoothDevice>();
    arrayListpaired = new ArrayList<String>();
    arrayListPairedBluetoothDevices = new ArrayList<BluetoothDevice>();

    adapter= new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, arrayListpaired);
    listItemClickedonPaired = new ListItemClickedonPaired();
    listViewPaired = (ListView) findViewById(R.id.listView3);
    listItemClicked = new ListItemClicked();
    listView = (ListView) findViewById(R.id.listView2);
    listAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_activated_1);
    listView.setAdapter(listAdapter);
    listAdapter.notifyDataSetChanged();
    listViewPaired.setAdapter(adapter);


    setupMessageButton1();
    setupMessageButton2();
    setupMessageButton3();
    setupMessageButton4();
    setupMessageButton5();
    init();
    getPairedDevices();

}

private void init() {

    listView.setOnItemClickListener(listItemClicked);
    listViewPaired.setOnItemClickListener(listItemClickedonPaired);

    filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

    receiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {

            String Action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(Action)) {
                Toast.makeText(getApplicationContext(), "One Device Found", Toast.LENGTH_SHORT).show();
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                if (arrayListBluetoothDevices.size() < 1) // this checks if the size of bluetooth device is 0,then add the
                {                                           // device to the arraylist.
                    listAdapter.add(device.getName() + "\n" + device.getAddress());
                    arrayListBluetoothDevices.add(device);
                    listAdapter.notifyDataSetChanged();
                }

                else
                {
                    boolean flag = true;    // flag to indicate that particular device is already in the arlist or not
                    for (int i = 0; i < arrayListBluetoothDevices.size(); i++) {
                        if (device.getAddress().equals(arrayListBluetoothDevices.get(i).getAddress())) {
                            flag = false;
                        }
                    }
                    if (flag == true) {
                        listAdapter.add(device.getName() + "\n" + device.getAddress());
                        arrayListBluetoothDevices.add(device);
                        listAdapter.notifyDataSetChanged();
                    }
                }

            }
        }
    };
    registerReceiver(receiver, filter);


}

private void createBond(BluetoothDevice btDevice){

    try
    {
        Method method = btDevice.getClass().getMethod("createBond", (Class[]) null);
        method.invoke(btDevice, (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 void getPairedDevices() {

    Set<BluetoothDevice> pairedDevice = btAdapter.getBondedDevices();
    if(pairedDevice.size()>0)
    {
        for(BluetoothDevice device : pairedDevice)
        {
            arrayListpaired.add(device.getName()+"\n"+device.getAddress());
            arrayListPairedBluetoothDevices.add(device);
        }
    }
    adapter.notifyDataSetChanged();
}


public class ListItemClicked implements OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // TODO Auto-generated method stub
        bdDevice = arrayListBluetoothDevices.get(position);

        Log.i("Log", "The device : " + bdDevice.toString());

        getPairedDevices();
        createBond(bdDevice);
        adapter.notifyDataSetChanged();

        Log.i("Log", "The bond is created: with" + bdDevice.toString());


    }
}


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

    public ConnectThread(BluetoothDevice device) {
        BluetoothSocket tmp = null;
        mmDevice = device;
        try {
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }

    public void run() {
        btAdapter.cancelDiscovery();
        try {
            mmSocket.connect();
        } catch (IOException connectException) {
            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;

        // 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;
    }

    public void run() {
        byte[] buffer;  // 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
                buffer  = new byte[1024];
                bytes = mmInStream.read(buffer);
                // Send the obtained bytes to the UI activity
                mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                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) { }
    }

    /* Call this from the main activity to shutdown the connection */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}




@Override
protected void onDestroy() {
    super.onDestroy();
    btAdapter.cancelDiscovery();
    unregisterReceiver(receiver);
}



class ListItemClickedonPaired implements OnItemClickListener
{
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
        bdDevice = arrayListPairedBluetoothDevices.get(position);

            unpairDevice(bdDevice);
            //arrayListPairedBluetoothDevices.clear();

    }
}

private void makeDiscoverable() {
    Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 150);
    startActivity(discoverableIntent);
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_CANCELED) {
        Toast.makeText(MainActivity.this, "Bluetooth must be enabled to start scanning", Toast.LENGTH_SHORT).show();

    } else

    {
        Toast.makeText(MainActivity.this, "Click on TURN_OFF to disable bluetooth", Toast.LENGTH_LONG).show();
    }

}

private void setupMessageButton1() {

    //1.get a reference for my button
    Button messageButton = (Button) findViewById(R.id.button1);

    //2. Set the click to run my code
    messageButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            listAdapter.clear();
            arrayListBluetoothDevices.clear();
            btAdapter.startDiscovery();

        }

    });
}

private void setupMessageButton2() {

    //1.get a reference to the button.
    Button messageButton = (Button) findViewById(R.id.button2);

    //2. set the click listener to run my code.
    messageButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            if (btAdapter.isEnabled()) {

                listAdapter.clear();
                btAdapter.disable();
            } else

            {
                Toast.makeText(MainActivity.this, "Dont worry it's already off", Toast.LENGTH_SHORT).show();
            }

        }
    });

}

private void setupMessageButton3() {

    //1.get a reference for my button
    Button messageButton = (Button) findViewById(R.id.button3);

    //2. Set the click to run my code
    messageButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            finish();

        }
    });

}

private void setupMessageButton4() {

    //1.get a reference for my button
    Button messageButton = (Button) findViewById(R.id.button4);

    //2. Set the click to run my code
    messageButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            btAdapter.enable();
        }

    });
}

private void setupMessageButton5() {

    //1.get a reference for my button
    Button messageButton = (Button) findViewById(R.id.button5);

    //2. Set the click to run my code
    messageButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            makeDiscoverable();
        }

    });
}
}

Concerning the log i have that message :

"D/BluetoothUtils﹕ isSocketAllowedBySecurityPolicy start : device null" "W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback" "D/BluetoothSocket﹕ connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[75]} "

public class ListItemClicked implements OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // TODO Auto-generated method stub
       bdDevice = arrayListBluetoothDevices.get(position);

           Log.i("Log", "The device : " + bdDevice.toString());


            createBond(bdDevice);

            adapter.notifyDataSetChanged();

            ConnectThread connect = new ConnectThread(bdDevice);
            connect.start();

    }

}

For the connection, i use the ConnectThread found in Bluetooth APi developer Website:

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

    public ConnectThread(BluetoothDevice device) {
        BluetoothSocket tmp = null;
        mmDevice = device;
        try {
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }

    public void run() {
        btAdapter.cancelDiscovery();
        try {
            mmSocket.connect();
        } catch (IOException connectException) {
            try {
                mmSocket.close();
            } catch (IOException closeException) { }
            return;
        }

        mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
    }


    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }

}
1
rather than dumping a lot of code, introduce SSCE paradigm. What errors do you get? What is the logcat telling you? What have you tried? All of those are a pre-requisite to enable SO to give you some guidance. just sayingt0mm13b
Thank you t0mm13b, i thought it's better to attach the whole code who want to understand how it works but you totally right.Hicham Ben

1 Answers

0
votes

it's ok i found the solution, i had the problem with the phone i'm using, he is not supporting SPP.

Thank you anyway