I am using the flutter_notification_listener library to get info related to the currently playing song (on Spotify). Then, when the user presses a button, the song either pauses/resumes. This works perfectly! More than this I was curious to know if there was any method to change the progress of the song using a progress bar in the app? Like: when the user drags the progress bar the song's progress is also changed? This is the code I'm using now:
late NotificationEvent audioEvent;
void onData(NotificationEvent event) {
setState(() {
audioEvent = event;
});
}
Future<void> initPlatformState() async {
NotificationsListener.initialize();
NotificationsListener.receivePort?.listen((evt) => onData(evt));
}
void startListening() async {
var hasPermission = await NotificationsListener.hasPermission;
if (!hasPermission!) {
NotificationsListener.openPermissionSettings();
return;
}
var isR = await NotificationsListener.isRunning;
if (!isR!) {
await NotificationsListener.startService();
}
}
void playPause() {
audioEvent.actions?[2].tap(); // It works
}
@override
void initState() {
initPlatformState();
Future.delayed(const Duration(seconds: 2), () => startListening());
super.initState();
}
Button:
TextButton(onPressed: playPause, child: const Text('Play/Pause'))
Any help is highly appreciated ! Thank you
Finally got the solution. By default there is no library/plugin, that I know of, can achieve this. We have to take advantage of the platform channels in flutter and use native java.
I created a new MethodChannel and invoked a method to communicate with the java code:
static const platform =
MethodChannel('com.example.foobar/playbackstatus');
Future<void> _setPlayBackDur() async {
try {
final int result = await platform.invokeMethod('setPlayBackDur');
} on PlatformException catch (e) {
}
}
Next follow the steps in the platform channels docs.
MainActivity.java :
package com.example.audionotification;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.os.BatteryManager;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationManagerCompat;
import java.util.List;
import java.util.Set;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "com.example.foobar/playbackstatus";
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
// This method is invoked on the main thread.
if (call.method.equals("setPlayBackDur")) {
if (!permissionGrantred()) {
Intent intent = new Intent(
"android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
startActivity(intent);
result.error("UNAVAILABLE", "...", null);
} else {
MediaSessionManager msm = (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
ComponentName cn = new ComponentName(this, MyNotificationService.class);
List<MediaController> list = msm.getActiveSessions(cn);
for (MediaController mc : list) {
if (mc.getPackageName().equals("com.spotify.music")) {
mc.getTransportControls().seekTo(136901); //ms to seekto
result.success(136901);
}
}
}
} else {
result.notImplemented();
}
}
);
}
private boolean permissionGrantred() {
Set<String> sets = NotificationManagerCompat.getEnabledListenerPackages(this);
if (sets != null && sets.contains(getPackageName())) {
return true;
} else {
return false;
}
}
//not included
private int getBatteryLevel() {
int batteryLevel = -1;
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
} else {
Intent intent = new ContextWrapper(getApplicationContext()).
registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
}
return batteryLevel;
}
}
MyNotificationService.java:
package com.example.audionotification;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
public class MyNotificationService extends NotificationListenerService {
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
super.onNotificationRemoved(sbn);
}
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
super.onNotificationPosted(sbn);
}
}
Hope it helps! (Thx to https://stackoverflow.com/a/66795488/14326852)