Skip to content

Commit

Permalink
fix: foreground service fixes for SDK 34 / Android 14 (#1320)
Browse files Browse the repository at this point in the history
* fix: allow work to run in the foreground

* fix: handle ForegroundServiceStartNotAllowedException
  • Loading branch information
HashEngineering authored Nov 5, 2024
1 parent f419160 commit 08d242f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
6 changes: 6 additions & 0 deletions wallet/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,12 @@
android:exported="false"
android:foregroundServiceType="dataSync" />

<!-- WorkManager -->
<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
android:exported="false" />

<!--service
android:name="de.schildbach.wallet.offline.AcceptBluetoothService"
android:exported="false"
Expand Down
42 changes: 33 additions & 9 deletions wallet/src/de/schildbach/wallet/service/BlockchainServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package de.schildbach.wallet.service;

import android.annotation.SuppressLint;
import android.app.ForegroundServiceStartNotAllowedException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
Expand All @@ -41,6 +42,7 @@
import android.os.PowerManager.WakeLock;
import android.text.format.DateUtils;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleService;
Expand Down Expand Up @@ -963,7 +965,7 @@ public void onCreate() {
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground();
startForegroundAndCatch();
}

final Wallet wallet = application.getWallet();
Expand Down Expand Up @@ -1119,7 +1121,7 @@ public int onStartCommand(final Intent intent, final int flags, final int startI
//Restart service as a Foreground Service if it's synchronizing the blockchain
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(START_AS_FOREGROUND_EXTRA)) {
startForeground();
startForegroundAndCatch();
}

log.info("service start command: " + intent + (intent.hasExtra(Intent.EXTRA_ALARM_COUNT)
Expand Down Expand Up @@ -1181,11 +1183,12 @@ private void startForeground() {
//Shows ongoing notification promoting service to foreground service and
//preventing it from being killed in Android 26 or later
Notification notification = createNetworkSyncNotification(null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(Constants.NOTIFICATION_ID_BLOCKCHAIN_SYNC, notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
else
} else {
startForeground(Constants.NOTIFICATION_ID_BLOCKCHAIN_SYNC, notification);
}
foregroundService = ForegroundService.BLOCKCHAIN_SYNC;
}

Expand All @@ -1197,6 +1200,30 @@ private void startForegroundCoinJoin() {
foregroundService = ForegroundService.COINJOIN_MIXING;
}

private void startForegroundAndCatch() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
try {
startForeground();
} catch (ForegroundServiceStartNotAllowedException e) {
log.info("failed to start in foreground", e);
}
} else {
startForeground();
}
}

private void startForegroundCoinJoinAndCatch() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
try {
startForegroundCoinJoin();
} catch (ForegroundServiceStartNotAllowedException e) {
log.info("failed to start in foreground", e);
}
} else {
startForegroundCoinJoin();
}
}

@Override
public void onDestroy() {
log.info(".onDestroy()");
Expand Down Expand Up @@ -1373,14 +1400,11 @@ private void handleBlockchainStateNotification(BlockchainState blockchainState,
log.info("foreground service: {}", foregroundService);
if (foregroundService == ForegroundService.NONE) {
log.info("foreground service not active, create notification");
startForegroundCoinJoin();
//Notification notification = createCoinJoinNotification();
//nm.notify(Constants.NOTIFICATION_ID_BLOCKCHAIN_SYNC, notification);
startForegroundCoinJoinAndCatch();
foregroundService = ForegroundService.COINJOIN_MIXING;
} else {
log.info("foreground service active, update notification");
Notification notification = createCoinJoinNotification();
//nm.cancel(Constants.NOTIFICATION_ID_BLOCKCHAIN_SYNC);
nm.notify(Constants.NOTIFICATION_ID_BLOCKCHAIN_SYNC, notification);
}
}
Expand All @@ -1403,7 +1427,7 @@ public void forceForeground() {
Intent intent = new Intent(this, BlockchainServiceImpl.class);
ContextCompat.startForegroundService(this, intent);
// call startForeground just after startForegroundService.
startForeground();
startForegroundAndCatch();
}
}

Expand Down

0 comments on commit 08d242f

Please sign in to comment.