fix/feat: fix some exceptions and add album art to notification

This commit is contained in:
2022-02-26 19:53:07 +02:00
parent d07b5e793f
commit bdf317a1bc
6 changed files with 32 additions and 23 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.illusionware.lyricsgrabbr.lyricsgrabbr"> package="com.illusionware.lyricsgrabbr.lyricsgrabbr">
<application <application
android:label="lyricsgrabbr" android:label="Lyrics Grabbr"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity
@@ -9,6 +9,8 @@ import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() { class MainActivity: FlutterActivity() {
private var streamHandler : NotificationStreamHandler? = null
companion object { companion object {
private const val ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS" private const val ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"
private const val EVENT_CHANNEL_NAME = "notifications.eventChannel" private const val EVENT_CHANNEL_NAME = "notifications.eventChannel"
@@ -32,12 +34,17 @@ class MainActivity: FlutterActivity() {
} }
val eventChannel = EventChannel(flutterEngine.dartExecutor.binaryMessenger, EVENT_CHANNEL_NAME) val eventChannel = EventChannel(flutterEngine.dartExecutor.binaryMessenger, EVENT_CHANNEL_NAME)
val streamHandler = NotificationStreamHandler(context) streamHandler = NotificationStreamHandler(context)
eventChannel.setStreamHandler(streamHandler) eventChannel.setStreamHandler(streamHandler)
} }
override fun onDestroy() {
super.onDestroy()
streamHandler?.cleanUp()
}
private fun isPermissionGranted(): Boolean { private fun isPermissionGranted(): Boolean {
val packageName = context.packageName val packageName = packageName
val pkgs = NotificationManagerCompat.getEnabledListenerPackages(context) val pkgs = NotificationManagerCompat.getEnabledListenerPackages(context)
for (name in pkgs) { for (name in pkgs) {
if (TextUtils.equals(packageName, name)) { if (TextUtils.equals(packageName, name)) {
@@ -12,8 +12,8 @@ import android.service.notification.StatusBarNotification
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import android.os.Bundle import android.os.Bundle
import android.util.Base64 import java.io.File
import java.io.ByteArrayOutputStream import java.io.FileOutputStream
/** /**
* Notification listening service. Intercepts notifications if permission is given to do so. * Notification listening service. Intercepts notifications if permission is given to do so.
@@ -49,10 +49,18 @@ class NotificationListener : NotificationListenerService() {
val duration = mediaCtrl?.metadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.div(1000) val duration = mediaCtrl?.metadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.div(1000)
val playbackState = mediaCtrl?.playbackState?.state val playbackState = mediaCtrl?.playbackState?.state
var albumArtPath = ""
if (sbn.packageName == "com.spotify.music") {
val albumArt = mediaCtrl?.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART) val albumArt = mediaCtrl?.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)
val outputStream = ByteArrayOutputStream() val tempArtFile = File(cacheDir, "albumart_temp.png")
albumArt?.compress(Bitmap.CompressFormat.PNG, 75, outputStream) tempArtFile.createNewFile()
val artB64 = Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP) val fileOutputStream = FileOutputStream(tempArtFile)
albumArt?.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)
fileOutputStream.flush()
fileOutputStream.close()
albumArtPath = tempArtFile.absolutePath
}
// Retrieve package name to set as title. // Retrieve package name to set as title.
val packageName = sbn.packageName val packageName = sbn.packageName
@@ -60,14 +68,12 @@ class NotificationListener : NotificationListenerService() {
val extras = sbn.notification.extras val extras = sbn.notification.extras
val packageMessage = extras?.getCharSequence(Notification.EXTRA_TEXT).toString() val packageMessage = extras?.getCharSequence(Notification.EXTRA_TEXT).toString()
val packageText = extras?.getCharSequence("android.title").toString() val packageText = extras?.getCharSequence("android.title").toString()
val packageExtra = convertBundleToJsonString(sbn.notification.extras)
// Pass data from one activity to another. // Pass data from one activity to another.
val intent = Intent(NOTIFICATION_INTENT) val intent = Intent(NOTIFICATION_INTENT)
intent.putExtra(NOTIFICATION_PACKAGE_NAME, packageName) intent.putExtra(NOTIFICATION_PACKAGE_NAME, packageName)
intent.putExtra(NOTIFICATION_PACKAGE_MESSAGE, packageMessage) intent.putExtra(NOTIFICATION_PACKAGE_MESSAGE, packageMessage)
intent.putExtra(NOTIFICATION_PACKAGE_TEXT, packageText) intent.putExtra(NOTIFICATION_PACKAGE_TEXT, packageText)
intent.putExtra(NOTIFICATION_PACKAGE_EXTRA, packageExtra) intent.putExtra(NOTIFICATION_PACKAGE_ART, albumArtPath)
intent.putExtra(NOTIFICATION_PACKAGE_ART, artB64)
intent.putExtra(NOTIFICATION_PACKAGE_DURATION, duration) intent.putExtra(NOTIFICATION_PACKAGE_DURATION, duration)
intent.putExtra(NOTIFICATION_PACKAGE_PLAYBACK_STATE, playbackState) intent.putExtra(NOTIFICATION_PACKAGE_PLAYBACK_STATE, playbackState)
sendBroadcast(intent) sendBroadcast(intent)
@@ -29,12 +29,15 @@ class NotificationStreamHandler(private val context: Context) : StreamHandler {
context.unregisterReceiver(receiver) context.unregisterReceiver(receiver)
} }
fun cleanUp() {
context.unregisterReceiver(receiver)
}
internal inner class NotificationReceiver : BroadcastReceiver() { internal inner class NotificationReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val packageName = intent.getStringExtra(NotificationListener.NOTIFICATION_PACKAGE_NAME) val packageName = intent.getStringExtra(NotificationListener.NOTIFICATION_PACKAGE_NAME)
val packageMessage = intent.getStringExtra(NotificationListener.NOTIFICATION_PACKAGE_MESSAGE) val packageMessage = intent.getStringExtra(NotificationListener.NOTIFICATION_PACKAGE_MESSAGE)
val packageText = intent.getStringExtra(NotificationListener.NOTIFICATION_PACKAGE_TEXT) val packageText = intent.getStringExtra(NotificationListener.NOTIFICATION_PACKAGE_TEXT)
val packageExtra = intent.getStringExtra(NotificationListener.NOTIFICATION_PACKAGE_EXTRA)
val packageArt = intent.getStringExtra(NotificationListener.NOTIFICATION_PACKAGE_ART) val packageArt = intent.getStringExtra(NotificationListener.NOTIFICATION_PACKAGE_ART)
val packagePlaybackState = intent.getIntExtra(NotificationListener.NOTIFICATION_PACKAGE_PLAYBACK_STATE, -1) val packagePlaybackState = intent.getIntExtra(NotificationListener.NOTIFICATION_PACKAGE_PLAYBACK_STATE, -1)
val packageDuration = intent.getLongExtra(NotificationListener.NOTIFICATION_PACKAGE_DURATION, -1) val packageDuration = intent.getLongExtra(NotificationListener.NOTIFICATION_PACKAGE_DURATION, -1)
@@ -42,7 +45,6 @@ class NotificationStreamHandler(private val context: Context) : StreamHandler {
map["packageName"] = packageName!! map["packageName"] = packageName!!
map["packageMessage"] = packageMessage!! map["packageMessage"] = packageMessage!!
map["packageText"] = packageText!! map["packageText"] = packageText!!
map["packageExtra"] = packageExtra!!
map["packageArt"] = packageArt!! map["packageArt"] = packageArt!!
map["packagePlaybackState"] = packagePlaybackState map["packagePlaybackState"] = packagePlaybackState
map["packageDuration"] = packageDuration map["packageDuration"] = packageDuration
+3 -5
View File
@@ -65,8 +65,8 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
@override @override
void initState() { void initState() {
WidgetsBinding.instance?.addObserver(this); WidgetsBinding.instance?.addObserver(this);
initPlatformState();
super.initState(); super.initState();
initPlatformState();
} }
@override @override
@@ -103,7 +103,6 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
SystemNavigator.pop(); SystemNavigator.pop();
return Future.value(false); return Future.value(false);
}, },
child: Expanded(
child: AlertDialog( child: AlertDialog(
title: const Text( title: const Text(
'Notifications Access Permission', 'Notifications Access Permission',
@@ -122,7 +121,6 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
child: const Text("OK")), child: const Text("OK")),
], ],
), ),
),
); );
}); });
} }
@@ -159,7 +157,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
showWhen: false, showWhen: false,
ongoing: true, ongoing: true,
playSound: false, playSound: false,
largeIcon: ByteArrayAndroidBitmap.fromBase64String(notification.art), largeIcon: FilePathAndroidBitmap(notification.art),
); );
final NotificationDetails notificationDetails = final NotificationDetails notificationDetails =
@@ -167,7 +165,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
notificationId, notificationId,
'${notification.songTitle} - ${notification.artist}', 'Playing [${notification.songTitle}] By [${notification.artist}]',
'Tap to get lyrics', 'Tap to get lyrics',
notificationDetails, notificationDetails,
); );
-4
View File
@@ -22,7 +22,6 @@ abstract class PlaybackState {
class NotificationEvent { class NotificationEvent {
final String artist; final String artist;
final String packageName; final String packageName;
final String packageExtra;
final String songTitle; final String songTitle;
final String art; final String art;
final int playbackState; final int playbackState;
@@ -34,7 +33,6 @@ class NotificationEvent {
required this.packageName, required this.packageName,
required this.artist, required this.artist,
required this.timeStamp, required this.timeStamp,
required this.packageExtra,
required this.songTitle, required this.songTitle,
required this.art, required this.art,
required this.playbackState, required this.playbackState,
@@ -46,7 +44,6 @@ class NotificationEvent {
String name = map['packageName']; String name = map['packageName'];
String message = map['packageMessage']; String message = map['packageMessage'];
String text = map['packageText']; String text = map['packageText'];
String extra = map['packageExtra'];
String icon = map['packageArt']; String icon = map['packageArt'];
int playbackState = map['packagePlaybackState']; int playbackState = map['packagePlaybackState'];
int duration = map['packageDuration']; int duration = map['packageDuration'];
@@ -56,7 +53,6 @@ class NotificationEvent {
artist: message, artist: message,
timeStamp: time, timeStamp: time,
songTitle: text, songTitle: text,
packageExtra: extra,
art: icon, art: icon,
playbackState: playbackState, playbackState: playbackState,
duration: duration duration: duration