diff --git a/app/build.gradle b/app/build.gradle
index 4236d52..5271c70 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,12 +4,12 @@ apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'
android {
- compileSdkVersion 29
- buildToolsVersion '28.0.3'
+ compileSdkVersion 35
defaultConfig {
applicationId "eu.droogers.smsmatrix"
+ namespace "eu.droogers.smsmatrix"
minSdkVersion 23
- targetSdkVersion 29
+ targetSdkVersion 35
versionCode 16
versionName "0.0.16"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -21,36 +21,30 @@ android {
}
}
- repositories {
- flatDir {
- dir 'libs'
- }
- }
-
compileOptions {
- sourceCompatibility 1.8
- targetCompatibility 1.8
+ sourceCompatibility 21
+ targetCompatibility 21
}
}
dependencies {
- implementation 'androidx.appcompat:appcompat:1.1.0'
- implementation 'androidx.preference:preference:1.1.0'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'androidx.preference:preference-ktx:1.2.1'
implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
- testImplementation 'junit:junit:4.12'
+ implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
+ testImplementation 'junit:junit:4.13.2'
/************* Matrix SDK management **************/
implementation 'com.github.Bubu:matrix-android-sdk:v0.9.30-no-webrtc'
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
- implementation 'com.google.code.gson:gson:2.8.5'
+ implementation 'com.google.code.gson:gson:2.11.0'
implementation 'com.squareup.okhttp3:okhttp:3.12.3'
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.3'
implementation 'com.facebook.stetho:stetho:1.5.0'
diff --git a/app/src/androidTest/java/eu/droogers/smsmatrix/ExampleInstrumentedTest.java b/app/src/androidTest/java/eu/droogers/smsmatrix/ExampleInstrumentedTest.java
deleted file mode 100644
index 3288948..0000000
--- a/app/src/androidTest/java/eu/droogers/smsmatrix/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package eu.droogers.smsmatrix;
-
-import android.content.Context;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumentation test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() throws Exception {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("eu.droogers.smsmatrix", appContext.getPackageName());
- }
-}
diff --git a/app/src/androidTest/java/eu/droogers/smsmatrix/ExampleInstrumentedTest.kt b/app/src/androidTest/java/eu/droogers/smsmatrix/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..39be027
--- /dev/null
+++ b/app/src/androidTest/java/eu/droogers/smsmatrix/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package eu.droogers.smsmatrix
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see [Testing documentation](http://d.android.com/tools/testing)
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ @Throws(Exception::class)
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+
+ Assert.assertEquals("eu.droogers.smsmatrix", appContext.packageName)
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b04e089..596f5fd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,12 +3,18 @@
xmlns:tools="http://schemas.android.com/tools"
package="eu.droogers.smsmatrix">
+
+
+
+
-
+
@@ -26,7 +33,9 @@
-
+
@@ -38,7 +47,11 @@
-
+
diff --git a/app/src/main/java/eu/droogers/smsmatrix/EventListener.java b/app/src/main/java/eu/droogers/smsmatrix/EventListener.java
deleted file mode 100644
index f06a2f6..0000000
--- a/app/src/main/java/eu/droogers/smsmatrix/EventListener.java
+++ /dev/null
@@ -1,204 +0,0 @@
-package eu.droogers.smsmatrix;
-
-import android.util.Log;
-
-import org.matrix.androidsdk.data.MyUser;
-import org.matrix.androidsdk.data.RoomState;
-import org.matrix.androidsdk.listeners.IMXEventListener;
-import org.matrix.androidsdk.rest.model.Event;
-import org.matrix.androidsdk.core.model.MatrixError;
-import org.matrix.androidsdk.rest.model.User;
-import org.matrix.androidsdk.rest.model.bingrules.BingRule;
-import org.matrix.androidsdk.rest.model.sync.AccountDataElement;
-
-import java.util.List;
-
-/**
- * Created by gerben on 8-10-17.
- */
-
-public class EventListener implements IMXEventListener {
- private static final String TAG = "EventListener";
- private boolean loaded = false;
- private Matrix mx;
-
- public EventListener (Matrix mx) {
- this.mx = mx;
- }
-
- @Override
- public void onStoreReady() {
-
- }
-
- @Override
- public void onPresenceUpdate(Event event, User user) {
-
- }
-
- @Override
- public void onAccountInfoUpdate(MyUser myUser) {
-
- }
-
- @Override
- public void onIgnoredUsersListUpdate() {
-
- }
-
- @Override
- public void onDirectMessageChatRoomsListUpdate() {
-
- }
-
- @Override
- public void onLiveEvent(Event event, RoomState roomState) {
- if (loaded) {
-// mx.getUnreadEvents();
- mx.sendEvent(event);
- }
- Log.e(TAG, "onLiveEvent: " + event);
- }
-
- @Override
- public void onLiveEventsChunkProcessed(String s, String s1) {
-
- }
-
- @Override
- public void onBingEvent(Event event, RoomState roomState, BingRule bingRule) {
-
- }
-
- @Override
- public void onEventSentStateUpdated(Event event) {
-
- }
-
- @Override
- public void onEventSent(Event event, String s) {
-
- }
-
- @Override
- public void onEventDecrypted(String s, String s1) {
-
- }
-
- @Override
- public void onBingRulesUpdate() {
-
- }
-
- @Override
- public void onInitialSyncComplete(String s) {
- loaded = true;
- mx.onEventStreamLoaded();
- mx.getUnreadEvents();
- }
-
- @Override
- public void onSyncError(MatrixError matrixError) {
-
- }
-
- @Override
- public void onCryptoSyncComplete() {
-
- }
-
- @Override
- public void onNewRoom(String s) {
-
- }
-
- @Override
- public void onJoinRoom(String s) {
-
- }
-
- @Override
- public void onRoomFlush(String s) {
-
- }
-
- @Override
- public void onRoomInternalUpdate(String s) {
-
- }
-
- @Override
- public void onNotificationCountUpdate(String s) {
-
- }
-
- @Override
- public void onLeaveRoom(String s) {
-
- }
-
- @Override
- public void onRoomKick(String s) {
-
- }
-
- @Override
- public void onReceiptEvent(String s, List list) {
-
- }
-
- @Override
- public void onRoomTagEvent(String s) {
-
- }
-
- @Override
- public void onReadMarkerEvent(String s) {
-
- }
-
- @Override
- public void onToDeviceEvent(Event event) {
-
- }
-
- @Override
- public void onNewGroupInvitation(String s) {
-
- }
-
- @Override
- public void onJoinGroup(String s) {
-
- }
-
- @Override
- public void onLeaveGroup(String s) {
-
- }
-
- @Override
- public void onGroupProfileUpdate(String s) {
-
- }
-
- @Override
- public void onGroupRoomsListUpdate(String s) {
-
- }
-
- @Override
- public void onGroupUsersListUpdate(String s) {
-
- }
-
- @Override
- public void onGroupInvitedUsersListUpdate(String s) {
-
- }
-
- @Override
- public void onAccountDataUpdated(AccountDataElement accountDataElement) {
-
- }
-}
diff --git a/app/src/main/java/eu/droogers/smsmatrix/EventListener.kt b/app/src/main/java/eu/droogers/smsmatrix/EventListener.kt
new file mode 100644
index 0000000..66b25d0
--- /dev/null
+++ b/app/src/main/java/eu/droogers/smsmatrix/EventListener.kt
@@ -0,0 +1,132 @@
+package eu.droogers.smsmatrix
+
+import android.util.Log
+import org.matrix.androidsdk.core.model.MatrixError
+import org.matrix.androidsdk.data.MyUser
+import org.matrix.androidsdk.data.RoomState
+import org.matrix.androidsdk.listeners.IMXEventListener
+import org.matrix.androidsdk.rest.model.Event
+import org.matrix.androidsdk.rest.model.User
+import org.matrix.androidsdk.rest.model.bingrules.BingRule
+import org.matrix.androidsdk.rest.model.sync.AccountDataElement
+
+/**
+ * Created by gerben on 8-10-17.
+ */
+class EventListener(private val mx: Matrix) : IMXEventListener {
+ private var loaded = false
+
+ override fun onStoreReady() {
+ }
+
+ override fun onPresenceUpdate(event: Event, user: User) {
+ }
+
+ override fun onAccountInfoUpdate(myUser: MyUser) {
+ }
+
+ override fun onIgnoredUsersListUpdate() {
+ }
+
+ override fun onDirectMessageChatRoomsListUpdate() {
+ }
+
+ override fun onLiveEvent(event: Event, roomState: RoomState) {
+ if (loaded) {
+// mx.getUnreadEvents();
+ mx.sendEvent(event)
+ }
+ Log.e(TAG, "onLiveEvent: $event")
+ }
+
+ override fun onLiveEventsChunkProcessed(s: String, s1: String) {
+ }
+
+ override fun onBingEvent(event: Event, roomState: RoomState, bingRule: BingRule) {
+ }
+
+ override fun onEventSentStateUpdated(event: Event) {
+ }
+
+ override fun onEventSent(event: Event, s: String) {
+ }
+
+ override fun onEventDecrypted(s: String, s1: String) {
+ }
+
+ override fun onBingRulesUpdate() {
+ }
+
+ override fun onInitialSyncComplete(s: String) {
+ loaded = true
+ mx.onEventStreamLoaded()
+ mx.getUnreadEvents()
+ }
+
+ override fun onSyncError(matrixError: MatrixError) {
+ }
+
+ override fun onCryptoSyncComplete() {
+ }
+
+ override fun onNewRoom(s: String) {
+ }
+
+ override fun onJoinRoom(s: String) {
+ }
+
+ override fun onRoomFlush(s: String) {
+ }
+
+ override fun onRoomInternalUpdate(s: String) {
+ }
+
+ override fun onNotificationCountUpdate(s: String) {
+ }
+
+ override fun onLeaveRoom(s: String) {
+ }
+
+ override fun onRoomKick(s: String) {
+ }
+
+ override fun onReceiptEvent(s: String, list: List) {
+ }
+
+ override fun onRoomTagEvent(s: String) {
+ }
+
+ override fun onReadMarkerEvent(s: String) {
+ }
+
+ override fun onToDeviceEvent(event: Event) {
+ }
+
+ override fun onNewGroupInvitation(s: String) {
+ }
+
+ override fun onJoinGroup(s: String) {
+ }
+
+ override fun onLeaveGroup(s: String) {
+ }
+
+ override fun onGroupProfileUpdate(s: String) {
+ }
+
+ override fun onGroupRoomsListUpdate(s: String) {
+ }
+
+ override fun onGroupUsersListUpdate(s: String) {
+ }
+
+ override fun onGroupInvitedUsersListUpdate(s: String) {
+ }
+
+ override fun onAccountDataUpdated(accountDataElement: AccountDataElement) {
+ }
+
+ companion object {
+ private const val TAG = "EventListener"
+ }
+}
diff --git a/app/src/main/java/eu/droogers/smsmatrix/MMSMonitor.java b/app/src/main/java/eu/droogers/smsmatrix/MMSMonitor.java
deleted file mode 100644
index 76c9764..0000000
--- a/app/src/main/java/eu/droogers/smsmatrix/MMSMonitor.java
+++ /dev/null
@@ -1,302 +0,0 @@
-package eu.droogers.smsmatrix;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Telephony;
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class MMSMonitor {
- private MatrixService mainActivity;
- private ContentResolver contentResolver = null;
- private Context mainContext;
- private Handler mmshandler = null;
- private ContentObserver mmsObserver = null;
- public boolean monitorStatus = false;
- private int mmsCount = 0;
- private static final String TAG = "MMSMonitor";
-
- public MMSMonitor(final MatrixService mainActivity, final Context mainContext) {
- this.mainActivity = mainActivity;
- contentResolver = mainActivity.getContentResolver();
- this.mainContext = mainContext;
- mmshandler = new MMSHandler();
- mmsObserver = new MMSObserver(mmshandler);
- Log.i(TAG, "***** Start MMS Monitor *****");
- }
-
-
- public void startMMSMonitoring() {
- try {
- monitorStatus = false;
- if (!monitorStatus) {
- contentResolver.registerContentObserver(
- Uri.parse("content://mms"),
- true,
- mmsObserver
- );
-
- // Save the count of MMS messages on start-up.
- Uri uriMMSURI = Uri.parse("content://mms-sms");
- Cursor mmsCur = mainActivity.getContentResolver().query(
- uriMMSURI,
- null,
- Telephony.Mms.MESSAGE_BOX + " = " + Telephony.Mms.MESSAGE_BOX_INBOX,
- null,
- Telephony.Mms._ID
- );
- if (mmsCur != null && mmsCur.getCount() > 0) {
- mmsCount = mmsCur.getCount();
- Log.d(TAG, "Init MMSCount = " + mmsCount);
- }
- }
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- }
- }
-
-
- public void stopMMSMonitoring() {
- try {
- monitorStatus = false;
- if (!monitorStatus){
- contentResolver.unregisterContentObserver(mmsObserver);
- }
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- }
- }
-
-
- class MMSHandler extends Handler {
- public void handleMessage(final Message msg) {
- //Log.i(TAG, "Handler");
- }
- }
-
-
- class MMSObserver extends ContentObserver {
- private Handler mms_handle = null;
- public MMSObserver(final Handler mmshandle) {
- super(mmshandle);
- mms_handle = mmshandle;
- }
-
- public void onChange(final boolean bSelfChange) {
- super.onChange(bSelfChange);
- Log.i(TAG, "Onchange");
-
- try {
- monitorStatus = true;
-
- // Send message to Activity.
- Message msg = new Message();
- mms_handle.sendMessage(msg);
-
- // Get the MMS count.
- Uri uriMMSURI = Uri.parse("content://mms/");
- Cursor mmsCur = mainActivity.getContentResolver().query(
- uriMMSURI,
- null,
- Telephony.Mms.MESSAGE_BOX + " = " + Telephony.Mms.MESSAGE_BOX_INBOX,
- null,
- Telephony.Mms._ID
- );
-
- int currMMSCount = 0;
- if (mmsCur != null && mmsCur.getCount() > 0) {
- currMMSCount = mmsCur.getCount();
- }
-
- // Proceed if there is a new message.
- if (currMMSCount > mmsCount) {
- mmsCount = currMMSCount;
- mmsCur.moveToLast();
-
- // Get the message id and subject.
- String subject = mmsCur.getString(mmsCur.getColumnIndex(Telephony.Mms.SUBJECT));
- int id = Integer.parseInt(mmsCur.getString(mmsCur.getColumnIndex(Telephony.Mms._ID)));
- Log.d(TAG, "_id = " + id);
- Log.d(TAG, "Subject = " + subject);
-
- byte[] mediaData = null;
- String message = "";
- String address = "";
- String fileName = "";
- String fileType = "";
- String messageType = "";
-
- // Get parts.
- Uri uriMMSPart = Uri.parse("content://mms/part");
- Cursor curPart = mainActivity.getContentResolver().query(
- uriMMSPart,
- null,
- Telephony.Mms.Part.MSG_ID + " = " + id,
- null,
- Telephony.Mms.Part._ID
- );
- Log.d(TAG, "Parts records length = " + curPart.getCount());
- curPart.moveToLast();
- do {
- String contentType = curPart.getString(curPart.getColumnIndex(Telephony.Mms.Part.CONTENT_TYPE));
- String partId = curPart.getString(curPart.getColumnIndex(Telephony.Mms.Part._ID));
- fileName = curPart.getString(curPart.getColumnIndex(Telephony.Mms.Part.NAME));
- Log.d(TAG, "partId = " + partId);
- Log.d(TAG, "Part mime type = " + contentType);
-
- if (contentType.equalsIgnoreCase("text/plain"))
- {
- // Get the message.
-
- Log.i(TAG,"==== Get the message start ====");
- messageType = Matrix.MESSAGE_TYPE_TEXT;
- byte[] messageData = readMMSPart(partId);
- if (messageData != null && messageData.length > 0) {
- message = new String(messageData);
- }
-
- if (message.isEmpty()) {
- Cursor curPart1 = mainActivity.getContentResolver().query(
- uriMMSPart,
- null,
- Telephony.Mms.Part.MSG_ID + " = " + id + " and "+ Telephony.Mms.Part._ID + " = " + partId,
- null,
- Telephony.Mms.Part._ID
- );
- for (int i = 0; i < curPart1.getColumnCount(); i++)
- {
- Log.d(TAG,"Column Name : " + curPart1.getColumnName(i));
- }
- curPart1.moveToLast();
- message = curPart1.getString(13);
- }
- Log.d(TAG,"Txt Message = " + message);
- } else if (isImageType(contentType) || isVideoType(contentType)) {
- // Get the media.
-
- if (isImageType(contentType)) {
- messageType = Matrix.MESSAGE_TYPE_IMAGE;
- } else if (isVideoType(contentType)) {
- messageType = Matrix.MESSAGE_TYPE_VIDEO;
- }
- Log.i(TAG, "==== Get the media start ====");
- fileType = contentType;
- mediaData = readMMSPart(partId);
- Log.i(TAG, "Media data length == " + mediaData.length);
- }
- } while (curPart.moveToPrevious());
-
-
-
- // Get the sender's address.
- Uri uriMMSAddr = Uri.parse("content://mms/" + id + "/addr");
- Cursor addrCur = mainActivity.getContentResolver().query(
- uriMMSAddr,
- null,
- Telephony.Mms.Addr.TYPE + " = 137", // PduHeaders.FROM
- null,
- Telephony.Mms.Addr._ID
- );
- if (addrCur != null) {
- addrCur.moveToLast();
- do{
- Log.d(TAG, "addrCur records length = " + addrCur.getCount());
- if (addrCur.getCount() > 0) {
- address = addrCur.getString(addrCur.getColumnIndex(Telephony.Mms.Addr.ADDRESS));
- }
- Log.d(TAG, "address = " + address);
-
- if (!message.isEmpty()) {
- Utilities.sendMatrix(mainActivity, message, address, messageType);
- }
- if (mediaData != null) {
- Utilities.sendMatrix(
- mainActivity,
- mediaData,
- address,
- messageType,
- fileName,
- fileType
- );
- }
- } while (addrCur.moveToPrevious());
- }
- }
-
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- }
- }
- }
-
-
- private byte[] readMMSPart(String partId) {
- byte[] partData = null;
- Uri partURI = Uri.parse("content://mms/part/" + partId);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- InputStream is = null;
-
- try {
-
- Log.i(TAG,"Entered into readMMSPart try.");
- ContentResolver mContentResolver = mainActivity.getContentResolver();
- is = mContentResolver.openInputStream(partURI);
-
- byte[] buffer = new byte[256];
- int len = is.read(buffer);
- while (len >= 0) {
- baos.write(buffer, 0, len);
- len = is.read(buffer);
- }
- partData = baos.toByteArray();
- //Log.i(TAG, "Text Msg :: " + new String(partData));
-
- } catch (IOException e) {
- Log.e(TAG, "Exception == Failed to load part data");
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- Log.e(TAG, "Exception :: Failed to close stream");
- }
- }
- }
- return partData;
- }
-
-
- private boolean isImageType(String mime) {
- boolean result = false;
- if (mime.equalsIgnoreCase("image/jpg")
- || mime.equalsIgnoreCase("image/jpeg")
- || mime.equalsIgnoreCase("image/png")
- || mime.equalsIgnoreCase("image/gif")
- || mime.equalsIgnoreCase("image/bmp")) {
- result = true;
- }
- return result;
- }
-
-
- private boolean isVideoType(String mime) {
- boolean result = false;
- if (mime.equalsIgnoreCase("video/3gpp")
- || mime.equalsIgnoreCase("video/3gpp2")
- || mime.equalsIgnoreCase("video/avi")
- || mime.equalsIgnoreCase("video/mp4")
- || mime.equalsIgnoreCase("video/mpeg")
- || mime.equalsIgnoreCase("video/webm")) {
- result = true;
- }
- return result;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/eu/droogers/smsmatrix/MMSMonitor.kt b/app/src/main/java/eu/droogers/smsmatrix/MMSMonitor.kt
new file mode 100644
index 0000000..5d1668e
--- /dev/null
+++ b/app/src/main/java/eu/droogers/smsmatrix/MMSMonitor.kt
@@ -0,0 +1,288 @@
+package eu.droogers.smsmatrix
+
+import android.content.ContentResolver
+import android.content.Context
+import android.database.ContentObserver
+import android.net.Uri
+import android.os.Handler
+import android.os.Message
+import android.provider.Telephony
+import android.util.Log
+import java.io.ByteArrayOutputStream
+import java.io.IOException
+import java.io.InputStream
+import java.util.Objects
+
+class MMSMonitor(private val mainActivity: MatrixService, mainContext: Context?) {
+ private val contentResolver: ContentResolver = mainActivity.contentResolver
+ private val mmsObserver: ContentObserver
+ var monitorStatus: Boolean = false
+ private var mmsCount = 0
+
+ init {
+ val mmshandler: Handler = MMSHandler()
+ mmsObserver = MMSObserver(mmshandler)
+ Log.i(TAG, "***** Start MMS Monitor *****")
+ }
+
+
+ fun startMMSMonitoring() {
+ try {
+ monitorStatus = false
+ contentResolver.registerContentObserver(
+ Uri.parse("content://mms"),
+ true,
+ mmsObserver
+ )
+
+ // Save the count of MMS messages on start-up.
+ val uriMMSURI = Uri.parse("content://mms-sms")
+ val mmsCur = mainActivity.contentResolver.query(
+ uriMMSURI,
+ null,
+ Telephony.Mms.MESSAGE_BOX + " = " + Telephony.Mms.MESSAGE_BOX_INBOX,
+ null,
+ Telephony.Mms._ID
+ )
+ if (mmsCur != null && mmsCur.count > 0) {
+ mmsCount = mmsCur.count
+ Log.d(TAG, "Init MMSCount = $mmsCount")
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, Objects.requireNonNull(e.message))
+ }
+ }
+
+
+ fun stopMMSMonitoring() {
+ try {
+ monitorStatus = false
+ contentResolver.unregisterContentObserver(mmsObserver)
+ } catch (e: Exception) {
+ Log.e(TAG, Objects.requireNonNull(e.message))
+ }
+ }
+
+
+ internal class MMSHandler : Handler() {
+ override fun handleMessage(msg: Message) {
+ //Log.i(TAG, "Handler");
+ }
+ }
+
+
+ internal inner class MMSObserver(private val mms_handle: Handler) : ContentObserver(
+ mms_handle
+ ) {
+ override fun onChange(bSelfChange: Boolean) {
+ super.onChange(bSelfChange)
+ Log.i(TAG, "Onchange")
+
+ try {
+ monitorStatus = true
+
+ // Send message to Activity.
+ val msg = Message()
+ mms_handle.sendMessage(msg)
+
+ // Get the MMS count.
+ val uriMMSURI = Uri.parse("content://mms/")
+ val mmsCur = mainActivity.contentResolver.query(
+ uriMMSURI,
+ null,
+ Telephony.Mms.MESSAGE_BOX + " = " + Telephony.Mms.MESSAGE_BOX_INBOX,
+ null,
+ Telephony.Mms._ID
+ )
+
+ var currMMSCount = 0
+ if (mmsCur != null && mmsCur.count > 0) {
+ currMMSCount = mmsCur.count
+ }
+
+ // Proceed if there is a new message.
+ if (currMMSCount > mmsCount) {
+ mmsCount = currMMSCount
+ checkNotNull(mmsCur)
+ mmsCur.moveToLast()
+
+ // Get the message id and subject.
+ val subject = mmsCur.getString(mmsCur.getColumnIndex(Telephony.Mms.SUBJECT))
+ val id = mmsCur.getString(mmsCur.getColumnIndex(Telephony.Mms._ID)).toInt()
+ Log.d(TAG, "_id = $id")
+ Log.d(TAG, "Subject = $subject")
+
+ var mediaData: ByteArray? = null
+ var message = ""
+ var address = ""
+ var fileName: String
+ var fileType = ""
+ var messageType = ""
+
+ // Get parts.
+ val uriMMSPart = Uri.parse("content://mms/part")
+ val curPart = checkNotNull(
+ mainActivity.contentResolver.query(
+ uriMMSPart,
+ null,
+ Telephony.Mms.Part.MSG_ID + " = " + id,
+ null,
+ Telephony.Mms.Part._ID
+ )
+ )
+ Log.d(TAG, "Parts records length = " + curPart.count)
+ curPart.moveToLast()
+ do {
+ val contentType =
+ curPart.getString(curPart.getColumnIndex(Telephony.Mms.Part.CONTENT_TYPE))
+ val partId =
+ curPart.getString(curPart.getColumnIndex(Telephony.Mms.Part._ID))
+ fileName =
+ curPart.getString(curPart.getColumnIndex(Telephony.Mms.Part.NAME))
+ Log.d(TAG, "partId = $partId")
+ Log.d(
+ TAG,
+ "Part mime type = $contentType"
+ )
+
+ if (contentType.equals("text/plain", ignoreCase = true)) {
+ // Get the message.
+
+ Log.i(TAG, "==== Get the message start ====")
+ messageType = Matrix.MESSAGE_TYPE_TEXT
+ val messageData = readMMSPart(partId)
+ if (messageData != null && messageData.size > 0) {
+ message = String(messageData)
+ }
+
+ if (message.isEmpty()) {
+ val curPart1 = mainActivity.contentResolver.query(
+ uriMMSPart,
+ null,
+ Telephony.Mms.Part.MSG_ID + " = " + id + " and " + Telephony.Mms.Part._ID + " = " + partId,
+ null,
+ Telephony.Mms.Part._ID
+ )
+ for (i in 0..= 0) {
+ baos.write(buffer, 0, len)
+ len = `is`.read(buffer)
+ }
+ partData = baos.toByteArray()
+
+ //Log.i(TAG, "Text Msg :: " + new String(partData));
+ } catch (e: IOException) {
+ Log.e(TAG, "Exception == Failed to load part data")
+ } finally {
+ if (`is` != null) {
+ try {
+ `is`.close()
+ } catch (e: IOException) {
+ Log.e(TAG, "Exception :: Failed to close stream")
+ }
+ }
+ }
+ return partData
+ }
+
+
+ private fun isImageType(mime: String): Boolean {
+ return mime.equals("image/jpg", ignoreCase = true)
+ || mime.equals("image/jpeg", ignoreCase = true)
+ || mime.equals("image/png", ignoreCase = true)
+ || mime.equals("image/gif", ignoreCase = true)
+ || mime.equals("image/bmp", ignoreCase = true)
+ }
+
+
+ private fun isVideoType(mime: String): Boolean {
+ return mime.equals("video/3gpp", ignoreCase = true)
+ || mime.equals("video/3gpp2", ignoreCase = true)
+ || mime.equals("video/avi", ignoreCase = true)
+ || mime.equals("video/mp4", ignoreCase = true)
+ || mime.equals("video/mpeg", ignoreCase = true)
+ || mime.equals("video/webm", ignoreCase = true)
+ }
+
+ companion object {
+ private const val TAG = "MMSMonitor"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/eu/droogers/smsmatrix/MainActivity.java b/app/src/main/java/eu/droogers/smsmatrix/MainActivity.java
deleted file mode 100644
index de21cfd..0000000
--- a/app/src/main/java/eu/droogers/smsmatrix/MainActivity.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package eu.droogers.smsmatrix;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-
-import androidx.core.app.ActivityCompat;
-import androidx.core.content.ContextCompat;
-
-import static android.Manifest.permission.READ_CONTACTS;
-import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
-import static android.Manifest.permission.READ_PHONE_STATE;
-import static android.Manifest.permission.READ_SMS;
-import static android.Manifest.permission.RECEIVE_SMS;
-import static android.Manifest.permission.SEND_SMS;
-import static android.content.ContentValues.TAG;
-
-public class MainActivity extends Activity {
- static Matrix mx;
- private SharedPreferences sp;
- private EditText botUsername;
- private EditText botPassword;
- private EditText username;
- private EditText device;
- private EditText hsUrl;
- private EditText syncDelay;
- private EditText syncTimeout;
- private static final String[] PERMISSIONS_REQUIRED = new String[]{
- READ_SMS, SEND_SMS, RECEIVE_SMS, READ_PHONE_STATE, READ_CONTACTS, READ_EXTERNAL_STORAGE
- };
- private static final int PERMISSION_REQUEST_CODE = 200;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- sp = getSharedPreferences("settings", Context.MODE_PRIVATE);
- botUsername = (EditText) findViewById(R.id.editText_botUsername);
- botPassword = (EditText) findViewById(R.id.editText_botpassword);
- username = (EditText) findViewById(R.id.editText_username);
- device = (EditText) findViewById(R.id.editText_device);
- hsUrl = (EditText) findViewById(R.id.editText_hsUrl);
- syncDelay = (EditText) findViewById(R.id.editText_syncDelay);
- syncTimeout = (EditText) findViewById(R.id.editText_syncTimeout);
-
- botUsername.setText(sp.getString("botUsername", ""));
- botPassword.setText(sp.getString("botPassword", ""));
- username.setText(sp.getString("username", ""));
- device.setText(sp.getString("device", ""));
- hsUrl.setText(sp.getString("hsUrl", ""));
- syncDelay.setText(sp.getString("syncDelay", "12"));
- syncTimeout.setText(sp.getString("syncTimeout", "30"));
-
-
- Button saveButton = (Button) findViewById(R.id.button_save);
- saveButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (!checkPermissions()) {
- askPermissions();
- } else {
- SharedPreferences.Editor editor = sp.edit();
- editor.putString("botUsername", botUsername.getText().toString());
- editor.putString("botPassword", botPassword.getText().toString());
- editor.putString("username", username.getText().toString());
- editor.putString("device", device.getText().toString());
- editor.putString("hsUrl", hsUrl.getText().toString());
- editor.putString("syncDelay", syncDelay.getText().toString());
- editor.putString("syncTimeout", syncTimeout.getText().toString());
- editor.apply();
-
- Log.e(TAG, "onClick: " + botUsername.getText().toString() );
- startService();
- }
-
- }
- });
- if (!checkPermissions()) {
- askPermissions();
- } else {
- startService();
- }
- }
-
- private boolean checkPermissions() {
- for (String permission: PERMISSIONS_REQUIRED) {
- int result = ContextCompat.checkSelfPermission(getApplicationContext(), permission);
- if (result != PackageManager.PERMISSION_GRANTED) {
- return false;
- }
- Log.i(TAG, "setOnClickListener - result result result" + result);
- }
- return true;
- }
-
- private void askPermissions() {
- ActivityCompat.requestPermissions(this, PERMISSIONS_REQUIRED, PERMISSION_REQUEST_CODE);
- }
-
-
- private void startService() {
- Intent intent = new Intent(this, MatrixService.class);
- startService(intent);
- }
-}
diff --git a/app/src/main/java/eu/droogers/smsmatrix/MainActivity.kt b/app/src/main/java/eu/droogers/smsmatrix/MainActivity.kt
new file mode 100644
index 0000000..98220d1
--- /dev/null
+++ b/app/src/main/java/eu/droogers/smsmatrix/MainActivity.kt
@@ -0,0 +1,160 @@
+package eu.droogers.smsmatrix
+
+import android.Manifest.permission
+import android.app.Activity
+import android.content.ContentValues
+import android.content.Intent
+import android.content.SharedPreferences
+import android.content.pm.PackageManager
+import android.os.Build
+import android.os.Bundle
+import android.util.Log
+import android.view.View
+import android.widget.Button
+import android.widget.EditText
+import android.widget.Toast
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
+import java.util.Arrays
+
+class MainActivity : Activity() {
+ private var sp: SharedPreferences? = null
+ private var botUsername: EditText? = null
+ private var botPassword: EditText? = null
+ private var username: EditText? = null
+ private var device: EditText? = null
+ private var hsUrl: EditText? = null
+ private var syncDelay: EditText? = null
+ private var syncTimeout: EditText? = null
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ sp = getSharedPreferences("settings", MODE_PRIVATE)
+ botUsername = findViewById(R.id.editText_botUsername)
+ botPassword = findViewById(R.id.editText_botpassword)
+ username = findViewById(R.id.editText_username)
+ device = findViewById(R.id.editText_device)
+ hsUrl = findViewById(R.id.editText_hsUrl)
+ syncDelay = findViewById(R.id.editText_syncDelay)
+ syncTimeout = findViewById(R.id.editText_syncTimeout)
+
+ botUsername.setText(sp.getString("botUsername", ""))
+ botPassword.setText(sp.getString("botPassword", ""))
+ username.setText(sp.getString("username", ""))
+ device.setText(sp.getString("device", ""))
+ hsUrl.setText(sp.getString("hsUrl", ""))
+ syncDelay.setText(sp.getString("syncDelay", "12"))
+ syncTimeout.setText(sp.getString("syncTimeout", "30"))
+
+ val saveButton = findViewById