Files
BeWoPlaner/Android/BewoMitarbeiterApp/app/src/main/java/beyondsoft/bewomitarbeiterapp/ChatActivity.java

455 lines
18 KiB
Java

package beyondsoft.bewomitarbeiterapp;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.octo.android.robospice.SpiceManager;
import com.octo.android.robospice.UncachedSpiceService;
import com.octo.android.robospice.persistence.exception.SpiceException;
import com.octo.android.robospice.request.listener.RequestListener;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapPrimitive;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;
import javax.crypto.NoSuchPaddingException;
import Database.DatabaseHandler;
import entities.ChatMessage;
import soapConnection.DataIdentifier;
import soapConnection.JsonSoapPrimitiveRequest;
import soapConnection.Packet;
import soapConnection.SoapCalls;
import soapConnection.SoapConnectionManager;
import tcpConnection.SocketManager;
import tcpConnection.UIHandler;
import util.ChatMessageDeserializer;
import util.SecurityUtils;
import util.Util;
/**
* Created by bib on 03.05.2016.
*/
public class ChatActivity extends ActionBarActivity {
private DatabaseHandler databaseHandler;
protected EditText text;
protected Button senden;
protected ListView listView;
public static List<ChatMessage> chatMessages;
public static ArrayAdapter<ChatMessage> adapter;
protected String recipientName;
protected int recipientPersonOid;
protected String teamMemberOids;
protected String teamMemberNames;
protected boolean isTeam;
private SpiceManager spiceManager = new SpiceManager(UncachedSpiceService.class);
private UIHandler chatUIHandler;
private View mCustomView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);
ActionBar action = getSupportActionBar();
action.setDisplayShowHomeEnabled(false);
action.setDisplayShowTitleEnabled(false);
LayoutInflater inflate = LayoutInflater.from(this);
mCustomView = inflate.inflate(R.layout.custom_menuebar, null);
action.setCustomView(mCustomView);
action.setDisplayShowCustomEnabled(true);
databaseHandler = DatabaseHandler.getInstance(this);
senden = (Button)findViewById(R.id.Sendebutton);
listView = (ListView)findViewById(R.id.list_msg);
Bundle zielkorb = getIntent().getExtras();
recipientName = zielkorb.getString("Name");
recipientPersonOid = zielkorb.getInt("RecipientOid");
byte[] bildArray = zielkorb.getByteArray("Bild");
isTeam = zielkorb.getBoolean("IsTeam");
teamMemberOids = zielkorb.getString("TeamMemberOids");
teamMemberNames = zielkorb.getString("TeamMemberNames");
ReloadChatView(recipientName, recipientPersonOid, bildArray, isTeam, teamMemberOids, teamMemberNames);
}
private void ReloadChatView(String contactName, int recipientOid, byte[] contactImage, boolean pIsTeam, String pTeamMemberOids, String pTeamMemberNames) {
chatMessages = new ArrayList<>();
recipientPersonOid = recipientOid;
recipientName = contactName;
isTeam = pIsTeam;
teamMemberOids = pTeamMemberOids;
teamMemberNames = pTeamMemberNames;
ImageView status = (ImageView) mCustomView.findViewById(R.id.status);
TextView titlename = (TextView) mCustomView.findViewById(R.id.PersonalName);
ImageView titlepic = (ImageView) mCustomView.findViewById(R.id.PersonalPic);
status.setImageResource((SocketManager.onlinePersonOids.contains(recipientPersonOid) ? R.drawable.online : R.drawable.offline));
Bitmap customerImage;
if(contactImage != null) {
customerImage = BitmapFactory.decodeByteArray(contactImage, 0, contactImage.length);
titlepic.setImageBitmap(GetCircleBitmap(customerImage));
}
titlename.setText(recipientName);
chatMessages = isTeam ? databaseHandler.getMessagesForTeam(recipientPersonOid) : databaseHandler.getMessagesForRecipient(recipientPersonOid);
adapter = new MessageAdapter(this, R.layout.item_chat_left, chatMessages);
listView.setAdapter(adapter);
chatUIHandler = new UIHandler() {
@Override
public void updateUserInterface(final Packet chatPacket) {
try {
switch(chatPacket.ChatDataIdentifier) {
case MESSAGE:
listView.post(new Runnable() {
@Override
public void run() {
ChatMessage message = new ChatMessage(chatPacket.SenderPersonOid, chatPacket.RecipientPersonOid, chatPacket.MessageTimeStamp, chatPacket.ChatMessage, false, chatPacket.ServerseitigeOid, false);
databaseHandler.addChatMessage(message);
if(chatPacket.SenderPersonOid == recipientPersonOid) {
chatMessages.add(message);
adapter.notifyDataSetChanged();
} else {
SetNotify(chatPacket.ChatName, chatPacket.ChatMessage, chatPacket.SenderPersonOid, false, null, null);
}
}
});
break;
case MESSAGE_RESPONSE:
ChatMessage cm = databaseHandler.getChatMessageById(chatPacket.ClientseitigeOid);
cm.ServerseitigeOid = chatPacket.ServerseitigeOid;
Log.i("CHAT_SOCKET_LISTENER", "" + cm.IsTeam + "; Clientseitige Id: " + cm.Id + "; Serverseitige Oid: " + cm.ServerseitigeOid);
databaseHandler.updateChatMessage(cm);
break;
case STATUS_NOTIFICATION_LOGIN:
if(!SocketManager.onlinePersonOids.contains(chatPacket.SenderPersonOid)) {
SocketManager.onlinePersonOids.add(chatPacket.SenderPersonOid);
}
break;
case STATUS_NOTIFICATION_LOGOUT:
if(SocketManager.onlinePersonOids.contains(chatPacket.SenderPersonOid)) {
SocketManager.onlinePersonOids.remove(Integer.valueOf(chatPacket.SenderPersonOid));
}
break;
case TEAM:
listView.post(new Runnable() {
@Override
public void run() {
ChatMessage message = new ChatMessage(chatPacket.SenderPersonOid, chatPacket.RecipientPersonOid, chatPacket.MessageTimeStamp, chatPacket.ChatMessage, false, chatPacket.ServerseitigeOid, false);
databaseHandler.addChatMessage(message);
if(chatPacket.SenderPersonOid == recipientPersonOid) {
chatMessages.add(message);
adapter.notifyDataSetChanged();
} else {
SetNotify(chatPacket.ChatName, chatPacket.ChatMessage, chatPacket.SenderPersonOid, isTeam, teamMemberOids, teamMemberNames);
}
}
});
break;
}
} catch(Exception pe) {
pe.printStackTrace();
}
}
};
text = (EditText)findViewById(R.id.editText);
senden.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!text.getText().toString().isEmpty()) {
Calendar c = Calendar.getInstance();
Date now = c.getTime();
Packet packet = new Packet();
packet.ChatMessage = text.getText().toString();
packet.ChatDataIdentifier = isTeam ? DataIdentifier.TEAM : DataIdentifier.MESSAGE;
packet.RecipientPersonOid = recipientPersonOid;
packet.MessageTimeStamp = now;
SharedPreferences settings = getSharedPreferences(Util.PREFS_NAME, 0);
byte[] tenantByteArray = Base64.decode(settings.getString(Util.PREFS_TENANT_KEY, null), Base64.DEFAULT);
ByteArrayInputStream tenantStream = new ByteArrayInputStream(tenantByteArray);
try {
packet.Tenant = SecurityUtils.decrypt(tenantStream).toString();
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
final ChatMessage message = new ChatMessage(packet.SenderPersonOid, packet.RecipientPersonOid, packet.MessageTimeStamp, packet.ChatMessage, false, 0, isTeam);
long coid = databaseHandler.addChatMessage(message);
packet.ClientseitigeOid = Long.valueOf(coid).intValue();
packet.writeToLog();
SocketManager.sendMessage(packet);
listView.post(new Runnable() {
@Override
public void run() {
chatMessages.add(message);
adapter.notifyDataSetChanged();
text.setText("");
}
});
} else {
Toast.makeText(ChatActivity.this, "Dieses Feld darf nicht leer sein", Toast.LENGTH_SHORT).show();
}
}
});
ArrayList<Integer> test = isTeam ? databaseHandler.getExistingTeamChatMessageIds() : databaseHandler.getExistingChatMessageIds();
String pExceptions = "";
for(int i = 0; i < test.size(); i++) {
pExceptions += test.get(i);
if(i < test.size() - 1) {
pExceptions += ";";
}
}
ArrayList<PropertyInfo> propertyInfos = new ArrayList<>();
propertyInfos.add(SoapConnectionManager.BuildProperty("pSenderPersonOid", SoapConnectionManager.User.getPersonOid(), Long.class));
propertyInfos.add(SoapConnectionManager.BuildProperty("pRecipientPersonOid", recipientPersonOid, Long.class));
propertyInfos.add(SoapConnectionManager.BuildProperty("pExceptions", pExceptions, String.class));
propertyInfos.add(SoapConnectionManager.BuildProperty("pIsForTeam", isTeam, Boolean.class));
JsonSoapPrimitiveRequest request = new JsonSoapPrimitiveRequest(SoapCalls.GET_ALL_CHAT_MESSAGES, propertyInfos);
spiceManager.execute(request, new JsonSoapPrimitiveRequestListener());
}
@Override
public void onResume() {
SocketManager.uiHandler = chatUIHandler;
super.onResume();
}
@Override
public void onStop(){
spiceManager.shouldStop();
databaseHandler.close();
super.onStop();
}
@Override
public void onPause() {
databaseHandler.close();
super.onPause();
}
@Override
protected void onStart() {
super.onStart();
spiceManager.start(this);
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menue_chat, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_delet_Storage:
recreate(); // ---> gegebenenfals umändern, aber fürs erste reichts
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Bundle zielkorb = intent.getExtras();
String rn = zielkorb.getString("Name");
int rpoid = zielkorb.getInt("RecipientOid");
boolean blahIsTeam = zielkorb.getBoolean("IsTeam");
String tMemberOids = zielkorb.getString("TeamMemberOids");
String tMemberNames = zielkorb.getString("TeamMemberNames");
byte[] imageAsByteArray = databaseHandler.getUserImage(rpoid);
Log.i("CHAT_ON_NEW_INTENT", "Bild ist null: " + (imageAsByteArray == null));
ReloadChatView(rn, rpoid, null, blahIsTeam, tMemberOids, tMemberNames);
}
public void SetNotify(String username, String message, int recipientOid, boolean isTeam, String teamMemberOids, String teamMemberNames){
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentTitle(username)
.setContentText(message)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_SOUND)
.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 }) //Notification.Default_Vibrate
.setLights(Color.YELLOW, 3000, 3000) //Notification.Default_Lights
.setOngoing(true);
Bundle bundle = new Bundle();
bundle.putString("Name", username);
bundle.putInt("RecipientOid", recipientOid);
bundle.putBoolean("IsTeam", isTeam);
bundle.putString("TeamMemberOids", teamMemberOids);
bundle.putString("TeamMemberNames", teamMemberNames);
//TODO: Bild laden
Intent resultIntent = new Intent(this, ChatActivity.class);
resultIntent.putExtras(bundle);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this.getApplicationContext(), (int) (Math.random() * 100), resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mBuilder.setContentIntent(resultPendingIntent);
mNotifyMgr.notify((new Random()).nextInt(9999 - 1000) + 1000, mBuilder.build());
}
private Bitmap GetCircleBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
int color = Color.RED;
Paint paint = new Paint();
Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
RectF rectF = new RectF(rect);
//bis hierhin war alles final
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
private final class JsonSoapPrimitiveRequestListener implements RequestListener<SoapPrimitive> {
@Override
public void onRequestFailure(SpiceException spiceException) {
Log.e("GET_ALL_MESSAGES", "" + spiceException.getMessage());
}
@Override
public void onRequestSuccess(SoapPrimitive soapPrimitive) {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(ChatMessage.class, new ChatMessageDeserializer());
Gson gson = builder.create();
Type listType = new TypeToken<ArrayList<ChatMessage>>(){}.getType();
final ArrayList<ChatMessage> result = gson.fromJson(soapPrimitive.toString(), listType);
databaseHandler.addChatMessages(result);
listView.post(new Runnable() {
@Override
public void run() {
chatMessages.addAll(result);
adapter.notifyDataSetChanged();
}
});
}
}
}