BluetoothServerSocket accept() not returning on HTC Desire - android-bluetooth

I'm working on a bluetooth-capable application, based on the well-known BluetoothChat example.
Basically with this app a client can send some packets to a server.
I have tested the application using two Xperia smartphones (Xperia X8 and Xperia Sola, android 2.1 and 4.0) and all is working fine: they both can act as client or server.
Unfortunately if I use an HTC Desire (android 2.3) as server, it won't be able to accept incoming connection from one of the Xperia client. It seems that the client connect() returns as if all was fine, but instead the server is blocked on its accept() as if nothing was happened.
Relevant code snippets:
1. "Accept Thread"
private class BluetoothAcceptThread extends Thread
{
private final BluetoothServerSocket serverSocket;
public BluetoothAcceptThread()
{
BluetoothServerSocket tmpSocket = null;
try
{
Method m = bluetoothAdapter.getClass().getMethod("listenUsingRfcommOn", new Class[] {int.class});
tmpSocket = (BluetoothServerSocket) m.invoke(bluetoothAdapter, APP_BT_CHANNEL);
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothAcceptThread listen() (with reflection) failed", e);
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
serverSocket = tmpSocket;
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread ServerSocket created");
}
#Override
public void run()
{
BluetoothSocket socket = null;
try
{
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread calling accept()...");
socket = serverSocket.accept();
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread accept() returned");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothAcceptThread accept() failed: " + e.getMessage());
}
if (socket != null)
{
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread accept() successfully");
synchronized (BluetoothManager.this)
{
if (currentState == SocketState.LISTENING || currentState == SocketState.CONNECTING)
startBluetoothConnection(socket); // all is ok, it can proceed
else if (currentState == SocketState.INACTIVE || currentState == SocketState.CONNECTED)
cancel(socket);
}
}
}
#Override
public void cancel()
{
try
{
serverSocket.close();
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread ServerSocket closed");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothAcceptThread close() failed", e);
}
}
private void cancel(BluetoothSocket newSocket)
{
try
{
newSocket.close();
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread client socket closed");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothAcceptThread client socket close() failed", e);
}
}
}
2. "Connect thread"
private class BluetoothConnectThread extends Thread
{
private final BluetoothSocket socket;
private final BluetoothDevice device;
public BluetoothConnectThread(BluetoothDevice d)
{
device = d;
BluetoothSocket tmpSocket = null;
try
{
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmpSocket = (BluetoothSocket) m.invoke(device, APP_BT_CHANNEL);
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothConnectThread create() (with reflection) failed", e);
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
socket = tmpSocket;
Log.d(MainActivity.DEBUG_TAG, "BluetoothConnectThread client socket created");
}
#Override
public void run()
{
stopBluetoothDiscovery(); // otherwise it will slow down the connection
try
{
socket.connect();
Log.d(MainActivity.DEBUG_TAG, "BluetoothConnectThread connect() successfully");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothConnectThread connect() failed", e);
String deviceName = device != null ? device.getName() : "none";
connectionFailed(deviceName); // notify UI thread
return;
}
synchronized (BluetoothManager.this)
{
bluetoothConnectThread = null;
}
startBluetoothConnection(socket); // create the "Communication" Thread
}
#Override
public void cancel()
{
try
{
socket.close();
Log.d(MainActivity.DEBUG_TAG, "BluetoothConnectThread client socket closed");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothConnectThread close() failed", e);
}
}
}
3. "Communication Thread" (aka ConnectedThread in BluetoothChat sample)
private class BluetoothCommunicationThread extends Thread
{
private final BluetoothSocket socket;
private final InputStream inputStream;
private final OutputStream outputStream;
public BluetoothCommunicationThread(BluetoothSocket s)
{
socket = s;
InputStream in = null;
OutputStream out = null;
try
{
in = socket.getInputStream();
out = socket.getOutputStream();
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothCommunicationThread failed to get streams", e);
}
inputStream = in;
outputStream = out;
}
#Override
public void run()
{
byte[] buffer = new byte[BT_BUFF_SIZE];
int readBytes;
while (true)
{
try
{
readBytes = inputStream.read(buffer, 0, buffer.length);
if (readBytes != -1)
{
Message message = messageHandler.obtainMessage(DATA_MSG, readBytes, -1, buffer);
message.sendToTarget(); // notify to UI thread the bytes counter
}
else
{
BluetoothDevice device = socket.getRemoteDevice();
String deviceName = device != null ? device.getName() : "none";
connectionLost(deviceName);
break;
}
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothCommunicationThread read() failed", e);
BluetoothDevice device = socket.getRemoteDevice();
String deviceName = device != null ? device.getName() : "none";
connectionLost(deviceName);
break;
}
}
}
public void write(byte[] buffer)
{
try
{
outputStream.write(buffer);
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothCommunicationThread write() failed", e);
}
}
#Override
public void cancel()
{
try
{
socket.close();
Log.d(MainActivity.DEBUG_TAG, "BluetoothCommunicationThread socket closed");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothCommunicationThread close() failed", e);
}
}
}
So the steps of the problem are the following:
HTC Desire server calls accept()
Xperia client calls connect()
The connect returns as if the connection was established
Nothing is happening on the HTC, always blocked on accept()
Xperia client thinks that it's connected, so it creates the CommunicationThread and calls the blocking read(); this function throws java.io.IOException: Software caused connection abort, probably because the socket is not connected.
Finally these are the relevant logcats:
Xperia client:
09-20 00:44:23.562 9106-9106/com.powertester D/[PowerTester Debug]﹕ BluetoothConnectThread client socket created
09-20 00:44:25.704 9106-9579/com.powertester D/[PowerTester Debug]﹕ BluetoothConnectThread connect() successfully
09-20 00:44:25.734 9106-9579/com.powertester D/[PowerTester Debug]﹕ BluetoothCommunicationThread started and I/O streams ready
09-20 00:44:25.764 9106-9589/com.powertester E/[PowerTester Error]﹕ BluetoothCommunicationThread read() failed
java.io.IOException: Software caused connection abort
at android.bluetooth.BluetoothSocket.readNative(Native Method)
at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:333)
at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96)
at com.powertester.net.BluetoothManager$BluetoothCommunicationThread.run(BluetoothManager.java:518)
09-20 00:44:25.844 9106-9106/com.powertester D/[PowerTester Debug]﹕ BluetoothCommunicationThread socket closed
HTC server:
09-19 15:47:07.591 2422-2422/com.powertester D/[PowerTester Debug]﹕ BluetoothAcceptThread ServerSocket created
09-19 15:47:07.591 2422-2484/com.powertester D/[PowerTester Debug]﹕ BluetoothAcceptThread calling accept()...
The really strange thing is that the HTC Desire works if used as client with one of the Xperia used as server.
So, is a problem of my app or a problem in the HTC Desire bluetooth stack?

After some troubles I have realized that the problem is the reflection itself and the explicit use of a Bluetooth Channel.
Using the normal way (i.e. the not-hidden bluetooth methods) my app works perfectly.

Related

java.io.IOException: closed error in a non-stop loop inside an asynctask

I try to create an asynctask that runs permanently (all the time my app is running). Thay task read every second a file on a server (status.xml).
My problem is that when I execute the app, I have an java.io.IOException: closed exception the second time I do :
reader.read(buffer); // HERE I HAVE AN IOException closed
(first loop is ok, then I have error each loop)
Thanks if someone can help me. I undesrtand the reason of the error, but I cannot find a solution...
Here is my code :
class StatusnAsync extends AsyncTask<Void, Void, Void> {
InputStream in = null;
int responseCode;
void Sleep(int ms) {
try {
Thread.sleep(ms);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onPreExecute() {
// inits for doInBackground thread
try {
URL url = new URL(address + "/status.xml");
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000 /* milliseconds */);
conn.setConnectTimeout(80000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected Void doInBackground(Void... arg0) {
while (not_end) {
try {
readStatus();
// Sleep 1 sec
Sleep(1000);
} catch (IOException e) {
e.printStackTrace ();
}
}
return null;
}
private void readStatus() throws IOException {
try {
conn.connect();
responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
in = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(in, 340);
// close the inputstream
in.close();
}
} catch (IOException e) {
e.printStackTrace ();
} finally {
if (in != null) in.close();
}
}
// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer); // HERE I HAVE AN IOException closed
return new String(buffer);
}
}
Thank you.
Sorry for my question, I found my error, a stupid error.
Of course I need to openConnection for each GET.
I give the corrected code if it can help someone :
class StatusnAsync extends AsyncTask<Void, Void, Void> {
InputStream in = null;
int responseCode;
URL url;
void Sleep(int ms) {
try {
Thread.sleep(ms);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onPreExecute() {
// inits for doInBackground thread
try {
url = new URL(address + "/file.xml");
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
#Override
protected Void doInBackground(Void... arg0) {
while (not_end) {
try {
readStatus();
// Sleep 1 sec
Sleep(1000);
} catch (IOException e) {
e.printStackTrace ();
}
}
return null;
}
private void readStatus() throws IOException {
try {
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000 /* milliseconds */);
conn.setConnectTimeout(80000 /* milliseconds */);
conn.connect();
responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
in = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(in, 340);
// close the inputstream
in.close();
}
} catch (IOException e) {
e.printStackTrace ();
} finally {
if (in != null) in.close();
}
}
// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
}

getBluetoothService() called with no BluetoothManagerCallback for Android Nexus 5

I am going to implemenet the module for sending commands from my Android smartphone to HC-06 via BLuetooth. WHen it comes to the execution , it show s the following exception and find no clue for the error message as title . Would you please tell the way to modifiy ?
Exception Log Message :
07-29 13:51:37.701: W/BluetoothAdapter(1928): getBluetoothService() called with no BluetoothManagerCallback
07-29 13:51:37.711: D/BluetoothSocket(1928): connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[51]}
07-29 13:51:42.831: W/System.err(1928): java.io.IOException: read failed, socket might closed or timeout, read ret: -1
07-29 13:51:42.831: W/System.err(1928): at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:505)
07-29 13:51:42.831: W/System.err(1928): at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:516)
07-29 13:51:42.831: W/System.err(1928): at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:320)
07-29 13:51:42.831: W/System.err(1928): at com.luugiathuy.apps.remotebluetooth.BluetoothCommandService$ConnectThread.run(BluetoothCommandService.java:260)
07-29 13:51:42.831: D/BluetoothCommandService(1928): setState() 2 -> 1
The below is my code
public class BluetoothCommandService {
// Debugging
private static final String TAG = "BluetoothCommandService";
private static final boolean D = true;
// Unique UUID for this application
// private static final UUID MY_UUID = UUID.fromString("04c6093b-0000-1000-8000-00805f9b34fb");
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// private BluetoothDevice mSavedDevice;
// private int mConnectionLostCount;
// 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_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
// Constants that indicate command to computer
public static final int EXIT_CMD = -1;
public static final int VOL_UP = 1;
public static final int VOL_DOWN = 2;
public static final int MOUSE_MOVE = 3;
/**
* Constructor. Prepares a new BluetoothChat session.
* #param context The UI Activity Context
* #param handler A Handler to send messages back to the UI Activity
*/
public BluetoothCommandService(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
//mConnectionLostCount = 0;
mHandler = handler;
}
/**
* Set the current state of the chat connection
* #param state An integer defining the current connection state
*/
private synchronized void setState(int state) {
if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
mState = state;
// Give the new state to the Handler so the UI Activity can update
mHandler.obtainMessage(RemoteBluetooth.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
/**
* Return the current connection state. */
public synchronized int getState() {
return mState;
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume() */
public synchronized void start() {
if (D) Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
setState(STATE_LISTEN);
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
* #param device The BluetoothDevice to connect
*/
public synchronized void connect(BluetoothDevice device) {
if (D) Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(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) {
if (D) Log.d(TAG, "connected");
// Cancel the thread that completed the connection
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(RemoteBluetooth.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(RemoteBluetooth.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
// save connected device
//mSavedDevice = device;
// reset connection lost count
//mConnectionLostCount = 0;
setState(STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
if (D) Log.d(TAG, "stop");
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
setState(STATE_NONE);
}
/**
* Write to the ConnectedThread in an unsynchronized manner
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
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 void write(int 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);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
private void connectionFailed() {
setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(RemoteBluetooth.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(RemoteBluetooth.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private void connectionLost() {
// mConnectionLostCount++;
// if (mConnectionLostCount < 3) {
// // Send a reconnect message back to the Activity
// Message msg = mHandler.obtainMessage(RemoteBluetooth.MESSAGE_TOAST);
// Bundle bundle = new Bundle();
// bundle.putString(RemoteBluetooth.TOAST, "Device connection was lost. Reconnecting...");
// msg.setData(bundle);
// mHandler.sendMessage(msg);
//
// connect(mSavedDevice);
// } else {
setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(RemoteBluetooth.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(RemoteBluetooth.TOAST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
// }
}
/**
* This thread runs while attempting to make an outgoing connection
* with a device. It runs straight through; the connection either
* succeeds or fails.
*/
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "create() failed", e);
}
mmSocket = tmp;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread");
setName("ConnectThread");
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
e.printStackTrace();
connectionFailed();
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
// Start the service over to restart listening mode
BluetoothCommandService.this.start();
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothCommandService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "create ConnectedThread");
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) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
// Keep listening to the InputStream while connected
while (true) {
try {
// Read from the InputStream
int bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(RemoteBluetooth.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
/**
* Write to the connected OutStream.
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
mmOutStream.flush();
// Share the sent message back to the UI Activity
// mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
// .sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void write(int out) {
try {
mmOutStream.write(out);
// Share the sent message back to the UI Activity
// mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
// .sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmOutStream.write(EXIT_CMD);
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
Here is my Activity
public class RemoteBluetooth extends Activity {
// Layout view
private TextView mTitle;
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
// Message types sent from the BluetoothChatService Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
// Key names received from the BluetoothCommandService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
// Name of the connected device
private String mConnectedDeviceName = null;
// Local Bluetooth adapter
private BluetoothAdapter mBluetoothAdapter = null;
// Member object for Bluetooth Command Service
private BluetoothCommandService mCommandService = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set up the window layout
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
// Set up the custom title
mTitle = (TextView) findViewById(R.id.title_left_text);
mTitle.setText(R.string.app_name);
mTitle = (TextView) findViewById(R.id.title_right_text);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
}
#Override
protected void onStart() {
super.onStart();
// If BT is not on, request that it be enabled.
// setupCommand() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
// otherwise set up the command service
else {
if (mCommandService==null)
setupCommand();
}
}
#Override
protected void onResume() {
super.onResume();
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
if (mCommandService != null) {
if (mCommandService.getState() == BluetoothCommandService.STATE_NONE) {
mCommandService.start();
}
}
}
private void setupCommand() {
// Initialize the BluetoothChatService to perform bluetooth connections
mCommandService = new BluetoothCommandService(this, mHandler);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mCommandService != null)
mCommandService.stop();
}
private void ensureDiscoverable() {
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
// The Handler that gets information back from the BluetoothChatService
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BluetoothCommandService.STATE_CONNECTED:
mTitle.setText(R.string.title_connected_to);
mTitle.append("HC-06");
break;
case BluetoothCommandService.STATE_CONNECTING:
mTitle.setText(R.string.title_connecting);
break;
case BluetoothCommandService.STATE_LISTEN:
case BluetoothCommandService.STATE_NONE:
mTitle.setText(R.string.title_not_connected);
break;
}
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
// Attempt to connect to the device
mCommandService.connect(device);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
setupCommand();
} else {
// User did not enable Bluetooth or an error occured
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.option_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.scan:
// Launch the DeviceListActivity to see devices and do scan
Intent serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
return true;
case R.id.discoverable:
// Ensure this device is discoverable by others
ensureDiscoverable();
return true;
}
return false;
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
String blinkCommand = "&$V00X77V0" ;
String empty = "";
for (int i = 0 ; i < (100 - blinkCommand.length()) ; i ++){
empty += "0";
}
String limiter = "\r\n";
String fullCommand = blinkCommand + empty + limiter;
mCommandService.write(fullCommand.getBytes());
// mCommandService.write(BluetoothCommandService.VOL_UP);
return true;
}
else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
String blinkCommand = "&$V00X77V0" + "\r\n";
mCommandService.write(blinkCommand.getBytes());
// mCommandService.write(BluetoothCommandService.VOL_DOWN);
return true;
}
return super.onKeyDown(keyCode, event);
}
}
since android 4.2 , bluetooth stack changed, so i guess you are testing on android>=4.2 .
your problem is here tmp = device.createRfcommSocketToServiceRecord(MY_UUID); . this socket creation method is not compatible starting with 4.2 , so you will need to use the fallback one after it fails : tmp =(BluetoothSocket) device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(device,1);
Don't worry about called with no BluetoothManagerCallback being thrown, it doesn't matter.
So if you do it like this, it will work:
try {
socket = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
} catch (Exception e) {Log.e("","Error creating socket");}
try {
socket.connect();
Log.e("","Connected");
} catch (IOException e) {
Log.e("",e.getMessage());
try {
Log.e("","trying fallback...");
socket =(BluetoothSocket) device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(device,1);
socket.connect();
Log.e("","Connected");
}
also, i answered here more detailed, about a similar problem.

I want to create a program that checks ip address continuously

I want to create a program that checks ip address continuously.
i have a code that checks ip address and port, like this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace WinNetworkIOCS {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void ConnectButton_Click(object sender, EventArgs e) {
DisableFields();
DoNetworkingConnection();
}
private void DisableFields() {
PortBox.Enabled = false;
IPAddressBox.Enabled = false;
SendMessageBox.Enabled = false;
ConnectButton.Enabled = false;
}
private void EnableFields() {
PortBox.Enabled = true;
IPAddressBox.Enabled = true;
SendMessageBox.Enabled = true;
ConnectButton.Enabled = true;
}
private void WriteToStatusBar(string Message) {
//EnableFields();
ThreadHelperClass.SetText(this, lblStatus, Message);
}
private void DoNetworkingConnection() {
Thread MyThread = null;
try {
ThreadStart ThreadMethod = new ThreadStart(ConnectTo);
MyThread = new Thread(ThreadMethod);
} catch (Exception e) {
WriteToStatusBar("Failed to create thread with error: " + e.Message);
return;
}
try {
MyThread.Start();
} catch (Exception e) {
WriteToStatusBar("The thread failed to start with error: " + e.Message);
}
}
private void ConnectTo() {
string ServerName = this.IPAddressBox.Text;
int Port = System.Convert.ToInt32(this.PortBox.Text);
WriteToStatusBar("IP Address: " + ServerName + "Port: " + Port);
Socket ClientSocket = null;
try {
// Let's connect to a listening server
try {
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
WriteToStatusBar("Socket is OK...");
} catch (Exception e) {
throw new Exception("Failed to create client Socket: " + e.Message);
}
IPEndPoint ServerEndPoint = new IPEndPoint(IPAddress.Parse(ServerName), Convert.ToInt16(Port));
try {
ClientSocket.Connect(ServerEndPoint);
WriteToStatusBar("Connect() is OK...");
} catch (Exception e) {
throw new Exception("Failed to connect client Socket: " + e.Message);
}
} catch (Exception e) {
WriteToStatusBar(e.Message);
ClientSocket.Close();
return;
}
// Let's create a network stream to communicate over the connected Socket.
NetworkStream ClientNetworkStream = null;
try {
try {
// Setup a network stream on the client Socket
ClientNetworkStream = new NetworkStream(ClientSocket, true);
WriteToStatusBar("Instantiating NetworkStream...");
} catch (Exception e) {
// We have to close the client socket here because the network
// stream did not take ownership of the socket.
ClientSocket.Close();
throw new Exception("Failed to create a NetworkStream with error: " + e.Message);
}
StreamWriter ClientNetworkStreamWriter = null;
try {
// Setup a Stream Writer
ClientNetworkStreamWriter = new StreamWriter(ClientNetworkStream);
WriteToStatusBar("Setting up StreamWriter...");
} catch (Exception e) {
ClientNetworkStream.Close();
throw new Exception("Failed to create a StreamWriter with error: " + e.Message);
}
try {
ClientNetworkStreamWriter.Write(this.SendMessageBox.Text.ToString());
ClientNetworkStreamWriter.Flush();
WriteToStatusBar("We wrote " + this.SendMessageBox.Text.Length.ToString() + " character(s) to the server.");
} catch (Exception e) {
throw new Exception("Failed to write to client NetworkStream with error: " + e.Message);
}
} catch (Exception e) {
WriteToStatusBar(e.Message);
} finally {
// Close the network stream once everything is done
ClientNetworkStream.Close();
}
}
delegate void SetTextCallback(string text);
}
Problem is that it does not check the ip address and port continuously.
What to add into my code to make this happen?
I am assuming that what you mean is that you wish to be able to run your program more than once, not that you wish for it to check over and over again and therefore that your problem is in fact that your program finishes the task of pinging but then never allows you to enter new information?
This is because in your function
private void ConnectButton_Click(object sender, EventArgs e) {
DisableFields();
DoNetworkingConnection();
}
You run the function DisableFields(); and DoNetworkingConnection(); Assuming that the DoNeworkingConnection(); works and it runs the code once then your problem is that you never enable your controls again since in
private void WriteToStatusBar(string Message) {
//EnableFields();
ThreadHelperClass.SetText(this, lblStatus, Message);
}
You have commented out EnableFields(); that re-enables your controls. If this is not the case and you are actually trying to make it run continuously you would have to wrap the sending part of the ConnectTo() in a while loop
while(true)
{
ClientNetworkStreamWriter.Write(this.SendMessageBox.Text.ToString());
ClientNetworkStreamWriter.Flush();
WriteToStatusBar("We wrote " + this.SendMessageBox.Text.Length.ToString() + " character(s) to the server.");
}
Though if this is the case please state what you are trying to achieve and you will probably get a better solution because this will quickly turn into something like a DOS attack..

Asynchronous Socket losing connection

I'm trying to develop socket based application on wp7 (client) and WPF (server) and I have issue that I don't understand.
I've written "Server" class which should handle connecting with client and recieving strings.
The problem is that server recieving just first string sent by client and then the connection is breaking, I have to reset my client app (only client). I'm assuming it's server side problem because I'm rewriting server application using Async calls. Before that client works well. My server side code:
public class StateObject
{
public byte[] Buffer { get; set; }
public Socket WorkSocket { get; set; }
}
public class MessageRecievedEventArgs : EventArgs
{
public string Message { get; set; }
}
public class Server
{
ManualResetEvent _done;
TcpListener _listener;
public event EventHandler<MessageRecievedEventArgs> OnMessageRecieved;
public Server()
{
_done = new ManualResetEvent(false);
_listener = new TcpListener(IPAddress.Any, 4124);
}
public void Start()
{
Thread th = new Thread(StartListening);
th.IsBackground = true;
th.Start();
}
private void StartListening()
{
_listener.Start();
while (true)
{
_done.Reset();
_listener.BeginAcceptTcpClient(new AsyncCallback(OnConnected), _listener);
_done.WaitOne();
}
}
private void OnConnected(IAsyncResult result)
{
TcpListener listener = result.AsyncState as TcpListener;
Socket socket = listener.EndAcceptSocket(result);
byte[] buffer = new byte[256];
StateObject state = new StateObject { Buffer = buffer, WorkSocket = socket };
socket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, new AsyncCallback(OnRead), state);
}
private void OnRead(IAsyncResult result)
{
var state = (StateObject)result.AsyncState;
int buffNum = state.WorkSocket.EndReceive(result);
string message = Encoding.UTF8.GetString(state.Buffer, 0, buffNum);
if (OnMessageRecieved != null)
{
MessageRecievedEventArgs args = new MessageRecievedEventArgs();
args.Message = message;
OnMessageRecieved(this, args);
}
_done.Set();
}
}
Client:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
try
{
base.OnNavigatedTo(e);
_socketEventArgs = new SocketAsyncEventArgs() { RemoteEndPoint = App.Connection.RemoteEndPoint };
Send("{ECHO}");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Send(string key)
{
var bytes = Encoding.UTF8.GetBytes(key + "$");
_socketEventArgs.SetBuffer(bytes, 0, bytes.Count());
if (Socket.Connected)
Socket.SendAsync(_socketEventArgs);
else
MessageBox.Show("Application is not connected. Please reset connection (press 'back' key and 'connect' button). It may be needed to restart server application");
}
The "{ECHO}" message is sent by client and recieved by server - each next is sent, but not recieved. I assuming that I don't understand sockets async calls mechanism... can someone enlighten me? :)
It seems like you are only reading once. Probably you want to call read repeatedly to deplete the entire stream.

Not able to receive messages from JMS temporary queue

I have searched for the solution but couldn't make it work. Here is the summary. I am trying to implement a webservice which runs on Glassfish 2.1 that implements a synchronous JMS Request-Response using Temporary queue. It sends a message to another Glassfish application running on remote server. I am able to send the message and process it but when the final message is sent back to temporary queue, the webservice gets the response as null. Here is the code:
private Message requestReply(String msg, Queue jmsRequestResponse, ConnectionFactory jmsRequestRespConnFactory) {
javax.jms.Connection conn = null;
javax.jms.MessageConsumer consumer = null;
javax.jms.Message replyMsg = null;
javax.jms.Session sess = null;
try {
logger.debug("[requestreply input message[" + msg);
conn = jmsRequestRespConnFactory.createConnection();
conn.start();
sess = conn.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
javax.jms.Message reqMessage = sess.createTextMessage(msg);
javax.jms.Destination replyDestination = (jmsRequestResponse instanceof javax.jms.Queue) ? sess.createTemporaryQueue() : sess.createTemporaryTopic();
reqMessage.setJMSReplyTo(replyDestination);
sess.createProducer(jmsRequestResponse).send(reqMessage);
replyMsg = consumer.receive(60000);
consumer.close();
sess.close();
conn.close();
} catch (JMSException ex) {
logger.debug("exception in requestreply");
} finally {
if (consumer != null) {
try {
consumer.close();
} catch (Exception e) {
}
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
}
}
}
return replyMsg;
}
what am I missing here?? When I print the replyMsg, it is always null.

Resources