diff --git a/ic_launcher-web.png b/ic_launcher-web.png
new file mode 100644
index 0000000..a169e78
Binary files /dev/null and b/ic_launcher-web.png differ
diff --git a/res/menu/main.xml b/res/menu/main.xml
new file mode 100644
index 0000000..30213a9
--- /dev/null
+++ b/res/menu/main.xml
@@ -0,0 +1,13 @@
+
diff --git a/res/values-en/strings.xml b/res/values-en/strings.xml
index 9011565..45750f6 100644
--- a/res/values-en/strings.xml
+++ b/res/values-en/strings.xml
@@ -27,7 +27,7 @@
-->
- 2
+ 3
@@ -131,5 +131,6 @@
Error #13: Unable to perform a connection to ownCloud instance
Error #14: Unable to parse server response
Error #15: Unable to parse server response
+ Error #16: No data connection available
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index c8b2a76..433b0ea 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -27,7 +27,7 @@
-->
- 2
+ 3
@@ -90,4 +90,6 @@
Processus de synchronisation
Synchonisation en cours...
Erreur fatale !
+
+ Erreur #16: Aucune connexion data disponible
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d6cfa6c..adcabad 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -27,7 +27,7 @@
-->
- 2
+ 3
ownCloud-SMS
@@ -142,5 +142,6 @@
Error #13: Unable to perform a connection to ownCloud instance
Error #14: Unable to parse server response
Error #15: Unable to parse server response
+ Error #16: No data connection available
diff --git a/src/fr/unix_experience/owncloud_sms/broadcast_receivers/ConnectivityChanged.java b/src/fr/unix_experience/owncloud_sms/broadcast_receivers/ConnectivityChanged.java
index 335d970..55fe4fa 100644
--- a/src/fr/unix_experience/owncloud_sms/broadcast_receivers/ConnectivityChanged.java
+++ b/src/fr/unix_experience/owncloud_sms/broadcast_receivers/ConnectivityChanged.java
@@ -1,30 +1,63 @@
package fr.unix_experience.owncloud_sms.broadcast_receivers;
+/*
+ * Copyright (c) 2014, Loic Blot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import org.json.JSONArray;
+
+import fr.unix_experience.owncloud_sms.engine.ASyncTask;
+import fr.unix_experience.owncloud_sms.engine.ConnectivityMonitor;
+import fr.unix_experience.owncloud_sms.engine.SmsFetcher;
+import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.util.Log;
-public class ConnectivityChanged extends BroadcastReceiver {
+public class ConnectivityChanged extends BroadcastReceiver implements ASyncTask {
@Override
- public void onReceive(Context context, Intent intent) {
- // Check the connectivity
- final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
- final android.net.NetworkInfo niWiFi = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- final android.net.NetworkInfo niMobile = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
-
+ public void onReceive(Context context, Intent intent) {
+ ConnectivityMonitor cMon = new ConnectivityMonitor(context);
// If data is available and previous dataConnectionState was false, then we need to sync
- if ((niWiFi.isAvailable() || niMobile.isAvailable()) && dataConnectionAvailable == false) {
+ if (cMon.isValid() && dataConnectionAvailable == false) {
dataConnectionAvailable = true;
Log.d(TAG,"ConnectivityChanged.onReceive, data conn available");
- // @TODO: check if last message is last synced msg (shared preference)
+ checkMessagesToSent(context);
}
// No data available and previous dataConnectionState was true
- else if (dataConnectionAvailable == true && !niWiFi.isAvailable() && !niMobile.isAvailable()) {
+ else if (dataConnectionAvailable == true && !cMon.isValid()) {
dataConnectionAvailable = false;
+ Log.d(TAG,"ConnectivityChanges.onReceive: data conn is off");
+ }
+ }
+
+ private void checkMessagesToSent(Context context) {
+ // Get last message synced from preferences
+ Long lastMessageSynced = (new OCSMSSharedPrefs(context)).getLastMessageDate();
+ Log.d(TAG,"Synced Last:" + lastMessageSynced);
+
+ // Now fetch messages since last stored date
+ JSONArray smsList = new SmsFetcher(context).bufferizeMessagesSinceDate(lastMessageSynced);
+ Log.d(TAG,"smsList " + smsList.toString());
+
+ if (smsList != null) {
+ new SyncTask(context, smsList).execute();
}
}
diff --git a/src/fr/unix_experience/owncloud_sms/engine/ASyncTask.java b/src/fr/unix_experience/owncloud_sms/engine/ASyncTask.java
new file mode 100644
index 0000000..e8a6ed3
--- /dev/null
+++ b/src/fr/unix_experience/owncloud_sms/engine/ASyncTask.java
@@ -0,0 +1,65 @@
+package fr.unix_experience.owncloud_sms.engine;
+
+/*
+ * Copyright (c) 2014, Loic Blot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import org.json.JSONArray;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Context;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.util.Log;
+import fr.unix_experience.owncloud_sms.R;
+import fr.unix_experience.owncloud_sms.exceptions.OCSyncException;
+
+public interface ASyncTask {
+ class SyncTask extends AsyncTask{
+ public SyncTask(Context context, JSONArray smsList) {
+ _context = context;
+ _smsList = smsList;
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ // Get ownCloud SMS account list
+ AccountManager _accountMgr = AccountManager.get(_context);
+
+ Account[] myAccountList = _accountMgr.getAccountsByType(_context.getString(R.string.account_type));
+ for (int i = 0; i < myAccountList.length; i++) {
+ Uri serverURI = Uri.parse(_accountMgr.getUserData(myAccountList[i], "ocURI"));
+
+ OCSMSOwnCloudClient _client = new OCSMSOwnCloudClient(_context,
+ serverURI, _accountMgr.getUserData(myAccountList[i], "ocLogin"),
+ _accountMgr.getPassword(myAccountList[i]));
+
+ try {
+ _client.doPushRequest(_smsList);
+ } catch (OCSyncException e) {
+ Log.e(TAG, _context.getString(e.getErrorId()));
+ }
+ }
+ return null;
+ }
+
+ private Context _context;
+ private JSONArray _smsList;
+ }
+
+ static final String TAG = ASyncTask.class.getSimpleName();
+}
diff --git a/src/fr/unix_experience/owncloud_sms/engine/ConnectivityMonitor.java b/src/fr/unix_experience/owncloud_sms/engine/ConnectivityMonitor.java
new file mode 100644
index 0000000..e5101a9
--- /dev/null
+++ b/src/fr/unix_experience/owncloud_sms/engine/ConnectivityMonitor.java
@@ -0,0 +1,29 @@
+package fr.unix_experience.owncloud_sms.engine;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+
+public class ConnectivityMonitor {
+ public ConnectivityMonitor(Context context) {
+ _context = context;
+ }
+
+ // Valid connection = WiFi or Mobile data
+ public boolean isValid() {
+ if (_cMgr == null) {
+ _cMgr = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ }
+
+ final android.net.NetworkInfo niWiFi = _cMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ final android.net.NetworkInfo niMobile = _cMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+
+ if (niWiFi.isAvailable() || niMobile.isAvailable()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private ConnectivityManager _cMgr;
+ private Context _context;
+}
diff --git a/src/fr/unix_experience/owncloud_sms/engine/OCSMSOwnCloudClient.java b/src/fr/unix_experience/owncloud_sms/engine/OCSMSOwnCloudClient.java
index 9440aea..4dc2272 100644
--- a/src/fr/unix_experience/owncloud_sms/engine/OCSMSOwnCloudClient.java
+++ b/src/fr/unix_experience/owncloud_sms/engine/OCSMSOwnCloudClient.java
@@ -32,7 +32,6 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
-import android.content.SharedPreferences;
import android.net.Uri;
import android.util.Log;
@@ -274,10 +273,19 @@ public class OCSMSOwnCloudClient {
// We try maximumHttpReqTries because sometimes network is slow or unstable
int tryNb = 0;
+ ConnectivityMonitor cMon = new ConnectivityMonitor(_context);
while (tryNb < maximumHttpReqTries) {
tryNb++;
+ if (!cMon.isValid()) {
+ if (tryNb == maximumHttpReqTries) {
+ req.releaseConnection();
+ throw new OCSyncException(R.string.err_sync_no_connection_available, OCSyncErrorType.IO);
+ }
+ continue;
+ }
+
try {
status = _ocClient.executeMethod(req);
diff --git a/src/fr/unix_experience/owncloud_sms/engine/SmsFetcher.java b/src/fr/unix_experience/owncloud_sms/engine/SmsFetcher.java
index 9d8f466..2873664 100644
--- a/src/fr/unix_experience/owncloud_sms/engine/SmsFetcher.java
+++ b/src/fr/unix_experience/owncloud_sms/engine/SmsFetcher.java
@@ -17,7 +17,6 @@ package fr.unix_experience.owncloud_sms.engine;
* along with this program. If not, see .
*/
-import java.util.Date;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -40,47 +39,34 @@ public class SmsFetcher {
public JSONArray fetchAllMessages() {
_jsonDataDump = new JSONArray();
- fetchInboxMessages();
- fetchSentMessages();
- fetchDraftMessages();
+ bufferizeMailboxMessages(MailboxID.INBOX);
+ bufferizeMailboxMessages(MailboxID.SENT);
+ bufferizeMailboxMessages(MailboxID.DRAFTS);
return _jsonDataDump;
}
- public void fetchInboxMessages() {
- bufferizeMailboxMessages("content://sms/inbox", MailboxID.INBOX);
- }
-
- public void fetchSentMessages() {
- bufferizeMailboxMessages("content://sms/sent", MailboxID.SENT);
- }
-
- public void fetchDraftMessages() {
- bufferizeMailboxMessages("content://sms/drafts", MailboxID.DRAFTS);
- }
-
- private void bufferizeMailboxMessages(String _mb, MailboxID _mbID) {
- if (_context == null || _mb.length() == 0) {
+ private void bufferizeMailboxMessages(MailboxID mbID) {
+ String mbURI = mapMailboxIDToURI(mbID);
+
+ if (_context == null || mbURI == null) {
return;
}
- if (_mbID != MailboxID.INBOX && _mbID != MailboxID.SENT &&
- _mbID != MailboxID.DRAFTS) {
- Log.e(TAG,"Unhandled MailboxID " + _mbID.ordinal());
+ if (mbID != MailboxID.INBOX && mbID != MailboxID.SENT &&
+ mbID != MailboxID.DRAFTS) {
+ Log.e(TAG,"Unhandled MailboxID " + mbID.ordinal());
return;
}
-
- Date startDate = new Date();
- // Fetch Sent SMS Message from Built-in Content Provider
-
+
// We generate a ID list for this message box
- String existingIDs = buildExistingMessagesString(_mbID);
+ String existingIDs = buildExistingMessagesString(mbID);
Cursor c = null;
if (existingIDs.length() > 0) {
- c = (new SmsDataProvider(_context)).query(_mb, "_id NOT IN (" + existingIDs + ")");
+ c = (new SmsDataProvider(_context)).query(mbURI, "_id NOT IN (" + existingIDs + ")");
}
else {
- c = (new SmsDataProvider(_context)).query(_mb);
+ c = (new SmsDataProvider(_context)).query(mbURI);
}
// Reading mailbox
@@ -90,8 +76,6 @@ public class SmsFetcher {
JSONObject entry = new JSONObject();
try {
- // Reading each mail element
- int msgId = -1;
for(int idx=0;idxgetMailboxMessages() Time spent: " + diffInMs + "ms");
}
// Used by Content Observer
- public JSONArray getLastMessage(String _mb) {
- if (_context == null || _mb.length() == 0) {
+ public JSONArray getLastMessage(MailboxID mbID) {
+ String mbURI = mapMailboxIDToURI(mbID);
+
+ if (_context == null || mbURI == null) {
return null;
}
-
+
// Fetch Sent SMS Message from Built-in Content Provider
- Cursor c = (new SmsDataProvider(_context)).query(_mb);
+ Cursor c = (new SmsDataProvider(_context)).query(mbURI);
c.moveToNext();
@@ -184,11 +165,8 @@ public class SmsFetcher {
}
// Mailbox ID is required by server
- switch (entry.getInt("type")) {
- case 1: entry.put("mbox", MailboxID.INBOX.ordinal()); break;
- case 2: entry.put("mbox", MailboxID.SENT.ordinal()); break;
- case 3: entry.put("mbox", MailboxID.DRAFTS.ordinal()); break;
- }
+ entry.put("mbox", mbID.ordinal());
+
results.put(entry);
} catch (JSONException e) {
Log.e(TAG, "JSON Exception when reading SMS Mailbox", e);
@@ -200,6 +178,96 @@ public class SmsFetcher {
return results;
}
+ // Used by ConnectivityChanged Event
+ public JSONArray bufferizeMessagesSinceDate(Long sinceDate) {
+ _jsonDataDump = new JSONArray();
+ bufferizeMessagesSinceDate(MailboxID.INBOX, sinceDate);
+ bufferizeMessagesSinceDate(MailboxID.SENT, sinceDate);
+ bufferizeMessagesSinceDate(MailboxID.DRAFTS, sinceDate);
+ return _jsonDataDump;
+ }
+
+ // Used by ConnectivityChanged Event
+ public void bufferizeMessagesSinceDate(MailboxID mbID, Long sinceDate) {
+ String mbURI = mapMailboxIDToURI(mbID);
+
+ if (_context == null || mbURI == null) {
+ return;
+ }
+
+ Cursor c = (new SmsDataProvider(_context)).query(mbURI, "date > " + sinceDate);
+
+ // Reading mailbox
+ if (c != null && c.getCount() > 0) {
+ c.moveToFirst();
+ do {
+ JSONObject entry = new JSONObject();
+
+ try {
+ for(int idx=0;idx 0 ? "true" : "false");
+ }
+ else {
+ // Special case for date, we need to record last without searching
+ if (colName.equals(new String("date"))) {
+ final Long tmpDate = c.getLong(idx);
+ if (tmpDate > _lastMsgDate) {
+ _lastMsgDate = tmpDate;
+ }
+ }
+ entry.put(colName, c.getString(idx));
+ }
+ }
+
+ // Mailbox ID is required by server
+ entry.put("mbox", mbID.ordinal());
+
+ _jsonDataDump.put(entry);
+
+ } catch (JSONException e) {
+ Log.e(TAG, "JSON Exception when reading SMS Mailbox", e);
+ c.close();
+ }
+ }
+ while(c.moveToNext());
+
+ Log.d(TAG, c.getCount() + " messages read from " + mbURI);
+
+ c.close();
+ }
+ }
+
+ private String mapMailboxIDToURI(MailboxID mbID) {
+ if (mbID == MailboxID.INBOX) {
+ return "content://sms/inbox";
+ }
+ else if (mbID == MailboxID.DRAFTS) {
+ return "content://sms/drafts";
+ }
+ else if (mbID == MailboxID.SENT) {
+ return "content://sms/sent";
+ }
+ else if (mbID == MailboxID.ALL) {
+ return "content://sms";
+ }
+
+ return null;
+ }
+
private String buildExistingMessagesString(MailboxID _mbID) {
JSONArray existingMessages = null;
if (_mbID == MailboxID.INBOX) {
diff --git a/src/fr/unix_experience/owncloud_sms/enums/MailboxID.java b/src/fr/unix_experience/owncloud_sms/enums/MailboxID.java
index f77f84d..b6dbe01 100644
--- a/src/fr/unix_experience/owncloud_sms/enums/MailboxID.java
+++ b/src/fr/unix_experience/owncloud_sms/enums/MailboxID.java
@@ -29,4 +29,5 @@ public enum MailboxID {
INBOX,
SENT,
DRAFTS,
+ ALL,
}
diff --git a/src/fr/unix_experience/owncloud_sms/observers/SmsObserver.java b/src/fr/unix_experience/owncloud_sms/observers/SmsObserver.java
index 6768b0d..0be1ca7 100644
--- a/src/fr/unix_experience/owncloud_sms/observers/SmsObserver.java
+++ b/src/fr/unix_experience/owncloud_sms/observers/SmsObserver.java
@@ -19,20 +19,16 @@ package fr.unix_experience.owncloud_sms.observers;
import org.json.JSONArray;
-import fr.unix_experience.owncloud_sms.R;
+import fr.unix_experience.owncloud_sms.engine.ASyncTask;
import fr.unix_experience.owncloud_sms.engine.OCSMSOwnCloudClient;
import fr.unix_experience.owncloud_sms.engine.SmsFetcher;
-import fr.unix_experience.owncloud_sms.exceptions.OCSyncException;
-import android.accounts.Account;
-import android.accounts.AccountManager;
+import fr.unix_experience.owncloud_sms.enums.MailboxID;
import android.content.Context;
import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
-public class SmsObserver extends ContentObserver {
+public class SmsObserver extends ContentObserver implements ASyncTask {
public SmsObserver(Handler handler) {
super(handler);
@@ -46,53 +42,20 @@ public class SmsObserver extends ContentObserver {
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.d(TAG, "onChange SmsObserver");
-
- if (_accountMgr == null && _context != null) {
- _accountMgr = AccountManager.get(_context);
- }
- String smsURI = "content://sms";
-
- SmsFetcher sFetch = new SmsFetcher(_context);
- JSONArray smsList = sFetch.getLastMessage(smsURI);
+
+ SmsFetcher fetcher = new SmsFetcher(_context);
+ JSONArray smsList = fetcher.getLastMessage(MailboxID.ALL);
if (smsList != null) {
- new SyncTask(smsList).execute();
+ new SyncTask(_context, smsList).execute();
}
}
-
- private class SyncTask extends AsyncTask{
- public SyncTask(JSONArray smsList) {
- _smsList = smsList;
- }
- @Override
- protected Void doInBackground(Void... params) {
- // Get ownCloud SMS account list
- Account[] myAccountList = _accountMgr.getAccountsByType(_context.getString(R.string.account_type));
- for (int i = 0; i < myAccountList.length; i++) {
- Log.d(TAG, "int i = 0; i < myAccountList.length; i++" + myAccountList[i] + " SmsObserver");
- Uri serverURI = Uri.parse(_accountMgr.getUserData(myAccountList[i], "ocURI"));
-
- OCSMSOwnCloudClient _client = new OCSMSOwnCloudClient(_context,
- serverURI, _accountMgr.getUserData(myAccountList[i], "ocLogin"),
- _accountMgr.getPassword(myAccountList[i]));
-
- try {
- _client.doPushRequest(_smsList);
- } catch (OCSyncException e) {
- Log.e(TAG, _context.getString(e.getErrorId()));
- }
- }
- return null;
- }
- private JSONArray _smsList;
- }
public void setContext(Context context) {
_context = context;
}
private Context _context;
- private static AccountManager _accountMgr;
private static final String TAG = OCSMSOwnCloudClient.class.getSimpleName();
}