I'm trying to write code that, when a button in the notification (e.g., back button) is pressed, will be received in a receiver indicating that it was clicked. However, it's not working, and I don't know what to do. So far, I haven't focused on the back button, that's why I temporarily set the others to null. Once I figure out what I'm doing wrong with the back button, I'll easily handle the rest.
public class NotificationChannelBuilder {
public static final String CHANNEL_ID = "channel1";
public static final int CHANNEL_ID_INT = 0;
public static final String CHANNEL_NAME = "MUSIC_NOTIFICATION_CHANNEL";
private static final String ACTION_PREVIOUS = "ACTION_PREVIOUS";
Intent actionIntent;
PendingIntent previousPendingIntent;
public NotificationChannelBuilder(Context context) {
actionIntent = new Intent(context, MusicNotification.class);
actionIntent.setAction("ACTION_PREVIOUS");
previousPendingIntent = PendingIntent.getActivity(context, 0, actionIntent , PendingIntent.FLAG_UPDATE_CURRENT);
}
public void showNotification(Context context, AudioModel song, int res) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.music_icon)
.addAction(R.drawable.baseline_skip_previous_24, "Previous", previousPendingIntent )
.addAction(res, "Play/Pause", null)
.addAction(R.drawable.baseline_skip_next_24, "Next", null)
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle())
.setContentTitle(song.getTitle())
.setOngoing(true)
.setOnlyAlertOnce(true)
.setSilent(true)
.setPriority(NotificationCompat.PRIORITY_HIGH);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions.
return;
}
notificationManager.notify(CHANNEL_ID_INT, builder.build());
}
}
public class MusicNotification extends BroadcastReceiver implements Observable {
List<Observer> observers = new ArrayList();
private String action = "";
@Override
public void onReceive(Context context, Intent intent) {
String receivedAction = intent.getAction();
if (receivedAction != null && receivedAction.equals("ACTION_PREVIOUS")) {
action = "ACTION_PREVIOUS";
Toast.makeText(context, "Cilcked", Toast.LENGTH_SHORT).show();
}
else if(receivedAction != null && receivedAction.equals("ACTION_NEXT"))
{
action = "ACTION_NEXT";
}
else if(receivedAction != null && receivedAction.equals("ACTION_PLAY/PAUSE"))
{
action = "ACTION_PLAY/PAUSE";
}
notifyObserver();
}
....
the rest of the code
...
}
public class MusicPlayerActivity extends AppCompatActivity implements Observer {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_player);
notificationChannelBuilder = new NotificationChannelBuilder(this);
...
createNotificationChannel();
notificationChannelBuilder.showNotification(this, songsList.get(MyMediaPlayer.currentIndex), R.drawable.baseline_pause_circle_outline_24);
...
}
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is not in the Support Library.
NotificationManager notificationManager = getSystemService(NotificationManager.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(NotificationChannelBuilder.CHANNEL_ID, NotificationChannelBuilder.CHANNEL_NAME, importance);
notificationManager.createNotificationChannel(channel);
}
}
}
In AndroidManifest.xml I have:
</activity>
<receiver android:name=".MusicNotification"
android:exported="false">
<intent-filter>
<action android:name="ACTION_PREVIOUS" />
</intent-filter>
</receiver>
Logs:
Expecting binder but got null!
2024-01-20 14:24:27.007 834-1058 EGL_emulation com.android.systemui D app_time_stats: avg=98.50ms min=3.05ms max=1948.32ms count=21
2024-01-20 14:24:27.238 626-646 CoreBackPreview system_server D Window{e75868 u0 Toast}: Setting back callback null
2024-01-20 14:24:27.241 626-646 InputManager-JNI system_server W Input channel object 'e75868 Toast (client)' was disposed without first being removed with the input manager!
2024-01-20 14:24:27.244 626-646 NotificationService system_server W Toast already killed. pkg=com.example.musicplayer token=android.os.BinderProxy@abacc80
2024-01-20 14:24:27.245 834-834 ToastPresenter com.android.systemui W Error calling back com.example.musicplayer to notify onToastHide()
android.os.DeadObjectException
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(BinderProxy.java:584)
at android.app.ITransientNotificationCallback$Stub$Proxy.onToastHidden(ITransientNotificationCallback.java:141)
at android.widget.ToastPresenter.hide(ToastPresenter.java:283)
at com.android.systemui.toast.ToastUI$ToastOutAnimatorListener.onAnimationEnd(ToastUI.java:4)
at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:600)
at android.animation.AnimatorSet.endAnimation(AnimatorSet.java:1301)
at android.animation.AnimatorSet.doAnimationFrame(AnimatorSet.java:1086)
at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:307)
at android.animation.AnimationHandler.-$$Nest$mdoAnimationFrame(Unknown Source:0)
at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:86)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
at android.view.Choreographer.doCallbacks(Choreographer.java:899)
at android.view.Choreographer.doFrame(Choreographer.java:827)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
What should I fix to make the previous buttons work?