You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tijder_SmsMatrix/app/src/main/java/eu/droogers/smsmatrix/Matrix.java

401 lines
14 KiB

package eu.droogers.smsmatrix;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.telephony.SmsManager;
import android.util.Log;
import android.widget.Toast;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.json.JSONException;
import org.matrix.androidsdk.HomeServerConnectionConfig;
import org.matrix.androidsdk.MXDataHandler;
import org.matrix.androidsdk.MXSession;
import org.matrix.androidsdk.data.Room;
import org.matrix.androidsdk.data.store.IMXStore;
import org.matrix.androidsdk.data.store.IMXStoreListener;
import org.matrix.androidsdk.data.store.MXFileStore;
import org.matrix.androidsdk.data.store.MXMemoryStore;
import org.matrix.androidsdk.listeners.IMXEventListener;
import org.matrix.androidsdk.listeners.MXMediaUploadListener;
import org.matrix.androidsdk.core.callback.SimpleApiCallback;
import org.matrix.androidsdk.core.model.MatrixError;
import org.matrix.androidsdk.rest.client.LoginRestClient;
import org.matrix.androidsdk.rest.model.CreatedEvent;
import org.matrix.androidsdk.rest.model.Event;
import org.matrix.androidsdk.rest.model.message.Message;
import org.matrix.androidsdk.rest.model.login.Credentials;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static android.content.ContentValues.TAG;
/**
* Created by gerben on 6-10-17.
*/
public class Matrix {
private final int syncDelay;
private final int syncTimeout;
HomeServerConnectionConfig hsConfig;
Context context;
MXSession session;
int transaction;
private String tag = "Matrix";
private List<NotSendMesage> notSendMesages = new ArrayList<>();
MXDataHandler dh;
private IMXEventListener evLis;
IMXStore store;
String deviceName;
private String botUsername;
private String botHSUrl;
private String realUserid;
// Message type constants.
public static final String MESSAGE_TYPE_TEXT = "m.text";
public static final String MESSAGE_TYPE_IMAGE = "m.image";
public static final String MESSAGE_TYPE_VIDEO = "m.video";
public static final String MESSAGE_TYPE_NOTICE = "m.notice";
public Matrix(final Context context, String url, String botUsername, String botPassword, String username, String device, String syncDelay, String syncTimeout) {
this.context = context;
HomeServerConnectionConfig.Builder builder = new HomeServerConnectionConfig.Builder();
hsConfig = builder.withHomeServerUri(Uri.parse(url)).build();
realUserid = username;
deviceName = device;
this.botUsername = botUsername;
botHSUrl = url;
this.syncDelay = Integer.parseInt(syncDelay);
this.syncTimeout = Integer.parseInt(syncTimeout);
login(botUsername, botPassword);
}
private void login(String username, String password) {
new LoginRestClient(hsConfig).loginWithUser(username, password, deviceName, deviceName, new SimpleApiCallback<Credentials>() {
@Override
public void onSuccess(Credentials credentials) {
onLogin(credentials);
}
@Override
public void onMatrixError(MatrixError e) {
Log.e(TAG, "onLogin MatrixError" + e);
}
@Override
public void onNetworkError(Exception e) {
Log.e(TAG, "onLogin Network error" + e);
}
@Override
public void onUnexpectedError(Exception e) {
Log.e(TAG, "onLogin Unexpected error" + e);
}
});
}
private void onLogin(Credentials credentials) {
hsConfig.setCredentials(credentials);
startEventStream();
}
public void startEventStream() {
evLis = new EventListener(this);
if (false) {
store = new MXFileStore(hsConfig, false, context);
} else {
store = new MXMemoryStore(hsConfig.getCredentials(), context);
}
dh = new MXDataHandler(store, hsConfig.getCredentials());
// NetworkConnectivityReceiver nwMan = new NetworkConnectivityReceiver();
MXSession.Builder builder = new MXSession.Builder(hsConfig, dh, context);
session = builder.build();
session.setSyncDelay(syncDelay * 1000);
session.setSyncTimeout(syncTimeout * 60 * 1000);
Log.e(TAG, "onLogin:" + session.getSyncTimeout());
if (store.isReady()) {
session.startEventStream(store.getEventStreamToken());
session.getDataHandler().addListener(evLis);
} else {
store.addMXStoreListener(new IMXStoreListener() {
@Override
public void postProcess(String s) {
}
@Override
public void onStoreReady(String s) {
session.startEventStream(store.getEventStreamToken());
session.getDataHandler().addListener(evLis);
}
@Override
public void onStoreCorrupted(String s, String s1) {
Log.e(TAG, "onStoreCorrupted: " + s );
}
@Override
public void onStoreOOM(String s, String s1) {
}
@Override
public void onReadReceiptsLoaded(String s) {
}
});
}
}
public void sendMessage(final String phoneNumber, final String body, final String type) {
if (session != null && session.isAlive()) {
Room room = getRoomByPhonenumber(phoneNumber);
if (room == null) {
if (!type.equals("m.notice")) {
Log.e(TAG, "sendMessage: not found" );
session.createDirectMessageRoom(realUserid, new SimpleApiCallback<String>() {
@Override
public void onSuccess(String info) {
session.getRoomsApiClient().updateTopic(info, phoneNumber, new SimpleApiCallback<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
changeDisplayname(info, getContactName(phoneNumber, context));
Room room = store.getRoom(info);
SendMesageToRoom(room, body, type);
}
});
}
} else {
changeDisplayname(room.getRoomId(), getContactName(phoneNumber, context));
SendMesageToRoom(room, body, type);
}
} else {
Log.e(tag, "Error with sending message");
notSendMesages.add(new NotSendMesage(phoneNumber, body, type));
}
}
public void sendFile(
final String phoneNumber,
final byte[] body,
final String type,
final String fileName,
final String contentType
) {
String uploadID = String.valueOf(transaction);
transaction++;
session.getMediaCache().uploadContent(
new ByteArrayInputStream(body),
fileName,
contentType,
uploadID,
new MXMediaUploadListener()
{
@Override
public void onUploadComplete(final String uploadId, final String contentUri) {
Room room = getRoomByPhonenumber(phoneNumber);
JsonObject json = new JsonObject();
json.addProperty("body", fileName);
json.addProperty("msgtype", type);
json.addProperty("url", contentUri);
JsonObject info = new JsonObject();
info.addProperty("mimetype", contentType);
json.add("info", info);
session.getRoomsApiClient().sendEventToRoom(
String.valueOf(transaction),
room.getRoomId(),
"m.room.message",
json,
new SimpleApiCallback<CreatedEvent>() {
@Override
public void onSuccess(CreatedEvent createdEvent) {
}
}
);
transaction++;
}
}
);
}
private void changeDisplayname(String roomId, String displayname) {
Map<String, Object> params = new HashMap<>();
params.put("displayname", displayname);
params.put("membership", "join");
session.getRoomsApiClient().sendStateEvent(roomId, "m.room.member", session.getMyUserId(), params, new SimpleApiCallback<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
}
public void SendMesageToRoom(Room room, String body, String type) {
Message msg = new Message();
msg.body = body;
msg.msgtype = type;
session.getRoomsApiClient().sendMessage(String.valueOf(transaction), room.getRoomId(), msg, new SimpleApiCallback<CreatedEvent>() {
@Override
public void onSuccess(CreatedEvent createdEvent) {
Log.e(TAG, "sendMessage success");
}
@Override
public void onMatrixError(MatrixError e) {
Log.e(TAG, "sendMessage MatrixError" + e);
}
@Override
public void onNetworkError(Exception e) {
Log.e(TAG, "sendMessage Network error" + e);
}
@Override
public void onUnexpectedError(Exception e) {
Log.e(TAG, "sendMessage Unexpected error" + e);
}
});
transaction++;
}
public void getUnreadEvents() {
List<String> types = new ArrayList<>();
types.add("m.room.message");
Collection<Room> rooms = store.getRooms();
for (Room room : rooms) {
List<Event> roomsDirect = store.unreadEvents(room.getRoomId(), types);
for (Event event : roomsDirect) {
sendEvent(event);
}
}
}
public void sendEvent(Event event) {
if ((event.sender != null) && (event.sender.equals(realUserid))) {
Room room = store.getRoom(event.roomId);
SmsManager smsManager = SmsManager.getDefault();
JsonObject json = event.getContent().getAsJsonObject();
if (event.type.equals("m.room.message")) {
if (json.get("msgtype").getAsString().equals(MESSAGE_TYPE_TEXT)) {
ArrayList<String> body = smsManager.divideMessage(json.get("body").getAsString());
smsManager.sendMultipartTextMessage(room.getTopic(), null, body, null, null);
} else {
ArrayList<String> url = smsManager.divideMessage(session.getContentManager().getDownloadableUrl(json.get("url").getAsString()));
smsManager.sendMultipartTextMessage(room.getTopic(), null, url, null, null);
}
} else if (event.type.equals("m.room.member")) {
if (json.get("membership").getAsString().equals("leave")) {
room.leave(new SimpleApiCallback<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
} else if (json.get("membership").getAsString().equals("invite")) {
room.join(new SimpleApiCallback<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
}
} else {
Log.e(TAG, "sendEvent: Event type not supported ");
}
room.markAllAsRead(new SimpleApiCallback<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
}
}
public void onEventStreamLoaded() {
sendMessageList(notSendMesages);
notSendMesages.clear();
}
public void sendMessageList(List<NotSendMesage> messages) {
for (NotSendMesage ms : messages) {
sendMessage(ms.getPhone(), ms.getBody(), ms.getType());
}
}
private Room getRoomByPhonenumber (String number) {
Collection<Room> rooms = store.getRooms();
Log.e(TAG, "getRoomByPhonenumber: " + number );
Log.e(TAG, "getRoomByPhonenumber: " + rooms.size() );
for (Room room : rooms) {
Log.e(TAG, "getRoomByPhonenumber: " + room.getTopic() );
if (room.getTopic() != null && room.getTopic().equals(number)) {
return room;
}
}
return null;
}
private String getContactName(final String phoneNumber, Context context)
{
Uri uri=Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,Uri.encode(phoneNumber));
String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME};
String contactName="";
Cursor cursor=context.getContentResolver().query(uri,projection,null,null,null);
if (cursor != null) {
if(cursor.moveToFirst()) {
contactName=cursor.getString(0);
}
cursor.close();
}
if (contactName.isEmpty()) {
contactName = phoneNumber;
}
return contactName;
}
public void destroy() {
session.stopEventStream();
dh.removeListener(evLis);
store.close();
}
}