I'm having a weird problem. I already lost a lot of time trying to understand
and solve this but nothing works.
I have an app that communicates with another device across bluetooth connection
to receive some sensor data. In that point, everything works fine, I can connect
to the device, receive and treat the messages.
But yesterday, I decided to create some kind of log file to directly save in the
internal memory the data received from the device without any kind of transformation from my app.
To receive the data from the device, I have a background thread:
public class CommunicationThread extends Thread {
private static final UUID UUID_DEVICE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final String TAG = CommunicationThread.class.getSimpleName();
private CommunicationListener mListener;
private boolean mRunning;
private BluetoothSocket mBluetoothSocket;
private InputStream mInputStream;
private OutputStream mOutputStream;
public interface CommunicationListener {
void onMessageReceived(String msg);
}
public CommunicationThread(
#NonNull BluetoothDevice device,
#Nullable CommunicationListener listener) throws IOException {
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID_DEVICE);
socket.connect();
this.mBluetoothSocket = socket;
this.mInputStream = socket.getInputStream();
this.mOutputStream = socket.getOutputStream();
this.mListener = listener;
}
#Override
public void run() {
mRunning = true;
byte[] bytes = new byte[1024];
int length;
while (mRunning) {
try {
Log.d(TAG, "Waiting for message");
// read the message (block until receive)
length = mInputStream.read(bytes);
String msg = new String(bytes, 0, length);
Log.d(TAG, "Message: " + msg);
// Message received, inform the listener
if (mListener != null)
mListener.onMessageReceived(msg);
} catch (Exception e) {
Log.e(TAG, "Error reading the message", e);
}
}
}
public void sendCommand(String msg) {
try {
mOutputStream.write((msg).getBytes());
} catch (Exception e) {
Log.e(TAG, "Error to send message", e);
}
}
public void stopCommunication() {
mRunning = false;
mListener = null;
try {
if (mBluetoothSocket != null) {
mBluetoothSocket.close();
}
if (mInputStream != null) {
mInputStream.close();
}
if (mOutputStream != null) {
mOutputStream.close();
}
} catch (IOException e) {
Log.e(TAG, "Error to stop communication", e);
}
}
}
This thread works pretty fine and when a message is received, it informs the listener,
my Controller class. The first thing that I try to do when a message comes, is save it:
public class Controller implements CommunicationThread.CommunicationListener
...
#Override
public void onMessageReceived(final String msg) {
Log.d(TAG, "onMessageReceived(msg): " + msg);
mLogCreator.saveThis(msg);
....
}
}
Here is the LogCreator class:
public class LogCreator {
private static final String TAG = LogCreator.class.getSimpleName();
public static final String LOG_FILE_NAME = "log.txt";
private final Context mContext;
private volatile String mTempFullLog;
public LogCreator(Context context) {
mContext = context.getApplicationContext();
File dir = new File(mContext.getFilesDir(), "log_folder");
if (!dir.exists()) {
dir.mkdirs();
File file = new File(dir, LOG_FILE_NAME);
writeString(file, "");
Log.d(TAG, "empty file created");
}
}
public void saveThis(final String data) {
mTempFullLog += "\n" + data;
Log.d(TAG, "New log: " + data);
}
public void start() {
File dir = new File(mContext.getFilesDir(), "log_folder");
File file = new File(dir, LOG_FILE_NAME);
mTempFullLog = readString(file);
Log.d(TAG, "File: " + file);
Log.d(TAG, "Temp full log: " + mTempFullLog);
}
public void stop() {
File dir = new File(mContext.getFilesDir(), "log_folder");
File file = new File(dir, LOG_FILE_NAME);
writeString(file, mTempFullLog);
Log.d(TAG, "log saved: " + mTempFullLog);
}
}
The LogCreator class is already initialized and it works properly, because
if I try to read the file later, everything is there.
The real problem is the following: there is a lot of calls to Log.d during
this execution flow, and this makes very easy to me to understand the all process.
But, the logs are only printed in the logcat until this Log.d call, in the
CommunicationThread class:
Log.d(TAG, "Waiting for message);
After the message received, all code executes normally, but no logs are printed in
the logcat and I really dont know why.
Logs not printed:
CommunicationThread:
Log.d(TAG, "Message: " + msg);
Controller:
Log.d(TAG, "onMessageReceived(msg): " + msg);
LogCreator:
Log.d(TAG, "New log: " + data);
Like I said, I know that everything is working fine with the code because the log
file is created in internal memory even without the logcat prints. It cost me
some hours to realize that the problem is only with the log and not really in
my code.
For testing purpose, if I add this code in the saveThis method of LogCreator,
it executes normally:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, data, Toast.LENGTH_SHORT).show();
}
});
This makes me think that everything could be a thread problem, because the start
and stop methods of LogCreator are both called from the main thread not the CommunicationThread and both methods have their logs printed. Because of this, in the onMessageReceived method
of the Controller class, I tried this:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
mLogCreator.saveThis(msg);
}
});
But, unfortunately, the logs don't get printed in the logcat. The toast is still
executed and the data are still saved to the file.
If anyone has any idea of what might be causing this, I really want to know, thanks.
I finally find the solution myself. The reason why the following not work is not clear for me, and IMO it should be treated like a bug.
I compile the app in debug mode and discover that the string received from the device has a "\r" in the end.
Example: "15.50\r"
So, for some strange reason, if I try to do this:
Log.d(TAG, "New log: " + data);
Nothing prints and we don't receive no warnings at all.
But, if I do this instead:
Log.d(TAG, "New log: " + data.replace("\r", ""));
Where data is: "15.50\r"
Everything works and the logcat prints the message.
Related
I am trying to make my own messaging application.I am able to send sms and mms I am able to write incoming sms into android database. I have made my app default messaging app. But how to show incoming mms into my inbox with images and text. I am using https://github.com/klinker41/android-smsmms as a library.
You should use MmsReceivedReceiver class of that library. Take a look on it implementation:
public class MmsReceivedReceiver extends BroadcastReceiver {
private static final String TAG = "MmsReceivedReceiver";
public static final String MMS_RECEIVED = "com.klinker.android.messaging.MMS_RECEIVED";
public static final String EXTRA_FILE_PATH = "file_path";
public static final String EXTRA_LOCATION_URL = "location_url";
private static final String LOCATION_SELECTION =
Telephony.Mms.MESSAGE_TYPE + "=? AND " + Telephony.Mms.CONTENT_LOCATION + " =?";
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "MMS has finished downloading, persisting it to the database");
String path = intent.getStringExtra(EXTRA_FILE_PATH);
Log.v(TAG, path);
FileInputStream reader = null;
try {
File mDownloadFile = new File(path);
final int nBytes = (int) mDownloadFile.length();
reader = new FileInputStream(mDownloadFile);
final byte[] response = new byte[nBytes];
reader.read(response, 0, nBytes);
DownloadRequest.persist(context, response,
new MmsConfig.Overridden(new MmsConfig(context), null),
intent.getStringExtra(EXTRA_LOCATION_URL),
Utils.getDefaultSubscriptionId(), null);
Log.v(TAG, "response saved successfully");
Log.v(TAG, "response length: " + response.length);
mDownloadFile.delete();
} catch (FileNotFoundException e) {
Log.e(TAG, "MMS received, file not found exception", e);
} catch (IOException e) {
Log.e(TAG, "MMS received, io exception", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
Log.e(TAG, "MMS received, io exception", e);
}
}
}
handleHttpError(context, intent);
DownloadManager.finishDownload(intent.getStringExtra(EXTRA_LOCATION_URL));
}
private void handleHttpError(Context context, Intent intent) {
final int httpError = intent.getIntExtra(SmsManager.EXTRA_MMS_HTTP_STATUS, 0);
if (httpError == 404 ||
httpError == 400) {
// Delete the corresponding NotificationInd
SqliteWrapper.delete(context,
context.getContentResolver(),
Telephony.Mms.CONTENT_URI,
LOCATION_SELECTION,
new String[]{
Integer.toString(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND),
intent.getStringExtra(EXTRA_LOCATION_URL)
});
}
}
}
and implement something like SmsReceiver from example of library.
I am building an Android app that communicates with an Arduino board via bluetooth, I have the bluetooth code in a class of it's own called BlueComms. To connect to the device I use the following methord:
public boolean connectDevice() {
CheckBt();
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Log.d(TAG, "Connecting to ... " + device);
mBluetoothAdapter.cancelDiscovery();
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
btSocket.connect();
outStream = btSocket.getOutputStream();
Log.d(TAG, "Connection made.");
return true;
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
Log.d(TAG, "Unable to end the connection");
return false;
}
Log.d(TAG, "Socket creation failed");
}
return false;
}
private void CheckBt() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (!mBluetoothAdapter.isEnabled()) {
System.out.println("Bt dsbld");
}
if (mBluetoothAdapter == null) {
System.out.println("Bt null");
}
}
This connects fine but as soon as I leave the activity I connected through it drops the connection, showing this through LogCat,
D/dalvikvm(21623): GC_CONCURRENT freed 103K, 10% free 2776K/3056K, paused 5ms+2ms, total 35ms
I can no longer connect to the device, but if I call killBt() it throws a fatal error and if I try to send data I get a 'Socket creation failed' error. My send message code is as follows:
public void sendData(String data, int recvAct) {
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.d(TAG, "Bug BEFORE Sending stuff", e);
}
String message = data;
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.d(TAG, "Bug while sending stuff", e);
}
}
How should I go about preventing the connection from being paused by the activity I connect with when I switch a different activity, I am switching activities with this code:
Intent myIntent = new Intent(v.getContext(), Timelapse.class);
startActivityForResult(myIntent, 0);
Many Thanks,
Rozz
Where did you store the instance of your BlueComms class? If you put it in the first activity then the class instance would have been killed when that activity was destroyed as you left it and moved to the next activity (NB activities also get destroyed on screen rotation)
So you need to find a way to keep the instance of BlueComms class alive for as long as you need it. You could pass it between activities via public properties and store it in onRetainNonConfigurationInstance() during rotations.
An easier trick is to create a class that extends Application use it as the application delegate for your app and add public property to it to store the instance of BlueComms class within it. That way the instance of BlueComms class would be alive for the lifetime of you app.
Extend Application
import android.app.Application;
public class cBaseApplication extends Application {
public BlueComms myBlueComms;
#Override
public void onCreate()
{
super.onCreate();
myBlueComms = new BlueComms();
}
}
Make your class the application delegate in the app manifest
<application
android:name="your.app.namespace.cBaseApplication"
android:icon="#drawable/icon"
android:label="#string/app_name" >
Access the base app from any of your Activities like this
((cBaseApplication)this.getApplicationContext()).myBlueComms.SomeMethod();
What I have done is, Created a singleton class for BluetoothConnection.
So socket creation happens only for one time.
When onCreate method of any activity is created, it first fetch instance of BluetoothConnection class.
Handler is used to send messages from thread in BluetoothConnection class to the corresponding activity by settings Handler.
Like:
Class MyBTConnection{
private static MyBTConnection connectionObj;
private Handler mHandler;
public MyBTConnection() { //constructor }
public static MyBTConnection getInstance() {
if(connectionObj == null) {
connectionObj = new MyBTConnection();
}
return connectionObj;
}
}
public void setHandler(Handler handler) {
mHandler = handler;
}
..... Code for Bluetooth Connection ....
to send message :
mHandler.obtainMessage(what).sendToTarget();
}
// in first activity
class MainActivity extends Activity {
private MyBTConnection connectionObj;
public onCreate(....) {
/*
* Since this is first call for getInstance. A new object
* of MyBTConnection will be created and a connection to
* remote bluetooth device will be established.
*/
connectionObj = MyBTConnection.getInstance();
connectionObj.setHandler(mHandler);
}
private Handler mHandler = new Handler(){
public void onReceive(...) {
/// handle received messages here
}
};
}
// in second activity
class SecondActivity extends Activity {
private MyBTConnection connectionObj;
public onCreate(....) {
/*
* Since this is second call for getInstance.
* Object for MyBTConnection was already created in previous
* activity. So getInstance will return that previously
* created object and in that object, connection to remote
* bluetooth device is already established so you can
* continue your work here.
*/
connectionObj = MyBTConnection.getInstance();
connectionObj.setHandler(mHandler);
}
private Handler mHandler = new Handler(){
public void onReceive(...) {
/// handle received messages here
}
};
}
I'm currently having exactly the same issue and I was thinking of opening/closing the Bluetooth socket each time an Activity asks for it. Each Activity has it's own BlueComms instance.
Because my application will became a bit complex and there will be Bluetooth threaded requests from different activities, I'm thinking that this way will become very difficult to use and troubleshoot.
Another way I came across by reading here...
https://developer.android.com/guide/components/services.html
A Service can be created on the background having a Bluetooth socket always on. All Bluetooth requests can be made using Intent towards this service. This also creates some fair amount of complexity but feels a lot more tidy and organized.
I'm currently having this dilemma, either to use a thread for each activity or use a service. I don't know which way is actually better.
When you are Selecting A device to connect and when you are click on the device list item for requesting a connection to the device use AsyncTask
and put the connect method inside the AsyncTask like this :-
AsyncTask.execute(new Runnable() {
#Override
public void run() {
try {
bluetoothSocket = Globals.bluetoothDevice.createRfcommSocketToServiceRecord(Globals.DEFAULT_SPP_UUID);
bluetoothSocket.connect();
// After successful connect you can open InputStream
} catch (IOException e) {
e.printStackTrace();
}
**Here is the full code for the same problem that i have cracked :-**
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
lablelexconnected.setText("Connecting ...");
bdDevice = arrayListBluetoothDevices.get(position);
//bdClass = arrayListBluetoothDevices.get(position)
// Toast.makeText(getApplicationContext()," " + bdDevice.getAddress(),Toast.LENGTH_SHORT).show();
Log.i("Log", "The dvice : " + bdDevice.toString());
bdDevice = bluetoothAdapter.getRemoteDevice(bdDevice.getAddress());
Globals.bluetoothDevice = bluetoothAdapter.getRemoteDevice(bdDevice.getAddress());
System.out.println("Device in GPS Settings : " + bdDevice);
// startService(new Intent(getApplicationContext(),MyService.class));
/* Intent i = new Intent(GpsSettings.this, MyService.class);
startService(i);*/
// finish();
// connectDevice();
AsyncTask.execute(new Runnable() {
#Override
public void run() {
try {
bluetoothSocket = Globals.bluetoothDevice.createRfcommSocketToServiceRecord(Globals.DEFAULT_SPP_UUID);
bluetoothSocket.connect();
// After successful connect you can open InputStream
InputStream in = null;
in = bluetoothSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
br = new BufferedReader(isr);
while (found == 0) {
String nmeaMessage = br.readLine();
Log.d("NMEA", nmeaMessage);
// parse NMEA messages
sentence = nmeaMessage;
System.out.println("Sentence : " + sentence);
if (sentence.startsWith("$GPRMC")) {
String[] strValues = sentence.split(",");
System.out.println("StrValues : " + strValues[3] + " " + strValues[5] + " " + strValues[8]);
if (strValues[3].equals("") && strValues[5].equals("") && strValues[8].equals("")) {
Toast.makeText(getApplicationContext(), "Location Not Found !!! ", Toast.LENGTH_SHORT).show();
} else {
latitude = Double.parseDouble(strValues[3]);
if (strValues[4].charAt(0) == 'S') {
latitude = -latitude;
}
longitude = Double.parseDouble(strValues[5]);
if (strValues[6].charAt(0) == 'W') {
longitude = -longitude;
}
course = Double.parseDouble(strValues[8]);
// Toast.makeText(getApplicationContext(), "latitude=" + latitude + " ; longitude=" + longitude + " ; course = " + course, Toast.LENGTH_SHORT).show();
System.out.println("latitude=" + latitude + " ; longitude=" + longitude + " ; course = " + course);
// found = 1;
NMEAToDecimalConverter(latitude, longitude);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
});
I'm trying to integrate the Twilio client into a larger application. Everything seems to work fine until I call device.connect(parameters, connectionListener). I get the 31100 Generic Malformed Request error and that's it.
On the same device, using the same Twilio account and the same Twilio application, the sample code supplied with the Twilio Android SDK (MonkeyPhone) works perfectly.
I can't find any more details about what the error means or what are the possible causes. While I'm assuming that I'm sending invalid data, I don't see how is that possible. The Capability Token is OK, I've verified it against the one generated in the MonkeyPhone sample app. Creating a Device works fine, no errors. The error is thrown even when I'm not sending any parameters in the connect() method. The onConnecting() method of the ConnectionListener gets called, but then the onDisconnected(Connection inConnection, int inErrorCode, String inErrorMessage) is called with the Malformed Request error.
The code for the Voice TwiML is working fine, it's just a simple PHP script generating the most simple <Dial> verb possible:
<Response>
<Dial>someone</Dial>
</Response>
Other specific information... I'm running another service in my application, used to do various other operations. Could this interfere in some way? Also, I'm using a trial account and I'm living in Romania, where calling real phone numbers is not supported (but I'm not using phone numbers anyway). Could this affect me in any way?
I apologize in advance for throwing the huge wall of code, but I hope a second pair of eyes can spot something wrong. This is the version of the code most similar to the MonkeyPhone sample. The only difference is that I'm using an AsyncTask to get the capability token (the JsonAsyncRequestWithError class.
public class MonkeyPhone implements Twilio.InitListener, DeviceListener {
private static final String TAG = "MonkeyPhone";
private Context context;
private Device device;
private Connection connection;
public MonkeyPhone(Context context) {
this.context = context;
Twilio.initialize(context, this /* Twilio.InitListener */);
}
#Override
/* Twilio.InitListener method */
public void onInitialized() {
Log.d(TAG, "Twilio SDK is ready");
// the Emulator has a somewhat unique "product" name
String clientName = "doug";
HttpGet get = new HttpGet("http://teamphoenix.zzl.org/capability.php?ClientName=" + clientName);
JsonAsyncRequestWithError asyncRequestWithError = new JsonAsyncRequestWithError(context, "test", new AsyncRequestWithErrorListener() {
#Override
public void onResult(AsyncRequestResponse response, Object destination) {
createDevice(response.getMessage());
}
#Override
public void onErrorResult(AsyncRequestResponse response, Object destination) {
}
});
asyncRequestWithError.execute(get);
}
public void createDevice(String token) {
try {
device = Twilio.createDevice(token, this /* DeviceListener */);
Intent intent = new Intent(context, SpringshotPhoneActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
device.setIncomingIntent(pendingIntent);
} catch (Exception e) {
Log.e(TAG, "", e);
}
}
#Override
/* Twilio.InitListener method */
public void onError(Exception e) {
Log.e(TAG, "Twilio SDK couldn't start: " + e.getLocalizedMessage());
}
#Override
/* DeviceListener method */
public void onStartListening(Device inDevice) {
Log.i(TAG, "Device is now listening for incoming connections");
}
#Override
/* DeviceListener method */
public void onStopListening(Device inDevice) {
Log.i(TAG, "Device is no longer listening for incoming connections");
}
#Override
/* DeviceListener method */
public void onStopListening(Device inDevice, int inErrorCode, String inErrorMessage) {
Log.i(TAG, "Device is no longer listening for incoming connections due to error " + inErrorCode + ": " + inErrorMessage);
}
#Override
/* DeviceListener method */
public boolean receivePresenceEvents(Device inDevice) {
return false; // indicate we don't care about presence events
}
#Override
/* DeviceListener method */
public void onPresenceChanged(Device inDevice, PresenceEvent inPresenceEvent) {
}
public void connect(String phoneNumber) {
Map<String, String> parameters = new HashMap<String, String>(1);
parameters.put("PhoneNumber", phoneNumber);
/// ---------------- THIS IS THE CALL THAT FAILS ------------------------------------//
connection = device.connect(parameters, null /* ConnectionListener */);
if (connection == null)
Log.w(TAG, "Failed to create new connection");
}
public void disconnect() {
if (connection != null) {
connection.disconnect();
connection = null;
}
}
public void handleIncomingConnection(Device inDevice, Connection inConnection) {
Log.i(TAG, "Device received incoming connection");
if (connection != null)
connection.disconnect();
connection = inConnection;
connection.accept();
}
#Override
protected void finalize() {
if (connection != null)
connection.disconnect();
if (device != null)
device.release();
}
}
Thank you very much!
I figured out the problem. Apparently, I had to read the InputStream from the server using the UTF-8 encoding (even if there are no special characters in the token).
char[] buf = new char[1024];
InputStream is = response.getEntity().getContent();
StringBuilder out = new StringBuilder();
Reader in = new InputStreamReader(is, "UTF-8");
int bin;
while ((bin = in.read(buf, 0, buf.length)) >= 0) {
out.append(buf, 0, bin);
}
return out.toString();
I'm developing an application for Android 4.03. The code of relevance is this:
public void startConnection() {
new Thread(new Runnable() {
#Override
public void run() {
try {
Log.i(LOG_TAG, "Beginning");
_socket = new Socket(_server, _port);
_socket.setSoTimeout(DEFAULT_SOCKET_TIMEOUT);
_writer = new BufferedWriter(new OutputStreamWriter(_socket.getOutputStream()));
_reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
_in = new InputThread(_reader, new InputThreadObserver());
_in.start();
Log.i(LOG_TAG, "End");
} catch (UnknownHostException e) {
Log.i(LOG_TAG, "UnknownHostException");
} catch (IOException e) {
Log.i(LOG_TAG, "IOException");
}
}
}).start();
}
The creation of the socket is performed in a new thread, otherwise the execution freezes for few seconds.
If I set the variable _server to an existing host (for example www.google.com) everything goes all right. But if I set the _server variable to an host that does not exist (for example asd.asd) I really expect "UnknownHostException" to be printed in the logger. This does not happen (but the _socket variable is null). It just prints "Beginning" (and not "End"). Any Idea?
EDIT:
The variables are declared like this:
private String _server;
private Socket _socket;
private int _port;
private BufferedWriter _writer;
private BufferedReader _reader;
private InputThread _in;
EDIT:
I'm trying this:
public void startConnection() {
new Thread(new Runnable() {
#Override
public void run() {
try {
Log.i(LOG_TAG, "Beginning");
_socket = new Socket(_server, _port);
if (_socket == null)
Log.i(LOG_TAG, "NULL SOCKET! (test 1)");
} catch (Exception e) {
Log.i(LOG_TAG, "EXCEPTION!");
}
if (_socket == null)
Log.i(LOG_TAG, "NULL SOCKET! (test 2)");
}
}).start();
}
Don't know why but the output is only:
Beginning
EDIT:
After 3 minutes and 13 seconds waiting i finally got:
EXCEPTION!
NULL SOCKET! (test 2)
Is that normal? Shouldn't the UnknownHostException be thrown immediatly?
Looking at the API docs, if _server is a String, then you'll get an UnknownHost exception. If it's any of the other possibilities, you won't.
In particular this signature will create the exception:
Socket(String host,
int port)
throws UnknownHostException,
IOException
Weird problem that seems to have been mentioned a few times on here. I have a thread, have used AsyncTask also, and I am trying to make it stop running, on the users request.
So, naturally, I use a boolean in the while loop. The thread always sees that boolean as true, even when it prints false elsewhere.
Code is below and any help is appreciated!
/**
* Opens new socket and listens on the specified port until a user stops the thread, the logview is updated with messages
*/
public void run() {
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
Log.e("Text2Server", "Starting Server");
this.running = true;
while(this.running) {
Log.i("Text2Server", "Server should be running: " + running);
try {
serverSocket = new DatagramSocket(port);
} catch (SocketException e1) {
e1.printStackTrace();
}
try {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
final String fromIP = new String(receivePacket.getAddress().toString());
final int fromPort = receivePacket.getPort();
final String received = new String(receivePacket.getData());
Date now = new Date();
final String logput = DateFormat.getDateTimeInstance().format(now) + " - Message from: " + fromIP + " through Port: " + fromPort + " with Message: " + received;
Log.i("Text2Server", logput);
//All UI Operations are done in this thread
uiHandler.post(new Runnable(){
#Override
public void run() {
logTextView.append(logput);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
serverSocket.close();
}
public void stopThread() {
this.running = false;
Log.i("Text2Server", "Stopping Server, value is now: " + running);
}
Calling stopThread() makes it false, but the thread still goes into the while and prints out true. Any thoughts?
Thanks!
Possible reasons:
1) You have spawned more than one thread and have closed only one of them.
2) You call stopThread before the thread starts running.
3) The thread has queued up many logTextView.append(logput) calls on the UI thread and therefore appears to be still running afterwards.