diff --git a/app/build.gradle b/app/build.gradle index 01ba6f9..99299a0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -36,6 +36,9 @@ dependencies { compile('com.mikepenz:materialdrawer:3.1.0@aar') { transitive = true } + compile('com.mikepenz:aboutlibraries:5.3.4@aar') { + transitive = true + } compile 'com.mikepenz:iconics:1.6.2@aar' compile 'com.mikepenz:community-material-typeface:1.1.71@aar' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 979915d..4f64223 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" package="ch.dissem.apps.abit"> + @@ -128,6 +129,13 @@ + + + + + + + diff --git a/app/src/main/java/ch/dissem/apps/abit/MainActivity.java b/app/src/main/java/ch/dissem/apps/abit/MainActivity.java index 5d7bee8..1d2a418 100644 --- a/app/src/main/java/ch/dissem/apps/abit/MainActivity.java +++ b/app/src/main/java/ch/dissem/apps/abit/MainActivity.java @@ -1,10 +1,9 @@ package ch.dissem.apps.abit; -import android.accounts.Account; -import android.accounts.AccountManager; +import android.app.AlertDialog; import android.content.ComponentName; -import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; @@ -49,7 +48,6 @@ import ch.dissem.apps.abit.listener.ActionBarListener; import ch.dissem.apps.abit.listener.ListSelectionListener; import ch.dissem.apps.abit.service.BitmessageService; import ch.dissem.apps.abit.service.Singleton; -import ch.dissem.apps.abit.synchronization.Authenticator; import ch.dissem.apps.abit.synchronization.SyncAdapter; import ch.dissem.apps.abit.util.Preferences; import ch.dissem.bitmessage.entity.BitmessageAddress; @@ -61,7 +59,6 @@ import ch.dissem.bitmessage.ports.MessageRepository; import static ch.dissem.apps.abit.service.BitmessageService.DATA_FIELD_IDENTITY; import static ch.dissem.apps.abit.service.BitmessageService.MSG_START_NODE; import static ch.dissem.apps.abit.service.BitmessageService.MSG_STOP_NODE; -import static ch.dissem.apps.abit.synchronization.StubProvider.AUTHORITY; /** @@ -300,12 +297,7 @@ public class MainActivity extends AppCompatActivity boolean isChecked) { if (messenger != null) { if (isChecked) { - try { - service.send(Message.obtain(null, - MSG_START_NODE)); - } catch (RemoteException e) { - LOG.error(e.getMessage(), e); - } + checkAndStartNode(buttonView); } else { try { service.send(Message.obtain(null, @@ -358,6 +350,37 @@ public class MainActivity extends AppCompatActivity .build(); } + private void checkAndStartNode(final CompoundButton buttonView) { + if (Preferences.isConnectionAllowed(MainActivity.this)) { + forceStartNode(); + } else { + new AlertDialog.Builder(MainActivity.this) + .setMessage(R.string.full_node_warning) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + forceStartNode(); + } + }) + .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + buttonView.setChecked(false); + } + }) + .show(); + } + } + + private void forceStartNode() { + try { + service.send(Message.obtain(null, + MSG_START_NODE)); + } catch (RemoteException e) { + LOG.error(e.getMessage(), e); + } + } + private void showSelectedLabel() { if (getSupportFragmentManager().findFragmentById(R.id.item_list) instanceof MessageListFragment) { diff --git a/app/src/main/java/ch/dissem/apps/abit/SettingsFragment.java b/app/src/main/java/ch/dissem/apps/abit/SettingsFragment.java index 75bd0bc..d92ac68 100644 --- a/app/src/main/java/ch/dissem/apps/abit/SettingsFragment.java +++ b/app/src/main/java/ch/dissem/apps/abit/SettingsFragment.java @@ -3,9 +3,13 @@ package ch.dissem.apps.abit; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; +import android.preference.Preference; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; +import com.mikepenz.aboutlibraries.Libs; +import com.mikepenz.aboutlibraries.LibsBuilder; + import ch.dissem.apps.abit.synchronization.SyncAdapter; import static ch.dissem.apps.abit.util.Constants.PREFERENCE_SERVER_POW; @@ -23,6 +27,20 @@ public class SettingsFragment // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); + + Preference about = findPreference("about"); + about.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + new LibsBuilder() + .withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR) + .withAboutIconShown(true) + .withAboutVersionShown(true) + .withAboutDescription(getString(R.string.about_app)) + .start(getActivity()); + return true; + } + }); } @Override diff --git a/app/src/main/java/ch/dissem/apps/abit/listener/WifiReceiver.java b/app/src/main/java/ch/dissem/apps/abit/listener/WifiReceiver.java new file mode 100644 index 0000000..ca34809 --- /dev/null +++ b/app/src/main/java/ch/dissem/apps/abit/listener/WifiReceiver.java @@ -0,0 +1,39 @@ +package ch.dissem.apps.abit.listener; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.wifi.SupplicantState; +import android.net.wifi.WifiManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.dissem.apps.abit.service.Singleton; +import ch.dissem.apps.abit.util.Preferences; +import ch.dissem.bitmessage.BitmessageContext; + +public class WifiReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context ctx, Intent intent) { + if (Preferences.isWifiOnly(ctx)) { + BitmessageContext bmc = Singleton.getBitmessageContext(ctx); + ConnectivityManager conMan = (ConnectivityManager) ctx.getSystemService(Context + .CONNECTIVITY_SERVICE); + NetworkInfo netInfo = conMan.getActiveNetworkInfo(); + + if (netInfo != null && netInfo.getType() != ConnectivityManager.TYPE_WIFI + && !bmc.isRunning()) { + bmc.shutdown(); + } + } + } + + public static boolean isConnectedToWifi(Context ctx) { + WifiManager wifiManager = (WifiManager) ctx.getSystemService(Context.WIFI_SERVICE); + SupplicantState state = wifiManager.getConnectionInfo().getSupplicantState(); + return state == SupplicantState.COMPLETED; + } +} \ No newline at end of file diff --git a/app/src/main/java/ch/dissem/apps/abit/service/BitmessageService.java b/app/src/main/java/ch/dissem/apps/abit/service/BitmessageService.java index d2184fd..5c81472 100644 --- a/app/src/main/java/ch/dissem/apps/abit/service/BitmessageService.java +++ b/app/src/main/java/ch/dissem/apps/abit/service/BitmessageService.java @@ -157,12 +157,17 @@ public class BitmessageService extends Service { // (I'm not quite sure this can be done here, though) service.get().startService(new Intent(service.get(), BitmessageService.class)); running = true; - service.get().startForeground(ONGOING_NOTIFICATION_ID, notification.getNotification()); - bmc.startup(); + service.get().startForeground(ONGOING_NOTIFICATION_ID, notification + .getNotification()); + if (!bmc.isRunning()) { + bmc.startup(); + } notification.show(); break; case MSG_STOP_NODE: - bmc.shutdown(); + if (bmc.isRunning()) { + bmc.shutdown(); + } running = false; service.get().stopForeground(false); service.get().stopSelf(); 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 682e165..7655044 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 @@ -52,12 +52,15 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter { @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { - if (account.equals(Authenticator.ACCOUNT_SYNC)) - syncData(); - else if (account.equals(Authenticator.ACCOUNT_POW)) + if (account.equals(Authenticator.ACCOUNT_SYNC)) { + if (Preferences.isConnectionAllowed(getContext())) { + syncData(); + } + } else if (account.equals(Authenticator.ACCOUNT_POW)) { syncPOW(); - else + } else { throw new RuntimeException("Unknown " + account); + } } private void syncData() { diff --git a/app/src/main/java/ch/dissem/apps/abit/util/Preferences.java b/app/src/main/java/ch/dissem/apps/abit/util/Preferences.java index 20c5862..df5b1c7 100644 --- a/app/src/main/java/ch/dissem/apps/abit/util/Preferences.java +++ b/app/src/main/java/ch/dissem/apps/abit/util/Preferences.java @@ -11,14 +11,15 @@ import java.net.InetAddress; import java.net.UnknownHostException; import ch.dissem.apps.abit.R; +import ch.dissem.apps.abit.listener.WifiReceiver; import ch.dissem.apps.abit.notification.ErrorNotification; -import static ch.dissem.apps.abit.util.Constants.PREFERENCE_SERVER_POW; import static ch.dissem.apps.abit.util.Constants.PREFERENCE_SYNC_TIMEOUT; import static ch.dissem.apps.abit.util.Constants.PREFERENCE_TRUSTED_NODE; +import static ch.dissem.apps.abit.util.Constants.PREFERENCE_WIFI_ONLY; /** - * Created by chrig on 01.12.2015. + * @author Christian Basler */ public class Preferences { private static Logger LOG = LoggerFactory.getLogger(Preferences.class); @@ -77,14 +78,18 @@ public class Preferences { return preference == null ? 120 : Long.parseLong(preference); } - public static boolean isServerPOW(Context ctx) { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx); - return preferences.getBoolean(PREFERENCE_SERVER_POW, false); - } - private static String getPreference(Context ctx, String name) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx); return preferences.getString(name, null); } + + public static boolean isConnectionAllowed(Context ctx) { + return !isWifiOnly(ctx) || WifiReceiver.isConnectedToWifi(ctx); + } + + public static boolean isWifiOnly(Context ctx) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx); + return preferences.getBoolean(PREFERENCE_WIFI_ONLY, true); + } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 19fda0d..694b211 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -51,4 +51,5 @@ Abonniert Server POW Der vertrauenswürdige Knoten macht den Proof of Work + Ein aktiver Bitmessage-Knoten muss viel hoch- und herunterladen, was auf einem mobilen Netzwerk teuer sein kann. Soll tatsächlich ein aktiver Knoten gestartet werden? \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index eb1f6e8..2920668 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -10,4 +10,9 @@ #727272 #212121 #B6B6B6 + + + @color/primary + @color/primary_dark + @color/accent diff --git a/app/src/main/res/values/library_jabit_strings.xml b/app/src/main/res/values/library_jabit_strings.xml new file mode 100644 index 0000000..bd4220c --- /dev/null +++ b/app/src/main/res/values/library_jabit_strings.xml @@ -0,0 +1,20 @@ + + + + + Christian Basler + dissem.ch + + Jabit + Jabit strives to be an easy to use Bitmessage library for Java developers to quickly implement their own Bitmessage clients. + https://github.com/Dissem/Jabit/wiki + 1.0.0 + + true + https://github.com/Dissem/Jabit + + ch.dissem.bitmessage.BitmessageContext + + apache_2_0 + + \ 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 19fd4f8..5746bbd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,6 @@ Abit + A Bitmessage client for Android Message Detail Subscription Detail Bitmessage Node @@ -51,4 +52,7 @@ Subscribed Server POW Trusted node does proof of work + Running a full Bitmessage uses a lot of traffic, which could be expensive on a mobile network. Are you sure you want to start a full node? + About Abit + Open source dependencies. diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 50fea51..696d443 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -31,4 +31,9 @@ android:title="@string/server_pow" android:summary="@string/server_pow_summary" /> + \ No newline at end of file