start/stop service as foreground service for devices running Oreo and above

This commit is contained in:
Rajaratnam, Roshan
2019-08-07 14:15:33 +02:00
parent e36b7a1e0c
commit 01180f1617
2 changed files with 1102 additions and 1074 deletions

View File

@@ -33,12 +33,12 @@ import android.net.Uri;
import android.os.Binder; import android.os.Binder;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import no.nordicsemi.android.ble.BleManager; import no.nordicsemi.android.ble.BleManager;
import no.nordicsemi.android.ble.BleManagerCallbacks; import no.nordicsemi.android.ble.BleManagerCallbacks;
import no.nordicsemi.android.ble.utils.ILogger; import no.nordicsemi.android.ble.utils.ILogger;
@@ -58,9 +58,13 @@ public abstract class BleProfileService extends Service implements BleManagerCal
public static final String BROADCAST_BATTERY_LEVEL = "no.nordicsemi.android.nrftoolbox.BROADCAST_BATTERY_LEVEL"; public static final String BROADCAST_BATTERY_LEVEL = "no.nordicsemi.android.nrftoolbox.BROADCAST_BATTERY_LEVEL";
public static final String BROADCAST_ERROR = "no.nordicsemi.android.nrftoolbox.BROADCAST_ERROR"; public static final String BROADCAST_ERROR = "no.nordicsemi.android.nrftoolbox.BROADCAST_ERROR";
/** The parameter passed when creating the service. Must contain the address of the sensor that we want to connect to */ /**
* The parameter passed when creating the service. Must contain the address of the sensor that we want to connect to
*/
public static final String EXTRA_DEVICE_ADDRESS = "no.nordicsemi.android.nrftoolbox.EXTRA_DEVICE_ADDRESS"; public static final String EXTRA_DEVICE_ADDRESS = "no.nordicsemi.android.nrftoolbox.EXTRA_DEVICE_ADDRESS";
/** The key for the device name that is returned in {@link #BROADCAST_CONNECTION_STATE} with state {@link #STATE_CONNECTED}. */ /**
* The key for the device name that is returned in {@link #BROADCAST_CONNECTION_STATE} with state {@link #STATE_CONNECTED}.
*/
public static final String EXTRA_DEVICE_NAME = "no.nordicsemi.android.nrftoolbox.EXTRA_DEVICE_NAME"; public static final String EXTRA_DEVICE_NAME = "no.nordicsemi.android.nrftoolbox.EXTRA_DEVICE_NAME";
public static final String EXTRA_DEVICE = "no.nordicsemi.android.nrftoolbox.EXTRA_DEVICE"; public static final String EXTRA_DEVICE = "no.nordicsemi.android.nrftoolbox.EXTRA_DEVICE";
public static final String EXTRA_LOG_URI = "no.nordicsemi.android.nrftoolbox.EXTRA_LOG_URI"; public static final String EXTRA_LOG_URI = "no.nordicsemi.android.nrftoolbox.EXTRA_LOG_URI";
@@ -142,6 +146,7 @@ public abstract class BleProfileService extends Service implements BleManagerCal
/** /**
* Sets whether the bound activity if changing configuration or not. * Sets whether the bound activity if changing configuration or not.
* If <code>false</code>, we will turn off battery level notifications in onUnbind(..) method below. * If <code>false</code>, we will turn off battery level notifications in onUnbind(..) method below.
*
* @param changing true if the bound activity is finishing * @param changing true if the bound activity is finishing
*/ */
public void setActivityIsChangingConfiguration(final boolean changing) { public void setActivityIsChangingConfiguration(final boolean changing) {
@@ -187,6 +192,7 @@ public abstract class BleProfileService extends Service implements BleManagerCal
/** /**
* Returns the connection state of given device. * Returns the connection state of given device.
*
* @return the connection state, as in {@link BleManager#getConnectionState()}. * @return the connection state, as in {@link BleManager#getConnectionState()}.
*/ */
public int getConnectionState() { public int getConnectionState() {
@@ -308,6 +314,7 @@ public abstract class BleProfileService extends Service implements BleManagerCal
/** /**
* Initializes the Ble Manager responsible for connecting to a single device. * Initializes the Ble Manager responsible for connecting to a single device.
*
* @return a new BleManager object * @return a new BleManager object
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@@ -424,6 +431,7 @@ public abstract class BleProfileService extends Service implements BleManagerCal
/** /**
* This method should return false if the service needs to do some asynchronous work after if has disconnected from the device. * This method should return false if the service needs to do some asynchronous work after if has disconnected from the device.
* In that case the {@link #stopService()} method must be called when done. * In that case the {@link #stopService()} method must be called when done.
*
* @return true (default) to automatically stop the service when device is disconnected. False otherwise. * @return true (default) to automatically stop the service when device is disconnected. False otherwise.
*/ */
protected boolean stopWhenDisconnected() { protected boolean stopWhenDisconnected() {
@@ -538,8 +546,7 @@ public abstract class BleProfileService extends Service implements BleManagerCal
/** /**
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread * Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
* *
* @param messageResId * @param messageResId an resource id of the message to be shown
* an resource id of the message to be shown
*/ */
protected void showToast(final int messageResId) { protected void showToast(final int messageResId) {
mHandler.post(() -> Toast.makeText(BleProfileService.this, messageResId, Toast.LENGTH_SHORT).show()); mHandler.post(() -> Toast.makeText(BleProfileService.this, messageResId, Toast.LENGTH_SHORT).show());
@@ -548,8 +555,7 @@ public abstract class BleProfileService extends Service implements BleManagerCal
/** /**
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread * Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
* *
* @param message * @param message a message to be shown
* a message to be shown
*/ */
protected void showToast(final String message) { protected void showToast(final String message) {
mHandler.post(() -> Toast.makeText(BleProfileService.this, message, Toast.LENGTH_SHORT).show()); mHandler.post(() -> Toast.makeText(BleProfileService.this, message, Toast.LENGTH_SHORT).show());

View File

@@ -34,11 +34,7 @@ import android.media.AudioManager;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.media.RingtoneManager; import android.media.RingtoneManager;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.NonNull; import android.os.Build;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@@ -46,6 +42,11 @@ import java.io.IOException;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import no.nordicsemi.android.log.LogContract; import no.nordicsemi.android.log.LogContract;
import no.nordicsemi.android.nrftoolbox.FeaturesActivity; import no.nordicsemi.android.nrftoolbox.FeaturesActivity;
import no.nordicsemi.android.nrftoolbox.R; import no.nordicsemi.android.nrftoolbox.R;
@@ -449,8 +450,12 @@ public class ProximityService extends BleMulticonnectProfileService implements P
} }
final Notification notification = builder.build(); final Notification notification = builder.build();
final NotificationManagerCompat nm = NotificationManagerCompat.from(this); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nm.notify(device.getAddress(), NOTIFICATION_ID, notification); startForeground(NOTIFICATION_ID, notification);
} else {
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NOTIFICATION_ID, notification);
}
} }
/** /**
@@ -475,9 +480,13 @@ public class ProximityService extends BleMulticonnectProfileService implements P
builder.setTicker(getString(R.string.proximity_notification_link_loss_alert, name)); builder.setTicker(getString(R.string.proximity_notification_link_loss_alert, name));
final Notification notification = builder.build(); final Notification notification = builder.build();
final NotificationManagerCompat nm = NotificationManagerCompat.from(this); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(NOTIFICATION_ID, notification);
} else {
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(device.getAddress(), NOTIFICATION_ID, notification); nm.notify(device.getAddress(), NOTIFICATION_ID, notification);
} }
}
private NotificationCompat.Builder getNotificationBuilder() { private NotificationCompat.Builder getNotificationBuilder() {
final Intent parentIntent = new Intent(this, FeaturesActivity.class); final Intent parentIntent = new Intent(this, FeaturesActivity.class);
@@ -498,21 +507,34 @@ public class ProximityService extends BleMulticonnectProfileService implements P
*/ */
private void cancelNotifications() { private void cancelNotifications() {
final NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); final NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
stopForeground(true);
} else {
nm.cancel(NOTIFICATION_ID); nm.cancel(NOTIFICATION_ID);
}
final List<BluetoothDevice> managedDevices = getManagedDevices(); final List<BluetoothDevice> managedDevices = getManagedDevices();
for (final BluetoothDevice device : managedDevices) { for (final BluetoothDevice device : managedDevices) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
stopForeground(true);
} else {
nm.cancel(device.getAddress(), NOTIFICATION_ID); nm.cancel(device.getAddress(), NOTIFICATION_ID);
} }
} }
}
/** /**
* Cancels the existing notification for given device. If there is no active notification this method does nothing * Cancels the existing notification for given device. If there is no active notification this method does nothing
*/ */
private void cancelNotification(final BluetoothDevice device) { private void cancelNotification(final BluetoothDevice device) {
final NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); final NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
stopForeground(true);
} else {
nm.cancel(device.getAddress(), NOTIFICATION_ID); nm.cancel(device.getAddress(), NOTIFICATION_ID);
} }
}
private void initializeAlarm() { private void initializeAlarm() {
mDevicesWithAlarm = new LinkedList<>(); mDevicesWithAlarm = new LinkedList<>();