use foregroundService on devices that can handle it

And show the notification regardless. Tested only on pre-Oreo device so far.
This commit is contained in:
Eric House 2018-11-22 15:18:57 -08:00
parent 6177914213
commit 2ba5982ddf
7 changed files with 99 additions and 48 deletions

View file

@ -179,15 +179,16 @@
<activity android:name=".loc.LocItemEditActivity"
/>
<service android:name="RelayService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"
/>
<service android:name="BTService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"
/>
<service android:name="SMSService"/>
<service android:name="SMSService"
android:exported="false"
/>
<service android:name="RelayService"
android:exported="false"
/>
<receiver android:name=".MountEventReceiver">
<intent-filter>

View file

@ -21,6 +21,8 @@
package org.eehouse.android.xw4;
import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass.Device.Major;
@ -29,7 +31,8 @@ import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.JobIntentService;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import junit.framework.Assert;
@ -66,6 +69,8 @@ public class BTService extends XWService {
private static final int BT_PROTO = BT_PROTO_JSONS; // change in a release or two
private enum BTAction { _NONE,
START_FOREGROUND,
START_BACKGROUND,
SCAN,
INVITE,
SEND,
@ -93,6 +98,8 @@ public class BTService extends XWService {
private static final String BT_NAME_KEY = "BT_NAME";
private static final String BT_ADDRESS_KEY = "BT_ADDRESS";
private static Boolean sInForeground;
private enum BTCmd {
BAD_PROTO,
PING,
@ -225,12 +232,33 @@ public class BTService extends XWService {
return result;
}
private static void onAppStateChange( Context context, boolean inForeground )
{
if ( sInForeground == null || sInForeground != inForeground ) {
sInForeground = inForeground;
Intent intent =
getIntentTo( context,
inForeground ? BTAction.START_FOREGROUND
: BTAction.START_BACKGROUND );
startService( context, intent );
}
}
static void onAppToForeground( Context context )
{
onAppStateChange( context, true );
}
static void onAppToBackground( Context context )
{
onAppStateChange( context, false );
}
public static void startService( Context context )
{
if ( XWApp.BTSUPPORTED ) {
startService( context, new Intent( context, BTService.class ) );
// didn't help
// startService( context, new Intent( /*context, BTService.class*/ ) );
}
}
@ -322,17 +350,26 @@ public class BTService extends XWService {
{
Log.d( TAG, "startService(%s)", intent );
if ( false ) {
// requires asking for Manifest.permission.FOREGROUND_SERVICE
if ( ! sInForeground && canRunForegroundService() ) {
context.startForegroundService( intent );
} else {
JobIntentService.enqueueWork( context, BTService.class, 1111, intent );
} else if ( sInForeground || Build.VERSION.SDK_INT < Build.VERSION_CODES.O ) {
context.startService( intent );
}
}
// We can run a foreground service IIF the OS version is recent enough AND
// user hasn't said not to do it.
private static boolean canRunForegroundService()
{
// added in API level 26
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
// && Prefs.runForegroundServiceEnabled( context, true )
;
}
private static Intent getIntentTo( Context context, BTAction cmd )
{
Intent intent = new Intent( /*context, BTService.class*/ );
Intent intent = new Intent( context, BTService.class );
intent.putExtra( CMD_KEY, cmd.ordinal() );
return intent;
}
@ -358,7 +395,13 @@ public class BTService extends XWService {
@Override
public int onStartCommand( Intent intent, int flags, int startId )
{
return handleCommand( intent );
int result = handleCommand( intent );
if ( Service.START_STICKY == result && !sInForeground ) {
startForeground();
}
return result;
}
private int handleCommand( Intent intent )
@ -375,6 +418,12 @@ public class BTService extends XWService {
BTAction cmd = BTAction.values()[ordinal];
Log.i( TAG, "onStartCommand; cmd=%s", cmd.toString() );
switch( cmd ) {
case START_FOREGROUND:
stopForeground( true ); // Kill the notification
// FALLTHRU
case START_BACKGROUND:
break;
case CLEAR:
String[] btAddrs = intent.getStringArrayExtra( CLEAR_KEY );
clearDevs( btAddrs );
@ -450,11 +499,21 @@ public class BTService extends XWService {
return result;
} // handleCommand()
@Override
protected void onHandleWork( Intent intent )
private void startForeground()
{
Log.e( TAG, "onHandleWork(%s)", intent );
/*(void)*/handleCommand( intent );
Intent notifIntent = GamesListDelegate.makeBackgroundIntent( this );
PendingIntent pendIntent = PendingIntent
.getActivity(this, Utils.nextRandomInt(), notifIntent, PendingIntent.FLAG_ONE_SHOT);
Notification notification =
new NotificationCompat.Builder(this, Utils.CHANNEL_ID)
.setSmallIcon( R.drawable.notify )
.setContentTitle( BTService.class.getSimpleName() )
.setContentText("listening for bluetooth messages...")
.setContentIntent(pendIntent)
.build();
Log.d( TAG, "calling startForeground()" );
startForeground( 1337, notification );
}
private class BTListenerThread extends Thread {

View file

@ -2665,6 +2665,12 @@ public class GamesListDelegate extends ListDelegateBase
return intent;
}
public static Intent makeBackgroundIntent( Context context )
{
Intent intent = makeSelfIntent( context );
return intent;
}
public static Intent makeRowidIntent( Context context, long rowid )
{
Intent intent = makeSelfIntent( context );

View file

@ -25,7 +25,6 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.support.v4.app.JobIntentService;
import android.text.TextUtils;
import junit.framework.Assert;
@ -201,10 +200,9 @@ public class RelayService extends XWService
Log.d( TAG, "startService(%s)", intent );
if ( false ) {
// requires asking for Manifest.permission.FOREGROUND_SERVICE
context.startForegroundService( intent );
} else {
JobIntentService.enqueueWork( context, RelayService.class, 1112, intent );
context.startService( intent );
}
}
@ -391,13 +389,6 @@ public class RelayService extends XWService
super.onDestroy();
}
@Override
protected void onHandleWork( Intent intent )
{
Log.e( TAG, "onHandleWork(%s)", intent );
handleCommand( intent );
}
// NetStateCache.StateChangedIf interface
public void onNetAvail( boolean nowAvailable )
{

View file

@ -84,7 +84,7 @@ public class Utils {
private static final String TAG = Utils.class.getSimpleName();
public static final int TURN_COLOR = 0x7F00FF00;
private static final String CHANNEL_ID = BuildConfig.APPLICATION_ID + "_channel_id";
static final String CHANNEL_ID = BuildConfig.APPLICATION_ID + "_channel_id";
private static final String DB_PATH = "XW_GAMES";
private static final String HIDDEN_PREFS = "xwprefs_hidden";

View file

@ -94,16 +94,23 @@ public class XWApp extends Application implements LifecycleObserver {
}
UpdateCheckReceiver.restartTimer( this );
BTService.startService( this );
RelayService.startService( this );
GCMIntentService.init( this );
WiDirWrapper.init( this );
}
@OnLifecycleEvent(ON_ANY)
public void onAny(LifecycleOwner source, Lifecycle.Event event)
public void onAny( LifecycleOwner source, Lifecycle.Event event )
{
Log.d( TAG, "onAny(%s, %s)", source, event );
Log.d( TAG, "onAny(%s)", event );
switch( event ) {
case ON_RESUME:
BTService.onAppToForeground( this );
break;
case ON_STOP:
BTService.onAppToBackground( this );
break;
}
}
// This is called on emulator only, but good for ensuring no memory leaks

View file

@ -23,9 +23,7 @@ package org.eehouse.android.xw4;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.v4.app.JobIntentService;
import junit.framework.Assert;
@ -39,7 +37,7 @@ import org.eehouse.android.xw4.jni.UtilCtxtImpl;
import java.util.HashSet;
import java.util.Set;
abstract class XWService extends JobIntentService {
abstract class XWService extends Service {
private static final String TAG = XWService.class.getSimpleName();
public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED };
@ -48,21 +46,10 @@ abstract class XWService extends JobIntentService {
private UtilCtxt m_utilCtxt;
// @Override
// public IBinder onBind( Intent intent )
// {
// IBinder result = null;
// if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ) {
// result = super.onBind( intent );
// }
// return result;
// }
@Override
protected void onHandleWork(Intent intent)
public IBinder onBind( Intent intent )
{
Log.e( TAG, "%s.onHandleWork(%s); dropping!!!", getClass().getSimpleName(),
intent );
return null;
}
public final static void setListener( MultiService.MultiEventListener li )