package tcpConnection; import android.util.Log; import android.widget.ImageView; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.NetworkInterface; import java.net.Socket; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Timer; import java.util.TimerTask; import Database.DatabaseHandler; import beyondsoft.bewomitarbeiterapp.BeWoChatApplication; import entities.ChatEntity; import entities.ChatMessage; import entities.NotificationLog; import soapConnection.DataIdentifier; import soapConnection.Packet; import soapConnection.SoapCalls; import soapConnection.SoapConnectionManager; import util.Util; /** * Created by JettenM on 04.08.2016. */ public class SocketManager { private static final String TAG = "SOCKET_MANAGER"; private static DatabaseHandler databaseHandler = DatabaseHandler.getInstance(BeWoChatApplication.getInstance()); public static String tenant; private static Socket socket; private static Thread listenerThread; private static SocketListener socketListener; public static UIHandler uiHandler; public static LoginCallback loginCallback; private static DataOutputStream dataOutputStream; public static ArrayList onlinePersonOids = new ArrayList<>(); public static ArrayList onlineEntities = new ArrayList<>(); public static HashMap notificationEntities = new HashMap<>(); public static void connectToServer(){ new Thread(new ConnectionOpener()).start(); } public static void sendMessage(Packet packet) { new Thread(new MessageSender(packet.getDataStream())).start(); } private static class ConnectionOpener implements Runnable { public void run() { try { if(socket != null) { socket.close(); } socket = null; socket = new Socket(SoapCalls.DESTINATION_ADDRESS, SoapCalls.DESTINATION_PORT); dataOutputStream = null; onlinePersonOids.clear(); onlineEntities.clear(); dataOutputStream = new DataOutputStream(socket.getOutputStream()); socketListener = new SocketListener(); listenerThread = new Thread(socketListener); listenerThread.start(); loginOnServer(); } catch(Exception exception) { socket = null; try { new Timer().schedule(new TimerTask() { @Override public void run() { connectToServer(); } }, 5000); } catch(Exception exception2) { exception2.printStackTrace(); } exception.printStackTrace(); } } } public static void logout() { if(socket != null && socket.isConnected()) { try { Packet packet = new Packet(); packet.ChatDataIdentifier = DataIdentifier.LOGOUT; new Thread(new MessageSender(packet.getDataStream())).start(); } catch(Exception exception) { exception.printStackTrace(); } } } public static void loginOnServer() { if(socket != null && socket.isConnected()) { try { Packet packet = new Packet(); packet.Tenant = tenant; packet.ChatMessage = getMACAddress(); packet.ChatDataIdentifier = DataIdentifier.LOGIN; new Thread(new MessageSender(packet.getDataStream())).start(); } catch(Exception exception) { exception.printStackTrace(); } } } public static class ConnectionCloser implements Runnable{ public void run(){ try { if (dataOutputStream != null) { dataOutputStream.flush(); dataOutputStream.close(); } if (socket != null) { socket.close(); } } catch (IOException se) { se.printStackTrace(); } } } public static class MessageSender implements Runnable { byte[] packetToSend; public MessageSender(byte[] packet2Send) { packetToSend = packet2Send; } @Override public void run() { if(socket == null || !socket.isConnected()) { Log.e("MESSAGE_SENDER", "Socket ist nicht verbunden"); } if(socket != null && dataOutputStream != null) { try { dataOutputStream.write(packetToSend); dataOutputStream.flush(); } catch (IOException e) { try { Packet packet = new Packet(new String(packetToSend, "UTF-8")); if(packet.ChatDataIdentifier == DataIdentifier.MESSAGE || packet.ChatDataIdentifier == DataIdentifier.TEAM) { DatabaseHandler db = DatabaseHandler.getInstance(BeWoChatApplication.getInstance().getApplicationContext()); ChatMessage undeliveredMessage = db.getChatMessageById(packet.ClientseitigeOid); if(undeliveredMessage != null) { undeliveredMessage.IsDelivered = false; int affectedRows = db.updateChatMessage(undeliveredMessage); } } } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } e.printStackTrace(); } } } } public static class SocketListener implements Runnable { Packet chatPacket; private volatile boolean isRunning = true; @Override public void run() { try { while (isRunning) { if (socket != null) { if (socket.isConnected()) { InputStream stream = socket.getInputStream(); int size = stream.available(); if(size == 0) { continue; } byte[] message = new byte[size]; stream.read(message, 0, size); try { chatPacket = new Packet(new String(message, "UTF-8")); Log.i("SOCKET_LISTENER", "Erstelle Packet; " + (chatPacket.ChatMessage.isEmpty() ? "<>" : chatPacket.ChatMessage) + "; Typ: " + chatPacket.ChatDataIdentifier + ": " + new String(message, "UTF-8")); } catch(Exception e) { e.printStackTrace(); } if(chatPacket.ChatDataIdentifier.equals(DataIdentifier.LOGIN_SUCCESS) && loginCallback != null) { Log.i(TAG, "Der Login war erfolgreich"); loginCallback.doCallback(); } try { switch (chatPacket.ChatDataIdentifier) { case MESSAGE: databaseHandler.addChatMessage(new ChatMessage(chatPacket.SenderPersonOid, chatPacket.RecipientPersonOid, chatPacket.MessageTimeStamp, chatPacket.ChatMessage, true, chatPacket.ServerseitigeOid, false)); break; case TEAM: databaseHandler.addChatMessage(new ChatMessage(chatPacket.SenderPersonOid, chatPacket.RecipientPersonOid, chatPacket.MessageTimeStamp, chatPacket.ChatMessage, true, chatPacket.ServerseitigeOid, true)); break; case MESSAGE_RESPONSE: ChatMessage cm = databaseHandler.getChatMessageById(chatPacket.ClientseitigeOid); cm.ServerseitigeOid = chatPacket.ServerseitigeOid; cm.IsDelivered = true; databaseHandler.updateChatMessage(cm); break; case STATUS_NOTIFICATION_LOGIN: if(!SocketManager.onlinePersonOids.contains(chatPacket.SenderPersonOid)) { SocketManager.onlinePersonOids.add(chatPacket.SenderPersonOid); } //if(!SocketManager.onlineEntities.) /* for(Map.Entry entry : SocketManager.notificationEntities.entrySet()) { if(!(entry.getKey().equals(chatEntity) && entry.getValue().equals(notificationLog))) { mNotifyMgr.cancel(entry.getValue().getNotificationId()); entities2remove.add(entry.getKey()); } } */ boolean isAlreadyLoggedIn = false; for(ChatEntity entity : SocketManager.onlineEntities) { if(entity.getOid() == chatPacket.SenderPersonOid) { isAlreadyLoggedIn = true; break; } } if(!isAlreadyLoggedIn) { SocketManager.onlineEntities.add(new ChatEntity(chatPacket.SenderPersonOid, false)); } break; case STATUS_NOTIFICATION_LOGOUT: if(SocketManager.onlinePersonOids.contains(chatPacket.SenderPersonOid)) { SocketManager.onlinePersonOids.remove(Integer.valueOf(chatPacket.SenderPersonOid)); } ChatEntity entity2delete = Util.getChatEntityFromOnlineEntitiesByOid(chatPacket.SenderPersonOid, chatPacket.ChatDataIdentifier == DataIdentifier.TEAM); SocketManager.onlineEntities.remove(entity2delete); break; case STATUS_NOTIFICATION_LOGIN_BROADCAST: String[] onlinePersons = chatPacket.ChatMessage.split(","); for (String onlinePerson : onlinePersons) { int personOid = Integer.parseInt(onlinePerson); if(!SocketManager.onlinePersonOids.contains(personOid)) { SocketManager.onlinePersonOids.add(personOid); } } break; case STATUS_REQUEST: String contactsCsv = chatPacket.ChatMessage; String[] stringOids = contactsCsv.split(","); SocketManager.onlinePersonOids.clear(); for(String item : stringOids) { SocketManager.onlinePersonOids.add(Integer.valueOf(item)); } break; } } catch(Exception e) { e.printStackTrace(); } if(uiHandler != null) { uiHandler.updateUserInterface(chatPacket); } else { Log.e("ERROR_SOCKETLISTENER", "uiHandler ist null"); } } } } } catch(Exception exception) { exception.printStackTrace(); } } } public static String getMACAddress() { try { List all = Collections.list(NetworkInterface.getNetworkInterfaces()); for(NetworkInterface nif : all) { if(!nif.getName().equalsIgnoreCase("wlan0")) { continue; } byte[] macBytes = nif.getHardwareAddress(); if(macBytes == null) { return "MAC-ADRESSE NICHT ERMITTELBAR"; } StringBuilder res1 = new StringBuilder(); for(byte b : macBytes) { res1.append(Integer.toHexString(b & 0xFF) + ":"); } if(res1.length() > 0) { res1.deleteCharAt(res1.length() - 1); } return res1.toString(); } } catch(Exception ex) { Log.e("GET_MAC_ADDRESS", ex.getMessage()); } return "02:00:00:00:00:00"; } }