mirror of
https://github.com/IllusionMan1212/lyrics-grabbr.git
synced 2026-10-24 02:12:27 +00:00
fix/feat: fix some exceptions and add album art to notification
This commit is contained in:
@@ -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
-2
@@ -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)) {
|
||||||
|
|||||||
+14
-8
@@ -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)
|
||||||
|
|||||||
+4
-2
@@ -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
@@ -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,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user