From 052319aba136dfba7253297999d647c1c6693800 Mon Sep 17 00:00:00 2001 From: Austin H Date: Mon, 26 Aug 2019 16:52:24 -0400 Subject: [PATCH 1/9] Notification Listener Service to listen to notifications and identify track information for Media Players initial commit. --- app/src/main/AndroidManifest.xml | 34 +-- app/src/main/assets/changelog.txt | 2 +- .../java/com/adam/aslfms/AboutDialog.java | 2 +- .../com/adam/aslfms/EditUserCredentials.java | 2 +- .../com/adam/aslfms/MusicAppsActivity.java | 2 +- .../java/com/adam/aslfms/OptionsActivity.java | 2 +- .../com/adam/aslfms/SeekBarPreference.java | 2 +- .../com/adam/aslfms/SettingsActivity.java | 20 +- .../java/com/adam/aslfms/StatusActivity.java | 2 +- .../com/adam/aslfms/UserCredActivity.java | 2 +- .../adam/aslfms/UserCredsListActivity.java | 2 +- .../aslfms/ViewScrobbleCacheActivity.java | 2 +- .../adam/aslfms/ViewScrobbleInfoDialog.java | 2 +- .../java/com/adam/aslfms/WhatsNewDialog.java | 2 +- .../receiver/BuiltInMusicAppReceiver.java | 22 +- .../receiver/GenericControllerReceiver.java | 98 +++++++ .../receiver/MyTouch4GMusicReceiver.java | 2 +- .../aslfms/receiver/RdioMusicReceiver.java | 2 +- .../aslfms/receiver/SamsungMusicReceiver.java | 2 +- .../receiver/ScrobbleDroidMusicReceiver.java | 2 +- .../aslfms/receiver/WinampMusicReceiver.java | 2 +- .../aslfms/service/AbstractSubmitter.java | 2 +- .../service/ControllerReceiverCallback.java | 262 ++++++++++++++++++ .../service/ControllerReceiverService.java | 199 +++++++++++++ .../adam/aslfms/service/ForegroundHide.java | 2 +- .../com/adam/aslfms/service/Handshaker.java | 2 +- .../java/com/adam/aslfms/service/Heart.java | 2 +- .../service/MyHandshakeCompletedListener.java | 2 +- .../service/MySecureSSLSocketFactory.java | 2 +- .../com/adam/aslfms/service/NPNotifier.java | 2 +- .../java/com/adam/aslfms/service/NetApp.java | 2 +- .../com/adam/aslfms/service/NetRunnable.java | 2 +- .../aslfms/service/NetRunnableComparator.java | 2 +- .../adam/aslfms/service/NetworkWaiter.java | 2 +- .../com/adam/aslfms/service/Networker.java | 2 +- .../adam/aslfms/service/NetworkerManager.java | 2 +- .../service/NotificationBarService.java | 1 - .../com/adam/aslfms/service/Scrobbler.java | 6 +- .../aslfms/service/ScrobblingService.java | 4 +- .../java/com/adam/aslfms/service/Sleeper.java | 2 +- .../com/adam/aslfms/service/UserInfo.java | 2 +- .../com/adam/aslfms/util/AppSettings.java | 2 +- .../java/com/adam/aslfms/util/AuthStatus.java | 2 +- .../aslfms/util/InternalTrackTransmitter.java | 2 +- .../adam/aslfms/util/ScrobblesDatabase.java | 2 +- .../main/java/com/adam/aslfms/util/Track.java | 2 +- .../main/java/com/adam/aslfms/util/Util.java | 2 +- app/src/main/res/values/strings.xml | 2 + .../res/values/strings_nontranslatable.xml | 6 +- 49 files changed, 654 insertions(+), 76 deletions(-) create mode 100644 app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java create mode 100644 app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java create mode 100644 app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bb46f33e..97ee5861 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,7 +18,7 @@ android:label="@string/app_name" android:theme="@style/AppTheme"> - + - + - - + + - + android:exported="true" + android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> - + - - + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/changelog.txt b/app/src/main/assets/changelog.txt index 618174a1..6fc1b074 100644 --- a/app/src/main/assets/changelog.txt +++ b/app/src/main/assets/changelog.txt @@ -1,5 +1,5 @@ Visit, -https://github.com/tgwizard/sls +https://github.com/simple-last-fm-scrobbler/sls For more details. - 1.5.8 (2018-6-24) diff --git a/app/src/main/java/com/adam/aslfms/AboutDialog.java b/app/src/main/java/com/adam/aslfms/AboutDialog.java index cdf66a1e..5027a45d 100644 --- a/app/src/main/java/com/adam/aslfms/AboutDialog.java +++ b/app/src/main/java/com/adam/aslfms/AboutDialog.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/EditUserCredentials.java b/app/src/main/java/com/adam/aslfms/EditUserCredentials.java index 6b022779..ccc9e27f 100644 --- a/app/src/main/java/com/adam/aslfms/EditUserCredentials.java +++ b/app/src/main/java/com/adam/aslfms/EditUserCredentials.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java b/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java index 4edd8dc3..19ec0c1f 100644 --- a/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java +++ b/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/OptionsActivity.java b/app/src/main/java/com/adam/aslfms/OptionsActivity.java index 8719da66..b02fb0e4 100644 --- a/app/src/main/java/com/adam/aslfms/OptionsActivity.java +++ b/app/src/main/java/com/adam/aslfms/OptionsActivity.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/SeekBarPreference.java b/app/src/main/java/com/adam/aslfms/SeekBarPreference.java index f470cdfb..095d217b 100644 --- a/app/src/main/java/com/adam/aslfms/SeekBarPreference.java +++ b/app/src/main/java/com/adam/aslfms/SeekBarPreference.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/SettingsActivity.java b/app/src/main/java/com/adam/aslfms/SettingsActivity.java index e4e7e1bb..42fdae4c 100644 --- a/app/src/main/java/com/adam/aslfms/SettingsActivity.java +++ b/app/src/main/java/com/adam/aslfms/SettingsActivity.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

@@ -35,6 +35,7 @@ import android.preference.PreferenceScreen; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; +import android.support.v4.app.NotificationManagerCompat; import android.support.v4.content.ContextCompat; import android.util.Log; import android.view.Menu; @@ -42,6 +43,7 @@ import android.view.MenuItem; import android.widget.Toast; +import com.adam.aslfms.service.ControllerReceiverService; import com.adam.aslfms.service.NetApp; import com.adam.aslfms.service.applemusic.NotificationService; import com.adam.aslfms.service.ScrobblingService; @@ -123,6 +125,13 @@ protected void onCreate(Bundle savedInstanceState) { permsCheck(); credsCheck(); + // TODO: MODIFY ME!!! + Log.e(TAG,"ControllerReceiverService starting.."); + Intent myIntent = new Intent(this, ControllerReceiverService.class); + this.startService(myIntent); + Log.e(TAG,"ControllerReceiverService started."); + // TODO: MODIFY ME!!! + // TODO: VERIFY EVERYTHING BELOW IS SAFE int v = Util.getAppVersionCode(this, getPackageName()); if (settings.getWhatsNewViewedVersion() < v) { @@ -251,6 +260,13 @@ private void credsCheck() { private void permsCheck() { //PERMISSION CHECK + if (!NotificationManagerCompat.getEnabledListenerPackages (getApplicationContext()).contains(getApplicationContext().getPackageName())) { + Toast.makeText(SettingsActivity.this, R.string.notification_access_required, Toast.LENGTH_LONG).show(); + getApplicationContext().startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } else { + + } + // external storage if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { try { if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { @@ -260,7 +276,7 @@ private void permsCheck() { Log.e(TAG, "Exception, READ_EXTERNAL_STORAGE. " + e); } } - + // battery optimization try { if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(SettingsActivity.this, new String[]{Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS}, REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); diff --git a/app/src/main/java/com/adam/aslfms/StatusActivity.java b/app/src/main/java/com/adam/aslfms/StatusActivity.java index 8f66a24b..a0da81e9 100644 --- a/app/src/main/java/com/adam/aslfms/StatusActivity.java +++ b/app/src/main/java/com/adam/aslfms/StatusActivity.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/UserCredActivity.java b/app/src/main/java/com/adam/aslfms/UserCredActivity.java index 787e628f..e26a483d 100644 --- a/app/src/main/java/com/adam/aslfms/UserCredActivity.java +++ b/app/src/main/java/com/adam/aslfms/UserCredActivity.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/UserCredsListActivity.java b/app/src/main/java/com/adam/aslfms/UserCredsListActivity.java index 2dcb4756..78d85dff 100644 --- a/app/src/main/java/com/adam/aslfms/UserCredsListActivity.java +++ b/app/src/main/java/com/adam/aslfms/UserCredsListActivity.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/ViewScrobbleCacheActivity.java b/app/src/main/java/com/adam/aslfms/ViewScrobbleCacheActivity.java index c4c1fc05..1f655d4b 100644 --- a/app/src/main/java/com/adam/aslfms/ViewScrobbleCacheActivity.java +++ b/app/src/main/java/com/adam/aslfms/ViewScrobbleCacheActivity.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/ViewScrobbleInfoDialog.java b/app/src/main/java/com/adam/aslfms/ViewScrobbleInfoDialog.java index 1ddf2d33..e39ca1b8 100644 --- a/app/src/main/java/com/adam/aslfms/ViewScrobbleInfoDialog.java +++ b/app/src/main/java/com/adam/aslfms/ViewScrobbleInfoDialog.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/WhatsNewDialog.java b/app/src/main/java/com/adam/aslfms/WhatsNewDialog.java index 82bd76e6..56c29561 100644 --- a/app/src/main/java/com/adam/aslfms/WhatsNewDialog.java +++ b/app/src/main/java/com/adam/aslfms/WhatsNewDialog.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/receiver/BuiltInMusicAppReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/BuiltInMusicAppReceiver.java index 78b28fb9..b657f003 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/BuiltInMusicAppReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/BuiltInMusicAppReceiver.java @@ -271,26 +271,24 @@ void readTrackFromBundleData(Track.Builder b, Bundle bundle) { CharSequence tr = bundle.getCharSequence("track"); // duration should be an Integer in seconds. - - if(bundle.containsKey("duration")){ + if (bundle.containsKey("duration")) { Object tmp = bundle.get("duration"); if (tmp != null) { - if (tmp instanceof Long) { + if (tmp instanceof Double) { try { - long du = bundle.getLong("duration"); - // TODO: fix google play music track duration by using Android Audio Focus as a Tracking tool for current listening music. - b.setDuration(new BigDecimal(bundle.getLong("duration") /1000).intValueExact()); - Log.d(TAG, "Long Integer: " + Long.toString(du)); + double du = bundle.getDouble("duration"); + b.setDuration(new BigDecimal(Math.round(bundle.getDouble("duration") / 1000)).intValueExact()); + Log.d(TAG, "Double: " + du); } catch (Exception e) { - Log.e(TAG, "duration: " + e); + Log.e(TAG, "dbl duration: " + e); } - } else if (tmp instanceof Integer){ + } else if (tmp instanceof Integer) { try { int du = bundle.getInt("duration"); - b.setDuration(bundle.getInt("duration")); - Log.d(TAG, "Integer: " + Integer.toString(du)); + b.setDuration(new BigDecimal(bundle.getInt("duration") / 1000).intValueExact()); + Log.d(TAG, "Integer: " + du); } catch (Exception e) { - Log.e(TAG, "duration: " + e); + Log.e(TAG, "int duration: " + e); } } } diff --git a/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java new file mode 100644 index 00000000..cc09a2e1 --- /dev/null +++ b/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java @@ -0,0 +1,98 @@ +package com.adam.aslfms.receiver; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.util.Log; + +import com.adam.aslfms.R; +import com.adam.aslfms.util.Track; +import com.adam.aslfms.util.Util; + +import java.math.BigDecimal; + +public class GenericControllerReceiver extends AbstractPlayStatusReceiver{ + public static final String ACTION_INTENT = "com.adam.aslfms.receiver.controller"; + static final String APP_NAME = "GenericController"; + static final String TAG = "GenControllerReceiver"; + + private MusicAPI mMusicApi = null; + + @Override + protected void parseIntent(Context ctx, String action, Bundle bundle) throws IllegalArgumentException { + String playerPackage = null; + String playerName = null; + try { + if (action == ACTION_INTENT) { + try { + if (bundle.containsKey("player")) { + playerPackage = bundle.getString("player"); + if (playerPackage != null && !playerPackage.isEmpty()) { + PackageManager packageManager = ctx.getPackageManager(); + try { + playerName = packageManager.getApplicationLabel(packageManager.getApplicationInfo(playerPackage, PackageManager.GET_META_DATA)).toString(); + } catch (Exception e) { + Log.e(TAG, e.toString()); + } + MusicAPI mMusicApi = MusicAPI.fromReceiver(ctx, playerName, playerPackage, null, false); + setMusicAPI(mMusicApi); + } + } + } catch (Exception e) { + Log.w(TAG, e.toString()); + } + Log.w(TAG, ctx.getPackageName()); + mMusicApi = MusicAPI.fromReceiver(ctx, ctx.getResources().getString(R.string.notification_controller), ctx.getPackageName(), null, false); + setMusicAPI(mMusicApi); + if (bundle.containsKey("track")) { + Track.Builder b = new Track.Builder(); + b.setMusicAPI(mMusicApi); + b.setWhen(Util.currentTimeSecsUTC()); + + b.setArtist(bundle.getString("artist")); + b.setAlbum(bundle.getString("album")); + b.setTrack(bundle.getString("track")); + b.setAlbumArtist(bundle.getString("albumartist")); + // duration should be an Integer in seconds. + if (bundle.containsKey("duration")) { + Object tmp = bundle.get("duration"); + if (tmp != null) { + if (tmp instanceof Double) { + try { + double du = bundle.getDouble("duration"); + b.setDuration(new BigDecimal(Math.round(bundle.getDouble("duration") / 1000)).intValueExact()); + Log.d(TAG, "Double: " + du); + } catch (Exception e) { + Log.e(TAG, "dbl duration: " + e); + } + } else if (tmp instanceof Integer) { + try { + int du = bundle.getInt("duration"); + b.setDuration(new BigDecimal(bundle.getInt("duration") / 1000).intValueExact()); + Log.d(TAG, "Integer: " + du); + } catch (Exception e) { + Log.e(TAG, "int duration: " + e); + } + } + } + } + Log.d(TAG, + bundle.getString("artist") + " - " + + bundle.getString("track") + " (" + + bundle.getInt("length", 0) + ")"); + setTrack(b.build()); + } + boolean playing = bundle.getBoolean("playing"); + if (playing) { + setState(Track.State.RESUME); + Log.d(TAG, "Setting state to RESUME"); + } else { + setState(Track.State.PAUSE); + Log.d(TAG, "Setting state to PAUSE"); + } + } + } catch (Exception e){ + Log.e(TAG,e.toString()); + } + } +} diff --git a/app/src/main/java/com/adam/aslfms/receiver/MyTouch4GMusicReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/MyTouch4GMusicReceiver.java index 92b560ec..48cf566d 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/MyTouch4GMusicReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/MyTouch4GMusicReceiver.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/receiver/RdioMusicReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/RdioMusicReceiver.java index 006f4cca..4784645b 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/RdioMusicReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/RdioMusicReceiver.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/receiver/SamsungMusicReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/SamsungMusicReceiver.java index b3562bce..4df0c5e7 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/SamsungMusicReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/SamsungMusicReceiver.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/receiver/ScrobbleDroidMusicReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/ScrobbleDroidMusicReceiver.java index bc2dd814..d2326a57 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/ScrobbleDroidMusicReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/ScrobbleDroidMusicReceiver.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/receiver/WinampMusicReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/WinampMusicReceiver.java index a1e7f8f1..9deab95e 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/WinampMusicReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/WinampMusicReceiver.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/AbstractSubmitter.java b/app/src/main/java/com/adam/aslfms/service/AbstractSubmitter.java index 72605b55..f67aa5a5 100644 --- a/app/src/main/java/com/adam/aslfms/service/AbstractSubmitter.java +++ b/app/src/main/java/com/adam/aslfms/service/AbstractSubmitter.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java new file mode 100644 index 00000000..f3cb239f --- /dev/null +++ b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java @@ -0,0 +1,262 @@ +package com.adam.aslfms.service; + +import android.annotation.TargetApi; +import android.app.NotificationManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.media.MediaMetadata; +import android.media.session.MediaController; +import android.media.session.MediaSessionManager; +import android.media.session.PlaybackState; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.support.annotation.RequiresApi; +import android.util.Log; + +import com.adam.aslfms.receiver.GenericControllerReceiver; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.util.List; + +public class ControllerReceiverCallback { + + private static final String TAG = "ControllerReceiverCall"; + private static MediaSessionManager.OnActiveSessionsChangedListener sessionListener; + private final MetadataUpdateListener metadataListener; + private MediaController controller; + private String mPlayer = null; + private static WeakReference sController = new WeakReference<>(null); + private MediaController.Callback controllerCallback; + private Handler handler = new Handler(); + private Bitmap lastBitmap; + + public ControllerReceiverCallback(MetadataUpdateListener metadataListener) { + this.metadataListener = metadataListener; + } + + + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + public static void registerFallbackControllerCallback(Context context, ControllerReceiverCallback controllerReceiverCallback) { + MediaSessionManager mediaSessionManager = ((MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE)); + ComponentName className = new ComponentName(context.getApplicationContext(), ControllerReceiverService.class); + if (sessionListener != null) + mediaSessionManager.removeOnActiveSessionsChangedListener(sessionListener); + sessionListener = list -> controllerReceiverCallback.registerActiveSessionCallback(context, list); + mediaSessionManager.addOnActiveSessionsChangedListener(sessionListener, className); + controllerReceiverCallback.registerActiveSessionCallback(context, mediaSessionManager.getActiveSessions(className)); + } + + public void registerActiveSessionCallback(Context context, List controllers) { + if (controllers.size() > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + controller = controllers.get(0); + sController = new WeakReference<>(controller); + if (controllerCallback != null) { + for (MediaController ctlr : controllers) + ctlr.unregisterCallback(controllerCallback); + } else { + controllerCallback = new MediaController.Callback() { + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + @Override + public void onPlaybackStateChanged(PlaybackState state) { + super.onPlaybackStateChanged(state); + if (state == null) + return; + boolean isPlaying = state.getState() == PlaybackState.STATE_PLAYING; + if (!isPlaying) { + NotificationManager notificationManager = + ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)); + notificationManager.cancel(0); + notificationManager.cancel(8); + } + if (controller != controller) + return; //ignore inactive sessions + broadcastControllerState(context, controller, isPlaying); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + @Override + public void onMetadataChanged(MediaMetadata metadata) { + super.onMetadataChanged(metadata); + if (controller != controller) + return; + if (metadata == null) + return; + broadcastControllerState(context, controller, null); + } + }; + } + controller.registerCallback(controllerCallback); + broadcastControllerState(context, controller, null); + } + } + + public static long getActiveControllerPosition(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && sController.get() != null) { + PlaybackState state = sController.get().getPlaybackState(); + if (state != null) + return state.getPosition(); + } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { + long kitkatPosition = ControllerReceiverService.getRemotePlayerPosition(); + if (kitkatPosition >= 0) + return kitkatPosition; + } + SharedPreferences preferences = context.getSharedPreferences("current_music", Context.MODE_PRIVATE); + long startTime = preferences.getLong("startTime", System.currentTimeMillis()); + long distance = System.currentTimeMillis() - startTime; + long position = preferences.getLong("position", -1L); + if (preferences.getBoolean("playing", true) && position >= 0L) + position += distance; + return position; + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public void removeControllerCallback() { + if (controllerCallback != null && controller != null) { + controller.unregisterCallback(controllerCallback); + } + controllerCallback = null; + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public void broadcastControllerState(Context context, MediaController controller, Boolean isPlaying) { + final MediaController[] controllers = new MediaController[]{controller}; + final Boolean[] playing = new Boolean[]{isPlaying}; + handler.postDelayed(() -> { + mPlayer = controllers[0].getPackageName(); + Log.e(TAG, "mPlayer: " + mPlayer); + MediaMetadata metadata = controllers[0].getMetadata(); + PlaybackState playbackState = controllers[0].getPlaybackState(); + if (metadata == null) + return; + String artist = null; + try { + artist = metadata.getString(MediaMetadata.METADATA_KEY_ARTIST); + if (artist == null) + artist = metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST); + } catch (Exception ignored) { + } + String albumArtist = null; + try { + albumArtist = metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST); + } catch (Exception ignored){ + } + String track = null; + try { + track = metadata.getString(MediaMetadata.METADATA_KEY_TITLE); + } catch (Exception ignored) { + } + Bitmap artwork = null; + try { + artwork = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); + if (artwork == null) + artwork = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART); + } catch (Exception ignored) { + } + + double duration; + try { + duration =(double) metadata.getLong(MediaMetadata.METADATA_KEY_DURATION); + } catch (RuntimeException ignored) { + duration = 0; + } + long position = duration == 0 || playbackState == null ? -1 : playbackState.getPosition(); + + if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("pref_filter_20min", true) && duration > 1200000) + return; + if (playing[0] == null) + playing[0] = playbackState != null && playbackState.getState() == PlaybackState.STATE_PLAYING; + + saveArtwork(context, artwork, artist, track); + + String player = controllers[0].getPackageName(); + if ("com.aimp.player".equals(player)) // Aimp is awful + position = -1; + broadcast(context, artist, track, playing[0], duration, position, albumArtist); + }, 100); + } + + public void broadcast(Context context, String artist, String track, boolean playing, int duration, long position, String albumArtist) { + Intent localIntent = new Intent(GenericControllerReceiver.ACTION_INTENT); + localIntent.putExtra("artist", artist); + localIntent.putExtra("track", track); + localIntent.putExtra("albumArtist", albumArtist); + localIntent.putExtra("playing", playing); + localIntent.putExtra("duration", duration); + localIntent.putExtra("player", mPlayer); + Log.d("title", track); + if (position != -1) + localIntent.putExtra("position", position); + context.sendBroadcast(localIntent); + Log.d(TAG,"title "+track); + } + + public void broadcast(Context context, String artist, String track, boolean playing, double duration, long position, String albumArtist) { + Intent localIntent = new Intent(GenericControllerReceiver.ACTION_INTENT); + localIntent.putExtra("artist", artist); + localIntent.putExtra("track", track); + localIntent.putExtra("albumArtist", albumArtist); + localIntent.putExtra("playing", playing); + localIntent.putExtra("duration", duration); + localIntent.putExtra("player", mPlayer); + Log.d("title", track); + if (position != -1) + localIntent.putExtra("position", position); + context.sendBroadcast(localIntent); + Log.d(TAG,"title "+track); + } + + public void saveArtwork(Context context, Bitmap artwork, String artist, String track) { + File artworksDir = new File(context.getCacheDir(), "artworks"); + if (artwork != null && (artworksDir.exists() || artworksDir.mkdir())) { + File artworkFile = new File(artworksDir, artist + track + ".png"); + if (!artworkFile.exists()) + try { + //noinspection ResultOfMethodCallIgnored + artworkFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + + if (artworkFile.length() == 0) { + FileOutputStream fos = null; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + artwork.compress(Bitmap.CompressFormat.PNG, 100, stream); + try { + fos = new FileOutputStream(artworkFile); + stream.writeTo(fos); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (fos != null) + { + fos.flush(); + fos.getFD().sync(); + fos.close(); + } + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + if (lastBitmap != null) { + lastBitmap.recycle(); + } + lastBitmap = artwork; + } + } + + public interface MetadataUpdateListener { + void onMetadataUpdated(Bundle metadata); + } +} diff --git a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java new file mode 100644 index 00000000..de54f0f2 --- /dev/null +++ b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java @@ -0,0 +1,199 @@ +package com.adam.aslfms.service; + +import android.annotation.TargetApi; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.media.AudioManager; +import android.media.MediaMetadataEditor; +import android.media.MediaMetadataRetriever; +import android.media.RemoteControlClient; +import android.media.RemoteController; +import android.os.Build; +import android.os.Bundle; +import android.os.IBinder; +import android.provider.Settings; +import android.support.v4.app.NotificationManagerCompat; +import android.util.Log; + +import java.lang.ref.WeakReference; +import java.util.Set; + +@SuppressWarnings("deprecation") +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +public class ControllerReceiverService extends android.service.notification.NotificationListenerService implements RemoteController.OnClientUpdateListener, ControllerReceiverCallback.MetadataUpdateListener { + + private static final String TAG = "ControllerReceiverSrvc"; + private static WeakReference mRemoteController = new WeakReference<>(null); + private ControllerReceiverCallback controllerReceiverCallback; + private String track; + private String artist; + private String albumArtist; + private Object durationObject; + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + @SuppressWarnings("NewApi") + public void onCreate() { + super.onCreate(); + if (NotificationManagerCompat.getEnabledListenerPackages (getApplicationContext()).contains(getApplicationContext().getPackageName())) { + mRemoteController = new WeakReference<>(new RemoteController(this, this)); + mRemoteController.get().setArtworkConfiguration(3000, 3000); + if (!((AudioManager) getSystemService(Context.AUDIO_SERVICE)).registerRemoteController(mRemoteController.get())) { + throw new RuntimeException("Error while registering RemoteController!"); + } + controllerReceiverCallback = new ControllerReceiverCallback(this); + } + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return START_STICKY; + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + if (mRemoteController != null && mRemoteController.get() != null) + ((AudioManager) getSystemService(Context.AUDIO_SERVICE)).unregisterRemoteController(mRemoteController.get()); + } + } + + public static boolean isControllerReceiverServiceEnabled(Context context) { + Set packageNames = NotificationManagerCompat.getEnabledListenerPackages(context); + return packageNames.contains(context.getPackageName()); + } + + private void disableControllerReceiverService() { + PackageManager pm = getPackageManager(); + pm.setComponentEnabledSetting(new ComponentName(getApplicationContext(), ControllerReceiverService.class), + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); + } + + /* KitKat stuff */ + + private boolean isRemoteControllerPlaying; + private boolean mHasBug = true; + + @Override + public void onClientChange(boolean clearing) { + // isListeningAuthorized(ControllerReceiverService.this); + } + + @Override + public void onClientPlaybackStateUpdate(int state) { + this.isRemoteControllerPlaying = state == RemoteControlClient.PLAYSTATE_PLAYING; + } + + + public static long getRemotePlayerPosition() { + return mRemoteController.get() != null ? + Math.min(3600000,mRemoteController.get().getEstimatedMediaPosition()) : -1L; + } + + @Override + public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs, long currentPosMs, float speed) { + this.isRemoteControllerPlaying = state == RemoteControlClient.PLAYSTATE_PLAYING; + mHasBug = false; + if (currentPosMs > 3600000) + currentPosMs = -1L; + SharedPreferences current = getSharedPreferences("current_music", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = current.edit(); + editor.putLong("position", currentPosMs); + + if (isRemoteControllerPlaying) { + long currentTime = System.currentTimeMillis(); + editor.putLong("startTime", currentTime); + } + editor.putBoolean("playing", isRemoteControllerPlaying); + editor.apply(); + + Log.d(TAG, "PlaybackStateUpdate - position stored: " + currentPosMs); + + long position = getRemotePlayerPosition(); + + if (durationObject instanceof Double) { + Log.d(TAG,"duration is Double"); + if (artist != null && !artist.isEmpty()) + controllerReceiverCallback.broadcast(this, artist, track, isRemoteControllerPlaying, (Double) durationObject, position,albumArtist); + } else if (durationObject instanceof Integer) { + Log.d(TAG,"duration is Integer"); + if (artist != null && !artist.isEmpty()) + controllerReceiverCallback.broadcast(this, artist, track, isRemoteControllerPlaying, (Integer) durationObject, position, albumArtist); + } else if (durationObject instanceof Long) + Log.d(TAG,"duration is Long"); + if (artist != null && !artist.isEmpty()) + controllerReceiverCallback.broadcast(this, artist, track, isRemoteControllerPlaying, (Long) durationObject, position, albumArtist); + } + + @Override + public void onClientTransportControlUpdate(int transportControlFlags) { + if (mHasBug && mRemoteController.get() != null) { + long position = mRemoteController.get().getEstimatedMediaPosition(); + if (position > 3600000) + position = -1L; + SharedPreferences current = getSharedPreferences("current_music", Context.MODE_PRIVATE); + current.edit().putLong("position", position).apply(); + if (isRemoteControllerPlaying) { + long currentTime = System.currentTimeMillis(); + current.edit().putLong("startTime", currentTime).apply(); + } + Log.d(TAG, "TransportControlUpdate - position stored: " + position); + } + } + + @Override + public void onClientMetadataUpdate(RemoteController.MetadataEditor metadataEditor) { + // isRemoteControllerPlaying = true; + + durationObject = metadataEditor.getObject(MediaMetadataRetriever.METADATA_KEY_DURATION, 1200); //allow it to pass if not present + artist = metadataEditor.getString(MediaMetadataRetriever.METADATA_KEY_ARTIST, ""); + albumArtist = metadataEditor.getString(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, ""); + track = metadataEditor.getString(MediaMetadataRetriever.METADATA_KEY_TITLE, ""); + Bitmap artwork = metadataEditor.getBitmap(MediaMetadataEditor.BITMAP_KEY_ARTWORK, null); + + controllerReceiverCallback.saveArtwork(this, artwork, artist, track); + } + + @Override + public void onMetadataUpdated(Bundle metadata) { + } + + // BEGIN listener stuff + + @Override + public void onListenerConnected() { + super.onListenerConnected(); + } + + @Override + @TargetApi(24) + public void onListenerDisconnected() { + super.onListenerDisconnected(); + requestRebind(new ComponentName(getApplicationContext(), ControllerReceiverService.class)); + } + + public static boolean isListeningAuthorized(Context context) { + ContentResolver contentResolver = context.getContentResolver(); + String enabledNotificationListeners = Settings.Secure.getString(contentResolver, "enabled_notification_listeners"); + String packageName = context.getPackageName(); + + return !(enabledNotificationListeners == null || !enabledNotificationListeners.contains(packageName)); + } + + public static boolean isNotificationListenerServiceEnabled(Context context) { + Set packageNames = NotificationManagerCompat.getEnabledListenerPackages(context); + return packageNames.contains(context.getPackageName()); + } + + // END listener stuff +} \ No newline at end of file diff --git a/app/src/main/java/com/adam/aslfms/service/ForegroundHide.java b/app/src/main/java/com/adam/aslfms/service/ForegroundHide.java index f95c0c46..794e1014 100644 --- a/app/src/main/java/com/adam/aslfms/service/ForegroundHide.java +++ b/app/src/main/java/com/adam/aslfms/service/ForegroundHide.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/Handshaker.java b/app/src/main/java/com/adam/aslfms/service/Handshaker.java index 24f93c40..cce3322d 100644 --- a/app/src/main/java/com/adam/aslfms/service/Handshaker.java +++ b/app/src/main/java/com/adam/aslfms/service/Handshaker.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/Heart.java b/app/src/main/java/com/adam/aslfms/service/Heart.java index 90c68c40..a9a331a1 100644 --- a/app/src/main/java/com/adam/aslfms/service/Heart.java +++ b/app/src/main/java/com/adam/aslfms/service/Heart.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/MyHandshakeCompletedListener.java b/app/src/main/java/com/adam/aslfms/service/MyHandshakeCompletedListener.java index 1a46eb03..5c1fcaf4 100644 --- a/app/src/main/java/com/adam/aslfms/service/MyHandshakeCompletedListener.java +++ b/app/src/main/java/com/adam/aslfms/service/MyHandshakeCompletedListener.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/MySecureSSLSocketFactory.java b/app/src/main/java/com/adam/aslfms/service/MySecureSSLSocketFactory.java index b96dc609..26e1dd37 100644 --- a/app/src/main/java/com/adam/aslfms/service/MySecureSSLSocketFactory.java +++ b/app/src/main/java/com/adam/aslfms/service/MySecureSSLSocketFactory.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/NPNotifier.java b/app/src/main/java/com/adam/aslfms/service/NPNotifier.java index f57a884e..ae10ba40 100644 --- a/app/src/main/java/com/adam/aslfms/service/NPNotifier.java +++ b/app/src/main/java/com/adam/aslfms/service/NPNotifier.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/NetApp.java b/app/src/main/java/com/adam/aslfms/service/NetApp.java index a8ea6924..90aaf964 100644 --- a/app/src/main/java/com/adam/aslfms/service/NetApp.java +++ b/app/src/main/java/com/adam/aslfms/service/NetApp.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/NetRunnable.java b/app/src/main/java/com/adam/aslfms/service/NetRunnable.java index c9ef1b13..9887f16d 100644 --- a/app/src/main/java/com/adam/aslfms/service/NetRunnable.java +++ b/app/src/main/java/com/adam/aslfms/service/NetRunnable.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/NetRunnableComparator.java b/app/src/main/java/com/adam/aslfms/service/NetRunnableComparator.java index cb1df460..9779b0fb 100644 --- a/app/src/main/java/com/adam/aslfms/service/NetRunnableComparator.java +++ b/app/src/main/java/com/adam/aslfms/service/NetRunnableComparator.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/NetworkWaiter.java b/app/src/main/java/com/adam/aslfms/service/NetworkWaiter.java index c415ce02..0edc3e5d 100644 --- a/app/src/main/java/com/adam/aslfms/service/NetworkWaiter.java +++ b/app/src/main/java/com/adam/aslfms/service/NetworkWaiter.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/Networker.java b/app/src/main/java/com/adam/aslfms/service/Networker.java index 4583117c..3475ffc7 100644 --- a/app/src/main/java/com/adam/aslfms/service/Networker.java +++ b/app/src/main/java/com/adam/aslfms/service/Networker.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/NetworkerManager.java b/app/src/main/java/com/adam/aslfms/service/NetworkerManager.java index 23475e28..41229942 100644 --- a/app/src/main/java/com/adam/aslfms/service/NetworkerManager.java +++ b/app/src/main/java/com/adam/aslfms/service/NetworkerManager.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java b/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java index a20c6c5c..1392c0ac 100644 --- a/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java +++ b/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java @@ -158,7 +158,6 @@ private void handleCommand(Intent i, int startId) { Log.e(TAG, "got null intent"); return; } - Log.e(TAG, "got intent"); String action = i.getAction(); Bundle extras = i.getExtras(); if (action.equals(ACTION_NOTIFICATION_BAR_UPDATE)) { diff --git a/app/src/main/java/com/adam/aslfms/service/Scrobbler.java b/app/src/main/java/com/adam/aslfms/service/Scrobbler.java index 5e386554..71568209 100644 --- a/app/src/main/java/com/adam/aslfms/service/Scrobbler.java +++ b/app/src/main/java/com/adam/aslfms/service/Scrobbler.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

@@ -275,7 +275,7 @@ public void scrobbleCommit(HandshakeResult hInfo, Track[] tracks) insecConn.setDoOutput(true); DataOutputStream outStream = new DataOutputStream(insecConn.getOutputStream()); - Log.e(TAG, baseObj.toString()); + Log.d(TAG, baseObj.toString()); outStream.write(baseObj.toString().getBytes("UTF-8")); outStream.flush(); outStream.close(); @@ -305,7 +305,7 @@ public void scrobbleCommit(HandshakeResult hInfo, Track[] tracks) conn.setDoOutput(true); DataOutputStream outStream = new DataOutputStream(conn.getOutputStream()); - Log.e(TAG, baseObj.toString()); + Log.d(TAG, baseObj.toString()); outStream.write(baseObj.toString().getBytes("UTF-8")); outStream.flush(); outStream.close(); diff --git a/app/src/main/java/com/adam/aslfms/service/ScrobblingService.java b/app/src/main/java/com/adam/aslfms/service/ScrobblingService.java index 5e99b1e3..14240414 100644 --- a/app/src/main/java/com/adam/aslfms/service/ScrobblingService.java +++ b/app/src/main/java/com/adam/aslfms/service/ScrobblingService.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

@@ -41,6 +41,8 @@ import com.adam.aslfms.service.NotificationBarService; +import java.net.Inet4Address; + /** * @author tgwizard */ diff --git a/app/src/main/java/com/adam/aslfms/service/Sleeper.java b/app/src/main/java/com/adam/aslfms/service/Sleeper.java index 84a96739..3a816de5 100644 --- a/app/src/main/java/com/adam/aslfms/service/Sleeper.java +++ b/app/src/main/java/com/adam/aslfms/service/Sleeper.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/service/UserInfo.java b/app/src/main/java/com/adam/aslfms/service/UserInfo.java index 51af9179..3f9294ee 100644 --- a/app/src/main/java/com/adam/aslfms/service/UserInfo.java +++ b/app/src/main/java/com/adam/aslfms/service/UserInfo.java @@ -3,7 +3,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/util/AppSettings.java b/app/src/main/java/com/adam/aslfms/util/AppSettings.java index 577e7172..d59801ae 100644 --- a/app/src/main/java/com/adam/aslfms/util/AppSettings.java +++ b/app/src/main/java/com/adam/aslfms/util/AppSettings.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/util/AuthStatus.java b/app/src/main/java/com/adam/aslfms/util/AuthStatus.java index 5b7aadac..461df264 100644 --- a/app/src/main/java/com/adam/aslfms/util/AuthStatus.java +++ b/app/src/main/java/com/adam/aslfms/util/AuthStatus.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/util/InternalTrackTransmitter.java b/app/src/main/java/com/adam/aslfms/util/InternalTrackTransmitter.java index 64ac241e..d1083d44 100644 --- a/app/src/main/java/com/adam/aslfms/util/InternalTrackTransmitter.java +++ b/app/src/main/java/com/adam/aslfms/util/InternalTrackTransmitter.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java b/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java index 06f51756..f68e7f1f 100644 --- a/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java +++ b/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/util/Track.java b/app/src/main/java/com/adam/aslfms/util/Track.java index 9c02af39..647a4782 100644 --- a/app/src/main/java/com/adam/aslfms/util/Track.java +++ b/app/src/main/java/com/adam/aslfms/util/Track.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/java/com/adam/aslfms/util/Util.java b/app/src/main/java/com/adam/aslfms/util/Util.java index 383b564c..49646bbe 100644 --- a/app/src/main/java/com/adam/aslfms/util/Util.java +++ b/app/src/main/java/com/adam/aslfms/util/Util.java @@ -1,7 +1,7 @@ /** * This file is part of Simple Last.fm Scrobbler. *

- * https://github.com/tgwizard/sls + * https://github.com/simple-last-fm-scrobbler/sls *

* Copyright 2011 Simple Last.fm Scrobbler Team *

diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 559d3fbb..2c0d5fcc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -121,6 +121,7 @@ Permission REQUIRED to work properly Credentials REQUIRED to work properly + Notification access REQUIRED to work properly Limited Network @@ -136,6 +137,7 @@ %1 music apps detected Play music in a supported app and it will appear here Unknown app (pre SLS v1.2.3) + Notification Controller diff --git a/app/src/main/res/values/strings_nontranslatable.xml b/app/src/main/res/values/strings_nontranslatable.xml index a528fdc7..bacae9fb 100644 --- a/app/src/main/res/values/strings_nontranslatable.xml +++ b/app/src/main/res/values/strings_nontranslatable.xml @@ -3,9 +3,9 @@ SLS Simple Last.fm Scrobbler simple.lfm.scrobbler@gmail.com - https://github.com/tgwizard/sls - https://github.com/tgwizard/sls/issues - https://github.com/tgwizard/sls/blob/master/TroubleShooting.md + https://github.com/simple-last-fm-scrobbler/sls + https://github.com/simple-last-fm-scrobbler/sls/issues + https://github.com/simple-last-fm-scrobbler/sls/blob/master/TroubleShooting.md Active App Clear Apps Nixtape URL From 780c0522f542ed6cab70c54f5f5690a1ba37fa2d Mon Sep 17 00:00:00 2001 From: Austin H Date: Mon, 26 Aug 2019 19:39:19 -0400 Subject: [PATCH 2/9] Album Added Album --- .../service/ControllerReceiverCallback.java | 17 ++++++++++++----- .../service/ControllerReceiverService.java | 11 +++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java index f3cb239f..2ee503c1 100644 --- a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java +++ b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java @@ -154,6 +154,11 @@ public void broadcastControllerState(Context context, MediaController controller track = metadata.getString(MediaMetadata.METADATA_KEY_TITLE); } catch (Exception ignored) { } + String album = null; + try { + album = metadata.getString(MediaMetadata.METADATA_KEY_ALBUM); + } catch (Exception ignored) { + } Bitmap artwork = null; try { artwork = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); @@ -175,19 +180,20 @@ public void broadcastControllerState(Context context, MediaController controller if (playing[0] == null) playing[0] = playbackState != null && playbackState.getState() == PlaybackState.STATE_PLAYING; - saveArtwork(context, artwork, artist, track); + saveArtwork(context, artwork, artist, track, album); String player = controllers[0].getPackageName(); if ("com.aimp.player".equals(player)) // Aimp is awful position = -1; - broadcast(context, artist, track, playing[0], duration, position, albumArtist); + broadcast(context, artist, track, album, playing[0], duration, position, albumArtist); }, 100); } - public void broadcast(Context context, String artist, String track, boolean playing, int duration, long position, String albumArtist) { + public void broadcast(Context context, String artist, String track, String album, boolean playing, int duration, long position, String albumArtist) { Intent localIntent = new Intent(GenericControllerReceiver.ACTION_INTENT); localIntent.putExtra("artist", artist); localIntent.putExtra("track", track); + localIntent.putExtra("album", album); localIntent.putExtra("albumArtist", albumArtist); localIntent.putExtra("playing", playing); localIntent.putExtra("duration", duration); @@ -199,10 +205,11 @@ public void broadcast(Context context, String artist, String track, boolean play Log.d(TAG,"title "+track); } - public void broadcast(Context context, String artist, String track, boolean playing, double duration, long position, String albumArtist) { + public void broadcast(Context context, String artist, String track, String album, boolean playing, double duration, long position, String albumArtist) { Intent localIntent = new Intent(GenericControllerReceiver.ACTION_INTENT); localIntent.putExtra("artist", artist); localIntent.putExtra("track", track); + localIntent.putExtra("album", album); localIntent.putExtra("albumArtist", albumArtist); localIntent.putExtra("playing", playing); localIntent.putExtra("duration", duration); @@ -214,7 +221,7 @@ public void broadcast(Context context, String artist, String track, boolean play Log.d(TAG,"title "+track); } - public void saveArtwork(Context context, Bitmap artwork, String artist, String track) { + public void saveArtwork(Context context, Bitmap artwork, String artist, String track, String album) { File artworksDir = new File(context.getCacheDir(), "artworks"); if (artwork != null && (artworksDir.exists() || artworksDir.mkdir())) { File artworkFile = new File(artworksDir, artist + track + ".png"); diff --git a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java index de54f0f2..4b4f77b1 100644 --- a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java +++ b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java @@ -18,6 +18,7 @@ import android.os.IBinder; import android.provider.Settings; import android.support.v4.app.NotificationManagerCompat; +import android.support.v4.media.session.MediaSessionCompat; import android.util.Log; import java.lang.ref.WeakReference; @@ -32,6 +33,7 @@ public class ControllerReceiverService extends android.service.notification.Noti private ControllerReceiverCallback controllerReceiverCallback; private String track; private String artist; + private String album; private String albumArtist; private Object durationObject; @@ -124,15 +126,15 @@ public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs, long if (durationObject instanceof Double) { Log.d(TAG,"duration is Double"); if (artist != null && !artist.isEmpty()) - controllerReceiverCallback.broadcast(this, artist, track, isRemoteControllerPlaying, (Double) durationObject, position,albumArtist); + controllerReceiverCallback.broadcast(this, artist, track, album, isRemoteControllerPlaying, (Double) durationObject, position,albumArtist); } else if (durationObject instanceof Integer) { Log.d(TAG,"duration is Integer"); if (artist != null && !artist.isEmpty()) - controllerReceiverCallback.broadcast(this, artist, track, isRemoteControllerPlaying, (Integer) durationObject, position, albumArtist); + controllerReceiverCallback.broadcast(this, artist, track, album, isRemoteControllerPlaying, (Integer) durationObject, position, albumArtist); } else if (durationObject instanceof Long) Log.d(TAG,"duration is Long"); if (artist != null && !artist.isEmpty()) - controllerReceiverCallback.broadcast(this, artist, track, isRemoteControllerPlaying, (Long) durationObject, position, albumArtist); + controllerReceiverCallback.broadcast(this, artist, track, album, isRemoteControllerPlaying, (Long) durationObject, position, albumArtist); } @Override @@ -159,9 +161,10 @@ public void onClientMetadataUpdate(RemoteController.MetadataEditor metadataEdito artist = metadataEditor.getString(MediaMetadataRetriever.METADATA_KEY_ARTIST, ""); albumArtist = metadataEditor.getString(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, ""); track = metadataEditor.getString(MediaMetadataRetriever.METADATA_KEY_TITLE, ""); + album = metadataEditor.getString(MediaMetadataRetriever.METADATA_KEY_ALBUM, ""); Bitmap artwork = metadataEditor.getBitmap(MediaMetadataEditor.BITMAP_KEY_ARTWORK, null); - controllerReceiverCallback.saveArtwork(this, artwork, artist, track); + controllerReceiverCallback.saveArtwork(this, artwork, artist, track, album); } @Override From 3e9988908e48cbf8fee069e8c202dbdbeacf3301 Mon Sep 17 00:00:00 2001 From: Austin H Date: Mon, 26 Aug 2019 21:19:15 -0400 Subject: [PATCH 3/9] Fix MusicApi & Controllers Removed some older android version bugs. --- app/src/main/AndroidManifest.xml | 44 +++-- app/src/main/assets/changelog.txt | 2 + .../aslfms/AppleMusicOptionsActivity.java | 126 -------------- .../com/adam/aslfms/SettingsActivity.java | 27 +-- .../adam/aslfms/receiver/BootReceiver.java | 41 +++++ .../receiver/GenericControllerReceiver.java | 13 +- .../service/ControllerReceiverCallback.java | 21 +-- .../service/ControllerReceiverService.java | 14 +- .../service/NotificationBarService.java | 5 +- .../applemusic/AppleMusicBroadcaster.java | 33 ---- .../service/applemusic/BroadcastState.java | 23 --- .../aslfms/service/applemusic/LfmApi.java | 116 ------------- .../applemusic/NotificationHandler.java | 155 ----------------- .../applemusic/NotificationService.java | 149 ---------------- .../service/applemusic/PlayingState.java | 12 -- .../aslfms/service/applemusic/TrackData.java | 162 ------------------ .../com/adam/aslfms/util/AppSettings.java | 24 --- app/src/main/res/xml/apple_music_options.xml | 18 -- app/src/main/res/xml/settings_prefs.xml | 9 - 19 files changed, 100 insertions(+), 894 deletions(-) delete mode 100644 app/src/main/java/com/adam/aslfms/AppleMusicOptionsActivity.java create mode 100644 app/src/main/java/com/adam/aslfms/receiver/BootReceiver.java delete mode 100644 app/src/main/java/com/adam/aslfms/service/applemusic/AppleMusicBroadcaster.java delete mode 100644 app/src/main/java/com/adam/aslfms/service/applemusic/BroadcastState.java delete mode 100644 app/src/main/java/com/adam/aslfms/service/applemusic/LfmApi.java delete mode 100644 app/src/main/java/com/adam/aslfms/service/applemusic/NotificationHandler.java delete mode 100644 app/src/main/java/com/adam/aslfms/service/applemusic/NotificationService.java delete mode 100644 app/src/main/java/com/adam/aslfms/service/applemusic/PlayingState.java delete mode 100644 app/src/main/java/com/adam/aslfms/service/applemusic/TrackData.java delete mode 100644 app/src/main/res/xml/apple_music_options.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 97ee5861..fe2a6ea3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,6 +10,7 @@ + - - - - - - - - - - + android:exported="false"> + - + + + + + + + - + - + - + \ No newline at end of file diff --git a/app/src/main/assets/changelog.txt b/app/src/main/assets/changelog.txt index 6fc1b074..1b3a99c5 100644 --- a/app/src/main/assets/changelog.txt +++ b/app/src/main/assets/changelog.txt @@ -3,6 +3,8 @@ https://github.com/simple-last-fm-scrobbler/sls For more details. - 1.5.8 (2018-6-24) + * Notification Listener + * Notification Fixes * Fixes (thanks to G00fY2) * Features (thanks to 4-Eyes) * Bugs & Languages fixes thanks to many diff --git a/app/src/main/java/com/adam/aslfms/AppleMusicOptionsActivity.java b/app/src/main/java/com/adam/aslfms/AppleMusicOptionsActivity.java deleted file mode 100644 index baf8ffd0..00000000 --- a/app/src/main/java/com/adam/aslfms/AppleMusicOptionsActivity.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.adam.aslfms; - -import android.content.DialogInterface; -import android.content.Intent; -import android.content.res.Resources; -import android.os.Build; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.Preference; -import android.provider.Settings; -import android.support.v4.app.NavUtils; -import android.support.v7.app.AlertDialog; -import android.util.Log; -import android.view.MenuItem; - -import com.adam.aslfms.service.applemusic.NotificationService; -import com.adam.aslfms.util.AppSettings; -import com.example.android.supportv7.app.AppCompatPreferenceActivity; - -/** - * Created by 4-Eyes on 15/3/2017. - * - */ - -public class AppleMusicOptionsActivity extends AppCompatPreferenceActivity { - - private static final String TAG = "AppleMusicActivity"; - - CheckBoxPreference notificationListeningCbp; - CheckBoxPreference repeatsCbp; - AppSettings settings; - - @Override - public Resources.Theme getTheme() { - settings = new AppSettings(this); - Resources.Theme theme = super.getTheme(); - theme.applyStyle(settings.getAppTheme(), true); - Log.d(TAG, getResources().getResourceName(settings.getAppTheme())); - // you could also use a switch if you have many themes that could apply - return theme; - } - - @Override - @SuppressWarnings("deprecation") - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.apple_music_options); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } - notificationListeningCbp = (CheckBoxPreference) findPreference("apple_notification_listening"); - repeatsCbp = (CheckBoxPreference) findPreference("apple_enable_repeat"); - if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { - notificationListeningCbp.setEnabled(false); - notificationListeningCbp.setSummary("Unfortunately your current version of android does not support this feature"); - } - settings = new AppSettings(this); - setTheme(settings.getAppTheme()); - } - - @Override - protected void onResume() { - super.onResume(); - notificationListeningCbp.setOnPreferenceClickListener(handleClick); - notificationListeningCbp.setChecked(settings.getAppleListenerEnabled()); - repeatsCbp.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - settings.setAppleRepeatEnabled(repeatsCbp.isChecked()); - return true; - } - }); - repeatsCbp.setChecked(settings.getAppleRepeatEnabled()); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - NavUtils.navigateUpFromSameTask(this); - return true; - } - return super.onOptionsItemSelected(item); - } - - Preference.OnPreferenceClickListener handleClick = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - if (!notificationListeningCbp.isEnabled()) return true; - final Intent intent = new Intent(AppleMusicOptionsActivity.this, NotificationService.class); - if (notificationListeningCbp.isChecked()) { - AlertDialog.Builder builder = new AlertDialog.Builder(AppleMusicOptionsActivity.this); - builder.setMessage("Enabling this feature will mean Simple Last.fm Scrobbler will be able to listen to your notifications. Are you sure you want to proceed?") - .setTitle("Are you sure?") - .setPositiveButton("Yes", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - settings.setAppleListenerEnabled(true); - notificationListeningCbp.setChecked(true); - // Start notification service - startService(intent); - // Redirect to settings for enabling notification listening - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { - Intent settingsIntent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS); - startActivityForResult(settingsIntent, 0); - } - } - }) - .setNegativeButton("No", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // Disable checkbox user cancelled action. - notificationListeningCbp.setChecked(false); - } - }); - - builder.create().show(); - } else { - // Update setting and stop service. - settings.setAppleListenerEnabled(false); - stopService(intent); - } - return true; - } - }; -} diff --git a/app/src/main/java/com/adam/aslfms/SettingsActivity.java b/app/src/main/java/com/adam/aslfms/SettingsActivity.java index 42fdae4c..72a5eb9f 100644 --- a/app/src/main/java/com/adam/aslfms/SettingsActivity.java +++ b/app/src/main/java/com/adam/aslfms/SettingsActivity.java @@ -43,9 +43,8 @@ import android.view.MenuItem; import android.widget.Toast; -import com.adam.aslfms.service.ControllerReceiverService; +import com.adam.aslfms.receiver.BootReceiver; import com.adam.aslfms.service.NetApp; -import com.adam.aslfms.service.applemusic.NotificationService; import com.adam.aslfms.service.ScrobblingService; import com.adam.aslfms.util.AppSettings; import com.adam.aslfms.util.ScrobblesDatabase; @@ -125,13 +124,6 @@ protected void onCreate(Bundle savedInstanceState) { permsCheck(); credsCheck(); - // TODO: MODIFY ME!!! - Log.e(TAG,"ControllerReceiverService starting.."); - Intent myIntent = new Intent(this, ControllerReceiverService.class); - this.startService(myIntent); - Log.e(TAG,"ControllerReceiverService started."); - // TODO: MODIFY ME!!! - // TODO: VERIFY EVERYTHING BELOW IS SAFE int v = Util.getAppVersionCode(this, getPackageName()); if (settings.getWhatsNewViewedVersion() < v) { @@ -140,11 +132,9 @@ protected void onCreate(Bundle savedInstanceState) { mDb.alterDataBaseOnce(); // version 1.5.8 only! } - // Start Apple listening service if applicabble - if (settings.getAppleListenerEnabled()) { - Intent intent = new Intent(this, NotificationService.class); - startService(intent); - } + // Start listening service if applicable + Intent localIntent = new Intent(BootReceiver.NOTIFICATION_RECEIVER); + this.sendBroadcast(localIntent); } @Override @@ -260,11 +250,12 @@ private void credsCheck() { private void permsCheck() { //PERMISSION CHECK - if (!NotificationManagerCompat.getEnabledListenerPackages (getApplicationContext()).contains(getApplicationContext().getPackageName())) { - Toast.makeText(SettingsActivity.this, R.string.notification_access_required, Toast.LENGTH_LONG).show(); - getApplicationContext().startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); - } else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + if (!NotificationManagerCompat.getEnabledListenerPackages(this).contains(getPackageName())) { //ask for permission + Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"); + startActivity(intent); + } } // external storage if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { diff --git a/app/src/main/java/com/adam/aslfms/receiver/BootReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/BootReceiver.java new file mode 100644 index 00000000..0d400af0 --- /dev/null +++ b/app/src/main/java/com/adam/aslfms/receiver/BootReceiver.java @@ -0,0 +1,41 @@ +package com.adam.aslfms.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Build; + +import com.adam.aslfms.service.ControllerReceiverCallback; +import com.adam.aslfms.service.ControllerReceiverService; +import com.adam.aslfms.service.NotificationBarService; + +public class BootReceiver extends BroadcastReceiver { + + private ControllerReceiverCallback controllerCallback = null; + private static final String TAG = "BootReceiver"; + + public static final String NOTIFICATION_RECEIVER = "com.adam.aslfms.notificationreceiver"; + public static final String NOTIFICATION_RECEIVER_WAKE = "com.adam.aslfms.notificationreceiverwake"; + + @Override + public void onReceive(Context context, Intent intent) { + if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Intent i = new Intent(context, NotificationBarService.class); + if (intent.getAction() == NOTIFICATION_RECEIVER) { + i.setAction(NotificationBarService.ACTION_NOTIFICATION_BAR_UPDATE); + i.putExtra("track", ""); + i.putExtra("artist", ""); + i.putExtra("album", ""); + i.putExtra("app_name", ""); + } else if (intent.getAction() == NOTIFICATION_RECEIVER_WAKE){ + i.setAction(NotificationBarService.ACTION_NOTIFICATION_BAR_WAKE); + } + context.startService(i); + context.startService(new Intent(context, ControllerReceiverService.class)); + if (controllerCallback == null) + controllerCallback = new ControllerReceiverCallback(); + if (ControllerReceiverService.isListeningAuthorized(context)) + ControllerReceiverCallback.registerFallbackControllerCallback(context, controllerCallback); + } + } +} diff --git a/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java index cc09a2e1..bbfb4935 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java @@ -29,21 +29,16 @@ protected void parseIntent(Context ctx, String action, Bundle bundle) throws Ill playerPackage = bundle.getString("player"); if (playerPackage != null && !playerPackage.isEmpty()) { PackageManager packageManager = ctx.getPackageManager(); - try { - playerName = packageManager.getApplicationLabel(packageManager.getApplicationInfo(playerPackage, PackageManager.GET_META_DATA)).toString(); - } catch (Exception e) { - Log.e(TAG, e.toString()); - } - MusicAPI mMusicApi = MusicAPI.fromReceiver(ctx, playerName, playerPackage, null, false); + playerName = packageManager.getApplicationLabel(packageManager.getApplicationInfo(playerPackage, PackageManager.GET_META_DATA)).toString(); + mMusicApi = MusicAPI.fromReceiver(ctx, playerName, playerPackage, null, false); setMusicAPI(mMusicApi); } } } catch (Exception e) { Log.w(TAG, e.toString()); + mMusicApi = MusicAPI.fromReceiver(ctx, ctx.getResources().getString(R.string.notification_controller), ctx.getPackageName(), null, false); + setMusicAPI(mMusicApi); } - Log.w(TAG, ctx.getPackageName()); - mMusicApi = MusicAPI.fromReceiver(ctx, ctx.getResources().getString(R.string.notification_controller), ctx.getPackageName(), null, false); - setMusicAPI(mMusicApi); if (bundle.containsKey("track")) { Track.Builder b = new Track.Builder(); b.setMusicAPI(mMusicApi); diff --git a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java index 2ee503c1..20e11c87 100644 --- a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java +++ b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java @@ -12,7 +12,6 @@ import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.os.Build; -import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; import android.support.annotation.RequiresApi; @@ -31,7 +30,6 @@ public class ControllerReceiverCallback { private static final String TAG = "ControllerReceiverCall"; private static MediaSessionManager.OnActiveSessionsChangedListener sessionListener; - private final MetadataUpdateListener metadataListener; private MediaController controller; private String mPlayer = null; private static WeakReference sController = new WeakReference<>(null); @@ -39,8 +37,8 @@ public class ControllerReceiverCallback { private Handler handler = new Handler(); private Bitmap lastBitmap; - public ControllerReceiverCallback(MetadataUpdateListener metadataListener) { - this.metadataListener = metadataListener; + public ControllerReceiverCallback() { + } @@ -132,7 +130,6 @@ public void broadcastControllerState(Context context, MediaController controller final Boolean[] playing = new Boolean[]{isPlaying}; handler.postDelayed(() -> { mPlayer = controllers[0].getPackageName(); - Log.e(TAG, "mPlayer: " + mPlayer); MediaMetadata metadata = controllers[0].getMetadata(); PlaybackState playbackState = controllers[0].getPlaybackState(); if (metadata == null) @@ -185,11 +182,11 @@ public void broadcastControllerState(Context context, MediaController controller String player = controllers[0].getPackageName(); if ("com.aimp.player".equals(player)) // Aimp is awful position = -1; - broadcast(context, artist, track, album, playing[0], duration, position, albumArtist); + broadcast(context, artist, track, album, playing[0], duration, position, albumArtist, player); }, 100); } - public void broadcast(Context context, String artist, String track, String album, boolean playing, int duration, long position, String albumArtist) { + public void broadcast(Context context, String artist, String track, String album, boolean playing, int duration, long position, String albumArtist, String player) { Intent localIntent = new Intent(GenericControllerReceiver.ACTION_INTENT); localIntent.putExtra("artist", artist); localIntent.putExtra("track", track); @@ -197,6 +194,8 @@ public void broadcast(Context context, String artist, String track, String album localIntent.putExtra("albumArtist", albumArtist); localIntent.putExtra("playing", playing); localIntent.putExtra("duration", duration); + if (mPlayer == null) + mPlayer = player; localIntent.putExtra("player", mPlayer); Log.d("title", track); if (position != -1) @@ -205,7 +204,7 @@ public void broadcast(Context context, String artist, String track, String album Log.d(TAG,"title "+track); } - public void broadcast(Context context, String artist, String track, String album, boolean playing, double duration, long position, String albumArtist) { + public void broadcast(Context context, String artist, String track, String album, boolean playing, double duration, long position, String albumArtist, String player) { Intent localIntent = new Intent(GenericControllerReceiver.ACTION_INTENT); localIntent.putExtra("artist", artist); localIntent.putExtra("track", track); @@ -213,6 +212,8 @@ public void broadcast(Context context, String artist, String track, String album localIntent.putExtra("albumArtist", albumArtist); localIntent.putExtra("playing", playing); localIntent.putExtra("duration", duration); + if (mPlayer == null) + mPlayer = player; localIntent.putExtra("player", mPlayer); Log.d("title", track); if (position != -1) @@ -262,8 +263,4 @@ public void saveArtwork(Context context, Bitmap artwork, String artist, String t lastBitmap = artwork; } } - - public interface MetadataUpdateListener { - void onMetadataUpdated(Bundle metadata); - } } diff --git a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java index 4b4f77b1..3deabb98 100644 --- a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java +++ b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java @@ -26,7 +26,7 @@ @SuppressWarnings("deprecation") @TargetApi(Build.VERSION_CODES.LOLLIPOP) -public class ControllerReceiverService extends android.service.notification.NotificationListenerService implements RemoteController.OnClientUpdateListener, ControllerReceiverCallback.MetadataUpdateListener { +public class ControllerReceiverService extends android.service.notification.NotificationListenerService implements RemoteController.OnClientUpdateListener { private static final String TAG = "ControllerReceiverSrvc"; private static WeakReference mRemoteController = new WeakReference<>(null); @@ -52,7 +52,7 @@ public void onCreate() { if (!((AudioManager) getSystemService(Context.AUDIO_SERVICE)).registerRemoteController(mRemoteController.get())) { throw new RuntimeException("Error while registering RemoteController!"); } - controllerReceiverCallback = new ControllerReceiverCallback(this); + controllerReceiverCallback = new ControllerReceiverCallback(); } } @@ -126,15 +126,15 @@ public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs, long if (durationObject instanceof Double) { Log.d(TAG,"duration is Double"); if (artist != null && !artist.isEmpty()) - controllerReceiverCallback.broadcast(this, artist, track, album, isRemoteControllerPlaying, (Double) durationObject, position,albumArtist); + controllerReceiverCallback.broadcast(this, artist, track, album, isRemoteControllerPlaying, (Double) durationObject, position, albumArtist, null); } else if (durationObject instanceof Integer) { Log.d(TAG,"duration is Integer"); if (artist != null && !artist.isEmpty()) - controllerReceiverCallback.broadcast(this, artist, track, album, isRemoteControllerPlaying, (Integer) durationObject, position, albumArtist); + controllerReceiverCallback.broadcast(this, artist, track, album, isRemoteControllerPlaying, (Integer) durationObject, position, albumArtist, null); } else if (durationObject instanceof Long) Log.d(TAG,"duration is Long"); if (artist != null && !artist.isEmpty()) - controllerReceiverCallback.broadcast(this, artist, track, album, isRemoteControllerPlaying, (Long) durationObject, position, albumArtist); + controllerReceiverCallback.broadcast(this, artist, track, album, isRemoteControllerPlaying, (Long) durationObject, position, albumArtist, null); } @Override @@ -167,10 +167,6 @@ public void onClientMetadataUpdate(RemoteController.MetadataEditor metadataEdito controllerReceiverCallback.saveArtwork(this, artwork, artist, track, album); } - @Override - public void onMetadataUpdated(Bundle metadata) { - } - // BEGIN listener stuff @Override diff --git a/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java b/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java index 1392c0ac..7261f369 100644 --- a/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java +++ b/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java @@ -26,6 +26,7 @@ public class NotificationBarService extends Service { private static final String TAG = "NotificationBarService"; public static final String ACTION_NOTIFICATION_BAR_UPDATE = "com.adam.aslfms.service.notificationbarupdate"; + public static final String ACTION_NOTIFICATION_BAR_WAKE = "com.adam.aslfms.service.notificationwake"; private AppSettings settings; private ScrobblesDatabase mDb; @@ -108,7 +109,7 @@ public void onDestroy() { @Override public int onStartCommand(Intent i, int flags, int startId) { handleCommand(i, startId); - if (settings.isActiveAppEnabled(Util.checkPower(mCtx))) { + if (settings.isActiveAppEnabled(Util.checkPower(mCtx)) && i.getAction() == ACTION_NOTIFICATION_BAR_UPDATE) { if (track != null) { String ar = artist; String tr = track; @@ -165,6 +166,8 @@ private void handleCommand(Intent i, int startId) { artist = extras.getString("artist"); album = extras.getString("album"); app_name = extras.getString("app_name"); + } else if (action.equals(ACTION_NOTIFICATION_BAR_WAKE)){ + } } } diff --git a/app/src/main/java/com/adam/aslfms/service/applemusic/AppleMusicBroadcaster.java b/app/src/main/java/com/adam/aslfms/service/applemusic/AppleMusicBroadcaster.java deleted file mode 100644 index 5ed3c9a0..00000000 --- a/app/src/main/java/com/adam/aslfms/service/applemusic/AppleMusicBroadcaster.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.adam.aslfms.service.applemusic; - -import android.content.Context; -import android.content.Intent; - -/** - * Created by 4-Eyes on 16/3/2017. - * - */ - -class AppleMusicBroadcaster { - - private final Context context; - private final String appName = "Apple Music"; - private final String packageName = "com.apple.android.music"; - - AppleMusicBroadcaster(Context context) { - this.context = context; - } - - void broadcast(TrackData data, BroadcastState state, long duration) { - Intent broadcastIntent = new Intent("com.adam.aslfms.notify.playstatechanged"); - broadcastIntent.putExtra("state", state.getValue()); - broadcastIntent.putExtra("app-name", appName); - broadcastIntent.putExtra("app-package", packageName); - broadcastIntent.putExtra("track", data.getTitle()); - broadcastIntent.putExtra("artist", data.getArtist()); - broadcastIntent.putExtra("album", data.getAlbum()); - broadcastIntent.putExtra("duration", (int)(duration / 1000)); - - context.sendBroadcast(broadcastIntent); - } -} diff --git a/app/src/main/java/com/adam/aslfms/service/applemusic/BroadcastState.java b/app/src/main/java/com/adam/aslfms/service/applemusic/BroadcastState.java deleted file mode 100644 index 81c2f095..00000000 --- a/app/src/main/java/com/adam/aslfms/service/applemusic/BroadcastState.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.adam.aslfms.service.applemusic; - -/** - * Created by 4-Eyes on 16/3/2017. - * - */ - -enum BroadcastState { - START(0), - RESUME(1), - PAUSE(2), - COMPLETE(3); - - private int value; - - BroadcastState(int i) { - value = i; - } - - public int getValue() { - return value; - } -} diff --git a/app/src/main/java/com/adam/aslfms/service/applemusic/LfmApi.java b/app/src/main/java/com/adam/aslfms/service/applemusic/LfmApi.java deleted file mode 100644 index f783effc..00000000 --- a/app/src/main/java/com/adam/aslfms/service/applemusic/LfmApi.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.adam.aslfms.service.applemusic; - -import android.util.Log; - -import com.adam.aslfms.service.NetApp; -import com.adam.aslfms.util.AppSettings; - -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLEncoder; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Created by 4-Eyes on 16/3/2017. - * - */ - -class LfmApi { - - private final AppSettings settings; - - LfmApi(AppSettings settings) { - this.settings = settings; - } - - private String getTrackInfo(TrackData data) { - HttpURLConnection conn = null; - try { - URL url = new URL(NetApp.LASTFM.getWebserviceUrl(settings)); - - conn = (HttpURLConnection) url.openConnection(); - - conn.setReadTimeout(7000); - conn.setConnectTimeout(7000); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - - conn.setDoInput(true); - conn.setDoOutput(true); - - Map params = new LinkedHashMap<>(); - params.put("method", "track.getInfo"); - params.put("track", data.getTitle()); - params.put("artist", data.getArtist()); - params.put("api_key", settings.rcnvK(settings.getAPIkey())); - params.put("format", "json"); - - StringBuilder postData = new StringBuilder(); - for (Map.Entry param : params.entrySet()) { - if (postData.length() != 0) postData.append('&'); - postData.append(URLEncoder.encode(param.getKey(), "UTF-8")); - postData.append('='); - postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8")); - } - byte[] postDataBytes = postData.toString().getBytes("UTF-8"); - conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); - - conn.getOutputStream().write(postDataBytes); - - conn.connect(); - - int resCode = conn.getResponseCode(); - BufferedReader r; - if (resCode == -1) { - return ""; - } else if (resCode == 200) { - r = new BufferedReader(new InputStreamReader(conn.getInputStream())); - } else { - r = new BufferedReader(new InputStreamReader(conn.getErrorStream())); - } - StringBuilder stringBuilder = new StringBuilder(); - String line; - while ((line = r.readLine()) != null) { - stringBuilder.append(line).append('\n'); - } - return stringBuilder.toString(); - } catch (IOException | NullPointerException e) { - e.printStackTrace(); - } finally { - if (conn != null) { - conn.disconnect(); - } - } - return ""; - } - - long getTrackDuration(TrackData data) { - String response = getTrackInfo(data); - - try { - JSONObject object = new JSONObject(response); - if (object.has("error")) { - // TODO maybe do something with this - int code = object.getInt("error"); - Log.e("LfmAPI", String.format("Failed to get track duration with error code %s", code)); - } else { - long duration = object.getJSONObject("track").getLong("duration"); - Log.i("LfmAPI", String.format("Successfully got duration for song %s, by %s", - data.getTitle(), data.getArtist())); - return duration == 0 ? NotificationService.DEFAULT_SONG_LENGTH : duration; - } - } catch (Exception e) { - e.printStackTrace(); - } - - return NotificationService.DEFAULT_SONG_LENGTH; - - } -} - diff --git a/app/src/main/java/com/adam/aslfms/service/applemusic/NotificationHandler.java b/app/src/main/java/com/adam/aslfms/service/applemusic/NotificationHandler.java deleted file mode 100644 index e07fdefb..00000000 --- a/app/src/main/java/com/adam/aslfms/service/applemusic/NotificationHandler.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.adam.aslfms.service.applemusic; - -import android.content.Context; -import android.os.AsyncTask; -import android.util.Log; - -import com.adam.aslfms.util.AppSettings; - -import java.util.Date; -import java.util.Timer; -import java.util.TimerTask; - -/** - * Created by 4-Eyes on 16/3/2017. - * This handles notifications which are parsed to it. Determining when to merge notifications and - * when to broadcast the states. - */ -class NotificationHandler { - - private final AppSettings settings; - private TrackData currentTrack; - private long currentTrackDuration = NotificationService.DEFAULT_SONG_LENGTH; - private AppleMusicBroadcaster broadcaster; - private LfmApi api; - private AsyncTask trackInfoTask = null; - - private static final long TRACK_TIMER_INTERVAL = 45000; // 45 seconds - private static final long TRACK_TIMER_REPEAT_CUTOFF = 10; // How many times to call the timer before killing it - private Timer trackTimer; - - NotificationHandler(Context context, AppSettings settings) { - broadcaster = new AppleMusicBroadcaster(context); - this.settings = settings; - api = new LfmApi(settings); - } - - /** - * Pushes a new notification to the handler for processing. - * @param data the new notification being parsed. - */ - void push(TrackData data) { - boolean newTrack = false; - if (currentTrack == null) { - currentTrack = data; - newTrack = true; - } else { - if (currentTrack.sameTrack(data) && currentTrack.currentTotalPlayTime() < currentTrackDuration) { - boolean stateChanged = currentTrack.mergeSame(data); - if (stateChanged) { - Log.i("AppleNotification", "State has changed to: " + currentTrack.getCurrentState()); - switch (currentTrack.getCurrentState()) { - case UNKNOWN: - break; - case PLAYING: - Log.i("AppleNotification", "Broadcasting track resumed for track " + currentTrack.getTitle()); - broadcaster.broadcast(data, BroadcastState.RESUME, currentTrackDuration); - break; - case PAUSED: - Log.i("AppleNotification", "Broadcasting track paused for track " + currentTrack.getTitle()); - broadcaster.broadcast(data, BroadcastState.PAUSE, currentTrackDuration); - break; - } - } - } else { - Log.i("AppleNotification", "New track detected"); - // Check to see if there is overlap time with the next song - // This is because if you're in the application the notifications don't always appear. - long overlapTime = currentTrack.finalisePlayTime(currentTrackDuration); - Log.i("AppleNotification", "Overlap time was " + overlapTime ); - data.addPlayTime(overlapTime); - - long recordedPlayTime = currentTrack.recordedTotalPlayTime(); - if (currentTrack.isRepeat() && !data.isRepeat() && recordedPlayTime < currentTrackDuration / 2) { - data.addPlayTime(recordedPlayTime); - } else { - // This attempts to verify that a track is properly completed - Log.i("AppleNotification", "Total time was " + recordedPlayTime); - Log.i("AppleNotification", "Track duration was " + currentTrackDuration); - if (currentTrack.isComplete(currentTrackDuration)) { - Log.i("AppleNotification", "Broadcasting track complete for track " + currentTrack.getTitle()); - broadcaster.broadcast(currentTrack, BroadcastState.COMPLETE, currentTrackDuration); - } - } - - currentTrack = data; - newTrack = true; - } - } - - if (newTrack) { - if (trackInfoTask != null) { - trackInfoTask.cancel(true); - } - - trackInfoTask = new AsyncTask() { - TrackData trackData; - @Override - protected Long doInBackground(TrackData... trackDatas) { - trackData = trackDatas[0]; - Log.i("AppleNotification", "Loading new data for song " + trackData.getTitle()); - return api.getTrackDuration(trackData); - } - - @Override - protected void onCancelled() { - super.onCancelled(); - currentTrackDuration = NotificationService.DEFAULT_SONG_LENGTH; - } - - @Override - protected void onPostExecute(final Long result) { - currentTrackDuration = result; - Log.i("AppleNotification", "Broadcasting song Start for " + trackData.getTitle()); - broadcaster.broadcast(trackData, BroadcastState.START, currentTrackDuration); - - if (!settings.getAppleRepeatEnabled()) { - return; - } - // Start timer - if (trackTimer != null) { - trackTimer.cancel(); - } - trackTimer = new Timer(); - trackTimer.schedule(new TimerTask() { - boolean isFinished = false; - int count = 0; - @Override - public void run() { - // Kill this timer if it has repeated too many times - if (++count >= TRACK_TIMER_REPEAT_CUTOFF) { - trackTimer.cancel(); - trackTimer.purge(); - } - long currPlayTime = currentTrack.currentTotalPlayTime(); - Log.i("AppleNotification", String.format("Checking for potential repeated song. Current Play Time: %s, Current Track Duration: %s", currPlayTime, result)); - if (currPlayTime > result && !isFinished) { - Log.i("AppleNotification", "Sending repeat track"); - TrackData repeatTrack = new TrackData(); - repeatTrack.setStartTime(new Date(System.currentTimeMillis())); - repeatTrack.setArtist(currentTrack.getArtist()); - repeatTrack.setAlbum(currentTrack.getAlbum()); - repeatTrack.setTitle(currentTrack.getTitle()); - repeatTrack.setContentType(currentTrack.getContentType()); - repeatTrack.setRepeat(true); - push(repeatTrack); - isFinished = true; - } - } - }, result - currentTrack.currentTotalPlayTime(), TRACK_TIMER_INTERVAL); - } - }.execute(currentTrack); - } - } -} - diff --git a/app/src/main/java/com/adam/aslfms/service/applemusic/NotificationService.java b/app/src/main/java/com/adam/aslfms/service/applemusic/NotificationService.java deleted file mode 100644 index 8ed222d1..00000000 --- a/app/src/main/java/com/adam/aslfms/service/applemusic/NotificationService.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.adam.aslfms.service.applemusic; - -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.service.notification.NotificationListenerService; -import android.service.notification.StatusBarNotification; -import android.support.annotation.RequiresApi; -import android.text.TextUtils; -import android.util.Log; -import android.widget.RemoteViews; - -import com.adam.aslfms.util.AppSettings; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Date; - -/** - * Created by 4-Eyes on 15/3/2017. - * - */ - -@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) -public class NotificationService extends NotificationListenerService { - - private NotificationHandler handler; - private PackageInfo applePackageInfo; - private static final String APPLE_PACKAGE_NAME = "com.apple.android.music"; - - static long DEFAULT_SONG_LENGTH = 4 * 60000; // Four minutes - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - return START_STICKY; - } - - @Override - public void onCreate() { - super.onCreate(); - AppSettings settings = new AppSettings(this); - handler = new NotificationHandler(this, settings); - Log.i("AppleNotification", "NotificationBarService listener created"); - try { - applePackageInfo = getPackageManager().getPackageInfo(APPLE_PACKAGE_NAME, 0); - Log.i("AppleNotification", "Package version is: " + applePackageInfo.versionCode); - } catch (PackageManager.NameNotFoundException e) { - Log.i("AppleNotification", "Apple Music package not installed"); - } - } - - @Override - public void onNotificationPosted(StatusBarNotification notification) { - super.onNotificationPosted(notification); - - // Filter out all notifications that do not come from Apple Music - if (!notification.getPackageName().equals(APPLE_PACKAGE_NAME)) return; - - // Attempt to retrieve the - RemoteViews views = notification.getNotification().bigContentView; - if (views == null) return; - - Log.i("AppleNotification", "New notification being processed"); - - TrackData data = new TrackData(); - int dataCount = 0; - try { - Field field = views.getClass().getDeclaredField("mActions"); - field.setAccessible(true); - - ArrayList actions = (ArrayList) field.get(views); - - for (Parcelable p : actions) { - Parcel parcel = Parcel.obtain(); - p.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - - int tag = parcel.readInt(); - if (tag != 2 && tag != 12) continue; - parcel.readInt(); - String methodName = parcel.readString(); - if (methodName == null) continue; - - if (tag == 2) { - // This is for ReflectionAction objects - switch (methodName) { - case "setText": { - parcel.readInt(); - - String text = TextUtils.CHAR_SEQUENCE_CREATOR - .createFromParcel(parcel).toString().trim(); - switch (dataCount) { - case 0: - data.setTitle(text); - break; - case 1: - if (applePackageInfo.versionCode < 431) { - data.setAlbum(text); - } else { - String[] dataList = text.split(" — "); - data.setArtist(dataList[0]); - data.setAlbum(dataList[1]); - } - break; - case 2: - data.setArtist(text); - break; - } - dataCount++; - break; - } - case "setContentDescription": { - parcel.readInt(); - - String text = TextUtils.CHAR_SEQUENCE_CREATOR - .createFromParcel(parcel).toString().trim(); - data.setContentType(text); - break; - } - case "setEnabled": - // parcel.readInt(); - - // boolean enabled = parcel.readByte() != 0; - // TODO see if this can be used in help determine when a song ends - break; - default: - break; - } - } - } - } catch (Exception e) { - Log.e("AppleNotification", "Failed to parse Apple NotificationBarService"); - e.printStackTrace(); - } - - data.setStartTime(new Date(System.currentTimeMillis())); - - handler.push(data); - } - - @Override - public void onNotificationRemoved(StatusBarNotification notification) { - super.onNotificationRemoved(notification); - } - -} diff --git a/app/src/main/java/com/adam/aslfms/service/applemusic/PlayingState.java b/app/src/main/java/com/adam/aslfms/service/applemusic/PlayingState.java deleted file mode 100644 index 28649c7f..00000000 --- a/app/src/main/java/com/adam/aslfms/service/applemusic/PlayingState.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.adam.aslfms.service.applemusic; - -/** - * Created by 4-Eyes on 16/3/2017. - * - */ - -enum PlayingState { - UNKNOWN, - PLAYING, - PAUSED, -} diff --git a/app/src/main/java/com/adam/aslfms/service/applemusic/TrackData.java b/app/src/main/java/com/adam/aslfms/service/applemusic/TrackData.java deleted file mode 100644 index 996aa925..00000000 --- a/app/src/main/java/com/adam/aslfms/service/applemusic/TrackData.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.adam.aslfms.service.applemusic; - -import java.util.ArrayList; -import java.util.Date; - -/** - * Created by 4-Eyes on 16/3/2017. - * - */ - -class TrackData { - - private String artist; - private String title; - private String album; - private String albumartist; - private String trackartist; - private Date startTime; - private PlayingState currentState = PlayingState.UNKNOWN; - private ArrayList playTimes = new ArrayList<>(); - private long lastStateChangedTime; - private boolean isRepeat = false; - - void setContentType(String contentType) { - switch (contentType) { - case "Pause": - currentState = PlayingState.PLAYING; - break; - case "Play": - currentState = PlayingState.PAUSED; - break; - default: - currentState = PlayingState.UNKNOWN; - break; - } - this.lastStateChangedTime = System.currentTimeMillis(); - } - - boolean mergeSame(TrackData data) { - if (this.currentState.equals(data.currentState)) return false; - if (this.currentState.equals(PlayingState.PLAYING) - && data.currentState.equals(PlayingState.PAUSED)) { - playTimes.add(data.startTime.getTime() - this.lastStateChangedTime); - } - this.currentState = data.currentState; - lastStateChangedTime = System.currentTimeMillis(); - return true; - } - - long recordedTotalPlayTime() { - long total = 0; - for (long playtime : playTimes) { - total += playtime; - } - return total; - } - - long currentTotalPlayTime() { - long recordedTime = this.recordedTotalPlayTime(); - if (currentState.equals(PlayingState.PLAYING)) { - recordedTime += System.currentTimeMillis() - lastStateChangedTime; - } - return recordedTime; - } - - long finalisePlayTime(long currentTrackDuration) { - if (currentState.equals(PlayingState.PLAYING)) { - long lastPlayTime = System.currentTimeMillis() - lastStateChangedTime; - long totalPlayTimes = recordedTotalPlayTime(); - long overlapTime = (totalPlayTimes + lastPlayTime - currentTrackDuration); - if (totalPlayTimes + lastPlayTime > currentTrackDuration + 5000 && - overlapTime < currentTrackDuration) { // check overlap time is not ridiculous - playTimes.add(lastPlayTime - overlapTime); - return overlapTime; - } - playTimes.add(lastPlayTime); - } - return 0; - } - - boolean sameTrack(TrackData other) { - return other != null & this.title != null && this.artist != null && this.album != null && - this.title.equals(other.title) && this.artist.equals(other.artist) && this.album.equals(other.album); - } - - boolean isComplete(long trackDuration) { - long playTime = recordedTotalPlayTime(); - return playTime >= (trackDuration - 5000); // Has been played for within 5 seconds of the actual song length. - } - - void setArtist(String artist) { - this.artist = artist; - } - - void setTitle(String title) { - this.title = title; - } - - void setAlbum(String album) { - this.album = album; - } - - void setAlbumArtist(String albumartist) { - this.albumartist = albumartist; - } - - void setTrackArtist(String trackartist) { - this.trackartist = trackartist; - } - - void setStartTime(Date startTime) { - this.startTime = startTime; - } - - String getTitle() { - return title; - } - - String getArtist() { - return artist; - } - - String getAlbum() { - return album; - } - - String getAlbumArtist() { - return albumartist; - } - - String getTrackArtist() { - return trackartist; - } - - PlayingState getCurrentState() { - return currentState; - } - - void addPlayTime(long playtime) { - playTimes.add(playtime); - } - - String getContentType() { - switch (this.currentState) { - case PLAYING: - return "Pause"; - case PAUSED: - return "Play"; - case UNKNOWN: - default: - return ""; - } - } - - public boolean isRepeat() { - return isRepeat; - } - - public void setRepeat(boolean repeat) { - isRepeat = repeat; - } -} diff --git a/app/src/main/java/com/adam/aslfms/util/AppSettings.java b/app/src/main/java/com/adam/aslfms/util/AppSettings.java index d59801ae..47cad3ec 100644 --- a/app/src/main/java/com/adam/aslfms/util/AppSettings.java +++ b/app/src/main/java/com/adam/aslfms/util/AppSettings.java @@ -87,9 +87,6 @@ public class AppSettings { // Widget stuff private static final String KEY_WIDGET_ALSO_DISABLE_NP = "widget_also_disable_np"; - private static final String KEY_APPLE_LISTENER_ENABLED = "apple_listener_enabled"; - private static final String KEY_APPLE_REPEAT_ENABLED = "apple_repeat_enabled"; - private static final String KEY_THEME = "my_theme"; private final Context mCtx; @@ -651,27 +648,6 @@ public boolean getWidgetAlsoDisableNP() { return prefs.getBoolean(KEY_WIDGET_ALSO_DISABLE_NP, false); } - public void setAppleListenerEnabled(boolean enabled) { - Editor e = prefs.edit(); - e.putBoolean(KEY_APPLE_LISTENER_ENABLED, enabled); - e.commit(); - } - - public boolean getAppleListenerEnabled() { - return prefs.getBoolean(KEY_APPLE_LISTENER_ENABLED, false); - } - - public void setAppleRepeatEnabled(boolean enabled) { - Editor e = prefs.edit(); - e.putBoolean(KEY_APPLE_REPEAT_ENABLED, enabled); - e.commit(); - } - - public boolean getAppleRepeatEnabled() { - return prefs.getBoolean(KEY_APPLE_REPEAT_ENABLED, false); - } - - public SecretKey getSecKey() { try { DESKeySpec keySpec = new DESKeySpec(getSecret2().getBytes("UTF8")); diff --git a/app/src/main/res/xml/apple_music_options.xml b/app/src/main/res/xml/apple_music_options.xml deleted file mode 100644 index 13bb850b..00000000 --- a/app/src/main/res/xml/apple_music_options.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/xml/settings_prefs.xml b/app/src/main/res/xml/settings_prefs.xml index 8e03268d..ba310f2d 100644 --- a/app/src/main/res/xml/settings_prefs.xml +++ b/app/src/main/res/xml/settings_prefs.xml @@ -27,15 +27,6 @@ android:targetPackage="com.adam.aslfms" /> - - - - Date: Mon, 26 Aug 2019 21:39:44 -0400 Subject: [PATCH 4/9] Code Cleanup & Fixed Notification Calls --- .../com/adam/aslfms/SettingsActivity.java | 2 +- .../service/NotificationBarService.java | 126 +++++++----------- 2 files changed, 47 insertions(+), 81 deletions(-) diff --git a/app/src/main/java/com/adam/aslfms/SettingsActivity.java b/app/src/main/java/com/adam/aslfms/SettingsActivity.java index 72a5eb9f..3a285594 100644 --- a/app/src/main/java/com/adam/aslfms/SettingsActivity.java +++ b/app/src/main/java/com/adam/aslfms/SettingsActivity.java @@ -133,7 +133,7 @@ protected void onCreate(Bundle savedInstanceState) { } // Start listening service if applicable - Intent localIntent = new Intent(BootReceiver.NOTIFICATION_RECEIVER); + Intent localIntent = new Intent(BootReceiver.NOTIFICATION_RECEIVER_WAKE); this.sendBroadcast(localIntent); } diff --git a/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java b/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java index 7261f369..ada56365 100644 --- a/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java +++ b/app/src/main/java/com/adam/aslfms/service/NotificationBarService.java @@ -1,6 +1,5 @@ package com.adam.aslfms.service; -import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; @@ -11,14 +10,12 @@ import android.os.Bundle; import android.os.IBinder; import android.support.v4.app.NotificationCompat; -import android.support.v4.app.NotificationCompatSideChannelService; import android.util.Log; import com.adam.aslfms.R; import com.adam.aslfms.SettingsActivity; import com.adam.aslfms.util.AppSettings; import com.adam.aslfms.util.ScrobblesDatabase; -import com.adam.aslfms.util.Track; import com.adam.aslfms.util.Util; public class NotificationBarService extends Service { @@ -57,44 +54,7 @@ public void onCreate() { int sdk = Build.VERSION.SDK_INT; if (sdk == Build.VERSION_CODES.GINGERBREAD || sdk == Build.VERSION_CODES.GINGERBREAD_MR1) { if (settings.isActiveAppEnabled(Util.checkPower(mCtx))) { - if (track != null) { - String ar = artist; - String tr = track; - String al = album; - String api = app_name; - - // Heart intent - Intent heartIntent = new Intent(mCtx, ScrobblingService.class); - heartIntent.setAction(ScrobblingService.ACTION_HEART); - PendingIntent heartPendingIntent = PendingIntent.getService(mCtx, 0, heartIntent, 0); - NotificationCompat.Action heartAction = new NotificationCompat.Action.Builder(R.drawable.ic_heart, getString(R.string.heart_title), heartPendingIntent).build(); - - // Copy intent - Intent copyIntent = new Intent(mCtx, ScrobblingService.class); - copyIntent.setAction(ScrobblingService.ACTION_COPY); - PendingIntent copyPendingIntent = PendingIntent.getService(mCtx, 0, copyIntent, 0); - NotificationCompat.Action copyAction = new NotificationCompat.Action.Builder(R.drawable.ic_content_copy, getString(R.string.copy_title), copyPendingIntent).build(); - - Intent targetIntent = new Intent(mCtx, SettingsActivity.class); - PendingIntent contentIntent = PendingIntent.getActivity(mCtx, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT); - NotificationCompat.Builder builder = - new NotificationCompat.Builder(mCtx) - .setContentTitle(tr + " by " + ar ) - .setSmallIcon(R.drawable.ic_icon) - .setColor(Color.RED) - .setContentText(al + " : " + api) - .setPriority(NotificationCompat.PRIORITY_MIN) - .addAction(heartAction) - .addAction(copyAction) - .setContentIntent(contentIntent); - - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB_MR2) { - builder.setLargeIcon(BitmapFactory.decodeResource(mCtx.getResources(), - R.drawable.ic_icon)); - } - - this.startForeground(24689, builder.build()); - } + buildNotification(); } else { this.stopForeground(true); // TODO: test if this conflicts/stops scrobbles } @@ -110,48 +70,54 @@ public void onDestroy() { public int onStartCommand(Intent i, int flags, int startId) { handleCommand(i, startId); if (settings.isActiveAppEnabled(Util.checkPower(mCtx)) && i.getAction() == ACTION_NOTIFICATION_BAR_UPDATE) { - if (track != null) { - String ar = artist; - String tr = track; - String al = album; - String api = app_name; - - // Heart intent - Intent heartIntent = new Intent(mCtx, ScrobblingService.class); - heartIntent.setAction(ScrobblingService.ACTION_HEART); - PendingIntent heartPendingIntent = PendingIntent.getService(mCtx, 0, heartIntent, 0); - NotificationCompat.Action heartAction = new NotificationCompat.Action.Builder(R.drawable.ic_heart, getString(R.string.heart_title), heartPendingIntent).build(); - - // Copy intent - Intent copyIntent = new Intent(mCtx, ScrobblingService.class); - copyIntent.setAction(ScrobblingService.ACTION_COPY); - PendingIntent copyPendingIntent = PendingIntent.getService(mCtx, 0, copyIntent, 0); - NotificationCompat.Action copyAction = new NotificationCompat.Action.Builder(R.drawable.ic_content_copy, getString(R.string.copy_title), copyPendingIntent).build(); - - Intent targetIntent = new Intent(mCtx, SettingsActivity.class); - PendingIntent contentIntent = PendingIntent.getActivity(mCtx, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT); - NotificationCompat.Builder builder = - new NotificationCompat.Builder(mCtx) - .setContentTitle(tr + " by " + ar ) - .setSmallIcon(R.drawable.ic_icon) - .setColor(Color.RED) - .setContentText(al + " : " + api) - .setPriority(NotificationCompat.PRIORITY_MIN) - .addAction(heartAction) - .addAction(copyAction) - .setContentIntent(contentIntent); - - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB_MR2) { - builder.setLargeIcon(BitmapFactory.decodeResource(mCtx.getResources(), - R.drawable.ic_icon)); - } - - this.startForeground(24689, builder.build()); - } + buildNotification(); + } else if (i.getAction() == ACTION_NOTIFICATION_BAR_WAKE) { + buildNotification(); } else { this.stopForeground(true); // TODO: test if this conflicts/stops scrobbles } return Service.START_STICKY; + + } + + public void buildNotification(){ + if (track != null) { + String ar = artist; + String tr = track; + String al = album; + String api = app_name; + + // Heart intent + Intent heartIntent = new Intent(mCtx, ScrobblingService.class); + heartIntent.setAction(ScrobblingService.ACTION_HEART); + PendingIntent heartPendingIntent = PendingIntent.getService(mCtx, 0, heartIntent, 0); + NotificationCompat.Action heartAction = new NotificationCompat.Action.Builder(R.drawable.ic_heart, getString(R.string.heart_title), heartPendingIntent).build(); + + // Copy intent + Intent copyIntent = new Intent(mCtx, ScrobblingService.class); + copyIntent.setAction(ScrobblingService.ACTION_COPY); + PendingIntent copyPendingIntent = PendingIntent.getService(mCtx, 0, copyIntent, 0); + NotificationCompat.Action copyAction = new NotificationCompat.Action.Builder(R.drawable.ic_content_copy, getString(R.string.copy_title), copyPendingIntent).build(); + + Intent targetIntent = new Intent(mCtx, SettingsActivity.class); + PendingIntent contentIntent = PendingIntent.getActivity(mCtx, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT); + NotificationCompat.Builder builder = + new NotificationCompat.Builder(mCtx) + .setContentTitle(tr + " by " + ar ) + .setSmallIcon(R.drawable.ic_icon) + .setColor(Color.RED) + .setContentText(al + " : " + api) + .setPriority(NotificationCompat.PRIORITY_MIN) + .addAction(heartAction) + .addAction(copyAction) + .setContentIntent(contentIntent); + + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB_MR2) { + builder.setLargeIcon(BitmapFactory.decodeResource(mCtx.getResources(), + R.drawable.ic_icon)); + } + this.startForeground(24689, builder.build()); + } } private void handleCommand(Intent i, int startId) { @@ -167,7 +133,7 @@ private void handleCommand(Intent i, int startId) { album = extras.getString("album"); app_name = extras.getString("app_name"); } else if (action.equals(ACTION_NOTIFICATION_BAR_WAKE)){ - + Log.d(TAG, "silent update for notification bar!"); } } } From a3512beddae19b1789e782e8f6381b4d49eb210d Mon Sep 17 00:00:00 2001 From: Austin H Date: Mon, 26 Aug 2019 22:04:23 -0400 Subject: [PATCH 5/9] Handle Use Cases --- .../java/com/adam/aslfms/receiver/BootReceiver.java | 4 ++-- .../java/com/adam/aslfms/util/ScrobblesDatabase.java | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/adam/aslfms/receiver/BootReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/BootReceiver.java index 0d400af0..680f247d 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/BootReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/BootReceiver.java @@ -21,13 +21,13 @@ public class BootReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Intent i = new Intent(context, NotificationBarService.class); - if (intent.getAction() == NOTIFICATION_RECEIVER) { + if (intent == null || intent.getAction() == NOTIFICATION_RECEIVER) { i.setAction(NotificationBarService.ACTION_NOTIFICATION_BAR_UPDATE); i.putExtra("track", ""); i.putExtra("artist", ""); i.putExtra("album", ""); i.putExtra("app_name", ""); - } else if (intent.getAction() == NOTIFICATION_RECEIVER_WAKE){ + } else if (intent.getAction() == NOTIFICATION_RECEIVER_WAKE) { i.setAction(NotificationBarService.ACTION_NOTIFICATION_BAR_WAKE); } context.startService(i); diff --git a/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java b/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java index f68e7f1f..59f631fd 100644 --- a/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java +++ b/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java @@ -507,7 +507,15 @@ public CorrectionRule fetchCorrectioneRule(int id) { // TODO: DELETE ME AFTER !!! public void alterDataBaseOnce(){ - mDb.execSQL("ALTER TABLE " + TABLENAME_SCROBBLES + " ADD COLUMN albumartist text"); - mDb.execSQL("ALTER TABLE " + TABLENAME_SCROBBLES + " ADD COLUMN trackartist text"); + try { + mDb.execSQL("ALTER TABLE " + TABLENAME_SCROBBLES + " ADD COLUMN albumartist text"); + } catch (Exception ignore) { + // may capture already exists albumartist + } + try { + mDb.execSQL("ALTER TABLE " + TABLENAME_SCROBBLES + " ADD COLUMN trackartist text"); + } catch (Exception ignore) { + // may capture already exists trackartist + } } } From 405fb51027451391cbd16507af461cb5ac8968bc Mon Sep 17 00:00:00 2001 From: Austin H Date: Mon, 26 Aug 2019 22:26:09 -0400 Subject: [PATCH 6/9] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index eb3e2422..5d022dd2 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,8 @@ Before the release of a new version of SLS, it will be available here to test fo * Read Notifications to Scrobble Music Also * Use Android audio focus detection to manage scrobbling. * Slow overhaul of the app to keep simplicity and allow for dynamic feature/functionality addition. + * Replace legacy user/pass with OAuth dance + * Possibly style intents and notifications similar to [https://github.com/peterjosling/scroball](https://github.com/peterjosling/scroball) 3. #### Core Feature Requests From 74bb239a44440d55764519e03b91d3e34f2d38cd Mon Sep 17 00:00:00 2001 From: Austin H Date: Mon, 26 Aug 2019 22:40:27 -0400 Subject: [PATCH 7/9] Update Ready! Breaks old Broadcasts and substitutes modern Notification Ready for API 21+ Keeps old Broadcasts for API < 26 --- app/build.gradle | 4 ++-- app/src/main/assets/changelog.txt | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 94ee6fcf..b1d15680 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,11 +1,11 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 25 + compileSdkVersion 26 defaultConfig { applicationId "com.adam.aslfms" minSdkVersion 9 - targetSdkVersion 25 + targetSdkVersion 26 versionCode=49 versionName="1.5.8" diff --git a/app/src/main/assets/changelog.txt b/app/src/main/assets/changelog.txt index 1b3a99c5..048cccce 100644 --- a/app/src/main/assets/changelog.txt +++ b/app/src/main/assets/changelog.txt @@ -3,6 +3,8 @@ https://github.com/simple-last-fm-scrobbler/sls For more details. - 1.5.8 (2018-6-24) + * Themes + * Many Apps Supported (API 21+) * Notification Listener * Notification Fixes * Fixes (thanks to G00fY2) From b6e16b5101a5c84c034f098e25b3985e1bc8427c Mon Sep 17 00:00:00 2001 From: Austin H Date: Mon, 26 Aug 2019 23:02:11 -0400 Subject: [PATCH 8/9] Min Api 26 breaks Gingerbread Cleanup and breaking Gingerbread support is official. --- app/build.gradle | 8 ++++---- .../adam/aslfms/service/ControllerReceiverService.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b1d15680..06cec934 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,7 +4,7 @@ android { compileSdkVersion 26 defaultConfig { applicationId "com.adam.aslfms" - minSdkVersion 9 + minSdkVersion 14 targetSdkVersion 26 versionCode=49 versionName="1.5.8" @@ -36,8 +36,8 @@ android { } dependencies { - implementation 'com.android.support:appcompat-v7:25.4.0' - implementation 'com.android.support:support-compat:25.4.0' - implementation 'com.android.support:design:25.4.0' + implementation 'com.android.support:appcompat-v7:26.1.0' + implementation 'com.android.support:support-compat:26.1.0' + implementation 'com.android.support:design:26.1.0' //compile 'info.guardianproject.netcipher:netcipher:1.2' } diff --git a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java index 3deabb98..46bc55ad 100644 --- a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java +++ b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverService.java @@ -14,11 +14,10 @@ import android.media.RemoteControlClient; import android.media.RemoteController; import android.os.Build; -import android.os.Bundle; import android.os.IBinder; import android.provider.Settings; +import android.support.annotation.RequiresApi; import android.support.v4.app.NotificationManagerCompat; -import android.support.v4.media.session.MediaSessionCompat; import android.util.Log; import java.lang.ref.WeakReference; @@ -26,6 +25,7 @@ @SuppressWarnings("deprecation") @TargetApi(Build.VERSION_CODES.LOLLIPOP) +@RequiresApi(Build.VERSION_CODES.LOLLIPOP) public class ControllerReceiverService extends android.service.notification.NotificationListenerService implements RemoteController.OnClientUpdateListener { private static final String TAG = "ControllerReceiverSrvc"; From 9b32fec5f78a6c0cc1b95af46a8d23fe9da5caf2 Mon Sep 17 00:00:00 2001 From: Austin H Date: Mon, 26 Aug 2019 23:07:41 -0400 Subject: [PATCH 9/9] Update .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e982e1fe..b383675c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,10 @@ script: "./gradlew clean assembleDebug" env: global: - - ANDROID_API=25 + - ANDROID_API=26 - ANDROID_BUILD_TOOLS=28.0.3 - HIGHEST_API=29 - - LOWEST_API=9 + - LOWEST_API=14 android: components: