I have 3 activities in my android Application. In the first activity, on the click of a bluetooth device from the list of paired devices, I'm starting a service to keep the bluetooth connection visible to all the actives. In the service class I'm reading data continuously from the bluetooth device and I'm binding the second activity to the service class to read the data received.
I'm not able to get the instance of the binder outside the onServiceConnected() method of service connection method. So I'm calling a user-defined thread from onServiceConnected() method. In this way I'm getting values continuously from the service class. But the app will not respond after few seconds of successful execution.
It is blocking the main thread I think. But I'm not getting where I need to modify my code. The code below is my second Activity(MainActivity). "bluetoothManager" is my service class. I need to do a similar task in third activity also.
I'm not getting whether the problem is with binding or the thread. I need to call the thread outside of the Service connection class. If I do so, I'll get a null pointer exception. So I'm calling the thread from onServiceConnected() function where the binder object is not null. I have to use the boolean mIsBound for the while loop. But now it will be always true. Please help me. I'm new to android.
bluetoothManager.class
public class bluetoothManager extends Service{
final int handlerState = 0; // used to identify handler message
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder recDataString = new StringBuilder();
public ConnectedThread mConnectedThread;
static Handler bluetoothIn;
int bp;
String sensor0,sensor1;
static Handler mHandler;
// SPP UUID service - this should work for most devices
private static final UUID BTMODULEUUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
IBinder mBinder = new LocalBinder();
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
bluetoothManager getService() {
return bluetoothManager.this;
}
}
#Override
public void onCreate() {
/// Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
// flag="created";
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
// creates secure outgoing connecetion with BT device using UUID
}
public String getBPM(){
return sensor1;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, " MyService Started", Toast.LENGTH_LONG).show();
final String address=intent.getStringExtra("address");
final int currentId = startId;
if(address!=null)
{
btAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = btAdapter.getRemoteDevice(address);
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Socket creation failed",
Toast.LENGTH_LONG).show();
}
// Establish the Bluetooth socket connection.
try {
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
// insert code to deal with this
}
}
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
// I send a character when resuming.beginning transmission to check
// device is connected
// If it is not an exception will be thrown in the write method and
// finish() will be called
mConnectedThread.write("x");
}
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) { // if message is what we want
String readMessage = (String) msg.obj; // msg.arg1 = bytes
// from connect
// thread
recDataString.append(readMessage); // keep appending to
// string until ~
int endOfLineIndex = recDataString.indexOf("~"); // determine
// the
// end-of-line
if (endOfLineIndex > 0) { // make sure there data before ~
String dataInPrint = recDataString.substring(0,
endOfLineIndex); // extract string
//txtString.setText("Data Received = " + dataInPrint);
/*int dataLength = */dataInPrint.length(); // get length of
// data received
/*txtStringLength.setText("String Length = "
+ String.valueOf(dataLength));*/
if (recDataString.charAt(0) == '#') // if it starts with
// # we know it is
// what we are
// looking for
{
sensor0 = recDataString.substring(1,3);
// get
sensor1=sensor0;
Log.d("bpm", sensor0);
}
recDataString.delete(0, recDataString.length()); // clear
// all
// string
// data
// strIncom =" ";
dataInPrint = " ";
}
}
}
};
// get Bluetooth
// adapter
return currentId;
}
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
// creation of the connect thread
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
// Create I/O streams for connection
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer); // read bytes from input
// buffer
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
bluetoothIn.obtainMessage(handlerState, bytes, -1,
readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
// write method
public void write(String input) {
byte[] msgBuffer = input.getBytes(); // converts entered String into
// bytes
try {
mmOutStream.write(msgBuffer); // write bytes over BT connection
// via outstream
} catch (IOException e) {
// if you cannot write, close the application
Toast.makeText(getBaseContext(), "Connection Failure",
Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onRebind(Intent intent) {
Log.v("myservice", "in onRebind");
super.onRebind(intent);
}
#Override
public boolean onUnbind(Intent intent) {
Log.v("myapp", "in onUnbind");
return true;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.v("myservice", "in onDestroy");
}
}
MainActivity.java
public class MainActivity extends Activity {
private ServiceConnection mConnection;
TextView sensorView0;
boolean mIsBound;
bluetoothManager bm;
private Handler bpmHandler;
private ServiceConnection mConnection;
final int handlerState = 0; // used to identify handler message
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sensorView0 = (TextView) findViewById(R.id.bpm);
bpmHandler=new Handler(){
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) {
String s=(String)msg.obj;
sensorView0.setText("BPM="+s);
}
}
};
}
#Override
public void onResume() {
super.onResume();
mConnection= new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
mIsBound = false;
bm=null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocalBinder myBinder = (LocalBinder)service;
mIsBound = true;
bm=myBinder.getService();
mConnectedService=new ConnectedService(mIsBound);
mConnectedService.start();
}
};
Intent intent = new Intent(this, bluetoothManager.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
private class ConnectedService extends Thread {
final boolean bound;
public ConnectedService(boolean mIsBound){
bound =mIsBound;
}
public void run() {
String s;
while (bound) {
s= bm.getBPM();
Message msg = new Message();
msg.what =handlerState ;
msg.obj=s; MainActivity.this.bpmHandler.sendMessage(msg);
}
}
};
#Override
public void onPause() {
super.onPause();
unbindService(mConnection);
mIsBound = false;
}
}
I feel the connectedservice thread code is causing the issue. Instead of continuously racing grtBPM method, why don't you post the message only when there is a change. You can use local broadcast manager to broadcast the message from service and catch that in activity and update UI accordingly. The connectedservice thread runs continuously and keep posting the message to handler which is causing load on the main thread.
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 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 want to create two apps, one to just send text over Bluetooth and the other to just receive it. But the problem is that even though both devices are connected successfully no text is being transferred. Particularly the outStream.write(bytes) in Messages activity is no working.
Unlike most questions, I just want one-way simplex chat from Sender to Receiver; not a two-way chat.
Any help would be appreciated.
This is the sender code:
//member variables
private BluetoothAdapter btAdapter=null;
private ConnectThread btConnectThread;
private ConnectedThread btConnectedThread;
private int btState;
// Constants that indicate the current connection state
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
//dev name to be returned to UI
private static final int DEVICE_NAME=0;
//sent message returned to UI
private static final int SENT_MESSAGE=1;
private static final int STATUS=2;
/**
* Return Intent extra
*/
public static String EXTRA_DEVICE_ADDRESS = "device_address";
// Unique UUID for this application
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
//handler for UI thread
private final Handler handle=new Handler(){
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
TextView dvNm=(TextView) findViewById(R.id.connectedTo);
TextView sntMsg=(TextView) findViewById(R.id.sentMessage);
TextView stat=(TextView) findViewById(R.id.statusTest);
EditText tyMsg=(EditText) findViewById(R.id.typedMessage);
String temp;
switch (msg.what)
{
case DEVICE_NAME:
{
temp=dvNm.getText().toString();
dvNm.setText(temp+": "+msg.obj.toString());
break;
}
case SENT_MESSAGE:
{
temp=msg.obj.toString();
sntMsg.setText("Sent: "+temp);
tyMsg.setText("");
break;
}
case STATUS:
{
temp=msg.obj.toString();
stat.setText(temp);
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messages);
btAdapter=BluetoothAdapter.getDefaultAdapter();
}
#Override
protected void onStart() {
super.onStart();
Intent dList=getIntent();
String macAddr=dList.getStringExtra(EXTRA_DEVICE_ADDRESS);
if(btState==STATE_NONE)
{
connect(macAddr);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(btState!=STATE_NONE)
stop();
}
//button listener for sending message
public void onSend(View v)
{
//get the typed message
EditText tyMsg=(EditText) findViewById(R.id.typedMessage);
//convert it to byte format
byte[] send=tyMsg.getText().toString().getBytes();
// Create temporary object
ConnectedThread cThrd;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (btState != STATE_CONNECTED) return;
cThrd = btConnectedThread;
}
// Perform the write asynchronized
cThrd.write(send);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_messages, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Bluetooth Client component code
*/
private class ConnectThread extends Thread {
private final BluetoothSocket btSocket;
private final BluetoothDevice btDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to btSocket,
// because btSocket is final
BluetoothSocket tmp = null;
btDevice = 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) { }
btSocket = tmp;
}
public void run() {
// Cancel discovery 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
btSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
btSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
connected(btSocket,btDevice);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
btSocket.close();
} catch (IOException e) { }
}
}
/**
* Code to manage the connected socket
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket btSocket;
private final OutputStream outStream;
public ConnectedThread(BluetoothSocket socket) {
btSocket = socket;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
outStream = tmpOut;
}
public void run() { }
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
Message msg2=handle.obtainMessage(STATUS,"Inside write of connectedthread");
handle.sendMessage(msg2);
outStream.write(bytes);
outStream.flush();
Message msg1=handle.obtainMessage(STATUS,"Wrote to outstream");
handle.sendMessage(msg1);
Message msg=handle.obtainMessage(SENT_MESSAGE,bytes);
handle.sendMessage(msg);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
btSocket.close();
} catch (IOException e) { }
}
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
*
* #param macAddr is the mac-address The BluetoothDevice to connect
*/
public synchronized void connect(String macAddr) {
//get Bluetooth device from mac-address
BluetoothDevice device = btAdapter.getRemoteDevice(macAddr);
// Cancel any thread attempting to make a connection
if (btState == STATE_CONNECTING) {
if (btConnectThread != null) {
btConnectThread.cancel();
btConnectThread = null;
}
}
// Cancel any thread currently running a connection
if (btConnectedThread != null) {
btConnectedThread.cancel();
btConnectedThread = null;
}
// Start the thread to connect with the given device
btConnectThread = new ConnectThread(device);
btConnectThread.start();
btState=STATE_CONNECTING;
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
*
* #param socket The BluetoothSocket on which the connection was made
* #param device The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
device) {
// Cancel the thread that completed the connection
if (btConnectThread != null) {
btConnectThread.cancel();
btConnectThread = null;
}
// Cancel any thread currently running a connection
if (btConnectedThread != null) {
btConnectedThread.cancel();
btConnectedThread = null;
}
// Start the thread to manage the connection and perform transmissions
btConnectedThread = new ConnectedThread(socket);
btConnectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = handle.obtainMessage(DEVICE_NAME,device.getName());
handle.sendMessage(msg);
btState=STATE_CONNECTED;
}
/**
* Stop all threads
*/
public synchronized void stop(){
// Cancel the thread that completed the connection
if (btConnectThread != null) {
btConnectThread.cancel();
btConnectThread = null;
}
// Cancel any thread currently running a connection
if (btConnectedThread != null) {
btConnectedThread.cancel();
btConnectedThread = null;
}
btState=STATE_NONE;
}
}
And this is the receiver code:
//member variables
private BluetoothAdapter btAdapter=null;
private AcceptThread btAcceptThread;
private ConnectedThread btConnectedThread;
private int btState;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTED = 3; // now connected to a remote device
//dev name to be returned to UI
private static final int DEVICE_NAME=0;
//received message returned to UI
private static final int RECEIVED_MESSAGE=1;
// Name for the SDP record when creating server socket
private static final String NAME = "BluetoothAnnouncement";
// Unique UUID for this application
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
//handler for UI thread
private final Handler handle=new Handler(){
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
TextView dvNm=(TextView) findViewById(R.id.connectedTo);
TextView rcvdMsg=(TextView) findViewById(R.id.receivedMessage);
String temp;
switch (msg.what)
{
case DEVICE_NAME:
{
temp=dvNm.getText().toString();
dvNm.setText(temp+": "+msg.obj.toString());
break;
}
case RECEIVED_MESSAGE:
{
temp=msg.obj.toString();
rcvdMsg.setText("Received: "+temp);
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Acquiring Bluetooth Adapter
btAdapter = BluetoothAdapter.getDefaultAdapter();
//setting initial state
}
#Override
protected void onStart() {
super.onStart();
if(!btAdapter.isEnabled())
{
Toast.makeText(this, "Please enable Bluetooth to receive announcements",
Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onResume() {
super.onResume();
if(btAdapter.isEnabled())
{
if(btState==STATE_NONE)
{
start();
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(btState!=STATE_NONE)
stop();
}
//enabling Bluetooth
public void btEnable(View v)
{
if (btAdapter.isEnabled())
{
Toast.makeText(this, "Bluetooth already enabled",
Toast.LENGTH_SHORT).show();
}
else
{
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
startActivity(discoverableIntent);
}
}
/**
* Server component code
*/
private class AcceptThread extends Thread {
private final BluetoothServerSocket btServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to btServerSocket,
// because btServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = btAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) { }
btServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
BluetoothDevice device;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = btServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
device=socket.getRemoteDevice();
// Do work to manage the connection (in a separate thread)
connected(socket, device);
try {
btServerSocket.close();
} catch (IOException e) { }
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
btServerSocket.close();
} catch (IOException e) { }
}
}
/**
* Code to manage the connected socket
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket btSocket;
private final InputStream inStream;
public ConnectedThread(BluetoothSocket socket) {
btSocket = socket;
InputStream tmpIn = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
} catch (IOException e) { }
inStream = tmpIn;
}
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 = inStream.read(buffer);
// Send the obtained bytes to the UI activity
Message msg = handle.obtainMessage(RECEIVED_MESSAGE,bytes);
handle.sendMessage(msg);
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
btSocket.close();
} catch (IOException e) { }
}
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume()
*/
public synchronized void start() {
// Cancel any thread currently running a connection
if (btConnectedThread != null) {
btConnectedThread.cancel();
btConnectedThread = null;
}
// Start the thread to listen on a BluetoothServerSocket
if (btAcceptThread == null) {
btAcceptThread = new AcceptThread();
btAcceptThread.start();
}
//set state
btState=STATE_LISTEN;
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
*
* #param socket The BluetoothSocket on which the connection was made
* #param device The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
device) {
// Cancel any thread currently running a connection
if (btConnectedThread != null) {
btConnectedThread.cancel();
btConnectedThread = null;
}
// Cancel the accept thread because we only want to connect to one device
if (btAcceptThread != null) {
btAcceptThread.cancel();
btAcceptThread = null;
}
// Start the thread to manage the connection and perform transmissions
btConnectedThread = new ConnectedThread(socket);
btConnectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = handle.obtainMessage(DEVICE_NAME,device.getName());
handle.sendMessage(msg);
btState=STATE_CONNECTED;
}
/**
* Stop all threads
*/
public synchronized void stop(){
// Cancel any thread currently running a connection
if (btConnectedThread != null) {
btConnectedThread.cancel();
btConnectedThread = null;
}
// Cancel the accept thread because we only want to connect to one device
if (btAcceptThread != null) {
btAcceptThread.cancel();
btAcceptThread = null;
}
btState=STATE_NONE;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
I am trying to send data from Android Client (Nexus 4) to Python Server (Linux Machine) over Bluetooth using Python-bluez. Whenever the client writes some bytes to the OutputStream it throws an IO exception "Broken Pipe". The server also seems that it does not accept any connections although the Android client did not throw any exceptions after "socket_name.connect()"
Android Client:
public class MainActivity extends Activity {
private BluetoothSocket ClientSocket;
private BluetoothDevice Client;
private ConnectedThread Writer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public BluetoothAdapter mblue;
public void connect(View sender)
{
mblue = BluetoothAdapter.getDefaultAdapter();
int REQUEST_ENABLE_BT = 1;
final TextView er = (TextView)findViewById(R.id.Error);
if(mblue == null)
er.setText("No Bluetooth!");
else if (mblue.isEnabled()) {
er.setText(mblue.getAddress() + " " + mblue.getName());
}
else{
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
public void disov(View sender)
{
final TextView er = (TextView)findViewById(R.id.Error);
boolean tr = mblue.startDiscovery();
if(tr == true)
{
er.setText("Disovering !!");
}
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
}
public void start(View sender)
{
final TextView er = (TextView)findViewById(R.id.Error);
final TextView lol = (TextView)findViewById(R.id.editText1);
Writer.write(lol.getText().toString().getBytes());
lol.setText("");
}
public void send(View sender)
{
ConnectThread con = new ConnectThread(Client);
con.start();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
//mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
final TextView er = (TextView)findViewById(R.id.Error);
if(device.getAddress().equals("9C:2A:70:49:61:B0") == true)
{
Client = device;
er.setText("Connected with the target device!");
}
}
}
};
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;
UUID myuuid = UUID.fromString("94f39d29-7d6d-437d-973b-fba39e49d4ee");
final TextView er = (TextView)findViewById(R.id.Error);
// 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(myuuid);
} catch (IOException e) {}
ClientSocket = mmSocket = tmp;
Writer = new ConnectedThread(ClientSocket);
}
public void run() {
// Cancel discovery because it will slow down the connection
mblue.cancelDiscovery();
final TextView er = (TextView)findViewById(R.id.Error);
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
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) {}
}
}
public class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
final TextView er = (TextView)findViewById(R.id.Error);
// 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;
er.setText(er.getText() + "\n" + socket.toString());
}
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);
// 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) {
final TextView er = (TextView)findViewById(R.id.Error);
try {
mmOutStream.write(bytes);
//mmOutStream.
} catch (IOException e)
{
er.setText(e.toString());
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
}
Python Server:
from bluetooth import *
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
advertise_service( server_sock, "SampleServer",
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
# protocols = [ OBEX_UUID ]
)
print("Waiting for connection on RFCOMM channel %d" % port)
client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)
try:
while True:
data = client_sock.recv(1024)
if len(data) == 0: break
print("received [%s]" % data)
except IOError:
pass
print("disconnected")
client_sock.close()
server_sock.close()
print("all done")
Any help is appreciated.
You have used two public classes i.e public class MainActivity extends Activity{} and public class ConnectedThread extends Thread {}. But in Java there should be one public class and any number of other classes in one JavaClass file. So remove public class ConnectedThread extends Thread {} from that file and create a new Java class: public class ConnectedThread extends Thread {} in the same package.
I've got problem and I don't know how to resolve it. I wanted create service which will sent sensor changes to client (thread).
I've got thread where inside I start services, and client thread receive answers and sent them through bluetooth. The problem is I can't handle service.
public class SensorMsgService extends Service implements SensorEventListener{
public static final int MSG_SAY_HELLO = 1;
public static final int MSG_REGISTER_CLIENT = 1;
public static final int MSG_UNREGISTER_CLIENT = 2;
public static final int MSG_SET_VALUE = 3;
static final String TAG = "Sensor Msg Service";
ArrayList<Messenger> mClients = new ArrayList<Messenger>();
private SensorManager mSensorManager;
private Sensor mSensor;
private ArrayList<Float> temp;
private Looper mServiceLooper;
public class IncomingHandler extends Handler{
public IncomingHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
break;
case MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
break;
case MSG_SET_VALUE:
//mValue = msg.arg1;
for (int i = mClients.size() - 1; i >= 0; i--) {
try {
/*mClients.get(i).send(
Message.obtain(null, MSG_SET_VALUE, 1, 0));*/
Log.d(TAG, "Message from client");
}
//catch (RemoteException e) {
catch (Exception e) {
// The client is dead. Remove it from the list;
// we are going through the list from back to front
// so this is safe to do inside the loop.
mClients.remove(i);
}
}
break;
default:
super.handleMessage(msg);
}
}
//Toast.makeText(getApplicationContext(), "Hello service test", Toast.LENGTH_SHORT).show();
}
final Messenger mMessenger = new Messenger(new IncomingHandler(mServiceLooper));
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.d(TAG, "binding");
//return null;
return mMessenger.getBinder();
}
#Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
// TODO Auto-generated method stub
super.bindService(service, conn, flags);
// mServiceLooper.prepare();
temp = new ArrayList<Float>();
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
return true;
}
#Override
public void unbindService(ServiceConnection conn) {
// TODO Auto-generated method stub
super.unbindService(conn);
mSensorManager.unregisterListener(this);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
temp.add(event.values[0]);
temp.add(event.values[1]);
temp.add(event.values[2]);
for (int i = mClients.size() - 1; i >= 0; i--) {
try {
mClients.get(i).send(
Message.obtain(null, MSG_SET_VALUE, temp));
Log.d(TAG, "Message service to client sending");
}
//catch (RemoteException e) {
catch (Exception e) {
// The client is dead. Remove it from the list;
// we are going through the list from back to front
// so this is safe to do inside the loop.
mClients.remove(i);
}
}
}
}
I've initiated this service as I said from thread:
public class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private Context mContext;
/** Messenger for communicating with service. */
Messenger mService = null;
/** Flag indicating whether we have called bind on the service. */
boolean mIsBound;
ArrayList<Float> temp;
private Looper mServiceLooper;
public ConnectedThread(BluetoothSocket socket, Context ctxx) {
Log.d("ConnectedThread", "constructor ConnectedThread");
mContext = ctxx;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
temp = new ArrayList<Float>();
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e("ConnectedThread", "it was trying create input and output sockets", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i("ConnectedThread", "run mConnectedThread");
byte[] buffer = new byte[1024];
/*int i = 0;
while(true)
{
Log.i("ConnectedThread", "sending int test value");
write(i++);
}*/
doBindService();
}
/**
* Write to the connected OutStream.
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
} catch (IOException e) {
Log.e("ConnectedThread", "Exception during write", e);
}
}
public void write(int out) {
try {
mmOutStream.write(out);
} catch (IOException e) {
Log.e("ConnectedThread", "Exception during write", e);
}
}
public void cancel() {
try {
//mmOutStream.write(EXIT_CMD);
mmSocket.close();
} catch (IOException e) {
Log.e("ConnectedThread", "close() of connect socket failed", e);
}
}
///------------------------------
/**
* Handler of incoming messages from service.
*/
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SensorMsgService.MSG_SET_VALUE:
temp = (ArrayList<Float>) msg.obj;
//mCallbackText.setText("Received from service: " + msg.arg1);
Log.d("Handle message from service", temp.get(0) + " " + temp.get(1) + " " + temp.get(2) + "\n");
break;
default:
super.handleMessage(msg);
}
}
}
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. We are communicating with our
// service through an IDL interface, so get a client-side
// representation of that from the raw service object.
mService = new Messenger(service);
//mCallbackText.setText("Attached.");
// We want to monitor the service for as long as we are
// connected to it.
try {
Message msg = Message.obtain(null,
SensorMsgService.MSG_REGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(msg);
// Give it some value as an example.
msg = Message.obtain(null, SensorMsgService.MSG_SET_VALUE, this
.hashCode(), 0);
mService.send(msg);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
// As part of the sample, tell the user what happened.
Toast.makeText(mContext, "Service connected",
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
//mCallbackText.setText("Disconnected.");
// As part of the sample, tell the user what happened.
Toast.makeText(mContext, "Service disconnedcted",
Toast.LENGTH_SHORT).show();
}
};
/**
* Target we publish for clients to send messages to IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
// do Bind
void doBindService() {
// Establish a connection with the service. We use an explicit
// class name because there is no reason to be able to let other
// applications replace our component.
mContext.bindService(new Intent(mContext, SensorMsgService.class),
mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
Log.d("ConnectedThread", "doBindService");
}
void doUnbindService() {
if (mIsBound) {
// If we have received the service, and hence registered with
// it, then now is the time to unregister.
if (mService != null) {
try {
Message msg = Message.obtain(null,
SensorMsgService.MSG_UNREGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(msg);
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
}
}
// Detach our existing connection.
mContext.unbindService(mConnection);
mIsBound = false;
//mCallbackText.setText("Unbinding.");
}
}
}
The problem is when I wanted run this thread:
04-04 01:36:26.853: W/dalvikvm(29341): threadid=12: thread exiting with uncaught exception (group=0x420372a0)
04-04 01:36:26.853: E/AndroidRuntime(29341): FATAL EXCEPTION: Thread-11596
04-04 01:36:26.853: E/AndroidRuntime(29341): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-04 01:36:26.853: E/AndroidRuntime(29341): at android.os.Handler.<init> (Handler.java:121)
04-04 01:36:26.853: E/AndroidRuntime(29341): at com.nauka.bluetooth.ConnectedThread$IncomingHandler.<init>(ConnectedThread.java:127)
04-04 01:36:26.853: E/AndroidRuntime(29341): at com.nauka.bluetooth.ConnectedThread.<init>(ConnectedThread.java:200)
Could you show me how to handle this issue? thx