Implemented option to only use WiFi
This commit is contained in:
		| @@ -3,6 +3,7 @@ | |||||||
|     xmlns:tools="http://schemas.android.com/tools" |     xmlns:tools="http://schemas.android.com/tools" | ||||||
|     package="ch.dissem.apps.abit"> |     package="ch.dissem.apps.abit"> | ||||||
|  |  | ||||||
|  |     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> | ||||||
|     <uses-permission android:name="android.permission.INTERNET" /> |     <uses-permission android:name="android.permission.INTERNET" /> | ||||||
|     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> |     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | ||||||
|     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||||||
| @@ -128,6 +129,13 @@ | |||||||
|             <meta-data android:name="android.content.SyncAdapter" |             <meta-data android:name="android.content.SyncAdapter" | ||||||
|                 android:resource="@xml/syncadapter" /> |                 android:resource="@xml/syncadapter" /> | ||||||
|         </service> |         </service> | ||||||
|  |  | ||||||
|  |         <!-- Receive Wi-Fi connection state changes --> | ||||||
|  |         <receiver android:name=".listener.WifiReceiver"> | ||||||
|  |             <intent-filter> | ||||||
|  |                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> | ||||||
|  |             </intent-filter> | ||||||
|  |         </receiver> | ||||||
|     </application> |     </application> | ||||||
|  |  | ||||||
| </manifest> | </manifest> | ||||||
|   | |||||||
| @@ -1,10 +1,9 @@ | |||||||
| package ch.dissem.apps.abit; | package ch.dissem.apps.abit; | ||||||
|  |  | ||||||
| import android.accounts.Account; | import android.app.AlertDialog; | ||||||
| import android.accounts.AccountManager; |  | ||||||
| import android.content.ComponentName; | import android.content.ComponentName; | ||||||
| import android.content.ContentResolver; |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
|  | import android.content.DialogInterface; | ||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
| import android.content.ServiceConnection; | import android.content.ServiceConnection; | ||||||
| import android.os.Bundle; | 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.listener.ListSelectionListener; | ||||||
| import ch.dissem.apps.abit.service.BitmessageService; | import ch.dissem.apps.abit.service.BitmessageService; | ||||||
| import ch.dissem.apps.abit.service.Singleton; | 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.synchronization.SyncAdapter; | ||||||
| import ch.dissem.apps.abit.util.Preferences; | import ch.dissem.apps.abit.util.Preferences; | ||||||
| import ch.dissem.bitmessage.entity.BitmessageAddress; | 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.DATA_FIELD_IDENTITY; | ||||||
| import static ch.dissem.apps.abit.service.BitmessageService.MSG_START_NODE; | 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.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) { |                                                                  boolean isChecked) { | ||||||
|                                         if (messenger != null) { |                                         if (messenger != null) { | ||||||
|                                             if (isChecked) { |                                             if (isChecked) { | ||||||
|                                                 try { |                                                 checkAndStartNode(buttonView); | ||||||
|                                                     service.send(Message.obtain(null, |  | ||||||
|                                                             MSG_START_NODE)); |  | ||||||
|                                                 } catch (RemoteException e) { |  | ||||||
|                                                     LOG.error(e.getMessage(), e); |  | ||||||
|                                                 } |  | ||||||
|                                             } else { |                                             } else { | ||||||
|                                                 try { |                                                 try { | ||||||
|                                                     service.send(Message.obtain(null, |                                                     service.send(Message.obtain(null, | ||||||
| @@ -358,6 +350,37 @@ public class MainActivity extends AppCompatActivity | |||||||
|                 .build(); |                 .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() { |     private void showSelectedLabel() { | ||||||
|         if (getSupportFragmentManager().findFragmentById(R.id.item_list) instanceof |         if (getSupportFragmentManager().findFragmentById(R.id.item_list) instanceof | ||||||
|                 MessageListFragment) { |                 MessageListFragment) { | ||||||
|   | |||||||
| @@ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -157,12 +157,17 @@ public class BitmessageService extends Service { | |||||||
|                     // (I'm not quite sure this can be done here, though) |                     // (I'm not quite sure this can be done here, though) | ||||||
|                     service.get().startService(new Intent(service.get(), BitmessageService.class)); |                     service.get().startService(new Intent(service.get(), BitmessageService.class)); | ||||||
|                     running = true; |                     running = true; | ||||||
|                     service.get().startForeground(ONGOING_NOTIFICATION_ID, notification.getNotification()); |                     service.get().startForeground(ONGOING_NOTIFICATION_ID, notification | ||||||
|  |                             .getNotification()); | ||||||
|  |                     if (!bmc.isRunning()) { | ||||||
|                         bmc.startup(); |                         bmc.startup(); | ||||||
|  |                     } | ||||||
|                     notification.show(); |                     notification.show(); | ||||||
|                     break; |                     break; | ||||||
|                 case MSG_STOP_NODE: |                 case MSG_STOP_NODE: | ||||||
|  |                     if (bmc.isRunning()) { | ||||||
|                         bmc.shutdown(); |                         bmc.shutdown(); | ||||||
|  |                     } | ||||||
|                     running = false; |                     running = false; | ||||||
|                     service.get().stopForeground(false); |                     service.get().stopForeground(false); | ||||||
|                     service.get().stopSelf(); |                     service.get().stopSelf(); | ||||||
|   | |||||||
| @@ -52,13 +52,16 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter { | |||||||
|     @Override |     @Override | ||||||
|     public void onPerformSync(Account account, Bundle extras, String authority, |     public void onPerformSync(Account account, Bundle extras, String authority, | ||||||
|                               ContentProviderClient provider, SyncResult syncResult) { |                               ContentProviderClient provider, SyncResult syncResult) { | ||||||
|         if (account.equals(Authenticator.ACCOUNT_SYNC)) |         if (account.equals(Authenticator.ACCOUNT_SYNC)) { | ||||||
|  |             if (Preferences.isConnectionAllowed(getContext())) { | ||||||
|                 syncData(); |                 syncData(); | ||||||
|         else if (account.equals(Authenticator.ACCOUNT_POW)) |             } | ||||||
|  |         } else if (account.equals(Authenticator.ACCOUNT_POW)) { | ||||||
|             syncPOW(); |             syncPOW(); | ||||||
|         else |         } else { | ||||||
|             throw new RuntimeException("Unknown " + account); |             throw new RuntimeException("Unknown " + account); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private void syncData() { |     private void syncData() { | ||||||
|         // If the Bitmessage context acts as a full node, synchronization isn't necessary |         // If the Bitmessage context acts as a full node, synchronization isn't necessary | ||||||
|   | |||||||
| @@ -11,14 +11,15 @@ import java.net.InetAddress; | |||||||
| import java.net.UnknownHostException; | import java.net.UnknownHostException; | ||||||
|  |  | ||||||
| import ch.dissem.apps.abit.R; | import ch.dissem.apps.abit.R; | ||||||
|  | import ch.dissem.apps.abit.listener.WifiReceiver; | ||||||
| import ch.dissem.apps.abit.notification.ErrorNotification; | 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_SYNC_TIMEOUT; | ||||||
| import static ch.dissem.apps.abit.util.Constants.PREFERENCE_TRUSTED_NODE; | 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 { | public class Preferences { | ||||||
|     private static Logger LOG = LoggerFactory.getLogger(Preferences.class); |     private static Logger LOG = LoggerFactory.getLogger(Preferences.class); | ||||||
| @@ -77,14 +78,18 @@ public class Preferences { | |||||||
|         return preference == null ? 120 : Long.parseLong(preference); |         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) { |     private static String getPreference(Context ctx, String name) { | ||||||
|         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx); |         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx); | ||||||
|  |  | ||||||
|         return preferences.getString(name, null); |         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); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -51,4 +51,5 @@ | |||||||
|     <string name="subscribed">Abonniert</string> |     <string name="subscribed">Abonniert</string> | ||||||
|     <string name="server_pow">Server POW</string> |     <string name="server_pow">Server POW</string> | ||||||
|     <string name="server_pow_summary">Der vertrauenswürdige Knoten macht den Proof of Work</string> |     <string name="server_pow_summary">Der vertrauenswürdige Knoten macht den Proof of Work</string> | ||||||
|  |     <string name="full_node_warning">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?</string> | ||||||
| </resources> | </resources> | ||||||
| @@ -51,4 +51,5 @@ | |||||||
|     <string name="subscribed">Subscribed</string> |     <string name="subscribed">Subscribed</string> | ||||||
|     <string name="server_pow">Server POW</string> |     <string name="server_pow">Server POW</string> | ||||||
|     <string name="server_pow_summary">Trusted node does proof of work</string> |     <string name="server_pow_summary">Trusted node does proof of work</string> | ||||||
|  |     <string name="full_node_warning">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?</string> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user