diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
new file mode 100644
index 0000000..10c1a5d
Binary files /dev/null and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 96cc43e..0000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index e7bedf3..0000000
--- a/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index ba7052b..e0d5b93 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,26 +5,31 @@
-
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 827b8fe..d107048 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,7 +2,7 @@
-
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 7eb3280..5d03b45 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -27,6 +27,8 @@ android {
dependencies {
implementation 'com.android.support:appcompat-v7:26.0.0'
+
+ implementation "com.android.support:support-compat:26.0.0"
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96900c5..d712e47 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,8 +4,14 @@
package="eu.droogers.smsmatrix">
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/eu/droogers/smsmatrix/DataManager.java b/app/src/main/java/eu/droogers/smsmatrix/DataManager.java
new file mode 100644
index 0000000..f2265d5
--- /dev/null
+++ b/app/src/main/java/eu/droogers/smsmatrix/DataManager.java
@@ -0,0 +1,308 @@
+package eu.droogers.smsmatrix;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.Log;
+
+import static eu.droogers.smsmatrix.DatabaseContract.SmsEntry;
+import static eu.droogers.smsmatrix.DatabaseContract.MmsEntry;
+
+public class DataManager {
+
+ private static DataManager ourInsance = null;
+ private static final String LOG_TAG = "UntidyLamp.DataManager";
+ public static final String[] ALLColumns = new String[] { "*" };
+ public static final String unread = "locked=0 AND read=0";
+ public static final String mmsTrIdError = "locked=1 AND read=0 AND error_code=1 AND mms_id=0";
+ //final String[] whatColumns = {SmsEntry.COLUMN_ADDRESS};
+ public static final int TYPE_RECIEVED = 2; //2 is recieved (1 is sent)
+ public static final int NOT_READ = 0; //messages has not been read yet
+ public static final int IS_READ = 1; //message has been read
+ public static final int NO_STATUS = -1; //No status yet
+ public static final int NOT_LOCKED = 0; //its not locked
+ public static final int LOCKED = 1; //its locked
+ public static final int ERROR_NO = 0; //no error yet
+ public static final int ERROR_onUnexpectedError = 1;
+ public static final int ERROR_onMatrixError = 2;
+ public static final int ERROR_onNetworkError = 3;
+
+ public static final int MMS_TR_ID_ERROR = 1; // cant find tr_id from onRecieve in mmssms.db
+
+ public static DataManager getInstance() {
+ if(ourInsance == null) {
+ ourInsance = new DataManager();
+ }
+ return ourInsance;
+ }
+
+ public static int dumpSmses(OpenHelper dbHelper) {
+ Log.i(LOG_TAG, "dumpSmses");
+ SQLiteDatabase db = dbHelper.getReadableDatabase();
+ Cursor smsQueryCursor = db.query(DatabaseContract.SmsEntry.TABLE_NAME, ALLColumns, null, null, null, null, null);
+ Log.i(LOG_TAG, "Heres what's in the cursor " + DatabaseUtils.dumpCursorToString(smsQueryCursor) );
+ int smsesCount = smsQueryCursor.getCount();
+ smsQueryCursor.close();
+ Log.i(LOG_TAG, "dumpSmses is done");
+ return smsesCount;
+ }
+
+
+ public static boolean markSmsRead(OpenHelper dbHelper, int smsId) {
+ Log.i(LOG_TAG, "markSmsRead called");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(SmsEntry.COLUMN_READ, IS_READ);
+ try {
+ db.update(DatabaseContract.SmsEntry.TABLE_NAME, values, "_id=" + smsId, null );
+ db.close();
+ return true;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "markSmsRead failed " + e );
+ db.close();
+ return false;
+ }
+ }
+
+ public static boolean lockSms(OpenHelper dbHelper, int smsId) {
+ Log.i(LOG_TAG, "lockSms called");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(SmsEntry.COLUMN_LOCKED, LOCKED);
+ try {
+ db.update(DatabaseContract.SmsEntry.TABLE_NAME, values, "_id=" + smsId, null );
+ db.close();
+ return true;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "lockSms failed " + e );
+ db.close();
+ return false;
+ }
+ }
+
+ public static boolean unlockSms(OpenHelper dbHelper, int smsId) {
+ Log.i(LOG_TAG, "unlockSms called");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(SmsEntry.COLUMN_LOCKED, NOT_LOCKED);
+ try {
+ db.update(DatabaseContract.SmsEntry.TABLE_NAME, values, "_id=" + smsId, null );
+ db.close();
+ return true;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "unlockSms failed " + e );
+ db.close();
+ return false;
+ }
+ }
+
+ public static boolean errorSms(OpenHelper dbHelper, int smsId, int error) {
+ Log.i(LOG_TAG, "errorSms called");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(SmsEntry.COLUMN_ERROR_CODE, error);
+ try {
+ db.update(DatabaseContract.SmsEntry.TABLE_NAME, values, "_id=" + smsId, null );
+ db.close();
+ return true;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "errorSms failed " + e );
+ db.close();
+ return false;
+ }
+ }
+
+
+ public static int dumpMmses(OpenHelper dbHelper) {
+ Log.i(LOG_TAG, "dumpMmses");
+ SQLiteDatabase db = dbHelper.getReadableDatabase();
+ Cursor mmsQueryCursor = db.query(DatabaseContract.MmsEntry.TABLE_NAME, ALLColumns, null, null, null, null, null);
+ Log.i(LOG_TAG, "Heres what's in the cursor " + DatabaseUtils.dumpCursorToString(mmsQueryCursor) );
+ int mmsesCount = mmsQueryCursor.getCount();
+ mmsQueryCursor.close();
+ db.close();
+ Log.i(LOG_TAG, "dumpMmses is done");
+ return mmsesCount;
+ }
+
+
+ public static boolean markMmsRead(OpenHelper dbHelper, int mmsId) {
+ Log.i(LOG_TAG, "markMmsRead called");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(MmsEntry.COLUMN_READ, IS_READ);
+ try {
+ db.update(DatabaseContract.MmsEntry.TABLE_NAME, values, "_id=" + mmsId, null );
+ db.close();
+ return true;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "markMmsRead failed " + e );
+ db.close();
+ return false;
+ }
+
+ }
+
+ public static boolean lockMms(OpenHelper dbHelper, int mmsId) {
+ Log.i(LOG_TAG, "lockMms called");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(MmsEntry.COLUMN_LOCKED, LOCKED);
+ try {
+ db.update(DatabaseContract.MmsEntry.TABLE_NAME, values, "_id=" + mmsId, null );
+ db.close();
+ return true;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "lockMms failed " + e );
+ db.close();
+ return false;
+ }
+ }
+
+ public static boolean unlockMms(OpenHelper dbHelper, int mmsId) {
+ Log.i(LOG_TAG, "unlockMms called");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(MmsEntry.COLUMN_LOCKED, NOT_LOCKED);
+ try {
+ db.update(DatabaseContract.MmsEntry.TABLE_NAME, values, "_id=" + mmsId, null );
+ db.close();
+ return true;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "unlockMms failed " + e );
+ db.close();
+ return false;
+ }
+ }
+
+ public static boolean errorMms(OpenHelper dbHelper, int mmsId, int error) {
+ Log.i(LOG_TAG, "errorMms called");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(MmsEntry.COLUMN_ERROR_CODE, error);
+ try {
+ db.update(DatabaseContract.MmsEntry.TABLE_NAME, values, "_id=" + mmsId, null );
+ db.close();
+ return true;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "errorMms failed " + e );
+ db.close();
+ return false;
+ }
+ }
+
+ public static int countSmses(OpenHelper dbHelper) {
+ Log.i(LOG_TAG, "countSmses");
+ SQLiteDatabase db = dbHelper.getReadableDatabase();
+ Cursor countSmsesCursor = db.query(DatabaseContract.SmsEntry.TABLE_NAME, ALLColumns, null, null, null, null, null);
+ int smsesCount = countSmsesCursor.getCount();
+ countSmsesCursor.close();
+ db.close();
+ Log.i(LOG_TAG, "countSmses is done");
+ return smsesCount;
+ }
+
+ public static int countMmses(OpenHelper dbHelper) {
+ Log.i(LOG_TAG, "countMmses");
+ SQLiteDatabase db = dbHelper.getReadableDatabase();
+ Cursor countMmsesCursor = db.query(DatabaseContract.MmsEntry.TABLE_NAME, ALLColumns, null, null, null, null, null);
+ int mmsesCount = countMmsesCursor.getCount();
+ countMmsesCursor.close();
+ db.close();
+ Log.i(LOG_TAG, "countMmses is done");
+ return mmsesCount;
+ }
+
+ public static long importSms(OpenHelper dbHelper, String address, long date, long dateSent, int read, int type, int status, String body, int locked, int errorCode) {
+ Log.i(LOG_TAG, "importSms");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(DatabaseContract.SmsEntry.COLUMN_ADDRESS, address);
+ values.put(DatabaseContract.SmsEntry.COLUMN_DATE, date);
+ values.put(DatabaseContract.SmsEntry.COLUMN_DATE_SENT, dateSent);
+ values.put(DatabaseContract.SmsEntry.COLUMN_READ, read);
+ values.put(DatabaseContract.SmsEntry.COLUMN_STATUS, status);
+ values.put(DatabaseContract.SmsEntry.COLUMN_TYPE, type);
+ values.put(DatabaseContract.SmsEntry.COLUMN_BODY, body);
+ values.put(DatabaseContract.SmsEntry.COLUMN_LOCKED, locked);
+ values.put(DatabaseContract.SmsEntry.COLUMN_ERROR_CODE, errorCode);
+ try {
+ long smsImportRowId = db.insert(DatabaseContract.SmsEntry.TABLE_NAME, null, values);
+ Log.i(LOG_TAG, "smsImportRowId " + smsImportRowId );
+ db.close();
+ return smsImportRowId;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "importSms failed " + e );
+ db.close();
+ return -1;
+ }
+ }
+
+ public static void updateLongSmsBody (OpenHelper dbHelper, long id, String body ){
+
+ Log.i(LOG_TAG, "updateLongSmsBody");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(DatabaseContract.SmsEntry.COLUMN_BODY, body);
+
+ try {
+ Log.i(LOG_TAG, " try updateLongSmsBody _id=" + id );
+ db.update(DatabaseContract.SmsEntry.TABLE_NAME, values, "_id=" + id, null );
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "updateLongSmsBody failed " + e );
+ }
+ db.close();
+ }
+
+
+ public static long importMms(OpenHelper dbHelper, String tr_id, String address, long date, long dateSent, int read, int type, int mmsId, int status, String body, int locked, int errorCode) {
+ Log.i(LOG_TAG, "importMms");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(DatabaseContract.MmsEntry.COLUMN_TR_ID, tr_id);
+ values.put(DatabaseContract.MmsEntry.COLUMN_ADDRESS, address);
+ values.put(DatabaseContract.MmsEntry.COLUMN_DATE, date);
+ values.put(DatabaseContract.MmsEntry.COLUMN_DATE_SENT, dateSent);
+ values.put(DatabaseContract.MmsEntry.COLUMN_READ, read);
+ values.put(DatabaseContract.MmsEntry.COLUMN_STATUS, status);
+ values.put(DatabaseContract.MmsEntry.COLUMN_TYPE, type);
+ values.put(DatabaseContract.MmsEntry.COLUMN_MMS_ID, mmsId);
+ values.put(DatabaseContract.MmsEntry.COLUMN_BODY, body);
+ values.put(DatabaseContract.MmsEntry.COLUMN_LOCKED, locked);
+ values.put(DatabaseContract.MmsEntry.COLUMN_ERROR_CODE, errorCode);
+ try {
+ long mmsImportRowId = db.insert(DatabaseContract.MmsEntry.TABLE_NAME, null, values);
+ Log.i(LOG_TAG, "smsImportRowId " + mmsImportRowId );
+ db.close();
+ return mmsImportRowId;
+ } catch (Exception e) {
+ db.close();
+ return -1;
+ }
+ }
+
+ public static void updateFailedMms (OpenHelper dbHelper, int id, int mmsId, String body, int locked, int errorCode ){
+ Log.i(LOG_TAG, "updateFailedMms");
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(DatabaseContract.MmsEntry.COLUMN_MMS_ID, mmsId);
+ values.put(DatabaseContract.MmsEntry.COLUMN_BODY, body);
+ values.put(DatabaseContract.MmsEntry.COLUMN_LOCKED, locked);
+ values.put(DatabaseContract.MmsEntry.COLUMN_ERROR_CODE, errorCode);
+
+ try {
+ Log.i(LOG_TAG, " try updateFailedMms _id=" + id );
+ db.update(DatabaseContract.MmsEntry.TABLE_NAME, values, "_id=" + id, null );
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "updateFailedMms _id="+ id + " failed: " + e );
+ }
+ db.close();
+ }
+
+ public static boolean deleteAll (OpenHelper dbHelper) {
+ return false;
+ }
+
+}
diff --git a/app/src/main/java/eu/droogers/smsmatrix/DatabaseContract.java b/app/src/main/java/eu/droogers/smsmatrix/DatabaseContract.java
new file mode 100644
index 0000000..bb482eb
--- /dev/null
+++ b/app/src/main/java/eu/droogers/smsmatrix/DatabaseContract.java
@@ -0,0 +1,68 @@
+package eu.droogers.smsmatrix;
+
+import android.provider.BaseColumns;
+
+public final class DatabaseContract {
+ private DatabaseContract () {}
+
+ public static final class SmsEntry implements BaseColumns {
+ public static final String TABLE_NAME = "sms";
+ public static final String COLUMN_ADDRESS = "address";
+ public static final String COLUMN_DATE = "date";
+ public static final String COLUMN_DATE_SENT = "date_sent";
+ public static final String COLUMN_READ = "read";
+ public static final String COLUMN_STATUS = "status";
+ public static final String COLUMN_TYPE = "type";
+ public static final String COLUMN_BODY = "body";
+ public static final String COLUMN_LOCKED = "locked";
+ public static final String COLUMN_ERROR_CODE = "error_code";
+
+ public static final String SQL_CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ _ID + " INTEGER PRIMARY KEY, " +
+ COLUMN_ADDRESS + " TEXT NOT NULL, " +
+ COLUMN_DATE + " INTEGER NOT NULL, " +
+ COLUMN_DATE_SENT + " INTEGER NOT NULL, " +
+ COLUMN_READ + " INTEGER NOT NULL, " +
+ COLUMN_STATUS + " INTEGER NOT NULL, " +
+ COLUMN_TYPE + " INTEGER NOT NULL, " +
+ COLUMN_BODY + " TEXT NOT NULL, " +
+ COLUMN_LOCKED + " INTEGER, " +
+ COLUMN_ERROR_CODE + " INTEGER )";
+
+
+ }
+
+ public static final class MmsEntry implements BaseColumns {
+ public static final String TABLE_NAME = "mms";
+ public static final String COLUMN_TR_ID = "tr_id";
+ public static final String COLUMN_ADDRESS = "address";
+ public static final String COLUMN_DATE = "date";
+ public static final String COLUMN_DATE_SENT = "date_sent";
+ public static final String COLUMN_READ = "read";
+ public static final String COLUMN_STATUS = "status";
+ public static final String COLUMN_TYPE = "type";
+ public static final String COLUMN_MMS_ID = "mms_id";
+ public static final String COLUMN_BODY = "body";
+ public static final String COLUMN_LOCKED = "locked";
+ public static final String COLUMN_ERROR_CODE = "error_code";
+
+ public static final String SQL_CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ _ID + " INTEGER PRIMARY KEY, " +
+ COLUMN_TR_ID + " TEXT NOT NULL, " +
+ COLUMN_ADDRESS + " TEXT NOT NULL, " +
+ COLUMN_DATE + " INTEGER NOT NULL, " +
+ COLUMN_DATE_SENT + " INTEGER NOT NULL, " +
+ COLUMN_READ + " INTEGER NOT NULL, " +
+ COLUMN_STATUS + " INTEGER NOT NULL, " +
+ COLUMN_TYPE + " INTEGER NOT NULL, " +
+ COLUMN_MMS_ID + " INTEGER NOT NULL, " +
+ COLUMN_BODY + " TEXT, " +
+ COLUMN_LOCKED + " INTEGER, " +
+ COLUMN_ERROR_CODE + " INTEGER )";
+ }
+
+
+
+}
diff --git a/app/src/main/java/eu/droogers/smsmatrix/DatabaseDataWorker.java b/app/src/main/java/eu/droogers/smsmatrix/DatabaseDataWorker.java
new file mode 100644
index 0000000..b4ccbcb
--- /dev/null
+++ b/app/src/main/java/eu/droogers/smsmatrix/DatabaseDataWorker.java
@@ -0,0 +1,50 @@
+package eu.droogers.smsmatrix;
+
+import android.content.ContentValues;
+import android.database.sqlite.SQLiteDatabase;
+import android.provider.ContactsContract;
+
+
+public class DatabaseDataWorker {
+ private SQLiteDatabase mDb;
+ public DatabaseDataWorker(SQLiteDatabase db) {
+ mDb = db;
+ }
+
+
+
+ private void insertSms(int address, int date, int dateSent, int read, int type, int status, String body, int locked, int errorCode) {
+ ContentValues values = new ContentValues();
+ values.put(DatabaseContract.SmsEntry.COLUMN_ADDRESS, address);
+ values.put(DatabaseContract.SmsEntry.COLUMN_DATE, date);
+ values.put(DatabaseContract.SmsEntry.COLUMN_DATE_SENT, dateSent);
+ values.put(DatabaseContract.SmsEntry.COLUMN_READ, read);
+ values.put(DatabaseContract.SmsEntry.COLUMN_STATUS, status);
+ values.put(DatabaseContract.SmsEntry.COLUMN_TYPE, type);
+ values.put(DatabaseContract.SmsEntry.COLUMN_BODY, body);
+ values.put(DatabaseContract.SmsEntry.COLUMN_LOCKED, locked);
+ values.put(DatabaseContract.SmsEntry.COLUMN_ERROR_CODE, errorCode);
+
+ long newRowId = mDb.insert(DatabaseContract.SmsEntry.TABLE_NAME, null, values);
+ }
+
+ private void insertMms(String tr_id, int address, int date, int dateSent, int read, int type, int mmsId, int status, String body, int locked, int errorCode) {
+ ContentValues values = new ContentValues();
+ values.put(DatabaseContract.MmsEntry.COLUMN_TR_ID, tr_id);
+ values.put(DatabaseContract.MmsEntry.COLUMN_ADDRESS, address);
+ values.put(DatabaseContract.MmsEntry.COLUMN_DATE, date);
+ values.put(DatabaseContract.MmsEntry.COLUMN_DATE_SENT, dateSent);
+ values.put(DatabaseContract.MmsEntry.COLUMN_READ, read);
+ values.put(DatabaseContract.MmsEntry.COLUMN_STATUS, status);
+ values.put(DatabaseContract.MmsEntry.COLUMN_TYPE, type);
+ values.put(DatabaseContract.MmsEntry.COLUMN_MMS_ID, mmsId);
+ values.put(DatabaseContract.MmsEntry.COLUMN_BODY, body);
+ values.put(DatabaseContract.MmsEntry.COLUMN_LOCKED, locked);
+ values.put(DatabaseContract.MmsEntry.COLUMN_ERROR_CODE, errorCode);
+
+ long newRowId = mDb.insert(DatabaseContract.MmsEntry.TABLE_NAME, null, values);
+ }
+
+
+
+}
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/MainActivity.java b/app/src/main/java/eu/droogers/smsmatrix/MainActivity.java
index 8c2334e..f5d5187 100644
--- a/app/src/main/java/eu/droogers/smsmatrix/MainActivity.java
+++ b/app/src/main/java/eu/droogers/smsmatrix/MainActivity.java
@@ -2,6 +2,7 @@ package eu.droogers.smsmatrix;
import android.Manifest;
import android.app.Activity;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -10,6 +11,7 @@ import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
+import android.widget.CheckBox;
import android.widget.EditText;
import android.support.v4.app.ActivityCompat;
@@ -20,6 +22,7 @@ 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.RECEIVE_MMS;
import static android.Manifest.permission.SEND_SMS;
import static android.content.ContentValues.TAG;
@@ -34,7 +37,7 @@ public class MainActivity extends Activity {
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
+ READ_SMS, SEND_SMS, RECEIVE_SMS, RECEIVE_MMS, READ_PHONE_STATE, READ_CONTACTS, READ_EXTERNAL_STORAGE
};
private static final int PERMISSION_REQUEST_CODE = 200;
@@ -51,6 +54,8 @@ public class MainActivity extends Activity {
hsUrl = (EditText) findViewById(R.id.editText_hsUrl);
syncDelay = (EditText) findViewById(R.id.editText_syncDelay);
syncTimeout = (EditText) findViewById(R.id.editText_syncTimeout);
+ final CheckBox notificationCheckBox = (CheckBox) findViewById(R.id.notification_check_box);
+ final CheckBox mmsCheckBox = (CheckBox) findViewById(R.id.mms_check_box);
botUsername.setText(sp.getString("botUsername", ""));
botPassword.setText(sp.getString("botPassword", ""));
@@ -59,6 +64,8 @@ public class MainActivity extends Activity {
hsUrl.setText(sp.getString("hsUrl", ""));
syncDelay.setText(sp.getString("syncDelay", "12"));
syncTimeout.setText(sp.getString("syncTimeout", "30"));
+ notificationCheckBox.setChecked(sp.getBoolean("notificationCheckBoxStatus", false));
+ mmsCheckBox.setChecked(sp.getBoolean("mmsCheckBoxStatus", false));
Button saveButton = (Button) findViewById(R.id.button_save);
@@ -76,6 +83,8 @@ public class MainActivity extends Activity {
editor.putString("hsUrl", hsUrl.getText().toString());
editor.putString("syncDelay", syncDelay.getText().toString());
editor.putString("syncTimeout", syncTimeout.getText().toString());
+ editor.putBoolean("notificationCheckBoxStatus", notificationCheckBox.isChecked());
+ editor.putBoolean("mmsCheckBoxStatus", mmsCheckBox.isChecked());
editor.apply();
Log.e(TAG, "onClick: " + botUsername.getText().toString() );
@@ -84,6 +93,23 @@ public class MainActivity extends Activity {
}
});
+
+
+
+ Button stopButton = (Button) findViewById(R.id.stop_button);
+ stopButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View testButtonView) {
+ if (!checkPermissions()) {
+ askPermissions();
+ } else {
+
+ Intent intnet = new Intent(getApplicationContext(), eu.droogers.smsmatrix.MatrixService.class);
+ stopService(intnet);
+ }
+ }
+ });
+
if (!checkPermissions()) {
askPermissions();
} else {
diff --git a/app/src/main/java/eu/droogers/smsmatrix/Matrix.java b/app/src/main/java/eu/droogers/smsmatrix/Matrix.java
index b251858..4e69d93 100644
--- a/app/src/main/java/eu/droogers/smsmatrix/Matrix.java
+++ b/app/src/main/java/eu/droogers/smsmatrix/Matrix.java
@@ -28,6 +28,7 @@ import org.matrix.androidsdk.listeners.MXMediaUploadListener;
import org.matrix.androidsdk.rest.callback.SimpleApiCallback;
import org.matrix.androidsdk.rest.client.LoginRestClient;
import org.matrix.androidsdk.rest.model.Event;
+import org.matrix.androidsdk.rest.model.MatrixError;
import org.matrix.androidsdk.rest.model.Message;
import org.matrix.androidsdk.rest.model.login.Credentials;
@@ -90,6 +91,12 @@ public class Matrix {
super.onSuccess(credentials);
onLogin(credentials);
}
+
+ @Override
+ public void onNetworkError(Exception e) {
+ //show in notification
+ super.onNetworkError(e);
+ }
});
}
@@ -155,7 +162,7 @@ public class Matrix {
}
}
- public void sendMessage(final String phoneNumber, final String body, final String type) {
+ public void sendMessage(final String phoneNumber, final String body, final String type, final int databaseId) {
if (session != null && session.isAlive()) {
Room room = getRoomByPhonenumber(phoneNumber);
if (room == null) {
@@ -168,17 +175,23 @@ public class Matrix {
session.getRoomsApiClient().updateTopic(info, phoneNumber, new SimpleApiCallback());
changeDisplayname(info, getContactName(phoneNumber, context));
Room room = store.getRoom(info);
- SendMesageToRoom(room, body, type);
+ SendMesageToRoom(room, body, type, databaseId);
}
});
}
} else {
changeDisplayname(room.getRoomId(), getContactName(phoneNumber, context));
- SendMesageToRoom(room, body, type);
+ SendMesageToRoom(room, body, type, databaseId);
}
} else {
+ if (databaseId > 0){
+ OpenHelper dbHelper = new OpenHelper(context);
+ DataManager.unlockSms(dbHelper, databaseId);
+ DataManager.errorSms(dbHelper, databaseId, DataManager.ERROR_onNetworkError);
+ dbHelper.close();
+ }
Log.e(tag, "Error with sending message");
- notSendMesages.add(new NotSendMesage(phoneNumber, body, type));
+ //notSendMesages.add(new NotSendMesage(phoneNumber, body, type));
}
}
@@ -187,7 +200,8 @@ public class Matrix {
final byte[] body,
final String type,
final String fileName,
- final String contentType
+ final String contentType,
+ final int databaseId
) {
String uploadID = String.valueOf(transaction);
transaction++;
@@ -209,14 +223,36 @@ public class Matrix {
info.addProperty("mimetype", contentType);
json.add("info", info);
session.getRoomsApiClient().sendEventToRoom(
- String.valueOf(transaction),
- room.getRoomId(),
- "m.room.message",
- json,
- new SimpleApiCallback()
- );
+ String.valueOf(transaction),
+ room.getRoomId(),
+ "m.room.message",
+ json,
+ new SimpleApiCallback(){
+ @Override
+ public void onSuccess(Event info) {
+ if (databaseId > 0) {
+ Log.i(TAG, "sendFile onSuccess, Marking _id=" + databaseId + " as read");
+ OpenHelper dbHelper = new OpenHelper(context);
+ DataManager.markMmsRead(dbHelper, databaseId);
+ DataManager.unlockMms(dbHelper, databaseId);
+ dbHelper.close();
+ } else {
+ //Case of MMS or other thing. maybe I need to add this into the MMS database to see if text made it.
+ Log.i(TAG, "sendFile onSuccess, databaseId is 0 - not marking as read");
+ }
+ }
+ });
transaction++;
}
+
+ @Override
+ public void onUploadError(String uploadId, int serverResponseCode, String serverErrorMessage) {
+ OpenHelper dbHelper = new OpenHelper(context);
+ DataManager.errorMms(dbHelper, databaseId, DataManager.ERROR_onUnexpectedError);
+ DataManager.unlockMms(dbHelper, databaseId);
+ dbHelper.close();
+ super.onUploadError(uploadId, serverResponseCode, serverErrorMessage);
+ }
}
);
}
@@ -228,11 +264,59 @@ public class Matrix {
session.getRoomsApiClient().sendStateEvent(roomId, "m.room.member", session.getMyUserId(), params, new SimpleApiCallback());
}
- public void SendMesageToRoom(Room room, String body, String type) {
+ public void SendMesageToRoom(Room room, String body, String type, final int databaseId) {
+ Log.i(TAG, "TTTHHHHHIIIISSS SendMesageToRoomSendMesageToRoom" );
Message msg = new Message();
msg.body = body;
msg.msgtype = type;
- session.getRoomsApiClient().sendMessage(String.valueOf(transaction), room.getRoomId(), msg, new SimpleApiCallback());
+ session.getRoomsApiClient().sendMessage(String.valueOf(transaction), room.getRoomId(), msg, new SimpleApiCallback(){
+ @Override
+ public void onSuccess(Event info) {
+ if (databaseId > 0) {
+ Log.i(TAG, "SendMessageToRoom onSuccess, Marking _id=" + databaseId + " as read");
+ OpenHelper dbHelper = new OpenHelper(context);
+ DataManager.markSmsRead(dbHelper, databaseId);
+ DataManager.unlockSms(dbHelper, databaseId);
+ dbHelper.close();
+ } else {
+ //Case of text in MMS message.
+ Log.i(TAG, "SendMessageToRoom onSuccess, databaseId is 0 - not marking as read");
+ }
+ }
+
+ @Override
+ public void onUnexpectedError(Exception e) {
+ if ( databaseId > 0 ) {
+ OpenHelper dbHelper = new OpenHelper(context);
+ DataManager.unlockSms(dbHelper, databaseId);
+ DataManager.errorSms(dbHelper, databaseId, DataManager.ERROR_onUnexpectedError);
+ dbHelper.close();
+ }
+ super.onUnexpectedError(e);
+ }
+
+ @Override
+ public void onMatrixError(MatrixError e) {
+ if ( databaseId > 0 ){
+ OpenHelper dbHelper = new OpenHelper(context);
+ DataManager.unlockSms(dbHelper, databaseId);
+ DataManager.errorSms(dbHelper, databaseId, DataManager.ERROR_onMatrixError);
+ dbHelper.close();
+ }
+ super.onMatrixError(e);
+ }
+
+ @Override
+ public void onNetworkError(Exception e) {
+ if ( databaseId > 0 ){
+ OpenHelper dbHelper = new OpenHelper(context);
+ DataManager.unlockSms(dbHelper, databaseId);
+ DataManager.errorSms(dbHelper, databaseId, DataManager.ERROR_onNetworkError);
+ dbHelper.close();
+ }
+ super.onNetworkError(e);
+ }
+ });
transaction++;
}
@@ -286,7 +370,7 @@ public class Matrix {
public void sendMessageList(List messages) {
for (NotSendMesage ms : messages) {
- sendMessage(ms.getPhone(), ms.getBody(), ms.getType());
+ sendMessage(ms.getPhone(), ms.getBody(), ms.getType(), 0);
}
}
@@ -327,6 +411,7 @@ public class Matrix {
}
public void destroy() {
+ Log.e(TAG, "marix.java destry called");
session.stopEventStream();
dh.removeListener(evLis);
store.close();
diff --git a/app/src/main/java/eu/droogers/smsmatrix/MatrixService.java b/app/src/main/java/eu/droogers/smsmatrix/MatrixService.java
index 9fbd89a..de1764b 100644
--- a/app/src/main/java/eu/droogers/smsmatrix/MatrixService.java
+++ b/app/src/main/java/eu/droogers/smsmatrix/MatrixService.java
@@ -1,14 +1,31 @@
package eu.droogers.smsmatrix;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.app.Service;
-import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
import android.os.IBinder;
+import android.support.v4.app.NotificationCompat;
+import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
/**
* Created by gerben on 7-10-17.
*/
@@ -23,7 +40,17 @@ public class MatrixService extends Service {
private String hsUrl;
private String syncDelay;
private String syncTimeout;
- private MMSMonitor mms;
+ private boolean notificationCheckBoxStatus;
+ private boolean mmsCheckBoxStatus;
+
+ private OpenHelper mDbOpenHelper;
+ private String onReceiveType = "nothing";
+ private int app_id = 0;
+
+ public static NotificationManager notificationManager = null;
+ public final static int PERSISTENT_NOTIFICATION_ID = 001;
+ public final static String NOTIFICATION_CHANNEL_ID = "smsmatrix";
+ public static NotificationCompat.Builder mBuilder = null;
@Override
public void onCreate() {
@@ -40,10 +67,15 @@ public class MatrixService extends Service {
hsUrl = sp.getString("hsUrl", "");
syncDelay = sp.getString("syncDelay", "12");
syncTimeout = sp.getString("syncTimeout", "60");
+ notificationCheckBoxStatus = sp.getBoolean("notificationCheckBoxStatus", false);
+ mmsCheckBoxStatus = sp.getBoolean("mmsCheckBoxStatus", false);
if (mx == null && !botUsername.isEmpty() && !botPassword.isEmpty() && !username.isEmpty() && !device.isEmpty() && !hsUrl.isEmpty() && !syncDelay.isEmpty() && !syncTimeout.isEmpty()) {
mx = new Matrix(getApplication(), hsUrl, botUsername, botPassword, username, device, syncDelay, syncTimeout);
Log.e(TAG, "onStartCommand: " + hsUrl );
+ if (notificationCheckBoxStatus){
+ persistentNotification();
+ }
Toast.makeText(this, "service starting:", Toast.LENGTH_SHORT).show();
} else if (mx == null) {
Toast.makeText(this, "Missing Information", Toast.LENGTH_SHORT).show();
@@ -51,36 +83,404 @@ public class MatrixService extends Service {
Log.e(TAG, "onStartCommand: Service");
- String phone = intent.getStringExtra("SendSms_phone");
- String type = intent.getStringExtra("SendSms_type");
- if (phone != null) {
- System.out.println(phone);
- if (type.equals(Matrix.MESSAGE_TYPE_TEXT) || type.equals(Matrix.MESSAGE_TYPE_NOTICE))
- {
- String body = intent.getStringExtra("SendSms_body");
- mx.sendMessage(phone, body, type);
- } else if (type.equals(Matrix.MESSAGE_TYPE_IMAGE) || type.equals(Matrix.MESSAGE_TYPE_VIDEO)) {
- byte[] body = intent.getByteArrayExtra("SendSms_body");
- String fileName = intent.getStringExtra("SendSms_fileName");
- String contentType = intent.getStringExtra("SendSms_contentType");
- mx.sendFile(phone, body, type, fileName, contentType);
- }
- }
+ //From ReceiverListener
+ onReceiveType = intent.getStringExtra("onReceiveType");
+
+ //Recieved a new SMS
+ if (onReceiveType != null && onReceiveType.equals("sms")) {
+ Log.i(TAG, "SMS ");
+ try {
+ mDbOpenHelper = new OpenHelper(this);
+ } catch (Exception e) {
+ Log.e(TAG, "error " + e);
+ }
+
+ try {
+ Map msg = null;
+ SmsMessage[] msgs = null;
+ Bundle bundle = intent.getExtras();
+ long sms_id = 0;
+
+ if (bundle != null && bundle.containsKey("pdus")) {
+ Object[] pdus = (Object[]) bundle.get("pdus");
+
+ if (pdus != null) {
+ int nbrOfpdus = pdus.length;
+ msg = new HashMap(nbrOfpdus);
+ msgs = new SmsMessage[nbrOfpdus];
+
+ // Send long SMS of same sender in one message
+ for (int i = 0; i < nbrOfpdus; i++) {
+ msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
+ String originatinAddress = msgs[i].getOriginatingAddress();
+
+ // Check if index with number exists
+ if (!msg.containsKey(originatinAddress)) {
+ // Index with number doesn't exist (First message from that person)
+ //date get NOW date when oncrecieved is called
+ //long date = Instant.now().toEpochMilli();
+ long date = 0;
+ //date_sent
+ long date_sent = msgs[i].getTimestampMillis();
+ msg.put(msgs[i].getOriginatingAddress(), msgs[i].getMessageBody());
+ String fromAddress = msgs[i].getOriginatingAddress();
+ String fromBody = msgs[i].getMessageBody();
+ sms_id = DataManager.importSms(mDbOpenHelper,
+ fromAddress,
+ date,
+ date_sent,
+ DataManager.NOT_READ,
+ DataManager.TYPE_RECIEVED,
+ DataManager.NO_STATUS,
+ fromBody,
+ DataManager.NOT_LOCKED,
+ DataManager.ERROR_NO);
+ } else {
+ //Make sure we know where to put the rest of the long sms data
+ if (sms_id > 0) {
+ // Number is there and we have the ID for the first imported long sms.
+ String previousparts = msg.get(originatinAddress);
+ String msgString = previousparts + msgs[i].getMessageBody();
+ msg.put(originatinAddress, msgString);
+
+ DataManager.updateLongSmsBody(mDbOpenHelper,
+ sms_id,
+ msgString);
+
+ } else {
+ Log.e(TAG, "Problem adding Log SMS to database");
+ }
+ }
+ }
+ //start sms stuff
+ Log.i(TAG, "SMSes done ");
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "error " + e);
+ }
- if (this.mms == null) {
- this.mms = new MMSMonitor(this , getApplicationContext());
- this.mms.startMMSMonitoring();
}
+ //Recieved a new SMS END
+
+ //Recieved a new MMS
+ if (onReceiveType != null && mmsCheckBoxStatus && onReceiveType.equals("mms")) {
+ Log.i(TAG, "MMS - MMS");
+ try {
+ mDbOpenHelper = new OpenHelper(this);
+ } catch (Exception e) {
+ Log.e(TAG, "MMS - OpenHelper error " + e);
+ }
+
+ //I dont know how to download MMSC from cell provider. so we will do soemthing with mmssms.sb
+ Bundle bundle = intent.getExtras();
+ if (bundle != null && mDbOpenHelper != null) {
+ byte[] buffer = bundle.getByteArray("data");
+ String bufferString = new String(buffer);
+ Log.i(TAG, "MMS - bufferString: " + bufferString);
+
+ //Get Phone Number (between + and /TYPE
+ int mmsIndex = bufferString.indexOf("/TYPE");
+ int mmsIndexPlus = bufferString.indexOf("+");
+ String address = bufferString.substring(mmsIndexPlus, mmsIndex);
+ //Got phone number, Remove +1
+ address = address.replace("+1", "");
+ Log.i(TAG, "MMS - buffer address: " + address);
+
+ //Get MMSCURL TR ID (first char string in buffer)
+ //try to match this with tr_id in mmssms.db
+ String tr_id = "";
+ for (char ch: bufferString.toCharArray()) {
+ if (Character.isLetterOrDigit(ch) || ch == '_' || ch == '-') {
+ tr_id += ch;
+ } else if ( !tr_id.isEmpty() ){
+ Log.i(TAG, "MMS - tr_id " + tr_id);
+ break;
+ }
+ }
+
+ //I have no idea how to download the MMSC - we'll query the mmssms.db
+ //If you can, please fix this or make it better.
+ Log.i(TAG, "MMS - address " + address);
+ Log.i(TAG, "MMS - tr_id " + tr_id);
+
+ DataManager.importMms(
+ mDbOpenHelper,
+ tr_id,
+ address,
+ 0,
+ 0,
+ DataManager.NOT_READ,
+ DataManager.TYPE_RECIEVED,
+ 0,
+ DataManager.NO_STATUS,
+ "",
+ DataManager.NOT_LOCKED,
+ DataManager.ERROR_NO);
+
+ //there is a new MMS - Lets sleep to let the default messenger download the MMS
+ Log.e(TAG, "Sleep to let android download mms ");
+ try { TimeUnit.SECONDS.sleep(9); } catch (Exception e) {}
+
+ } else {
+ Log.e(TAG, "MMS - Error with MMS bundle or Database");
+ }
+
+ } else if (!mmsCheckBoxStatus) {
+ Log.i(TAG, "MMS - MMS not enabled");
+ }
+ //Recieved a new MMS END
+
+
+ //Ran each time service is started.
+ //Checks for unread messages in database and send them
+ if (mx != null ) {
+ //Check Database everytime something calls this and try to send all unread messages
+
+ // SMS and MMS
+ OpenHelper dbHelper = new OpenHelper(this);
+
+
+ //SMS Start
+ Log.i(TAG, "checking for SMSes");
+ Log.i(TAG, "unreadSmses called");
+ SQLiteDatabase unreadSmsesDb = dbHelper.getReadableDatabase();
+ String[] notLocked = new String[] { "locked" };
+
+
+ Cursor unreadSms = unreadSmsesDb.query(
+ DatabaseContract.SmsEntry.TABLE_NAME,
+ DataManager.ALLColumns,
+ DataManager.unread,
+ null,
+ null,
+ null,
+ null);
+
+
+ if (unreadSms.moveToFirst()) {
+ //Found unread SMS
+ do {
+ Log.i(TAG, "sending unread messages");
+ String body = unreadSms.getString(unreadSms.getColumnIndex("body"));
+ String address = unreadSms.getString(unreadSms.getColumnIndex("address"));
+ int smsId = unreadSms.getInt(unreadSms.getColumnIndex("_id"));
+ //locking SMS
+ Log.i(TAG, "Locking unread messages");
+ DataManager.lockSms(dbHelper, smsId);
+ //trying to send SMS
+ Log.i(TAG, "sending unread messages");
+ mx.sendMessage(address, body, Matrix.MESSAGE_TYPE_TEXT, smsId);
+ } while (unreadSms.moveToNext());
+ } else {
+ Log.i(TAG, "No unread SMSes in Database");
+ }
+ unreadSms.close();
+ unreadSmsesDb.close();
+ // SMS done
+
+
+ // MMS Start
+ if (mmsCheckBoxStatus) {
+ Log.i(TAG, "Checking for MMSes");
+ SQLiteDatabase appDatabase = dbHelper.getReadableDatabase();
+ Cursor appDatabaseCursor = appDatabase.query(
+ DatabaseContract.MmsEntry.TABLE_NAME,
+ DataManager.ALLColumns,
+ DataManager.unread,
+ null,
+ null,
+ null,
+ null);
+ //Log.i(TAG, "appDatabaseCursor cursor " + DatabaseUtils.dumpCursorToString(appDatabaseCursor) );
+
+ while (appDatabaseCursor.moveToNext()) {
+ String appTr_id = appDatabaseCursor.getString(appDatabaseCursor.getColumnIndex("tr_id"));
+ int app_id = appDatabaseCursor.getInt(appDatabaseCursor.getColumnIndex("_id"));
+ DataManager.lockMms(dbHelper, app_id);
+ String address = appDatabaseCursor.getString(appDatabaseCursor.getColumnIndex("address"));
+
+
+
+ Log.i(TAG, "Found tr_id="+ appTr_id + " in app database marked as unread (not sent).");
+ Uri mmsInboxDatabase = Uri.parse("content://mms/inbox");
+
+ //Match tr_id in app database(that I got from MMS onRecieve)
+ //to tr_id in the mmssms.db inbox(the pdu table) to get the _id
+ Cursor mmsInboxDatabaseCursor = getContentResolver().query(
+ mmsInboxDatabase,
+ null,
+ "tr_id='" + appTr_id + "'",
+ null,
+ null);
+
+ if (mmsInboxDatabaseCursor.moveToFirst()) {
+ //there should only be one tr_id match here.
+ //Log.i(TAG, "Second (only one, want mid cursor " + DatabaseUtils.dumpCursorToString(mmsInboxDatabaseCursor) );
+ int mid = mmsInboxDatabaseCursor.getInt(mmsInboxDatabaseCursor.getColumnIndex("_id"));
+ mmsInboxDatabaseCursor.close();
+
+
+ //the _id from mmssms.db content://mms/inbox(pdu table) will be matched to mid in mmssms.db part
+
+
+ String selectionPart = "mid=" + String.valueOf(mid) + " AND NOT ct=\'application/smil\'";
+ Uri uri = Uri.parse("content://mms/part");
+ Cursor mmsPartCursor = getContentResolver().query(uri, null, selectionPart, null, null );
+ Log.i(TAG, "THIRDDDDD cursor " + DatabaseUtils.dumpCursorToString(mmsPartCursor) );
+
+ //The part table will have 2+ entries with the same mid.
+ //The first is information about the rest - application/smil - I ignore this
+ //The second++ is each picture set to us
+ //The Last (if provided) is the text message along with all the pictures - text/plain
+ //So an MMS with 2 pictures with text will have 4 parts. information, picture, picture, text.
+ while (mmsPartCursor.moveToNext()) {
+ String type = mmsPartCursor.getString(mmsPartCursor.getColumnIndex("ct"));
+ Log.i(TAG, "typetype: " + type );
+
+ if (type.equals("text/plain")){
+ String text = mmsPartCursor.getString(mmsPartCursor.getColumnIndex("text"));
+ Log.i(TAG, "MMS message with text: " + text );
+ mx.sendMessage(address, text, Matrix.MESSAGE_TYPE_TEXT, 0);
+ } else {
+ String name = mmsPartCursor.getString(mmsPartCursor.getColumnIndex("name"));
+ Log.i(TAG, "MMS message picture: " + name );
+ byte[] mediaData = null;
+ String fileName = "";
+
+ fileName = mmsPartCursor.getString(mmsPartCursor.getColumnIndex("name"));
+ Log.e(TAG, "mmsPartCursor - fileName " + fileName);
+
+ mediaData = readMMSPart(mmsPartCursor.getString(mmsPartCursor.getColumnIndex("_id")));
+ Log.e(TAG, "mmsPartCursor - mediaData " + mediaData);
+
+ String contentType = mmsPartCursor.getString(mmsPartCursor.getColumnIndex("ct"));
+ Log.e(TAG, "mmsPartCursor - contentType " + contentType);
+
+ if (isImageType(contentType)) {
+ mx.sendFile(address, mediaData, Matrix.MESSAGE_TYPE_IMAGE, fileName, contentType, app_id);
+ } else if (isVideoType(contentType)) {
+ mx.sendFile(address, mediaData, Matrix.MESSAGE_TYPE_VIDEO, fileName, contentType, app_id);
+ }
+
+ }
+ }
+ } else {
+ DataManager.unlockMms(dbHelper, app_id);
+
+ Log.e(TAG, "I cant find tr_id="+appTr_id+" in the MMS Inbox. perhaps the MMS has not been downloaded yet");
+ mmsInboxDatabaseCursor.close();
+ }
+
+ }
+
+ Log.i(TAG, "Unread MMSes have been processes.");
+ } else {
+ Log.i(TAG, "MMS not enabled");
+ }
+ // MMS Done
+
+
+
+
+ }
+ //Ran each time service is started END
return START_NOT_STICKY;
}
+
+ public void persistentNotification() {
+ notificationManager = getSystemService(NotificationManager.class);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+
+
+ CharSequence name = "Persistent";
+ String description = "Sms Matrix Service is running";
+ int importance = NotificationManager.IMPORTANCE_DEFAULT;
+ NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance);
+ channel.setDescription(description);
+ notificationManager.createNotificationChannel(channel);
+ }
+
+ mBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(R.mipmap.ic_launcher_round)
+ .setContentTitle("SmsMatrix")
+ .setContentText("Matrix service running")
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+ .setOngoing(true);
+ notificationManager.notify(PERSISTENT_NOTIFICATION_ID, mBuilder.build());
+ }
+
+ 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 = 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();
+
+ } 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;
+ }
+
@Override
public void onDestroy() {
+ if (notificationCheckBoxStatus) {
+ try {
+ notificationManager.cancel(PERSISTENT_NOTIFICATION_ID);
+ } catch (Exception e) {}
+ }
mx.destroy();
- this.mms.stopMMSMonitoring();
- this.mms = null;
super.onDestroy();
}
diff --git a/app/src/main/java/eu/droogers/smsmatrix/OpenHelper.java b/app/src/main/java/eu/droogers/smsmatrix/OpenHelper.java
new file mode 100644
index 0000000..4304c3c
--- /dev/null
+++ b/app/src/main/java/eu/droogers/smsmatrix/OpenHelper.java
@@ -0,0 +1,25 @@
+package eu.droogers.smsmatrix;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class OpenHelper extends SQLiteOpenHelper {
+
+ public static final String DATABASE_NAME = "SmsMatrix.db";
+ public static final int DATABASE_VERSION = 1;
+ public OpenHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(DatabaseContract.SmsEntry.SQL_CREATE_TABLE);
+ db.execSQL(DatabaseContract.MmsEntry.SQL_CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+
+ }
+}
diff --git a/app/src/main/java/eu/droogers/smsmatrix/ReceiverListener.java b/app/src/main/java/eu/droogers/smsmatrix/ReceiverListener.java
index cf1e6c0..b2d3bb0 100644
--- a/app/src/main/java/eu/droogers/smsmatrix/ReceiverListener.java
+++ b/app/src/main/java/eu/droogers/smsmatrix/ReceiverListener.java
@@ -1,6 +1,7 @@
package eu.droogers.smsmatrix;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -16,54 +17,34 @@ import java.util.Map;
public class ReceiverListener extends BroadcastReceiver {
private static final String TAG = "ReceiverListener";
+ private static final String ACTION_MMS_RECEIVED = "android.provider.Telephony.WAP_PUSH_RECEIVED";
+ public static final String MMS_DATA_TYPE = "application/vnd.wap.mms-message";
+ private OpenHelper mDbOpenHelper;
+
+
+
+
@Override
public void onReceive(Context context, Intent intent) {
+ mDbOpenHelper = new OpenHelper(context);
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
- handleIncomingSMS(context, intent);
+ Log.d(TAG, "got SMS");
+ Intent newIntent = new Intent(intent);
+ newIntent.setComponent(new ComponentName(context, eu.droogers.smsmatrix.MatrixService.class));
+ newIntent.putExtra("onReceiveType", "sms");
+ context.startService(newIntent);
+ } else if (intent.getAction().equals(ACTION_MMS_RECEIVED) && intent.getType().equals(MMS_DATA_TYPE)) {
+ Log.d(TAG, "got MMS");
+ Intent newIntent = new Intent(intent);
+ newIntent.setComponent(new ComponentName(context, eu.droogers.smsmatrix.MatrixService.class));
+ newIntent.putExtra("onReceiveType", "mms");
+ context.startService(newIntent);
} else if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
handleIncomingCall(context, intent);
}
}
- private void handleIncomingSMS(Context context, Intent intent) {
- Map msg = null;
- SmsMessage[] msgs = null;
- Bundle bundle = intent.getExtras();
-
- if (bundle != null && bundle.containsKey("pdus")) {
- Object[] pdus = (Object[]) bundle.get("pdus");
-
- if (pdus != null) {
- int nbrOfpdus = pdus.length;
- msg = new HashMap(nbrOfpdus);
- msgs = new SmsMessage[nbrOfpdus];
-
- // Send long SMS of same sender in one message
- for (int i = 0; i < nbrOfpdus; i++) {
- msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
-
- String originatinAddress = msgs[i].getOriginatingAddress();
-
- // Check if index with number exists
- if (!msg.containsKey(originatinAddress)) {
- // Index with number doesn't exist
- msg.put(msgs[i].getOriginatingAddress(), msgs[i].getMessageBody());
-
- } else {
- // Number is there.
- String previousparts = msg.get(originatinAddress);
- String msgString = previousparts + msgs[i].getMessageBody();
- msg.put(originatinAddress, msgString);
- }
- }
- }
- }
- for (String originatinAddress : msg.keySet()) {
- Utilities.sendMatrix(context, msg.get(originatinAddress), originatinAddress, Matrix.MESSAGE_TYPE_TEXT);
- }
- }
-
private void handleIncomingCall(Context context, Intent intent) {
String cal_state = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String cal_from = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
@@ -79,6 +60,14 @@ public class ReceiverListener extends BroadcastReceiver {
body += " is calling";
break;
}
- Utilities.sendMatrix(context, body, cal_from, Matrix.MESSAGE_TYPE_NOTICE);
+ //sendMatrix(context, body, cal_from, Matrix.MESSAGE_TYPE_NOTICE);
+ //public static void sendMatrix(Context context, String body, String phone, String type) {
+ // Intent intent = new Intent(context, MatrixService.class);
+ // intent.putExtra("SendSms_phone", phone);
+ // intent.putExtra("SendSms_body", body);
+ // intent.putExtra("SendSms_type", type);
+ // context.startService(intent);
+ //}
}
+
}
diff --git a/app/src/main/java/eu/droogers/smsmatrix/Utilities.java b/app/src/main/java/eu/droogers/smsmatrix/Utilities.java
deleted file mode 100644
index cd2b27e..0000000
--- a/app/src/main/java/eu/droogers/smsmatrix/Utilities.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package eu.droogers.smsmatrix;
-
-import android.content.Context;
-import android.content.Intent;
-
-public class Utilities {
- public static void sendMatrix(Context context, String body, String phone, String type) {
- Intent intent = new Intent(context, MatrixService.class);
- intent.putExtra("SendSms_phone", phone);
- intent.putExtra("SendSms_body", body);
- intent.putExtra("SendSms_type", type);
- context.startService(intent);
- }
-
- public static void sendMatrix(Context context, byte[] body, String phone, String type, String fileName, String contentType) {
- Intent intent = new Intent(context, MatrixService.class);
- intent.putExtra("SendSms_phone", phone);
- intent.putExtra("SendSms_body", body);
- intent.putExtra("SendSms_type", type);
- intent.putExtra("SendSms_fileName", fileName);
- intent.putExtra("SendSms_contentType", contentType);
- context.startService(intent);
- }
-}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index b386f52..339f2d8 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -134,12 +134,33 @@
android:hint="30"
android:inputType="number" />
+
+
+
+
+ android:text="Save and Start" />
+
+
\ No newline at end of file