Search code examples
androidsocketstcpandroid-asynctaskandroid-handler

Android send received data from a socket service to Activity


I am looking for a way to send received data (receive while flag is set) from a socket service to an activity that is bound to the service. What is the best way to do this ? Handlers , AsyncTask or something else ?

this is the SocketClass I am using to start a connection and handle the incoming messages :

    class connectSocket implements Runnable {

    @Override
    public void run() {

        running= true;
        try {
            socket = new Socket(serverAddr, SERVERPORT);
            try {
                mBufferOut = new ObjectOutputStream(socket.getOutputStream());
                mBufferIn = new ObjectInputStream(socket.getInputStream());
                while(running){
                     msg = (Message) mBufferIn.readObject();
                }

            }
            catch (Exception e) {
                Log.e("TCP", "S: Error", e);
            }
        } catch (Exception e) {
            Log.e("TCP", "C: Error", e);
        }

    }

}

Update :

public class SocketService extends Service {
private static final String TAG = "com.oos.kiesa.chat";
public static final String SERVERIP = "192.168.X.X";
public static final int SERVERPORT = 4444;
private ObjectOutputStream mBufferOut;
private ObjectInputStream mBufferIn;
Socket socket;
InetAddress serverAddr;
boolean mRun;
Object msg;
public Integer command;
@Override
public IBinder onBind(Intent intent) {
    return myBinder;
}

private final IBinder myBinder = new LocalBinder();

public class LocalBinder extends Binder {
    public SocketService getService() {
        return SocketService.this;

    }
}

@Override
public void onCreate() {
    super.onCreate();
}

public void IsBoundable(){
    Toast.makeText(this,"is boundable", Toast.LENGTH_LONG).show();
}


public void sendMessage(String message) throws IOException {
    if (mBufferOut != null) {
        mBufferOut.writeObject(message);
        mBufferOut.flush();
    }
}

public void sendMessage(Message message) throws IOException {
    if (mBufferOut != null) {
        mBufferOut.writeObject(message);
        mBufferOut.flush();
    }
}

public void sendMessage(User user) throws IOException {
    if (mBufferOut != null) {
        mBufferOut.writeObject(user);
        mBufferOut.flush();
    }
}

public void sendMessage(int command) throws IOException {
    if (mBufferOut != null) {
        mBufferOut.writeInt(command);
        mBufferOut.flush();
    }
}


@Override
public int onStartCommand(Intent intent,int flags, int startId){
    super.onStartCommand(intent, flags, startId);
    System.out.println("I am in on start");
    Runnable connect = new connectSocket();
    new Thread(connect).start();
    return START_STICKY;
}

public void stopClient() throws IOException{

    if (mBufferOut != null) {
        mBufferOut.flush();
        mBufferOut.close();
    }

    mBufferIn = null;
    mBufferOut = null;
    socket.close();
}

class connectSocket implements Runnable {

    @Override
    public void run() {

        mRun = true;
        try {
            socket = new Socket(serverAddr, SERVERPORT);
            try {
                mBufferOut = new ObjectOutputStream(socket.getOutputStream());
                mBufferIn = new ObjectInputStream(socket.getInputStream());
                while(mRun){
                    switch(command.intValue()){
                        case Constants.ADD_MESSAGE:
                            msg = (Message) mBufferIn.readObject(); // send message to Activity 
                            break;
                    }
                }

            }
            catch (Exception e) {
                Log.e("TCP", "S: Error", e);
            }
        } catch (Exception e) {
            Log.e("TCP", "C: Error", e);
        }

    }

}
@Override
public void onDestroy() {
    super.onDestroy();
    try {
        socket.close();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    socket = null;
}

}

Some guidance / examples would be greatly appreciated


Solution

  • I am sending you mine, hope it will help :

    class SocketRequestHandler extends Thread {
    
        static String EOF = "<EOF>";
    
        TCPResponseModel tcpResponseDS;
        Activity activity;
        boolean doSkip = false;
    
        String responseStringComplete = "";
        Socket clientSocekt;
        OutputStream clientSocketOutputStream;
        PrintWriter clinetSocketPrintWriter;
        DataInputStream clientSocketInputStream;
    
        private SocketRequestHandler(TCPResponseModel tcpResponseDS, Activity activity, SaloonListener listener) {
            this.tcpResponseDS = tcpResponseDS;
            this.activity = activity;
            this.listener = listener;
            moreStores = tcpResponseDS.StoresFound;
        }
    
        public static SocketRequestHandler pingAll(Activity activity, TCPResponseModel tcpResponseDS, SaloonListener listener) {
            SocketRequestHandler requestHandler = new SocketRequestHandler(tcpResponseDS, activity, listener);
            requestHandler.start();
            return requestHandler;
        }
    
        private void closeStreams() {
            try {
                clientSocekt.close();
                clientSocketInputStream.close();
                clinetSocketPrintWriter.close();
                clientSocketOutputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
            try {
                String pingingHost = "URL_TO_PING";
                clientSocekt = new Socket(pingingHost, 12000);
                clientSocketOutputStream = clientSocekt.getOutputStream();
                clinetSocketPrintWriter = new PrintWriter(clientSocketOutputStream);
                String firstPing = "{\"RequestId\":" + tcpResponseDS.RequestId + "}<EOF>";
                clinetSocketPrintWriter.println(firstPing);
                clinetSocketPrintWriter.flush();
                byte[] bytes;
                String pingStr = "";
                clientSocketInputStream = new DataInputStream(clientSocekt.getInputStream());
                while (true) {
                    bytes = new byte[1024];
                    clientSocketInputStream.read(bytes);
                    bytes = trim(bytes);
                    if (bytes.length > 0 && !doSkip) {
                        String newString = new String(bytes, "UTF-8");
                        String decoded = pingStr + newString;
                        pingStr = checkForMessage(decoded);
                        responseStringComplete += newString;
                    }
                    if (doSkip) {
                        break;
                    }
                }
                closeStreams();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                System.out.print(responseStringComplete);
            }
        }
    
    
    }
    

    To broadcast chat data just do :

    msg = (Message) mBufferIn.readObject(); // Do code after this line                            
     Intent localIntent = new Intent("CHAT_MESSAGE");
     localIntent.putExtra("message", msg); 
    

    LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent);

    Now in the activity where you are showing the chat list you can do

    class ReceiveMessages extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                final String action = intent.getAction();
                if (action.equals("CHAT_MESSAGE")) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            String chatMessage = getIntent().getStringExtra("message");
                            //get data from intent and update your chat list.
                        }
                    });
                }
            }
        }
        ReceiveMessages myReceiver;
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //your code
            myReceiver = new ReceiveMessages();
        }
    
        @Override
        protected void onStart() {
            super.onStart();
            LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver,
                    new IntentFilter("CHAT_MESSAGE"));
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
        }