This repository has been archived by the owner on Dec 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 477
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When the MusicService is started, the a dummy notification saying "Shuttle service running..." is shown, and the app is moved into the foreground state. This ensures that the system does not cause an ANR if we don't otherwise call through to stopService() (for example when we've decided not to foreground the service, because it's about to be shut down). The dummy notification is silent, and is removed 12.5 seconds after it is created (unless removed earlier). According to the source on github, the Android system will ANR your app if you don't call startForeground 10 seconds after starting the foreground service. So, we wait an extra 2.5 seconds before we shut down. If Shuttle is then moved into the foreground because it actually needs to be, the dummy notification is removed, as it's no longer required. When the MusicService is destroyed, the dummy notification is removed. It seems that it's OK for this to happen within the ANR delay, as long as we have called startForeground() at some point. Thia seems like the least annoying way to resolve this issue.
- Loading branch information
Showing
4 changed files
with
137 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
app/src/main/java/com/simplecity/amp_library/playback/DummyNotificationHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package com.simplecity.amp_library.playback; | ||
|
||
import android.app.Notification; | ||
import android.app.NotificationChannel; | ||
import android.app.NotificationManager; | ||
import android.app.Service; | ||
import android.os.Build; | ||
import android.support.annotation.Nullable; | ||
import com.simplecity.amp_library.R; | ||
import io.reactivex.Completable; | ||
import io.reactivex.disposables.Disposable; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
class DummyNotificationHelper { | ||
|
||
private static int NOTIFICATION_ID_DUMMY = 5; | ||
|
||
private boolean isShowingDummyNotification; | ||
private boolean isForegroundedByApp = false; | ||
|
||
private static String CHANNEL_ID = "channel_dummy"; | ||
|
||
// Must be greater than 10000 | ||
// See https://github.com/aosp-mirror/platform_frameworks_base/blob/e80b45506501815061b079dcb10bf87443bd385d/services/core/java/com/android/server/am/ActiveServices.java | ||
// (SERVICE_START_FOREGROUND_TIMEOUT = 10*1000) | ||
// | ||
private static int NOTIFICATION_STOP_DELAY = 1250; | ||
|
||
@Nullable | ||
private Disposable dummyNotificationDisposable = null; | ||
|
||
void setForegroundedByApp(boolean foregroundedByApp) { | ||
isForegroundedByApp = foregroundedByApp; | ||
} | ||
|
||
void showDummyNotification(Service service) { | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||
if (!isShowingDummyNotification) { | ||
NotificationManager notificationManager = service.getSystemService(NotificationManager.class); | ||
NotificationChannel channel = notificationManager.getNotificationChannel(CHANNEL_ID); | ||
if (channel == null) { | ||
channel = new NotificationChannel(CHANNEL_ID, service.getString(R.string.app_name), NotificationManager.IMPORTANCE_DEFAULT); | ||
channel.enableLights(false); | ||
channel.enableVibration(false); | ||
channel.setSound(null, null); | ||
channel.setShowBadge(false); | ||
channel.setImportance(NotificationManager.IMPORTANCE_LOW); | ||
notificationManager.createNotificationChannel(channel); | ||
} | ||
|
||
Notification notification = new Notification.Builder(service, CHANNEL_ID) | ||
.setContentTitle(service.getString(R.string.app_name)) | ||
.setContentText(service.getString(R.string.notification_text_shuttle_running)) | ||
.setSmallIcon(R.drawable.ic_stat_notification) | ||
.build(); | ||
|
||
notificationManager.notify(NOTIFICATION_ID_DUMMY, notification); | ||
|
||
if (!isForegroundedByApp) { | ||
service.startForeground(NOTIFICATION_ID_DUMMY, notification); | ||
} | ||
|
||
isShowingDummyNotification = true; | ||
} | ||
} | ||
|
||
if (dummyNotificationDisposable != null) { | ||
dummyNotificationDisposable.dispose(); | ||
} | ||
dummyNotificationDisposable = Completable.timer(NOTIFICATION_STOP_DELAY, TimeUnit.MILLISECONDS).doOnComplete(() -> removeDummyNotification(service)).subscribe(); | ||
} | ||
|
||
void teardown(Service service) { | ||
|
||
removeDummyNotification(service); | ||
|
||
if (dummyNotificationDisposable != null) { | ||
dummyNotificationDisposable.dispose(); | ||
} | ||
} | ||
|
||
private void removeDummyNotification(Service service) { | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||
if (isShowingDummyNotification) { | ||
|
||
if (dummyNotificationDisposable != null) { | ||
dummyNotificationDisposable.dispose(); | ||
} | ||
|
||
if (!isForegroundedByApp) { | ||
service.stopForeground(true); | ||
} | ||
|
||
NotificationManager notificationManager = service.getSystemService(NotificationManager.class); | ||
notificationManager.cancel(NOTIFICATION_ID_DUMMY); | ||
|
||
isShowingDummyNotification = false; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters