Android: How can i show a toast from a thread running in a remote service? Whenever i run from a different thread in a service, the app crashes...
public class BroadcastService extends Service {
private static final String TAG = BroadcastService.class.getSimpleName();
private MessageFormatter mFormatter = new MessageFormatter();
private BroadcastComm broadCastComm = new BroadcastComm();
private Task commTask = new Task();
private volatile static boolean stopBroadcastRequested = false;
private volatile static boolean isSocketOpen = false;
private volatile static byte[] messageToBeSent;
private Handler serviceHandler;
private ConnectivityStatus connStatus;
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "Service creating");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
serviceHandler = new Handler();
serviceHandler.post(commTask);
stopBroadcastRequested = false;
messageToBeSent = mFormatter.formBroadCastMessage("GET_PERIPH_DATA");
}
class Task implements Runnable{
@Override
public void run() {
while(!stopBroadcastRequested){
Toast.makeText(context, "SSSSSSSSSS", 5).show();
Log.i(TAG, "Thread Task started");
try {
Log.d("SERVICE CLASS", "STARTED THREAD - Writing in output stream");
isSocketOpen = broadCastComm.isAliveOrOpenSocket("192.168.43.2", 6000, 17, 0);
if(isSocketOpen){
OutputStream outStream = broadCastComm.getCurrentOutputStream();
outStream.write(messageToBeSent);
if(Integer.valueOf(messageToBeSent[2]) != (byte)0xA0){
Log.e("REVERTING", "REVERTING");
messageToBeSent = mFormatter.formBroadCastMessage("GET_PERIPH_DATA");
}
Log.d("OUTPUT STREAM", "Message sent ->" + ByteArrayToString(messageToBeSent));
}
Thread.sleep(3000L);
if(isSocketOpen){
Log.d("SERVICE CLASS", "Started input");
InputStream inStream = broadCastComm.getCurrentInputStream();
BufferedInputStream buf = new BufferedInputStream(inStream);
byte[] buffer;
while(buf.available() > 0){
Log.d("SERVICE CLASS", "Input available");
int size = buf.available();
buffer = new byte[size];
inStream.read(buffer, 0, size);
if(buffer[2] == (byte)0xA0){
BroadcastPacket packet = broadCastComm.decodeSocketData(buffer);
synchronized (incomingPacketLock) {
latestBroadcastPacket = packet;
}
synchronized (listeners) {
for (BroadcastListener listener : listeners) {
try {
listener.handlePacketsUpdated();
} catch (RemoteException e) {
Log.w(TAG, "Failed to notify listener " + listener, e);
}
}
}
}
}
}
} catch (Throwable t) {
Log.e(TAG, "Failed to retrieve data in thread", t);
}
Log.d("SERVICE CLASS", "End of THREAD");
}
if(stopBroadcastRequested){
Log.e("SERVICE", "STOPPED THREAD");
}
}
public synchronized void stopThread(){
stopBroadcastRequested = true;
}
}
...........
@Override
public IBinder onBind(Intent intent) {
if (BroadcastService.class.getName().equals(intent.getAction())) {
Log.d(TAG, "Bound by intent " + intent);
return apiEndpoint;
} else {
return null;
}
}
.........
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "Service destroying");
stopBroadcastRequested = true;
broadCastComm.clearConnections();
try {
serviceHandler.removeCallbacks(commTask);
serviceHandler = null;
} catch (Exception e) {
Log.d("SERVICE", "FAILED TO REMOVE CALL BACKS");
}
commTask.stopThread();
//currentThread = null;
}
}
You can't show a Toast on a thread that is not the activity's ui thread.
myActivity. runOnUiThread(new Runnable() { public void run() { Toast. makeText(myActivity, "Toast Message Text!", Toast.
To do a toast popup, add another method to the ICapture interface and implement it in the app. Your service can then call it any time it knows the screen can accept it.
android.widget.Toast. A toast is a view containing a quick little message for the user. The toast class helps you create and show those. When the view is shown to the user, appears as a floating view over the application. It will never receive focus.
if someone don't understand what context is in @Alex Gitelman answer. write your class name in place of context in which you are writing this handler code like this
Handler h = new Handler(MyClassName.this.getMainLooper());
h.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MyClassName.this,"show toast message",Toast.LENGTH_LONG).show();
}
});
This is how I did it. Of course, you need to pass appropriate context.
Handler h = new Handler(context.getMainLooper());
h.post(new Runnable() {
@Override
public void run() {
Toast.makeText(context,message,Toast.LENGTH_LONG).show();
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With