diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7489cd6..f43e1e6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -103,9 +103,10 @@
+
diff --git a/app/src/main/java/ch/dissem/apps/abit/MessageListActivity.java b/app/src/main/java/ch/dissem/apps/abit/MessageListActivity.java
index dbe16ea..bc40eec 100644
--- a/app/src/main/java/ch/dissem/apps/abit/MessageListActivity.java
+++ b/app/src/main/java/ch/dissem/apps/abit/MessageListActivity.java
@@ -2,27 +2,15 @@ package ch.dissem.apps.abit;
import android.accounts.Account;
import android.accounts.AccountManager;
-import android.content.Context;
+import android.content.ContentResolver;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
-
-import ch.dissem.apps.abit.listeners.ActionBarListener;
-import ch.dissem.apps.abit.listeners.ListSelectionListener;
-import ch.dissem.apps.abit.service.Singleton;
-import ch.dissem.apps.abit.synchronization.Authenticator;
-import ch.dissem.apps.abit.synchronization.SyncAdapter;
-import ch.dissem.bitmessage.BitmessageContext;
-import ch.dissem.bitmessage.entity.BitmessageAddress;
-import ch.dissem.bitmessage.entity.Plaintext;
-import ch.dissem.bitmessage.entity.Streamable;
-import ch.dissem.bitmessage.entity.valueobject.Label;
+import android.widget.CompoundButton;
import com.mikepenz.community_material_typeface_library.CommunityMaterial;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
@@ -34,10 +22,11 @@ import com.mikepenz.materialdrawer.accountswitcher.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem;
-import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
+import com.mikepenz.materialdrawer.model.SwitchDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IProfile;
import com.mikepenz.materialdrawer.model.interfaces.Nameable;
+import com.mikepenz.materialdrawer.model.interfaces.OnCheckedChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,6 +34,17 @@ import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList;
+import ch.dissem.apps.abit.listeners.ActionBarListener;
+import ch.dissem.apps.abit.listeners.ListSelectionListener;
+import ch.dissem.apps.abit.service.Singleton;
+import ch.dissem.apps.abit.synchronization.Authenticator;
+import ch.dissem.bitmessage.BitmessageContext;
+import ch.dissem.bitmessage.entity.BitmessageAddress;
+import ch.dissem.bitmessage.entity.Plaintext;
+import ch.dissem.bitmessage.entity.valueobject.Label;
+
+import static ch.dissem.apps.abit.synchronization.StubProvider.AUTHORITY;
+
/**
* An activity representing a list of Messages. This activity
@@ -69,10 +69,9 @@ public class MessageListActivity extends AppCompatActivity
public static final String ACTION_SHOW_INBOX = "ch.dissem.abit.ShowInbox";
private static final Logger LOG = LoggerFactory.getLogger(MessageListActivity.class);
+ private static final long SYNC_FREQUENCY = 15 * 60; // seconds
private static final int ADD_IDENTITY = 1;
- private Account account;
-
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
@@ -82,7 +81,6 @@ public class MessageListActivity extends AppCompatActivity
private AccountHeader accountHeader;
private BitmessageContext bmc;
private Label selectedLabel;
- private Menu menu;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -119,39 +117,22 @@ public class MessageListActivity extends AppCompatActivity
onItemSelected(getIntent().getSerializableExtra(EXTRA_SHOW_MESSAGE));
}
- account = createSyncAccount(this);
- getContentResolver().setSyncAutomatically(account, SyncAdapter.AUTHORITY, true);
+ createSyncAccount();
}
- private Account createSyncAccount(Context context) {
- // Create the account type and default account
- Account newAccount = new Account(Authenticator.ACCOUNT_NAME, Authenticator.ACCOUNT_TYPE);
- // Get an instance of the Android account manager
- AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE);
- /*
- * Add the account and account type, no password or user data
- * If successful, return the Account object, otherwise report an error.
- */
- if (accountManager.addAccountExplicitly(newAccount, null, null)) {
- /*
- * If you don't set android:syncable="true" in
- * in your element in the manifest,
- * then call context.setIsSyncable(account, AUTHORITY, 1)
- * here.
- */
- } else {
- /*
- * The account exists or some other error occurred. Log this, report it,
- * or handle it internally.
- */
- LOG.error("Couldn't add account");
+ private void createSyncAccount() {
+ // Create account, if it's missing. (Either first run, or user has deleted account.)
+ Account account = new Account(Authenticator.ACCOUNT_NAME, Authenticator.ACCOUNT_TYPE);
+
+ if (AccountManager.get(this).addAccountExplicitly(account, null, null)) {
+ // Inform the system that this account supports sync
+ ContentResolver.setIsSyncable(account, AUTHORITY, 1);
+ // Inform the system that this account is eligible for auto sync when the network is up
+ ContentResolver.setSyncAutomatically(account, AUTHORITY, true);
+ // Recommend a schedule for automatic synchronization. The system may modify this based
+ // on other scheduled syncs and network utilization.
+ ContentResolver.addPeriodicSync(account, AUTHORITY, new Bundle(), SYNC_FREQUENCY);
}
- return newAccount;
- }
-
- @Override
- protected void onResume() {
- super.onResume();
}
private void changeList(AbstractItemListFragment> listFragment) {
@@ -253,12 +234,24 @@ public class MessageListActivity extends AppCompatActivity
.withAccountHeader(accountHeader)
.withDrawerItems(drawerItems)
.addStickyDrawerItems(
- new SecondaryDrawerItem()
+ new PrimaryDrawerItem()
.withName(R.string.subscriptions)
.withIcon(CommunityMaterial.Icon.cmd_rss_box),
- new SecondaryDrawerItem()
+ new PrimaryDrawerItem()
.withName(R.string.settings)
- .withIcon(GoogleMaterial.Icon.gmd_settings)
+ .withIcon(GoogleMaterial.Icon.gmd_settings),
+ new SwitchDrawerItem()
+ .withName(R.string.full_node)
+ .withIcon(CommunityMaterial.Icon.cmd_cloud_outline)
+ .withOnCheckedChangeListener(new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(IDrawerItem drawerItem, CompoundButton buttonView, boolean isChecked) {
+ // TODO: warn user, option to restrict to WiFi
+ if (isChecked && !bmc.isRunning()) bmc.startup();
+ else if (bmc.isRunning()) bmc.shutdown();
+ }
+ })
+ .withChecked(bmc.isRunning())
)
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
@Override
@@ -288,6 +281,8 @@ public class MessageListActivity extends AppCompatActivity
case R.string.settings:
startActivity(new Intent(MessageListActivity.this, SettingsActivity.class));
break;
+ case R.string.full_node:
+ return true;
}
}
return false;
@@ -297,36 +292,6 @@ public class MessageListActivity extends AppCompatActivity
.build();
}
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.main, menu);
- this.menu = menu;
- updateMenu();
- return true;
- }
-
- private void updateMenu() {
- boolean running = bmc.isRunning();
- menu.findItem(R.id.sync_enabled).setVisible(running);
- menu.findItem(R.id.sync_disabled).setVisible(!running);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.sync_disabled:
- bmc.startup();
- updateMenu();
- return true;
- case R.id.sync_enabled:
- bmc.shutdown();
- updateMenu();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
/**
* Callback method from {@link ListSelectionListener}
* indicating that the item with the given ID was selected.
diff --git a/app/src/main/java/ch/dissem/apps/abit/service/Singleton.java b/app/src/main/java/ch/dissem/apps/abit/service/Singleton.java
index 76c3301..e16b235 100644
--- a/app/src/main/java/ch/dissem/apps/abit/service/Singleton.java
+++ b/app/src/main/java/ch/dissem/apps/abit/service/Singleton.java
@@ -1,6 +1,5 @@
package ch.dissem.apps.abit.service;
-import android.app.NotificationManager;
import android.content.Context;
import ch.dissem.apps.abit.listeners.MessageListener;
diff --git a/app/src/main/java/ch/dissem/apps/abit/synchronization/StubProvider.java b/app/src/main/java/ch/dissem/apps/abit/synchronization/StubProvider.java
index c79f074..f5b3d2d 100644
--- a/app/src/main/java/ch/dissem/apps/abit/synchronization/StubProvider.java
+++ b/app/src/main/java/ch/dissem/apps/abit/synchronization/StubProvider.java
@@ -10,6 +10,8 @@ import android.net.Uri;
* all methods
*/
public class StubProvider extends ContentProvider {
+ public static final String AUTHORITY = "ch.dissem.apps.abit.provider";
+
/*
* Always return true, indicating that the
* provider loaded correctly.
@@ -18,6 +20,7 @@ public class StubProvider extends ContentProvider {
public boolean onCreate() {
return true;
}
+
/*
* Return no type for MIME type
*/
@@ -25,6 +28,7 @@ public class StubProvider extends ContentProvider {
public String getType(Uri uri) {
return null;
}
+
/*
* query() always returns no results
*
@@ -38,6 +42,7 @@ public class StubProvider extends ContentProvider {
String sortOrder) {
return null;
}
+
/*
* insert() always returns null (no URI)
*/
@@ -45,6 +50,7 @@ public class StubProvider extends ContentProvider {
public Uri insert(Uri uri, ContentValues values) {
return null;
}
+
/*
* delete() always returns "no rows affected" (0)
*/
@@ -52,6 +58,7 @@ public class StubProvider extends ContentProvider {
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
+
/*
* update() always returns "no rows affected" (0)
*/
diff --git a/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncAdapter.java b/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncAdapter.java
index 890b097..c12d30c 100644
--- a/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncAdapter.java
+++ b/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncAdapter.java
@@ -25,17 +25,32 @@ import ch.dissem.bitmessage.BitmessageContext;
public class SyncAdapter extends AbstractThreadedSyncAdapter {
private final static Logger LOG = LoggerFactory.getLogger(SyncAdapter.class);
- public static final String AUTHORITY = "ch.dissem.bitmessage.provider";
-
private final BitmessageContext bmc;
- public SyncAdapter(Context context) {
- super(context, true, false);
+ /**
+ * Set up the sync adapter
+ */
+ public SyncAdapter(Context context, boolean autoInitialize) {
+ super(context, autoInitialize);
+ bmc = Singleton.getBitmessageContext(context);
+ }
+
+ /**
+ * Set up the sync adapter. This form of the
+ * constructor maintains compatibility with Android 3.0
+ * and later platform versions
+ */
+ public SyncAdapter(
+ Context context,
+ boolean autoInitialize,
+ boolean allowParallelSyncs) {
+ super(context, autoInitialize, allowParallelSyncs);
bmc = Singleton.getBitmessageContext(context);
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
+ LOG.info("Synchronizing Bitmessage");
// If the Bitmessage context acts as a full node, synchronization isn't necessary
if (bmc.isRunning()) return;
@@ -52,7 +67,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
String portString = trustedNode.substring(index + 1);
trustedNode = trustedNode.substring(0, index);
try {
- port = Integer.parseInt(portString);// FIXME
+ port = Integer.parseInt(portString);
} catch (NumberFormatException e) {
LOG.error("Invalid port " + portString);
// TODO: show error as notification
diff --git a/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncService.java b/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncService.java
index fb6fd9f..4beaa04 100644
--- a/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncService.java
+++ b/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncService.java
@@ -27,7 +27,7 @@ public class SyncService extends Service {
*/
synchronized (syncAdapterLock) {
if (syncAdapter == null) {
- syncAdapter = new SyncAdapter(getApplicationContext());
+ syncAdapter = new SyncAdapter(getApplicationContext(), true);
}
}
}
diff --git a/app/src/main/res/menu/compose.xml b/app/src/main/res/menu/compose.xml
index ee25c89..dae8007 100644
--- a/app/src/main/res/menu/compose.xml
+++ b/app/src/main/res/menu/compose.xml
@@ -5,5 +5,5 @@
android:id="@+id/send"
app:showAsAction="always"
android:icon="@drawable/ic_action_send"
- android:title="@string/disable_sync"/>`
+ android:title="@string/send"/>`
\ No newline at end of file
diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml
index 9f35ce1..9eb7100 100644
--- a/app/src/main/res/menu/main.xml
+++ b/app/src/main/res/menu/main.xml
@@ -1,14 +1,4 @@
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index b86c0f8..43a43cc 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -5,8 +5,6 @@
Nur WLAN
Nicht mit Mobilfunknetz verbinden
Bitmessage ist aktiv
- Synchronisieren ausschalten
- Synchronisieren einschalten
Betreff
An
Nachricht
@@ -37,4 +35,7 @@
Timeout in Sekunden
Vertrauenswürdiger Knoten
Diese Adresse wird für die Synchronisation verwendet
+ Aktiver Knoten
+ Senden
+ Schreiben
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 72fa388..adf6794 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,8 +2,6 @@
Abit
Message Detail
Subscription Detail
- Disable Sync
- Enable Sync
Bitmessage active
Wi-Fi Connection Mode
Settings
@@ -38,4 +36,6 @@
Synchronization Timeout
Timeout in seconds
Write message
+ Full node
+ Send