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