From 31a96ba0303a4032cf29d5f5b696a06931c3d9d8 Mon Sep 17 00:00:00 2001 From: AbdurazaaqMohammed <56937889+AbdurazaaqMohammed@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:23:38 -0400 Subject: [PATCH 1/5] Update ForegroundService.java Remove dependency on androidx --- .../youtube/pro/ForegroundService.java | 608 ++++++++---------- 1 file changed, 276 insertions(+), 332 deletions(-) diff --git a/app/src/main/java/com/google/android/youtube/pro/ForegroundService.java b/app/src/main/java/com/google/android/youtube/pro/ForegroundService.java index 6f43ce0..e3d910a 100644 --- a/app/src/main/java/com/google/android/youtube/pro/ForegroundService.java +++ b/app/src/main/java/com/google/android/youtube/pro/ForegroundService.java @@ -5,356 +5,300 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.media.MediaMetadata; +import android.media.session.MediaSession; +import android.media.session.PlaybackState; import android.os.Build; import android.os.IBinder; import android.util.Base64; -import android.content.BroadcastReceiver; -import android.content.IntentFilter; - - -import androidx.core.app.NotificationCompat; -import androidx.media.app.NotificationCompat.MediaStyle; -import android.support.v4.media.session.MediaSessionCompat; -import android.support.v4.media.MediaMetadataCompat; -import android.support.v4.media.session.PlaybackStateCompat; public class ForegroundService extends Service { -public static final String CHANNEL_ID = "Media"; -public static final String ACTION_UPDATE_NOTIFICATION = "UPDATE_NOTIFICATION"; -private MediaSessionCompat mediaSession; -private NotificationManager notificationManager; -private static boolean isRunning = false; -private BroadcastReceiver updateReceiver; - -@Override -public void onCreate() { -super.onCreate(); - -isRunning=true; - -registerUpdateReceiver(); -initMediaSession(); -createNotificationChannel(); -} - -private void initMediaSession() { -mediaSession = new MediaSessionCompat(getApplicationContext(), "YourMediaSessionTag"); -mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); - -mediaSession.setCallback(new MediaSessionCompat.Callback() { -@Override -public void onPlay() { -super.onPlay(); -getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") -.putExtra("actionname", "PLAY_ACTION")); - -} - -@Override -public void onPause() { -super.onPause(); -getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") -.putExtra("actionname", "PAUSE_ACTION")); -} - -@Override -public void onSkipToNext() { -super.onSkipToNext(); + public static final String CHANNEL_ID = "Media"; + public static final String ACTION_UPDATE_NOTIFICATION = "UPDATE_NOTIFICATION"; + private NotificationManager notificationManager; + private BroadcastReceiver updateReceiver; + private MediaSession mediaSession; + + @Override + public void onCreate() { + super.onCreate(); + initMediaSession(); + registerUpdateReceiver(); + createNotificationChannel(); + } + + + private void initMediaSession() { + mediaSession = new MediaSession(getApplicationContext(), "YourMediaSessionTag"); + mediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); + + mediaSession.setCallback(new MediaSession.Callback() { + @Override + public void onPlay() { + super.onPlay(); + getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") + .putExtra("actionname", "PLAY_ACTION")); + + } + + @Override + public void onPause() { + super.onPause(); + getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") + .putExtra("actionname", "PAUSE_ACTION")); + } + + @Override + public void onSkipToNext() { + super.onSkipToNext(); // Handle skip to next -getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") -.putExtra("actionname", "NEXT_ACTION")); -} + getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") + .putExtra("actionname", "NEXT_ACTION")); + } -@Override -public void onSkipToPrevious() { -super.onSkipToPrevious(); + @Override + public void onSkipToPrevious() { + super.onSkipToPrevious(); // Handle skip to previous -getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") -.putExtra("actionname", "PREV_ACTION")); - -} -@Override -public void onSeekTo(long pos) { -super.onSeekTo(pos); -getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") -.putExtra("actionname", "SEEKTO").putExtra("pos", pos+"")); - - -} -}); - -mediaSession.setActive(true); -} - -private void createNotificationChannel() { -if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { -NotificationChannel channel = new NotificationChannel( -CHANNEL_ID, -"Background Play", -NotificationManager.IMPORTANCE_MIN -); -notificationManager = getSystemService(NotificationManager.class); -if (notificationManager != null) { -notificationManager.createNotificationChannel(channel); -} -} -} - - - - -private void updateMediaSessionMetadata(String title, String artist, String album, Bitmap albumArt, long duration) { -MediaMetadataCompat metadata = new MediaMetadataCompat.Builder() -.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title) -.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist) -.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, album) -.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt) -.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration) -.build(); - -mediaSession.setMetadata(metadata); -} - - - - - - - -private void updatePlaybackState(long currentPosition, int state) { -PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder() -.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE -| PlaybackStateCompat.ACTION_SKIP_TO_NEXT -| PlaybackStateCompat.ACTION_PAUSE -| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS | PlaybackStateCompat.ACTION_SEEK_TO) -.setState(state, currentPosition, 1.0f) // 1.0f for playback speed -.build(); - -mediaSession.setPlaybackState(playbackState); -} - - - - - - - - -private void setupNotification(Intent intent) { - - -long duration = intent.getLongExtra("duration", 0); -long currentPosition = intent.getLongExtra("currentPosition", 0); -int playbackState = intent.getIntExtra("playbackState", PlaybackStateCompat.STATE_NONE); -String title= intent.getStringExtra("title"); -String subtitle= intent.getStringExtra("subtitle"); -String icon= intent.getStringExtra("icon"); - - - - -byte[] decodedBytes = Base64.decode(icon, Base64.DEFAULT); -Bitmap largeIcon = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length); - - - - -updateMediaSessionMetadata(title, subtitle, "YT PRO", largeIcon, duration); -updatePlaybackState(currentPosition, PlaybackStateCompat.STATE_PLAYING -); - - - - -Intent openAppIntent = new Intent(this, MainActivity.class); -openAppIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); -PendingIntent openAppPendingIntent = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); + getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") + .putExtra("actionname", "PREV_ACTION")); -Intent playIntent = new Intent(this, NotificationActionService.class); -playIntent.setAction("PAUSE_ACTION"); -PendingIntent playPendingIntent = PendingIntent.getBroadcast(this, 0, playIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); + } + @Override + public void onSeekTo(long pos) { + super.onSeekTo(pos); + getApplicationContext().sendBroadcast(new Intent("TRACKS_TRACKS") + .putExtra("actionname", "SEEKTO").putExtra("pos", pos+"")); -Intent nextIntent = new Intent(this, NotificationActionService.class); -nextIntent.setAction("NEXT_ACTION"); -PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); -Intent prevIntent = new Intent(this, NotificationActionService.class); -prevIntent.setAction("PREV_ACTION"); -PendingIntent prevPendingIntent = PendingIntent.getBroadcast(this, 0, prevIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); + } + }); -NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) -.setSmallIcon(R.drawable.app_icon) -.setContentTitle(title) -.setContentText(subtitle) -.setLargeIcon(largeIcon) -.setContentIntent(openAppPendingIntent) -.setStyle(new MediaStyle().setMediaSession(mediaSession.getSessionToken())) -.addAction(R.drawable.ic_skip_previous_white, "Previous", prevPendingIntent) -.addAction(R.drawable.ic_pause_white, "Pause", playPendingIntent) -.addAction(R.drawable.ic_skip_next_white, "Next", nextPendingIntent); + mediaSession.setActive(true); + } -Notification notification = builder.build(); + private void createNotificationChannel() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel( + CHANNEL_ID, + "Background Play", + NotificationManager.IMPORTANCE_MIN + ); + notificationManager = getSystemService(NotificationManager.class); + if (notificationManager != null) { + notificationManager.createNotificationChannel(channel); + } + } + } + + + public void updateNotification(String icon, String title, String subtitle, String action, long duration, long currentPosition) { -/* if(!isRunning){ -isRunning=true; -startForeground(1, notification); -} -*/ - -startForeground(1, notification); - - -notificationManager.notify(1, notification); -} - - - - - - - - -@Override -public int onStartCommand(Intent intent, int flags, int startId) { - -if (intent != null) { - -notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - -setupNotification(intent); -} - -return START_NOT_STICKY; -} - - - - - - - - - - - -public void updateNotification(String icon, String title, String subtitle, String action, long duration, long currentPosition) { - -Context cont=getApplicationContext(); - -byte[] decodedBytes = Base64.decode(icon, Base64.DEFAULT); -Bitmap largeIcon = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length); - - -int playbackState; -if("pause".equals(action)){ -playbackState= PlaybackStateCompat.STATE_PAUSED; -} -else if("play".equals(action)){ -playbackState= PlaybackStateCompat.STATE_PLAYING; -}else{ -playbackState= PlaybackStateCompat.STATE_BUFFERING; -} - -updateMediaSessionMetadata(title, subtitle, "YT PRO", largeIcon, duration); // Example usage -updatePlaybackState(currentPosition, playbackState); // Example usage - -Intent openAppIntent = new Intent(cont, MainActivity.class); -openAppIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); -PendingIntent openAppPendingIntent = PendingIntent.getActivity(cont, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); - -Intent playIntent = new Intent(cont, NotificationActionService.class); -playIntent.setAction("PLAY_ACTION"); -PendingIntent playPendingIntent = PendingIntent.getBroadcast(cont, 0, playIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); - -Intent pauseIntent = new Intent(cont, NotificationActionService.class); -pauseIntent.setAction("PAUSE_ACTION"); -PendingIntent pausePendingIntent = PendingIntent.getBroadcast(cont, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); - -Intent nextIntent = new Intent(cont, NotificationActionService.class); -nextIntent.setAction("NEXT_ACTION"); -PendingIntent nextPendingIntent = PendingIntent.getBroadcast(cont, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); - -Intent prevIntent = new Intent(cont, NotificationActionService.class); -prevIntent.setAction("PREV_ACTION"); -PendingIntent prevPendingIntent = PendingIntent.getBroadcast(cont, 0, prevIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); - -NotificationCompat.Builder builder = new NotificationCompat.Builder(cont, CHANNEL_ID) -.setSmallIcon(R.drawable.app_icon) -.setContentTitle(title) -.setContentText(subtitle) -.setLargeIcon(largeIcon) -.setContentIntent(openAppPendingIntent) -.setStyle(new MediaStyle().setMediaSession(mediaSession.getSessionToken())) -.addAction(R.drawable.ic_skip_previous_white, "Previous", prevPendingIntent); - -if ("play".equals(action)) { -builder.addAction(R.drawable.ic_pause_white, "Pause", pausePendingIntent) -.addAction(R.drawable.ic_skip_next_white, "Next", nextPendingIntent); -} else if ("pause".equals(action)) { -builder.addAction(R.drawable.ic_play_arrow_white, "Play", playPendingIntent) -.addAction(R.drawable.ic_skip_next_white, "Next", nextPendingIntent); -}else{ - -builder.addAction(R.drawable.ic_pause_white, "Pause", pausePendingIntent) -.addAction(R.drawable.ic_skip_next_white, "Next", nextPendingIntent); - -} - - - -notificationManager.notify(1, builder.build()); -} - - - - - - - -private void registerUpdateReceiver() { -updateReceiver = new BroadcastReceiver() { -@Override -public void onReceive(Context context, Intent intent) { -if (ACTION_UPDATE_NOTIFICATION.equals(intent.getAction())) { -String icon = intent.getStringExtra("icon"); -String title = intent.getStringExtra("title"); -String subtitle = intent.getStringExtra("subtitle"); -String action = intent.getStringExtra("action"); -long duration = intent.getLongExtra("duration", 0); -long currentPosition = intent.getLongExtra("currentPosition", 0); - - -updateNotification(icon, title, subtitle, action, duration, currentPosition); - - -} -} -}; - - -IntentFilter filter = new IntentFilter(ACTION_UPDATE_NOTIFICATION); -registerReceiver(updateReceiver, filter); -} - - -@Override -public void onDestroy() { -super.onDestroy(); -isRunning=false; -if (mediaSession != null) { -mediaSession.release(); -} -unregisterReceiver(updateReceiver); -} - -@Override -public IBinder onBind(Intent intent) { -return null; -} + Context cont=getApplicationContext(); + + byte[] decodedBytes = Base64.decode(icon, Base64.DEFAULT); + Bitmap largeIcon = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length); + + + int playbackState; + if("pause".equals(action)){ + playbackState= PlaybackState.STATE_PAUSED; + } + else if("play".equals(action)){ + playbackState= PlaybackState.STATE_PLAYING; + }else{ + playbackState= PlaybackState.STATE_BUFFERING; + } + + updateMediaSessionMetadata(title, subtitle, largeIcon, duration); // Example usage + updatePlaybackState(currentPosition, playbackState); // Example usage + + Intent openAppIntent = new Intent(cont, MainActivity.class); + openAppIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + PendingIntent openAppPendingIntent = PendingIntent.getActivity(cont, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); + + Intent playIntent = new Intent(cont, NotificationActionService.class); + playIntent.setAction("PLAY_ACTION"); + PendingIntent playPendingIntent = PendingIntent.getBroadcast(cont, 0, playIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); + + Intent pauseIntent = new Intent(cont, NotificationActionService.class); + pauseIntent.setAction("PAUSE_ACTION"); + PendingIntent pausePendingIntent = PendingIntent.getBroadcast(cont, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); + + Intent nextIntent = new Intent(cont, NotificationActionService.class); + nextIntent.setAction("NEXT_ACTION"); + PendingIntent nextPendingIntent = PendingIntent.getBroadcast(cont, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); + + Intent prevIntent = new Intent(cont, NotificationActionService.class); + prevIntent.setAction("PREV_ACTION"); + PendingIntent prevPendingIntent = PendingIntent.getBroadcast(cont, 0, prevIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); + + Notification.Builder builder = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) ? new Notification.Builder(this, CHANNEL_ID) : new Notification.Builder(this); + + builder.setSmallIcon(R.drawable.app_icon) + .setContentTitle(title) + .setContentText(subtitle) + .setLargeIcon(largeIcon) + .setContentIntent(openAppPendingIntent) + .setStyle(new Notification.MediaStyle().setMediaSession(mediaSession.getSessionToken())) + .addAction(R.drawable.ic_skip_previous_white, "Previous", prevPendingIntent); + + if ("play".equals(action)) { + builder.addAction(R.drawable.ic_pause_white, "Pause", pausePendingIntent) + .addAction(R.drawable.ic_skip_next_white, "Next", nextPendingIntent); + } else if ("pause".equals(action)) { + builder.addAction(R.drawable.ic_play_arrow_white, "Play", playPendingIntent) + .addAction(R.drawable.ic_skip_next_white, "Next", nextPendingIntent); + }else{ + + builder.addAction(R.drawable.ic_pause_white, "Pause", pausePendingIntent) + .addAction(R.drawable.ic_skip_next_white, "Next", nextPendingIntent); + + } + + + + notificationManager.notify(1, builder.build()); + } + + + + private void registerUpdateReceiver() { + updateReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (ACTION_UPDATE_NOTIFICATION.equals(intent.getAction())) { + String icon = intent.getStringExtra("icon"); + String title = intent.getStringExtra("title"); + String subtitle = intent.getStringExtra("subtitle"); + String action = intent.getStringExtra("action"); + long duration = intent.getLongExtra("duration", 0); + long currentPosition = intent.getLongExtra("currentPosition", 0); + + updateNotification(icon, title, subtitle, action, duration, currentPosition); + } + } + }; + + IntentFilter filter = new IntentFilter(ACTION_UPDATE_NOTIFICATION); + registerReceiver(updateReceiver, filter); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent != null) { + notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + setupNotification(intent); + } + return START_NOT_STICKY; + } + + private void setupNotification(Intent intent) { + long duration = intent.getLongExtra("duration", 0); + long currentPosition = intent.getLongExtra("currentPosition", 0); + int playbackState = intent.getIntExtra("playbackState", PlaybackState.STATE_NONE); + String title = intent.getStringExtra("title"); + String subtitle = intent.getStringExtra("subtitle"); + String icon = intent.getStringExtra("icon"); + + byte[] decodedBytes = Base64.decode(icon, Base64.DEFAULT); + Bitmap largeIcon = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length); + + Intent openAppIntent = new Intent(this, MainActivity.class); + openAppIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + PendingIntent openAppPendingIntent = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + Intent playIntent = new Intent(this, NotificationActionService.class); + playIntent.setAction("PLAY_ACTION"); + PendingIntent playPendingIntent = PendingIntent.getBroadcast(this, 0, playIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + Intent pauseIntent = new Intent(this, NotificationActionService.class); + pauseIntent.setAction("PAUSE_ACTION"); + PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + Intent nextIntent = new Intent(this, NotificationActionService.class); + nextIntent.setAction("NEXT_ACTION"); + PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + Intent prevIntent = new Intent(this, NotificationActionService.class); + prevIntent.setAction("PREV_ACTION"); + PendingIntent prevPendingIntent = PendingIntent.getBroadcast(this, 0, prevIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + Notification.Builder builder = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) ? new Notification.Builder(this, CHANNEL_ID) : new Notification.Builder(this); + + builder.setSmallIcon(R.drawable.app_icon) + .setContentTitle(title) + .setContentText(subtitle) + .setLargeIcon(largeIcon) + .setContentIntent(openAppPendingIntent); + + // Set appropriate actions based on playback state + switch (playbackState) { + case PlaybackState.STATE_PLAYING: + builder.addAction(R.drawable.ic_pause_white, "Pause", pausePendingIntent); + break; + case PlaybackState.STATE_PAUSED: + builder.addAction(R.drawable.ic_play_arrow_white, "Play", playPendingIntent); + break; + case PlaybackState.STATE_BUFFERING: + // Add buffering related actions if needed + break; + default: + break; + } + + builder.addAction(R.drawable.ic_skip_previous_white, "Previous", prevPendingIntent) + .addAction(R.drawable.ic_skip_next_white, "Next", nextPendingIntent); + + Notification notification = builder.build(); + + // Update MediaSession metadata and playback state + updateMediaSessionMetadata(title, subtitle, largeIcon, duration); + updatePlaybackState(currentPosition, playbackState); + + startForeground(1, notification); + } + private void updateMediaSessionMetadata(String title, String artist, Bitmap albumArt, long duration) { + MediaMetadata metadata = new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_TITLE, title) + .putString(MediaMetadata.METADATA_KEY_ARTIST, artist) + .putString(MediaMetadata.METADATA_KEY_ALBUM, "YT PRO") + .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, albumArt) + .putLong(MediaMetadata.METADATA_KEY_DURATION, duration) + .build(); + + mediaSession.setMetadata(metadata); + } + + private void updatePlaybackState(long currentPosition, int state) { + PlaybackState playbackState = new PlaybackState.Builder() + .setActions(PlaybackState.ACTION_PLAY_PAUSE + | PlaybackState.ACTION_SKIP_TO_NEXT + | PlaybackState.ACTION_PAUSE + | PlaybackState.ACTION_SKIP_TO_PREVIOUS | PlaybackState.ACTION_SEEK_TO) + .setState(state, currentPosition, 1.0f) // 1.0f for playback speed + .build(); + + mediaSession.setPlaybackState(playbackState); + } + + + @Override + public void onDestroy() { + super.onDestroy(); + unregisterReceiver(updateReceiver); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } } From 76d0851e645a0a72cda9e8cc642794fc2d89de83 Mon Sep 17 00:00:00 2001 From: AbdurazaaqMohammed <56937889+AbdurazaaqMohammed@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:24:11 -0400 Subject: [PATCH 2/5] Update build.gradle Remove dependency on androidx --- app/build.gradle | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c2ef398..aa2b900 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,9 +20,5 @@ android { } dependencies { - - implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'androidx.media:media:1.6.0' - implementation 'androidx.core:core-ktx:1.7.0' } From 1d45ee79f99616fb4112f8901cb53409b32fe998 Mon Sep 17 00:00:00 2001 From: AbdurazaaqMohammed <56937889+AbdurazaaqMohammed@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:24:26 -0400 Subject: [PATCH 3/5] Update gradle.properties Remove dependency on androidx --- gradle.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 47426b2..0417b81 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,11 +14,9 @@ # AndroidX package structure to make it clearer which packages are bundled with the # Android operating system, and which are packaged with your app's APK # https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true #org.gradle.debug=true android.enableAapt2JniMode=true # Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true org.gradle.jvmargs=-Xmx1536M \ --add-exports=java.base/sun.nio.ch=ALL-UNNAMED \ --add-opens=java.base/java.lang=ALL-UNNAMED \ From 9a25c85b0de27f608dae805103d70c05c892f540 Mon Sep 17 00:00:00 2001 From: AbdurazaaqMohammed <56937889+AbdurazaaqMohammed@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:39:06 -0400 Subject: [PATCH 4/5] Update ForegroundService.java Add flag mutable for SDK 31+ --- .../android/youtube/pro/ForegroundService.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/google/android/youtube/pro/ForegroundService.java b/app/src/main/java/com/google/android/youtube/pro/ForegroundService.java index e3d910a..51cde4e 100644 --- a/app/src/main/java/com/google/android/youtube/pro/ForegroundService.java +++ b/app/src/main/java/com/google/android/youtube/pro/ForegroundService.java @@ -214,23 +214,23 @@ private void setupNotification(Intent intent) { Intent openAppIntent = new Intent(this, MainActivity.class); openAppIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); - PendingIntent openAppPendingIntent = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent openAppPendingIntent = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); Intent playIntent = new Intent(this, NotificationActionService.class); playIntent.setAction("PLAY_ACTION"); - PendingIntent playPendingIntent = PendingIntent.getBroadcast(this, 0, playIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent playPendingIntent = PendingIntent.getBroadcast(this, 0, playIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); Intent pauseIntent = new Intent(this, NotificationActionService.class); pauseIntent.setAction("PAUSE_ACTION"); - PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 0, pauseIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); Intent nextIntent = new Intent(this, NotificationActionService.class); nextIntent.setAction("NEXT_ACTION"); - PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 0, nextIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); Intent prevIntent = new Intent(this, NotificationActionService.class); prevIntent.setAction("PREV_ACTION"); - PendingIntent prevPendingIntent = PendingIntent.getBroadcast(this, 0, prevIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent prevPendingIntent = PendingIntent.getBroadcast(this, 0, prevIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); Notification.Builder builder = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) ? new Notification.Builder(this, CHANNEL_ID) : new Notification.Builder(this); @@ -277,7 +277,13 @@ private void updateMediaSessionMetadata(String title, String artist, Bitmap albu mediaSession.setMetadata(metadata); } - + + + + + + + private void updatePlaybackState(long currentPosition, int state) { PlaybackState playbackState = new PlaybackState.Builder() .setActions(PlaybackState.ACTION_PLAY_PAUSE From fb7c4271bd43dfc9a84502e6b91d4b3189f096aa Mon Sep 17 00:00:00 2001 From: AbdurazaaqMohammed <56937889+AbdurazaaqMohammed@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:39:39 -0400 Subject: [PATCH 5/5] Update AndroidManifest.xml specify foregroundServiceType https://developer.android.com/about/versions/14/changes/fgs-types-required --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0869543..8dab607 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -64,6 +64,7 @@ android:name=".ForegroundService" android:enabled="true" android:exported="true" + android:foregroundServiceType="mediaPlayback" />