diff --git a/xwords4/android/app/src/main/AndroidManifest.xml b/xwords4/android/app/src/main/AndroidManifest.xml index ef8e0f2d7..d50e00959 100644 --- a/xwords4/android/app/src/main/AndroidManifest.xml +++ b/xwords4/android/app/src/main/AndroidManifest.xml @@ -211,6 +211,9 @@ + + + diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTReceiver.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTReceiver.java index 19b21e6a9..c010b62ad 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTReceiver.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTReceiver.java @@ -29,6 +29,9 @@ import android.content.Intent; public class BTReceiver extends BroadcastReceiver { private static final String TAG = BTReceiver.class.getSimpleName(); + // This string is also used in AndroidManifest (as a string literal) + static final String ACTION_STOP_BT = "org.eehouse.android.ACTION_STOP_BT"; + @Override public void onReceive( Context context, Intent intent ) { @@ -37,9 +40,14 @@ public class BTReceiver extends BroadcastReceiver { Log.d( TAG, "BTReceiver.onReceive(action=%s, intent=%s)", action, intent.toString() ); - if ( action.equals( BluetoothDevice.ACTION_ACL_CONNECTED ) ) { + switch (action ) { + case ACTION_STOP_BT: + BTService.stopBackground( context ); + break; + case BluetoothDevice.ACTION_ACL_CONNECTED: BTService.onACLConnected( context ); - } else if ( action.equals( BluetoothAdapter.ACTION_STATE_CHANGED ) ) { + break; + case BluetoothAdapter.ACTION_STATE_CHANGED: int newState = intent.getIntExtra( BluetoothAdapter.EXTRA_STATE, -1 ); switch ( newState ) { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTService.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTService.java index 4b984958a..db2ecb329 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTService.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTService.java @@ -80,7 +80,7 @@ public class BTService extends XWService { private static final String BOGUS_MARSHMALLOW_ADDR = "02:00:00:00:00:00"; private static final String KEY_KEEPALIVE_UNTIL_SECS = "keep_secs"; // half minute for testing; maybe 15 on ship? Or make it a debug config. - private static int DEFAULT_KEEPALIVE_SECONDS = 30; + private static int DEFAULT_KEEPALIVE_SECONDS = 15 * 60; private static final long RESEND_TIMEOUT = 5; // seconds private static final int MAX_SEND_FAIL = 3; @@ -91,6 +91,7 @@ public class BTService extends XWService { private static final int BT_PROTO = BT_PROTO_JSONS; // change in a release or two private enum BTAction { _NONE, + CANCEL_SERVICE, START_FOREGROUND, START_BACKGROUND, SCAN, @@ -265,7 +266,7 @@ public class BTService extends XWService { startService( context, getIntentTo( context, inForeground ? BTAction.START_FOREGROUND - : BTAction.START_BACKGROUND ) );; + : BTAction.START_BACKGROUND ) ); } } @@ -299,6 +300,12 @@ public class BTService extends XWService { BTListenerThread.startYourself( context ); } + public static void stopBackground( Context context ) + { + startService( context, + getIntentTo( context, BTAction.CANCEL_SERVICE ) ); + } + public static void radioChanged( Context context, boolean cameOn ) { Intent intent = getIntentTo( context, BTAction.RADIO ); @@ -471,6 +478,7 @@ public class BTService extends XWService { BTAction cmd = BTAction.values()[ordinal]; Log.i( TAG, "handleCommand; cmd=%s", cmd.toString() ); switch( cmd ) { + case CANCEL_SERVICE: case START_FOREGROUND: stopForeground( true ); // Kill the notification break; @@ -563,11 +571,19 @@ public class BTService extends XWService { PendingIntent pendIntent = PendingIntent .getActivity( this, Utils.nextRandomInt(), notifIntent, PendingIntent.FLAG_ONE_SHOT ); + + Intent stopIntent = new Intent(this, BTReceiver.class); + stopIntent.setAction( BTReceiver.ACTION_STOP_BT ); + PendingIntent stopPI = + PendingIntent.getBroadcast(this, 0, stopIntent, 0); + m_notification = new NotificationCompat.Builder( this, Utils.getChannelId(this) ) .setSmallIcon( R.drawable.notify_btservice ) .setContentText( getString(R.string.bkng_notify_text) ) .setContentIntent( pendIntent ) + .addAction( R.drawable.notify_btservice, + getString(R.string.bkng_stop_text), stopPI ) .build(); } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java index 1079a8afd..54f5d533e 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java @@ -2270,8 +2270,7 @@ public class GamesListDelegate extends ListDelegateBase private void tryBackgroundIntent( Intent intent ) { if ( intent.getBooleanExtra( BACKGROUND_EXTRA, false ) ) { - makeNotAgainBuilder( R.string.not_again_btservice, - R.string.key_notagain_btservice ) + makeOkOnlyBuilder( R.string.btservice_expl ) .show(); } } diff --git a/xwords4/android/app/src/main/res/values/common_rsrc.xml b/xwords4/android/app/src/main/res/values/common_rsrc.xml index 389e79ddb..ecf62b8ed 100644 --- a/xwords4/android/app/src/main/res/values/common_rsrc.xml +++ b/xwords4/android/app/src/main/res/values/common_rsrc.xml @@ -136,8 +136,6 @@ key_invite_multi key_notagain_rematch_two_only key_notagain_dfltname - key_notagain_btservice - key_na_comms_bt key_na_comms_p2p key_na_comms_sms diff --git a/xwords4/android/app/src/main/res/values/strings.xml b/xwords4/android/app/src/main/res/values/strings.xml index 448076ff7..c7b7660ae 100644 --- a/xwords4/android/app/src/main/res/values/strings.xml +++ b/xwords4/android/app/src/main/res/values/strings.xml @@ -2030,6 +2030,7 @@ Experimental, uses lots of battery Accepting Bluetooth messages… + Stop Confirm your SMS plan @@ -2646,13 +2647,11 @@ player name \"%1$s\". Would you like to personalize with your own name before you create this game? - This notification is present - whenever CrossWords is ready to receive Bluetooth messages in the - background. This readiness has a slight impact on battery. If you - don\'t want to listen in the background disable the \"Enable - Background Listener\" preference. CrossWords will still receive - Bluetooth moves and invitations while in the foreground, but any - sent while it\'s in the background will be lost. + This notification is present whenever + CrossWords is running in the background to accept Bluetooth messages. + Because messages come in clusters, it usually runs for + about 15 minutes after the last message is received. + This game has sent no invitations