Android 4.04(java) server to ubuntu 12.04(python) client with bluetooth (RFCOMM)
I'm currently trying to get a bluetooth communication between and android 4.04 galaxy taplet and linux computer with python (the computer will be running a ROS robot, and I need the tablet for GPS and INS data). I need the taplet to function as a server. Both drivers support RFCOMM, but the python option connects based on "Address" and "Port" where the java android connects on "UUID".
I'm currently looking for a way to give my android server a static port number, but I'm also open for other ways to solve the problem.
I have been stuck here for quite a while and have found lots of simular issues but none which solved my case, hope you guys can help me out.
Question: how can I bind my android bluetooth server to a socket ?
Ps: forgive that the code android code isen't perfect it have been modified quite a few times looking for workarounds
My current android code:
public class MainActivity extends Activity{
ArrayAdapter<String> listadapter;
ListView listView;
BluetoothAdapter mBluetoothAdapter;
Set<BluetoothDevice> devicesArray;
ArrayList<String> pairedDevices;
BroadcastReceiver receiver;
AcceptThread acceptThread;
public static final UUID MY_UUID = UUID.fromString("94f39d29-7d6d-437d-973b-fba39e49d4ee");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
acceptThread = new AcceptThread();
acceptThread.start();
if(mBluetoothAdapter == null){
Toast.makeText(getApplicationContext(), "No bluetooth detected", 0).show();
finish();
}
else{
if(!mBluetoothAdapter.isEnabled()){
turnOnBluetooth();
}
getPairedDevices();
startDiscorevy();
}
}
private void startDiscorevy() {
mBluetoothAdapter.cancelDiscovery();
mBluetoothAdapter.startDiscovery();
}
private void turnOnBluetooth() {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private void getPairedDevices() {
devicesArray = mBluetoothAdapter.getBondedDevices();
if(devicesArray.size()>0){
for(BluetoothDevice device:devicesArray){
pairedDevices.add(device.getName()+"\n"+device.getAddress());
}
}
}
private void init(){
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 600);
startActivity(discoverableIntent);
listView = (ListView) findViewById(R.id.listView);
listadapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);
listView.setAdapter(listadapter);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
}
#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 enable to continue", 0).show();
finish();
}
}
#Override
protected void onPause() {
super.onPause();
acceptThread.cancel();
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
tmp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("Location_Service", MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
if (socket != null) {
manageConnectedSocket(socket);
try {
mmServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
private void manageConnectedSocket(BluetoothSocket socket) {
OutputStream mmOutStream;
BluetoothSocket mmSocket;
mmSocket = socket;
OutputStream tmpOut = null;
try {
tmpOut = mmSocket.getOutputStream();
} catch (IOException e) { }
mmOutStream = tmpOut;
byte[] bytes = null;
String toSend = "hello world";
bytes = toSend.getBytes();
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
try {
mmSocket.close();
} catch (IOException e) { }
}
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
}
My current python code:
#!python
import bluetooth
from bluetooth import *
import sys
bluetooth_name = "GT-P5110"
bluetooth_address = None
uuid = None
print "looking for device"
nearby_devices = bluetooth.discover_devices()
for bdaddr in nearby_devices:
if bluetooth_name == bluetooth.lookup_name( bdaddr):
bluetooth_address == bdaddr
print "device found on address:"
print bdaddr
service_matches = find_service(uuid = uuid, address = bluetooth_address)
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]
print " --- "
print port
print name
print host
print " --- "
sock = bluetooth.BluetoothSocket( bluetooth.RFCOMM)
sock.connect((bluetooth_address, port))
sock.close()
Note that the python code finds the device in both searches, returns its address correctly, and concludes the port and name to be none. I then get an error in sock.connect(addr,port) since port carnt be none.
Related
I am trying to send String message via Bluetooh. I am using code from this post:send message
I would like to send message on OnClick() to another connected device. Currently i can display paired devices and i am able to connect with them.
P.S I am trying to send message in write() function. When i tried to debug the code, i've figured out that debugger don't enter toMESSAGE WRITE on MESSAGE READ statement. Thanks for any help.
public class BluetoothActivity extends AppCompatActivity {
public static final int REQUEST_ENABLE_BT=1;
ListView lv_paired_devices;
Button sendMessage;
Set<BluetoothDevice> set_pairedDevices;
ArrayAdapter adapter_paired_devices;
BluetoothAdapter bluetoothAdapter;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public static final int MESSAGE_READ=0;
public static final int MESSAGE_WRITE=1;
public static final int CONNECTING=2;
public static final int CONNECTED=3;
public static final int NO_SOCKET_FOUND=4;
String bluetooth_message="00";
#SuppressLint("HandlerLeak")
Handler mHandler=new Handler()
{
#Override
public void handleMessage(Message msg_type) {
super.handleMessage(msg_type);
switch (msg_type.what){
case MESSAGE_READ:
byte[] readbuf=(byte[])msg_type.obj;
String string_recieved=new String(readbuf);
Log.i("TAGREAD", "Bluetooth not supported");
Toast.makeText(getApplicationContext(),string_recieved,Toast.LENGTH_LONG).show();
//do some task based on recieved string
break;
case MESSAGE_WRITE:
if(msg_type.obj!=null){
ConnectedThread connectedThread=new ConnectedThread((BluetoothSocket)msg_type.obj);
connectedThread.write(bluetooth_message.getBytes());
Log.i("TAGWRITE", "Bluetooth not supported");
}
break;
case CONNECTED:
Toast.makeText(getApplicationContext(),"Connected",Toast.LENGTH_SHORT).show();
break;
case CONNECTING:
Toast.makeText(getApplicationContext(),"Connecting...",Toast.LENGTH_SHORT).show();
break;
case NO_SOCKET_FOUND:
Toast.makeText(getApplicationContext(),"No socket found",Toast.LENGTH_SHORT).show();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setTitle("Sparowane urzÄ…dzenia");
bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Log.i("TAGTAG", "Bluetooth not supported");
// Show proper message here
finish();
}
else{
setContentView(R.layout.activity_bluetooth);
initialize_layout();
initialize_bluetooth();
start_accepting_connection();
initialize_clicks();
}
}
public void start_accepting_connection()
{
//call this on button click as suited by you
AcceptThread acceptThread = new AcceptThread();
acceptThread.start();
Toast.makeText(getApplicationContext(),"accepting",Toast.LENGTH_SHORT).show();
}
public void initialize_clicks()
{
lv_paired_devices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Object[] objects = set_pairedDevices.toArray();
BluetoothDevice device = (BluetoothDevice) objects[position];
ConnectThread connectThread = new ConnectThread(device);
connectThread.start();
Toast.makeText(getApplicationContext(),"device choosen "+device.getName(),Toast.LENGTH_SHORT).show();
}
});
}
public void initialize_layout()
{
lv_paired_devices = (ListView)findViewById(R.id.lv_paired_devices);
adapter_paired_devices = new ArrayAdapter(getApplicationContext(),R.layout.support_simple_spinner_dropdown_item);
lv_paired_devices.setAdapter(adapter_paired_devices);
sendMessage=findViewById(R.id.send_button);
}
public void initialize_bluetooth()
{
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
// Device doesn't support Bluetooth
Toast.makeText(getApplicationContext(),"Your Device doesn't support bluetooth. you can play as Single player",Toast.LENGTH_SHORT).show();
finish();
}
//Add these permisions before
// <uses-permission android:name="android.permission.BLUETOOTH" />
// <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
// <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
// <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
else {
set_pairedDevices = bluetoothAdapter.getBondedDevices();
if (set_pairedDevices.size() > 0) {
for (BluetoothDevice device : set_pairedDevices) {
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
adapter_paired_devices.add(device.getName() + "\n" + device.getAddress());
}
}
}
}
public class AcceptThread extends Thread
{
private final BluetoothServerSocket serverSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = bluetoothAdapter.listenUsingRfcommWithServiceRecord("NAME",MY_UUID);
} catch (IOException e) { }
serverSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null)
{
// Do work to manage the connection (in a separate thread)
mHandler.obtainMessage(CONNECTED).sendToTarget();
}
}
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
bluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mHandler.obtainMessage(CONNECTING).sendToTarget();
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
// bluetooth_message = "Initial message"
// mHandler.obtainMessage(MESSAGE_WRITE,mmSocket).sendToTarget();
}
/** Will cancel an in-progress connection, and close the socket */
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 = new byte[2]; // 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);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
Toast.makeText(BluetoothActivity.this,bytes,Toast.LENGTH_LONG).show();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
sendMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
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) { }
}
}
I'm trying to make an app that communicates with nearby devices.
My app is composed of the main activity that asks to enable bluetooth and sets the discoverable mode, so it waits for a connection to be made.
The second activity takes care of finding nearby devices and making the pairing.
After pairing pairing some configuration messages are exchanged and then both start a ThirdActivity that deals with the communication between the two devices.
I can successfully exchange these messages but the problem is that I need to pass the BluetoothService object (which keeps the communication information) to the Third Activity.
Since I don't think I can implement parcelable then I simply closed the connection without eliminating the pairing and then recreate AcceptThread and ConnectThread in the thirdActivity by creating a new BluetoothService object but always passing the same BluetoothDevice.
From the various logs what happens is that the AcceptThread waits on the accept(), while the ConnectThread fails the connect() reporting this error.
W/System.err: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:762)
at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:776)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:399)
at com.crossthebox.progetto.BluetoothService$ConnectThread.run(BluetoothService.java:118)
What can I do?
This is the BluetoothService Class
public class BluetoothService {
private UUID myid = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private static final String appName = "myapp";
private static final int STATE_NONE = 0; // we're doing nothing
private static final int STATE_LISTEN = 1; // now listening for incoming connections
private static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
private static final int STATE_CONNECTED = 3;
private static final int STATE_BUFFER_NOT_EMPTY = 4;
private String message ="";
private int mState;
private final BluetoothAdapter mBluetoothAdapter;
Context mContext;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private BluetoothDevice mDevice;
private UUID deviceUUID;
private ConnectedThread mConnectedThread;
public BluetoothService(Context context) {
mContext = context;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket bluetoothServerSocket;
public AcceptThread(){
BluetoothServerSocket tmp = null;
try{
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(appName, myid);
}catch (IOException e){
}
bluetoothServerSocket = tmp;
mState = STATE_LISTEN;
}
public void run() {
BluetoothSocket socket = null;
try {
socket = bluetoothServerSocket.accept();
} catch (IOException e) {
}
if (socket != null) {
mState = STATE_CONNECTING;
connected(socket);
}
}
public void cancel() {
try {
bluetoothServerSocket.close();
} catch (IOException e) {
}
}
}
private class ConnectThread extends Thread {
private BluetoothSocket mSocket;
public ConnectThread(BluetoothDevice device, UUID uuid) {
mDevice = device;
deviceUUID = uuid;
}
public void run(){
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = mDevice.createRfcommSocketToServiceRecord(deviceUUID);
} catch (IOException e) {
}
mSocket = tmp;
mBluetoothAdapter.cancelDiscovery();
try {
mSocket.connect(); //this throws exception for socket close ( but only the second time)
} catch (IOException e) {
// Close the socket
try {
mSocket.close();
} catch (IOException e1) {
}
e.printStackTrace();
}
connected(mSocket);
}
public void cancel() {
try {
mSocket.close();
} catch (IOException e) {
}
}
}
public synchronized void start() {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mAcceptThread == null) {
mAcceptThread = new AcceptThread();
mAcceptThread.start();
}
}
public void startClient(BluetoothDevice device,UUID uuid){
mConnectThread = new ConnectThread(device, uuid);
mConnectThread.start();
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mSocket;
private final InputStream mInStream;
private final OutputStream mOutStream;
public ConnectedThread(BluetoothSocket socket) {
mSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = mSocket.getInputStream();
tmpOut = mSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mInStream = tmpIn;
mOutStream = tmpOut;
}
public void run(){
byte[] buffer = new byte[1024];
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
// Read from the InputStream
try {
bytes = mInStream.read(buffer);
if(bytes != 0) {
String incomingMessage = new String(buffer, 0, bytes);
message = incomingMessage;
System.out.println("HO LETTO " + message);
mState = STATE_BUFFER_NOT_EMPTY;
}
} catch (IOException e) {
break;
}
}
}
//Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
try {
mOutStream.write(bytes);
} catch (IOException e) {
}
}
//termina la connessione
public void cancel() {
try {
mSocket.close();
} catch (IOException e) { }
}
}
private void connected(BluetoothSocket mSocket) {
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(mSocket);
mConnectedThread.start();
mState = STATE_CONNECTED;
}
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) {
return;}
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
public int getState(){
return mState;
}
public String getMessage(){
String tmp = null;
if(!message.equals("")){
tmp = message;
message = "";
}
mState = STATE_CONNECTED;
return tmp;
}
public void setState(int state){
this.mState = state;
}
public void cancel(){
if(mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
if(mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if(mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transition);
/* * */
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
/* * */
if(requestCode == DISCOVER_REQUEST){
if(resultCode == 120){
bluetoothService = new BluetoothService(this);
bluetoothService.start();
//after receiving some message correctly
Intent thirdActivity = new Intent(this, com.project.ThirdActivity.class);
bluetoothService.cancel();
this.startActivity(thirdActivity);
finish();
}
if(resultCode == RESULT_CANCELED){
finish();
}
}
}
}
SecondActivity the way I cancel the connection is pretty the same as MainActivity. I close the socket after some message and then start ThirdActivity
ThirdActivity
if(mode == CLIENT){
BluetoothDEvice bluetoothDevice = getIntent().getExtras().getParcelable("btdevice");
bluetoothService.startClient(bluetoothDevice,myid);
}else //SERVER
bluetoothService.start();
Possible solution:
Pass the selected MAC address from Activity2 to Activity3
In Activity3 Start the ConnectThread in the Bluetooth Service.
Use a Handler to communicate between service and the Activity3.
Make sure you close the Thread when sockets disconnect.
A brilliant example is in the following link:
https://github.com/googlesamples/android-BluetoothChat
i am building an app to display the Ecg in mobile .so i try to
establish a connection via bluetooth .but when i try to pair the
Bluetooth, the paired devices are shown. but when i try to connect, it
says device not found..i don't know how to solve the problem. Please
advise on issues in my code to connect to paired devices:Any help on
this would be greatly appreciate
this is my bluetooth.java
public class bluetooth extends Activity implements AdapterView.OnItemClickListener {
public static void disconnect(){
if (connectedThread !=null){
connectedThread.cancel();
connectedThread= null;
}
}
public static void gethandler(Handler handler){
mHandler= handler;
}
static Handler mHandler =new Handler();
static ConnectedThread connectedThread;
public static final UUID my_UUID= UUID.fromString("f53a07d4-3010-11e9-b210-d663bd873d93");
protected static final int SUCCESS_CONNECT=0;
protected static final int MESSAGE_READ=1;
ListView listView;
//ArrayAdapter is an Android SDK class for adapting an array of objects as a datasource.
// Adapters are used by Android to treat a result set uniformly whether it's from a database, file, or in-memory objects
// so that it can be displayed in a UI element.
// The ArrayAdapter is useful for the latter. Use it anywhere you would use an Adapter. E.g. attach to Android UI elements.
ArrayAdapter<String> list_adapter;
static BluetoothAdapter btAdapter;
Set<BluetoothDevice> devicesArray;
///ArrayList is an implementation of java.util.List that's backed by an array. You can use it anywhere you would use a java.util.List.
//// E.g. where you need to maintain order of a collection of objects where duplicates are allowed.
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devies;
IntentFilter filter;
BroadcastReceiver receiver;
#Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//in Android the visual design is created in xml . And each Activity is associated to a design
//
//setContentView(R.layout.main)
//R means Resource
//
//layout means design
//
//main is the xml you have created under res->layout->main.xml
//
//Whenever you want to change your current Look of an Activity or when you move from
// one Activity to another . The other Activity must have a design to show . So we call this method in onCreate
// and this is the second statement to set the design
setContentView(R.layout.activity_bluetooth);
init();
if(btAdapter==null){
Toast.makeText(getApplicationContext(),"no bt detected", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onCreate: no");
finish();
}
else{
if(!btAdapter.isEnabled()){
turnOnBT();
}
getPairedDevices();
startDiscovery();
}
}
private void getPairedDevices(){
btAdapter.cancelDiscovery();
btAdapter.startDiscovery();
}
private void turnOnBT(){
Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,1);
}
private void startDiscovery(){
devicesArray = btAdapter.getBondedDevices();
if(devicesArray.size()>0){
for(BluetoothDevice device:devicesArray){
pairedDevices.add(device.getName());
String s="";
list_adapter.add(device.getName()+" "+s+""+"\n"+device.getAddress());
}
}
}
private void init() {
listView =(ListView)findViewById(R.id.list_item);
listView.setOnItemClickListener(this);
list_adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,0);
listView.setAdapter(list_adapter);
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices =new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devies = 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);
devies.add(device); //!!!!!!!!!!
String s="";
for (int a=0;a<pairedDevices.size();a++){
if(device.getName().equals(pairedDevices.get(a))){
s="(paired)";
break;
}
}
list_adapter.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);
}
#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();
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(btAdapter.isDiscovering()){
btAdapter.cancelDiscovery();
}
if(list_adapter.getItem(position).contains("(paired)")){
BluetoothDevice selectedDevice = devies.get(position);
ConnectThread connect = new ConnectThread(selectedDevice);
connect.start();
}
else{
Toast.makeText(getApplicationContext(),"device not paired", Toast.LENGTH_SHORT).show();
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice=device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(my_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discover y because it will slow down the connection
btAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
//connectedThread = new ConnectedThread(mmSocket);
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
// Incoming and the outgoing strings are carried out inside this thread read is for reading incoming messages through a socket and write is for sending messages to the remote device
static 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 BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
// socket not created
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
StringBuffer sbb = new StringBuffer();
public void run() {
byte[] buffer ;
int bytes;
// receiving message
while(true) {
try {
try {
sleep(30);
} catch (InterruptedException e) {
break;
}
buffer = new byte[1024];
// Read from the InputStream
bytes = mmInStream.read(buffer);
// message is in bytes form so reading them to obtain message
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
// connection was lost and start your connection again
Log.e(TAG, "disconnected", e);
break;
}
}
}
public void write(String income) {
try {
mmOutStream.write(income.getBytes());
for (int i=0;i<income.getBytes().length;i++)
Log.v("outStream"+Integer.toString(i),Character.toString((char)(Integer.parseInt(Byte.toString(income.getBytes()[i])))));
try{
Thread.sleep(20);
}
catch (InterruptedException e1){
e1.printStackTrace();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void cancel(){
try {
mmSocket.close();
}
catch (IOException e){}
}
}
}
but my question is, are there any problem with mmsocket
enter image description here
i geeting like beow in my android phone.
enter image description here
i use these codes but Bluetooth socket never created.
i have two phones, SAMSUNG galaxy S5 and Huwaii. i run server code on Huwaii and client code in galaxy but state string in both is "waiting", that means never can create Bluetooth socket, these codes are exactly copied from GOOGLE android Tutriol and I don't know what wrong is.
myClientCode is this :
public class BluetoothActivity extends Activity implements OnItemClickListener {
protected static final int SUCCESS_CONNECT = 0;
public static final int MESSAGE_READ = 1;
TextView state;
BluetoothAdapter btadaptor;
ListView list;
ArrayAdapter<String> array;
Set<BluetoothDevice> btarray;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
IntentFilter filter;
BroadcastReceiver receiver;
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case SUCCESS_CONNECT:
//Do something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket) msg.obj);
Toast.makeText(getApplicationContext(), "connected", 0).show();
String s = "SSSSSS";
connectedThread.write(s.getBytes());
break;
case MESSAGE_READ:
byte[] readbuf = (byte[]) msg.obj;
String string = new String(readbuf);
Toast.makeText(getApplicationContext(), "sus message", 0).show();
break;
}
}
};
public static final UUID MY_UUID = UUID.fromString("0efe5656-27d7-11e6-b67b-9e71128cae77");
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
if (btadaptor == null)
Toast.makeText(getApplicationContext(), "bluetooth not supported", Toast.LENGTH_SHORT).show();
else
{
if ( !btadaptor.enable())
{
startbt();
}
getPairedDevice();
startActivity();
}
}
private void startActivity() {
btadaptor.cancelDiscovery();
btadaptor.startDiscovery();
}
private void getPairedDevice() {
btarray = btadaptor.getBondedDevices();
if (btarray.size() > 0)
{
for (BluetoothDevice bt: btarray)
{
pairedDevices.add(bt.getName());
// Toast.makeText(getApplicationContext(), bt.getName(), 0).show();
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1)
if (resultCode == RESULT_CANCELED)
{
Toast.makeText(getApplicationContext(), "you need to turn on the bluetooth to continue", Toast.LENGTH_SHORT);
finish();
}
super.onActivityResult(requestCode, resultCode, data);
}
private void init() {
state = (TextView) findViewById(R.id.textView1);
state.setText("waitingforlist");
list = (ListView) findViewById(R.id.listView);
list.setOnItemClickListener(this);
array = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
list.setAdapter(array);
btadaptor = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devices = new ArrayList<BluetoothDevice>();
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context contex, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
BluetoothDevice bt = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices.add(bt);
String s = "";
for (int a = 0; a < pairedDevices.size(); a++) {
if (bt.getName().equals(pairedDevices.get(a))) {
s = "(PAIRED)";
}
}
array.add(bt.getName() + s + "\n" + bt.getAddress());
}
}
};
registerReceiver(receiver, filter);
}
#Override
protected void onPause() {
unregisterReceiver(receiver);
super.onPause();
}
protected void startbt() {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
if (btadaptor.isDiscovering()) {
btadaptor.cancelDiscovery();
}
Toast.makeText(getApplicationContext(), array.getItem(arg2), 0).show();
if (array.getItem(arg2).contains("PAIRED")) {
// Toast.makeText(getApplicationContext(), "OK", 0).show();
BluetoothDevice selectedDevice = devices.get(arg2);
Toast.makeText(getApplicationContext(), selectedDevice.getAddress(), 0).show();
ConnectThread connectThread = new ConnectThread(selectedDevice);
state.setText("CreatedThread");
connectThread.start();
}
else
Toast.makeText(getApplicationContext(), "Device is not Paried", 0).show();
}
public class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
}
catch (IOException e) {}
mmSocket = tmp;
state.setText(device.getName());
}
#Override
public void run() {
// Cancel discovery because it will slow down the connection
// btadaptor.cancelDiscovery();
// state.setText("DONE RUN2");
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
state.setText("waiting");
mmSocket.connect();
state.setText("connected");
}
catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
}
catch (IOException closeException) {}
return;
}
// Do work to manage the connection (in a separate thread)
// manageConnectedSocket(mmSocket);
}
}
/** Will cancel an in-progress connection, and close the socket */
/* 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;
}
#Override
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 {
buffer = new byte[1024];
// Read from the InputStream
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) {}
}
}
}
myServerCode is this :
public class BluetoothActivity extends Activity {
protected static final int SUCCESS_CONNECT = 0;
public static final int MESSAGE_READ = 1;
Button bt;
BluetoothAdapter btadaptor;
TextView state;
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case SUCCESS_CONNECT:
//Do something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket) msg.obj);
Toast.makeText(getApplicationContext(), "connected", 0).show();
String s = "SSSSSS";
connectedThread.write(s.getBytes());
break;
case MESSAGE_READ:
byte[] readbuf = (byte[]) msg.obj;
String string = new String(readbuf);
Toast.makeText(getApplicationContext(), "sus message", 0).show();
break;
}
}
};
public static final UUID MY_UUID = UUID.fromString("0efe5656-27d7-11e6-b67b-9e71128cae77");
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
if (btadaptor == null)
Toast.makeText(getApplicationContext(), "bluetooth not supported", Toast.LENGTH_SHORT).show();
else
{
if ( !btadaptor.enable())
{
startbt();
}
startActivity();
startDiscovering();
OnClickListener temp = new OnClickListener() {
#Override
public void onClick(View arg0) {
AcceptThread acceptThread = new AcceptThread();
state.setText("THreadCreAted");
acceptThread.start();
}
};
bt.setOnClickListener(temp);
}
}
private void startActivity() {
btadaptor.cancelDiscovery();
btadaptor.startDiscovery();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1)
if (resultCode == RESULT_CANCELED)
{
Toast.makeText(getApplicationContext(), "you need to turn on the bluetooth to continue", Toast.LENGTH_SHORT);
}
super.onActivityResult(requestCode, resultCode, data);
}
private void init() {
bt = (Button) findViewById(R.id.button1);
state = (TextView) findViewById(R.id.textView1);
state.setText("START");
btadaptor = BluetoothAdapter.getDefaultAdapter();
}
private void startDiscovering() {
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
state.setText("StartDiscovering");
}
protected void startbt() {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
btadaptor.cancelDiscovery();
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = btadaptor.listenUsingRfcommWithServiceRecord("MYAPP", MY_UUID);
}
catch (IOException e) {}
mmServerSocket = tmp;
}
#Override
public void run() {
state.setText("runStart");
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
state.setText("WAIITING");
state.setText("WAIITING2");
socket = mmServerSocket.accept();
state.setText("ConnectionREquesRECIEVED");
}
catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
state.setText("ACCEPTED");
// Do work to manage the connection (in a separate thread)
// manageConnectedSocket(socket);
try {
mmServerSocket.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
}
catch (IOException e) {}
}
}
private void manageConnectedSocket(BluetoothSocket mmSocket2) {
}
///////////////////////
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;
}
#Override
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 {
buffer = new byte[1024];
// Read from the InputStream
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) {}
}
}
}
is any body know whats wrong ?
or can anybody show me very simple code (both server and client) Bluetooth socket just for connection and sending message ?
I have created an app to display paired devices successfully but not able to connect to it.
I tried a lot but i'm getting "app has been stopped working".
Please advise on issues in my code to connect to paired devices:
public class MainActivity extends AppCompatActivity {
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothAdapter bt;
ArrayAdapter<String> listAdapter;
Set<BluetoothDevice> devicesArray;
ListView listview;
Button connectbutton;
Handler mHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Toast.makeText(getApplicationContext(), "CONNECT", Toast.LENGTH_SHORT).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
if(bt==null){
Toast.makeText(getApplicationContext(), "no bluetooth on device",Toast.LENGTH_SHORT).show();
finish();
}
else
{
if(!bt.isEnabled()){
Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,1);
}
}
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View arg1, int arg2, long arg3) {
Toast.makeText(getApplicationContext(), (CharSequence) parent.getItemAtPosition(arg2), Toast.LENGTH_SHORT).show();
if(bt.isDiscovering())
{
bt.cancelDiscovery();
}
BluetoothDevice selectedDevice = (BluetoothDevice) parent.getItemAtPosition(arg2);
}
});
}
public void onButtonClick(View v)
{
getpaireddevices();
}
public void onButtonClick2(View v)
{
startdiscovery();
}
private void getpaireddevices() {
devicesArray = bt.getBondedDevices();
if (devicesArray.size() > 0) {
for (BluetoothDevice device : devicesArray)
listAdapter.add(device.getName());
}
}
private void startdiscovery()
{
bt.cancelDiscovery();
bt.startDiscovery();
}
private void init() {
listview = (ListView)findViewById(R.id.listView);
connectbutton = (Button)findViewById(R.id.button);
listAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,0);
listview.setAdapter(listAdapter);
bt= BluetoothAdapter.getDefaultAdapter();
}
#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 turned on to continue",Toast.LENGTH_SHORT).show();
finish();
}
}
when I wanted to get a list of connected Bluetooth devices for my app aw well and this helped me,
Get List Of Paired Bluetooth Devices
in the first link, besides giving you a list of paired devices it has onclick, which then I used second link (how to send images via Bluetooth) to communicate with my selected device
Sending Images Over Bluetooth In Android
example:
class SendData extends Thread {
private BluetoothDevice device = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
public SendData(){
device = mBluetoothAdapter.getRemoteDevice(address);
try
{
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
}
catch (Exception e) {
// TODO: handle exception
}
mBluetoothAdapter.cancelDiscovery();
try {
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
}
}
Toast.makeText(getBaseContext(), "Connected to " + device.getName(), Toast.LENGTH_SHORT).show();
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
}
}
public void sendMessage()
{
try {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.white);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100,baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
Toast.makeText(getBaseContext(), String.valueOf(b.length), Toast.LENGTH_SHORT).show();
outStream.write(b);
outStream.flush();
} catch (IOException e) {
}
}
}
}
hope it helps you too!