Skip to content
This repository has been archived by the owner on Dec 28, 2022. It is now read-only.

Commit

Permalink
A possible hack to resolve ANR's due to not calling startForeground()
Browse files Browse the repository at this point in the history
  • Loading branch information
timusus committed Feb 11, 2019
1 parent c1fd5ac commit ca57e99
Showing 1 changed file with 100 additions and 10 deletions.
110 changes: 100 additions & 10 deletions app/src/main/java/com/simplecity/amp_library/playback/MusicService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
Expand Down Expand Up @@ -37,7 +41,6 @@
import com.simplecity.amp_library.ui.screens.queue.QueueItem;
import com.simplecity.amp_library.utils.AnalyticsManager;
import com.simplecity.amp_library.utils.LogUtils;
import com.simplecity.amp_library.utils.MediaButtonIntentReceiver;
import com.simplecity.amp_library.utils.SettingsManager;
import com.simplecity.amp_library.utils.ShuttleUtils;
import com.simplecity.amp_library.utils.playlists.FavoritesPlaylistManager;
Expand Down Expand Up @@ -340,6 +343,23 @@ public void onDestroy() {
super.onDestroy();
}

void fakeForegroundNotification() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = "channel_1";
NotificationManager notificationManager = getSystemService(NotificationManager.class);
NotificationChannel channel = notificationManager.getNotificationChannel(channelId);
if (channel == null) {
channel = new NotificationChannel(channelId, getString(R.string.app_name), NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(false);
channel.enableVibration(false);
notificationManager.createNotificationChannel(channel);
}

Notification notification = new Notification.Builder(this, channelId).build();
startForeground(45, notification);
}
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
serviceStartId = startId;
Expand All @@ -355,51 +375,121 @@ public int onStartCommand(Intent intent, int flags, int startId) {
if (action != null) {
switch (action) {
case ServiceCommand.NEXT:
fakeForegroundNotification();

// If the service is not already started:
// - With queue: Force to next song, start playback, update notification, no ANR
// - No queue: ANR

// Possible solution: (A) Show the Shuttle notification, despite the fact that music isn't playing. Need to customise notification to allow for an empty queue (no current song)
// We could try to generate a queue of random songs as well, but there's no guarantee the user has music on their device.

gotoNext(true);

break;
case ServiceCommand.PREV:
fakeForegroundNotification();

// If the service is not already started:
// - With queue: ANR
// - No queue: ANR

// Possible solution: (A) Show the Shuttle notification, despite the fact that music isn't playing. Need to customise notification to allow for an empty queue (no current song)

previous(false);

break;
case ServiceCommand.PAUSE:
fakeForegroundNotification();

// If the service is not already started:
// - With queue: ANR
// - No queue: ANR

// Possible solution: (A) Show the Shuttle notification, despite the fact that music isn't playing. Need to customise notification to allow for an empty queue (no current song)

pause(true);
break;
case ServiceCommand.PLAY:
case ShortcutCommands.PLAY:
fakeForegroundNotification();

// If the service is not already started:
// - No queue: ANR
// - With queue: No ANR

// Possible solution: (A) Show the Shuttle notification, despite the fact that music isn't playing. Need to customise notification to allow for an empty queue (no current song)

play();
break;
case ServiceCommand.TOGGLE_PLAYBACK:
fakeForegroundNotification();

if (isPlaying()) {

// It's not possible to be playing and the service not be started. No ANR

pause(intent.getBooleanExtra(MediaButtonCommand.FORCE_PREVIOUS, false));
} else {

// Same as ServiceCommand.PLAY

play();
}
break;
case ServiceCommand.PAUSE:
pause(true);
break;
case ServiceCommand.PLAY:
play();
break;
case ServiceCommand.STOP:
fakeForegroundNotification();

// If the service is already started & we're not playing: ANR
// If the service is not already started: ANR

pause(false);
releaseServiceUiAndStop();
notificationStateHandler.removeCallbacksAndMessages(null);
//For some reason, the notification will only go away if this call is delayed.
new Handler().postDelayed(() -> stopForegroundImpl(true, false), 150);
break;
case ServiceCommand.SHUFFLE:
fakeForegroundNotification();

// If the service is not already started: ANR

toggleShuffleMode();
break;
case ServiceCommand.REPEAT:
fakeForegroundNotification();

// If the service is not already started: ANR

toggleRepeat();
break;
case ServiceCommand.TOGGLE_FAVORITE:
fakeForegroundNotification();

// If the service is not already started: ANR

toggleFavorite();
break;
case ExternalIntents.PLAY_STATUS_REQUEST:
fakeForegroundNotification();

// If the service is not already started: ANR

notifyChange(ExternalIntents.PLAY_STATUS_RESPONSE);
break;
case ServiceCommand.SHUTDOWN:
fakeForegroundNotification();

// If the service is not already started: ANR

shutdownScheduled = false;
releaseServiceUiAndStop();
return START_NOT_STICKY;
case ShortcutCommands.PLAY:
play();
break;
case ShortcutCommands.SHUFFLE_ALL:
fakeForegroundNotification();

// If service is not already started: ANR

queueManager.makeShuffleList();
playAutoShuffleList();
break;
Expand Down

0 comments on commit ca57e99

Please sign in to comment.