From 6d69c75de28b565abf051bdfc77c11ea4a9a1351 Mon Sep 17 00:00:00 2001 From: Austin Hogan Date: Sat, 21 Sep 2019 04:14:15 -0400 Subject: [PATCH 1/5] Partial Commit For New DataBase Better database management. Still to do. Allow the user to store all scrobbles and review them, grey out sent scrobbles, list the amount of unsent scrobbles. --- app/src/main/assets/changelog.txt | 3 +- .../com/adam/aslfms/SettingsActivity.java | 4 +- .../receiver/AbstractPlayStatusReceiver.java | 12 +- .../receiver/GenericControllerReceiver.java | 1 - .../service/ControllerReceiverCallback.java | 3 +- .../com/adam/aslfms/service/Handshaker.java | 5 +- .../java/com/adam/aslfms/service/Heart.java | 77 ++-- .../com/adam/aslfms/service/Networker.java | 6 +- .../adam/aslfms/service/NetworkerManager.java | 12 +- .../com/adam/aslfms/service/Scrobbler.java | 6 +- .../aslfms/service/ScrobblingService.java | 41 ++- .../adam/aslfms/util/ScrobblesDatabase.java | 336 ++++++++++++------ .../main/java/com/adam/aslfms/util/Util.java | 2 +- 13 files changed, 319 insertions(+), 189 deletions(-) diff --git a/app/src/main/assets/changelog.txt b/app/src/main/assets/changelog.txt index 29e43c2a..105252ab 100644 --- a/app/src/main/assets/changelog.txt +++ b/app/src/main/assets/changelog.txt @@ -5,11 +5,12 @@ https://github.com/simple-last-fm-scrobbler/sls/wiki/Privacy-Concerns For privacy concerns. - 1.6.8 (2019-9-15) codename: kingus - * Correction Rules database problem fixed + * Database overwrite problem fixed * Back button in permissions fixed * Privacy information in permissions * Russian thanks to alexesprit + - 1.6.7 (2019-9-15) codename: jingus * Fixed non-foreground service crash Bug * Show user permissions each update diff --git a/app/src/main/java/com/adam/aslfms/SettingsActivity.java b/app/src/main/java/com/adam/aslfms/SettingsActivity.java index fe0638a1..99a3dda4 100644 --- a/app/src/main/java/com/adam/aslfms/SettingsActivity.java +++ b/app/src/main/java/com/adam/aslfms/SettingsActivity.java @@ -168,6 +168,7 @@ public boolean onPreferenceTreeClick(PreferenceScreen prefScreen, * whether stuff is enabled or checked, etc. */ private void update() { + mDb = new ScrobblesDatabase(this); int numCache = mDb.queryNumberOfTracks(); mScrobbleAllNow.setSummary(getString(R.string.scrobbles_cache).replace( "%1", Integer.toString(numCache))); @@ -206,12 +207,9 @@ public void onReceive(Context context, Intent intent) { private void runChecks(){ settings = new AppSettings(this); - // TODO: VERIFY EVERYTHING BELOW IS SAFE int v = Util.getAppVersionCode(this, getPackageName()); if (settings.getWhatsNewViewedVersion() < v){ settings.setKeyBypassNewPermissions(2); - mDb.rebuildScrobblesDatabaseOnce(); // keep as not all users have the newest database. - // TODO: verify only needed databases are destroyed } if (settings.getKeyBypassNewPermissions() == 2){ startActivity(new Intent(this, PermissionsActivity.class)); diff --git a/app/src/main/java/com/adam/aslfms/receiver/AbstractPlayStatusReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/AbstractPlayStatusReceiver.java index 373ab674..f2f0ac12 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/AbstractPlayStatusReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/AbstractPlayStatusReceiver.java @@ -91,16 +91,6 @@ public final void onReceive(Context context, Intent intent) { bundle = Bundle.EMPTY; } - // we must be logged in to scrobble - AppSettings settings = new AppSettings(context); - if (!settings.isAnyAuthenticated()) { - Util.myNotify(context, context.getResources().getString(R.string.warning) , context.getResources().getString(R.string.not_logged_in),05233, UserCredActivity.class); - Log - .d(TAG, - "The user has not authenticated, won't propagate the submission request"); - return; - } - mService = new Intent(context, ScrobblingService.class); mService.setAction(ScrobblingService.ACTION_PLAYSTATECHANGED); @@ -124,7 +114,7 @@ public final void onReceive(Context context, Intent intent) { // submit track for the ScrobblingService InternalTrackTransmitter.appendTrack(mTrack); - + AppSettings settings = new AppSettings(context); // start/call the Scrobbling Service if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && settings.isActiveAppEnabled(Util.checkPower(context))) { context.startForegroundService(mService); 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 8e7925bb..ebbc40ce 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java @@ -142,7 +142,6 @@ private void parseData(Context ctx, String action, Bundle bundle){ break; case 5: default: - setState(Track.State.UNKNOWN_NONPLAYING); break; } } 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 ecfec759..0fb93aaf 100644 --- a/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java +++ b/app/src/main/java/com/adam/aslfms/service/ControllerReceiverCallback.java @@ -71,6 +71,7 @@ public void onPlaybackStateChanged(PlaybackState state) { case PlaybackState.STATE_ERROR: case PlaybackState.STATE_PAUSED: case PlaybackState.STATE_STOPPED: + case PlaybackState.STATE_NONE: playing = 3; // pause break; case PlaybackState.STATE_SKIPPING_TO_NEXT: @@ -78,9 +79,7 @@ public void onPlaybackStateChanged(PlaybackState state) { case PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM: playing = 4; // complete break; - case PlaybackState.STATE_NONE: default: - playing = 5; // unknown break; } localIntent.putExtra("playing", playing); 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 970858d7..e7921cdd 100644 --- a/app/src/main/java/com/adam/aslfms/service/Handshaker.java +++ b/app/src/main/java/com/adam/aslfms/service/Handshaker.java @@ -35,6 +35,7 @@ import com.adam.aslfms.util.AuthStatus.TemporaryFailureException; import com.adam.aslfms.util.AuthStatus.UnknownResponseException; import com.adam.aslfms.util.MD5; +import com.adam.aslfms.util.ScrobblesDatabase; import com.adam.aslfms.util.Util; import com.adam.aslfms.util.Util.NetworkStatus; @@ -133,10 +134,10 @@ public void run() { // we don't need/want it anymore, settings.getPwdMd5() is enough settings.setPassword(getNetApp(), ""); + ScrobblesDatabase db = new ScrobblesDatabase(mCtx); notifyAuthStatusUpdate(AuthStatus.AUTHSTATUS_OK); - // launch services after login Util.runServices(mCtx); @@ -198,9 +199,11 @@ public void run() { getNetworker().resetSleeper(); getNetworker().launchNetworkWaiter(); getNetworker().launchScrobbler(); + getNetworker().launchHeart(); } else { getNetworker().launchSleeper(); getNetworker().launchScrobbler(); + getNetworker().launchHeart(); } e.getStackTrace(); } 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 ca62d069..4bad59aa 100644 --- a/app/src/main/java/com/adam/aslfms/service/Heart.java +++ b/app/src/main/java/com/adam/aslfms/service/Heart.java @@ -28,6 +28,7 @@ import com.adam.aslfms.R; import com.adam.aslfms.util.AppSettings; import com.adam.aslfms.util.MD5; +import com.adam.aslfms.util.ScrobblesDatabase; import com.adam.aslfms.util.Track; import org.json.JSONObject; @@ -52,64 +53,72 @@ public class Heart extends NetRunnable { private static final String TAG = "Heart"; - protected Track hearTrack; + protected ScrobblesDatabase db; protected AppSettings settings; Context mCtx; - public Heart(NetApp napp, Context ctx, Networker net, Track hearTrack, AppSettings settings) { + public Heart(NetApp napp, Context ctx, Networker net, ScrobblesDatabase db) { super(napp, ctx, net); - this.hearTrack = hearTrack; - this.settings = settings; + this.db = db; this.mCtx = ctx; } public final void run() { + + settings = new AppSettings(mCtx); // can't heart track - String sigText = "api_key" - + settings.rcnvK(settings.getAPIkey()) - + "artist" + hearTrack.getArtist() - + "methodtrack.lovesk" - + settings.getSessionKey(getNetApp()) - + "track" + hearTrack.getTrack() - + settings.rcnvK(settings.getSecret()); - String signature = MD5.getHashString(sigText); + String[][] strings = db.fetchHeartsArray(); - try { - String response = postHeartTrack(hearTrack, settings.rcnvK(settings.getAPIkey()), signature, settings.getSessionKey(getNetApp())); - // TODO: ascertain if string is Json - if (response.equals("okSuccess")) { - Handler h = new Handler(mCtx.getMainLooper()); - h.post(() -> Toast.makeText(mCtx, mCtx.getString(R.string.loved_track) + " " + getNetApp().getName(), Toast.LENGTH_SHORT).show()); - Log.d(TAG, "Successful heart track: " + getNetApp().getName()); - } else { - JSONObject jObject = new JSONObject(response); - if (jObject.has("error")) { - int code = jObject.getInt("error"); - if (code == 6) { - // store hearTrack in database or allow failure. - // settings.setSessionKey(getNetApp(), ""); + for (String[] s : strings) { + + boolean failure = false; + String sigText = "api_key" + + settings.rcnvK(settings.getAPIkey()) + + "artist" + s[1] + + "methodtrack.lovesk" + + settings.getSessionKey(getNetApp()) + + "track" + s[0] + + settings.rcnvK(settings.getSecret()); + + String signature = MD5.getHashString(sigText); + + try { + String response = postHeartTrack(s, settings.rcnvK(settings.getAPIkey()), signature, settings.getSessionKey(getNetApp())); + // TODO: ascertain if string is Json + if (response.equals("okSuccess")) { + Log.d(TAG, "Successful heart track: " + getNetApp().getName()); + } else { + JSONObject jObject = new JSONObject(response); + if (jObject.has("error")) { + int code = jObject.getInt("error"); + if (code == 9 || code == 11) { + Log.d(TAG, "Failed heart track."); + } + } else { Log.d(TAG, "Failed heart track."); + failure = true; } - } else { - Log.d(TAG, "Failed heart track."); } + } catch (Exception e) { + Log.e(TAG, "Heart track fail " + e); + //e.printStackTrace(); + failure = true; } - } catch (Exception e) { - Log.e(TAG, "Heart track fail " + e); - //e.printStackTrace(); + if (failure) db.deleteHeart(s); } } - private String postHeartTrack(Track track, String testAPI, String signature, String + private String postHeartTrack(String[] track, String testAPI, String signature, String sessionKey) { URL url; HttpURLConnection conn = null; try { + url = new URL(getNetApp().getWebserviceUrl(settings)); conn = (HttpURLConnection) url.openConnection(); @@ -125,8 +134,8 @@ private String postHeartTrack(Track track, String testAPI, String signature, Str Map params = new LinkedHashMap<>(); params.put("method", "track.love"); - params.put("track", track.getTrack()); - params.put("artist", track.getArtist()); + params.put("track", track[0]); + params.put("artist", track[1]); params.put("api_key", testAPI); params.put("api_sig", signature); params.put("sk", sessionKey); 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 bff1be6a..98dced03 100644 --- a/app/src/main/java/com/adam/aslfms/service/Networker.java +++ b/app/src/main/java/com/adam/aslfms/service/Networker.java @@ -120,7 +120,7 @@ public void launchNPNotifier(Track track) { mExecutor.execute(n); } - public void launchHeartTrack(Track track) { + public void launchHeart() { Iterator i = mExecutor.getQueue().iterator(); while (i.hasNext()) { Runnable r = i.next(); @@ -129,8 +129,8 @@ public void launchHeartTrack(Track track) { } } - Heart n = new Heart(mNetApp, mCtx, this, track, settings); - mExecutor.execute(n); + Heart s = new Heart(mNetApp, mCtx, this, mDb); + mExecutor.execute(s); } public void launchUserInfo() { 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 9f5f3d62..11f2a45b 100644 --- a/app/src/main/java/com/adam/aslfms/service/NetworkerManager.java +++ b/app/src/main/java/com/adam/aslfms/service/NetworkerManager.java @@ -89,8 +89,16 @@ public void launchAllScrobblers() { } } - public void launchHeartTrack(Track track, NetApp napp) { - mSupportedNetApps.get(napp).launchHeartTrack(track); + public void launchAllHearts(){ + for (NetApp napp : NetApp.values()) { + if( napp != NetApp.LISTENBRAINZ && napp != NetApp.LISTENBRAINZCUSTOM){ + launchHeart(napp); + } + } + } + + public void launchHeart(NetApp napp) { + mSupportedNetApps.get(napp).launchHeart(); } public void launchGetUserInfo(NetApp napp) { 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 9e94b421..7eb5cda8 100644 --- a/app/src/main/java/com/adam/aslfms/service/Scrobbler.java +++ b/app/src/main/java/com/adam/aslfms/service/Scrobbler.java @@ -108,7 +108,7 @@ public boolean doRun(HandshakeResult hInfo) { // delete scrobbles (not tracks) from db (not array) for (Track track : tracks) { - mDb.deleteScrobble(netApp, track.getRowId()); + mDb.setSentField(netApp, track.getRowId()); } // clean up tracks if no one else wants to scrobble them @@ -484,10 +484,6 @@ public void scrobbleCommit(HandshakeResult hInfo, Track[] tracks) if (track.getTrackNr() != null) { params.put("trackNumber" + is, track.getTrackNr()); } - - if (track.getRating().equals("L")) { - mNetManager.launchHeartTrack(track, netApp); - } } for (Map.Entry param : params.entrySet()) { sign += param.getKey() + String.valueOf(param.getValue()); 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 9996915b..ae5b4e89 100644 --- a/app/src/main/java/com/adam/aslfms/service/ScrobblingService.java +++ b/app/src/main/java/com/adam/aslfms/service/ScrobblingService.java @@ -32,6 +32,7 @@ import com.adam.aslfms.PermissionsActivity; import com.adam.aslfms.R; +import com.adam.aslfms.UserCredActivity; import com.adam.aslfms.util.AppSettings; import com.adam.aslfms.util.InternalTrackTransmitter; import com.adam.aslfms.util.NotificationCreator; @@ -184,15 +185,21 @@ private void handleCommand(Intent i, int startId) { Toast.makeText(this, this.getString(R.string.no_heart_track), Toast.LENGTH_LONG).show(); } else { - mDb.loveRecentTrack(); + for (NetApp napp : NetApp.values()){ + if (napp != NetApp.LISTENBRAINZCUSTOM && napp != NetApp.LISTENBRAINZ) mDb.insertHeart(mCurrentTrack, napp); + } + mNetManager.launchAllHearts(); Toast.makeText(this, this.getString(R.string.song_is_ready), Toast.LENGTH_SHORT).show(); - Log.d(TAG, "Love Track Rating!"); + Log.d(TAG, "Love track insert"); } } catch (Exception e) { Log.e(TAG, "CAN'T HEART TRACK" + e); } } else if (mCurrentTrack != null) { - mCurrentTrack.setRating(); + for (NetApp napp : NetApp.values()){ + if (napp != NetApp.LISTENBRAINZCUSTOM && napp != NetApp.LISTENBRAINZ) mDb.insertHeart(mCurrentTrack, napp); + } + mNetManager.launchAllHearts(); Toast.makeText(this, this.getString(R.string.song_is_ready), Toast.LENGTH_SHORT).show(); Log.d(TAG, "Love Track Rating!"); } else { @@ -278,7 +285,13 @@ private synchronized void onPlayStateChanged(Track track, Track.State state) { tryNotifyNP(mCurrentTrack); foreGroundService(); - + // we must be logged in to scrobble + if (!settings.isAnyAuthenticated()) { + Util.myNotify(this, this.getResources().getString(R.string.warning) , this.getResources().getString(R.string.not_logged_in),05233, UserCredActivity.class); + Log + .d(TAG, + "The user has not authenticated, won't propagate the submission request"); + } } else if (state == Track.State.PAUSE) { // pause // TODO: test this state if (mCurrentTrack == null) { @@ -417,16 +430,18 @@ private void queue(Track track) { // now set up scrobbling rels for (NetApp napp : NetApp.values()) { - if (settings.isAuthenticated(napp)) { - Log.d(TAG, "inserting scrobble: " + napp.getName()); - mDb.insertScrobble(napp, rowId); - - // tell interested parties - Intent i = new Intent( - ScrobblingService.BROADCAST_ONSTATUSCHANGED); - i.putExtra("netapp", napp.toString()); - sendBroadcast(i); + Log.d(TAG, "inserting scrobble: " + napp.getName()); + if (mDb.insertScrobble(napp, rowId)){ + Log.d(TAG, "inserting scrobble successful"); + mDb.verifyOrUpdateScrobblesAlreadyInCache(napp); + } else { + Log.d(TAG, "inserting scrobble failure"); } + // tell interested parties + Intent i = new Intent( + ScrobblingService.BROADCAST_ONSTATUSCHANGED); + i.putExtra("netapp", napp.toString()); + sendBroadcast(i); } } else { Log.e(TAG, "Could not insert scrobble into the db"); 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 f9b6994c..f9d20c13 100644 --- a/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java +++ b/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java @@ -21,6 +21,7 @@ package com.adam.aslfms.util; +import android.app.TaskStackBuilder; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; @@ -33,6 +34,11 @@ import com.adam.aslfms.service.NetApp; import com.adam.aslfms.util.enums.SortField; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + /** * * @author tgwizard @@ -47,75 +53,101 @@ public class ScrobblesDatabase { private final Context mCtx; public static final String DATABASE_NAME = "data"; - private static final int DATABASE_VERSION = 6; + private static final int DATABASE_VERSION = 7; private static final String ENABLE_FOREIGN_KEYS = "PRAGMA foreign_keys = ON;"; private static final String TABLENAME_SCROBBLES = "scrobbles"; + private static final String TABLENAME_HEARTS = "hearts"; private static final String TABLENAME_CORRNETAPP = "scrobbles_netapp"; + private static final String TABLENAME_CORRNETAPP_REPAIRED = "scrobbles_netapp_repaired"; private static final String TABLENAME_CORRECTION_RULES = "correction_rules"; private static final String TABLENAME_RULE_CHANGES = "rule_changes"; private static final String TRIGGER_NAME_CHECK_CORRECTION_RULES = "check_correction_rules"; - private static final String DATABASE_CREATE_CORRECTION_RULES = - "create table correction_rules (" + - " _id integer primary key autoincrement," + - " track_to_change text not null," + - " album_to_change text not null," + - " artist_to_change text not null," + - " track_correction text not null," + - " album_correction text not null," + - " artist_correction text not null" + // Remember to add ',' when integrating musicapp support -// " musicapp integer not null" + - ");"; - - private static final String DATABASE_CREATE_RULE_CHANGES = - "create table rule_changes (" + - " track_id integer primary key," + - " original_track text not null," + - " original_album text not null," + - " original_artist text not null," + - " foreign key (track_id) references scrobbles(_id) on delete cascade on update cascade" + - ");"; - - private static final String DATABASE_CREATE_SCROBBLES = "create table scrobbles (" - + "_id integer primary key autoincrement, " // - + "musicapp integer not null, " // - + "artist text not null, " // - + "album text not null, " // - + "albumartist text not null, " // - + "trackartist text not null, " // - + "track text not null, " // - + "tracknr text not null, " // - + "mbid text not null, " // - + "source text not null, " // - + "duration integer not null, " // - + "whenplayed integer not null," // - + "rating text not null);"; - - private static final String DATABASE_CREATE_CORRNETAPP = "create table scrobbles_netapp (" - + "netappid integer not null, " - + "trackid integer not null, " - + "primary key (netappid, trackid), " - + "foreign key (trackid) references scrobbles(_id) " - + "on delete cascade on update cascade)"; + private static final String end_cmd = ";"; + private static final String begin_curve_brace = "("; + private static final String end_curve_brace = ")"; + private static final String comma = ","; + private static final String sp = " "; + private static final String if_exists = "IF EXISTS"; + private static final String if_not_exists = "IF NOT EXISTS"; + private static final String table = "table"; + private static final String create = "create"; + private static final String drop = "drop"; + private static final String alter = "alter"; + private static final String trigger = "trigger"; + private static final String add_column = "add column"; + private static final String int_opt = "INTEGER NOT NULL"; + private static final String str_opt = "TEXT NOT NULL DEFAULT ''"; + private static final String id_int_prim_key_auto_opt = "_id integer primary key autoincrement"; + private static final String music_api_int = "musicapp integer not null"; + private static final String on_update_cascade = "on delete cascade on update cascade"; + private static final String foreign_key_ref_track_id_refs_scrobbles_id = "foreign key (track_id) references scrobbles(_id)"; + private static final String foreign_key_ref_trackid_refs_scrobbles_id = "foreign key (trackid) references scrobbles(_id)"; + + private static final String[] correction_rules_strings = {"track_to_change", "album_to_change", "artist_to_change", "track_correction", "album_correction", "artist_correction"}; + + private static final String rule_changes_track_id = "track_id integer primary key"; + private static final String[] rule_changes_strings = {"original_track","original_album","original_artist"}; + + private static final String[] scrobbles_heart_only_strings = {"track", "artist", "netapp", "rating"}; + private static final String[] scrobbles_strings = {"album", "albumartist", "trackartist", "tracknr", "mbid", "source"}; + private static final String[] scrobbles_ints = {"duration", "whenplayed"}; + + private static final String[] scrobbles_netapp_strings = {"netappid", "trackid", "sentstatus", "acceptedstatus"}; + private static final String scrobbles_netapp_primary_key = "primary key (netappid, trackid)"; // failure DEPRECATED, do not use + + + private static String buildStringOptions(String[] stringArray, String option){ + StringBuilder stringBuilder = new StringBuilder(); + for (int j = 0; j < stringArray.length; j++){ + stringBuilder.append(sp); + stringBuilder.append(stringArray[j]); + stringBuilder.append(sp); + stringBuilder.append(option); + if (j != stringArray.length - 1) stringBuilder.append(comma); + } + return stringBuilder.toString(); + } + private static final String DATABASE_CREATE_CORRECTION_RULES = TABLENAME_CORRECTION_RULES + sp + begin_curve_brace + id_int_prim_key_auto_opt + comma + buildStringOptions(correction_rules_strings,str_opt) + end_curve_brace + end_cmd; + private static final String DATABASE_CREATE_RULE_CHANGES = TABLENAME_RULE_CHANGES + sp + begin_curve_brace + rule_changes_track_id + comma + buildStringOptions(rule_changes_strings, str_opt) + comma + sp + foreign_key_ref_track_id_refs_scrobbles_id + on_update_cascade + end_curve_brace + end_cmd; + private static final String DATABASE_CREATE_SCROBBLES = TABLENAME_SCROBBLES + sp + begin_curve_brace + id_int_prim_key_auto_opt + comma + sp + music_api_int + comma + sp + + buildStringOptions(scrobbles_heart_only_strings, str_opt) + comma + sp + buildStringOptions(scrobbles_strings, str_opt) + comma + sp + buildStringOptions(scrobbles_ints, int_opt) + end_curve_brace + end_cmd; + private static final String DATABASE_CREATE_CORRNETAPP_REPAIRED = TABLENAME_CORRNETAPP_REPAIRED + sp + begin_curve_brace + sp + id_int_prim_key_auto_opt + comma + buildStringOptions(scrobbles_netapp_strings, str_opt) + comma + sp + foreign_key_ref_trackid_refs_scrobbles_id + on_update_cascade + end_curve_brace ; + private static final String DATABASE_CREATE_HEARTS = TABLENAME_HEARTS + sp + begin_curve_brace + id_int_prim_key_auto_opt + comma + buildStringOptions(scrobbles_heart_only_strings, str_opt) + end_curve_brace + end_cmd; private static final String TRIGGGER_CREATE_CHECK_CORRECTION_RULES = - "create trigger check_correction_rules" + - " after insert on scrobbles" + + "check_correction_rules" + + " after insert on "+ TABLENAME_SCROBBLES + " for each row" + " when (select count(*) from correction_rules where new.track = track_to_change and new.album = album_to_change and new.artist = artist_to_change) = 1 " + "begin" + " insert into rule_changes (track_id, original_track, original_album, original_artist)" + " select _id track_id, track original_track, album original_album, artist original_artist" + - " from scrobbles" + + " from " + TABLENAME_SCROBBLES + " where _id = new._id;" + - " update scrobbles" + + " update " + TABLENAME_SCROBBLES + " set track = (select track_correction from correction_rules where new.track = track_to_change and new.album = album_to_change and new.artist = artist_to_change)," + " album = (select album_correction from correction_rules where new.track = track_to_change and new.album = album_to_change and new.artist = artist_to_change)," + " artist = (select artist_correction from correction_rules where new.track = track_to_change and new.album = album_to_change and new.artist = artist_to_change) where _id = new._id; " + "end;"; + private static final String TRIGGGER_CREATE_CHECK_CORRECTION_RULES_HEARTS = + "check_correction_rules_hearts" + + " after insert on "+ TABLENAME_HEARTS + + " for each row" + + " when (select count(*) from correction_rules where new.track = track_to_change and new.artist = artist_to_change) = 1 " + + "begin" + + " insert into rule_changes (track_id, original_track,original_artist)" + + " select _id track_id, track original_track, artist original_artist" + + " from " + TABLENAME_HEARTS + + " where _id = new._id;" + + " update " + TABLENAME_HEARTS + + " set track = (select track_correction from correction_rules where new.track = track_to_change and new.artist = artist_to_change)," + + " artist = (select artist_correction from correction_rules where new.track = track_to_change and new.artist = artist_to_change) where _id = new._id; " + + "end;"; + private static class DatabaseHelper extends SQLiteOpenHelper { private DatabaseHelper(Context _context) { @@ -163,28 +195,76 @@ public static void closeDatabase() { @Override public void onCreate(SQLiteDatabase db) { + db.execSQL(ENABLE_FOREIGN_KEYS); + String pre_cmd = create + sp + table + sp; + String pre_cmd_with_trigger = create + sp + trigger + sp; Log.d(TAG, "create sql scrobbles: " + DATABASE_CREATE_SCROBBLES); - Log.d(TAG, "create sql corrnetapp: " + DATABASE_CREATE_CORRNETAPP); - db.execSQL(DATABASE_CREATE_SCROBBLES); - db.execSQL(DATABASE_CREATE_CORRNETAPP); + Log.d(TAG, "create sql corrnetapp: " + DATABASE_CREATE_CORRNETAPP_REPAIRED); + db.execSQL(pre_cmd + DATABASE_CREATE_SCROBBLES); + db.execSQL(pre_cmd + DATABASE_CREATE_CORRNETAPP_REPAIRED); // Tables and trigger for updating scrobbles based on rules. - db.execSQL(DATABASE_CREATE_CORRECTION_RULES); - db.execSQL(DATABASE_CREATE_RULE_CHANGES); - db.execSQL(TRIGGGER_CREATE_CHECK_CORRECTION_RULES); + Log.d(TAG, "create sql correction_rules: " + DATABASE_CREATE_CORRECTION_RULES); + Log.d(TAG, "create sql rules_changes: " + DATABASE_CREATE_RULE_CHANGES); + Log.d(TAG, "create sql hearts: " + DATABASE_CREATE_HEARTS); + Log.d(TAG, "create sql triggers: " + TRIGGGER_CREATE_CHECK_CORRECTION_RULES); + Log.d(TAG, "create sql triggers_hearts: " + TRIGGGER_CREATE_CHECK_CORRECTION_RULES_HEARTS); + db.execSQL(pre_cmd + DATABASE_CREATE_CORRECTION_RULES); + db.execSQL(pre_cmd + DATABASE_CREATE_RULE_CHANGES); + db.execSQL(pre_cmd + DATABASE_CREATE_HEARTS); + db.execSQL(pre_cmd_with_trigger + TRIGGGER_CREATE_CHECK_CORRECTION_RULES); + db.execSQL(pre_cmd_with_trigger + TRIGGGER_CREATE_CHECK_CORRECTION_RULES_HEARTS); + } + + private void verifyOrAddColumnInTable(String[] cols, String opt, String myTable, SQLiteDatabase db){ + Cursor cursor = db.rawQuery("SELECT * FROM " + myTable, null); + for (String col : cols) { + int columnIndex = cursor.getColumnIndex(col); + if (columnIndex < 0) { + db.execSQL(alter + sp + table + sp + myTable + sp + add_column + sp + col + sp + opt); + } + } + } + + private void repairCoreNetAppTable(SQLiteDatabase db){ + Cursor c = db.rawQuery( "SELECT name FROM sqlite_master WHERE type='table' AND name='" + TABLENAME_CORRNETAPP + "'",null); // check if table exists + if (c.getCount() > 0) { + Cursor dbCursor = db.query(TABLENAME_CORRNETAPP_REPAIRED, null, null, null, null, null, null); + String[] columnNames = dbCursor.getColumnNames(); + Log.d(TAG, columnNames[0]); + db.execSQL("INSERT INTO " + TABLENAME_CORRNETAPP_REPAIRED + " SELECT " + null + "," + scrobbles_netapp_strings[0] + "," + scrobbles_netapp_strings[1] + " FROM " + TABLENAME_CORRNETAPP + ";"); + } + db.execSQL(drop + sp + table + sp + if_exists + sp + TABLENAME_CORRNETAPP); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + String pre_cmd = create + sp + table + sp + if_not_exists + sp; + String pre_cmd_with_trigger = create + sp + trigger + sp + if_not_exists + sp; Log.w(TAG, "Upgrading scrobbles database from version " + oldVersion + " to " + newVersion - + ", which will destroy all old data"); - db.execSQL("DROP TABLE IF EXISTS " + TABLENAME_SCROBBLES); - db.execSQL("DROP TABLE IF EXISTS " + TABLENAME_CORRNETAPP); - // TODO add migration of old rules if/when necessary - db.execSQL("DROP TABLE IF EXISTS " + TABLENAME_CORRECTION_RULES); - db.execSQL("DROP TABLE IF EXISTS " + TABLENAME_RULE_CHANGES); - db.execSQL("DROP TRIGGER IF EXISTS " + TRIGGER_NAME_CHECK_CORRECTION_RULES); - onCreate(db); + + ", which will test and update database functionality."); + if (newVersion > oldVersion) { + db.execSQL(ENABLE_FOREIGN_KEYS); + db.execSQL(pre_cmd + DATABASE_CREATE_CORRNETAPP_REPAIRED); + db.execSQL(pre_cmd + DATABASE_CREATE_SCROBBLES); + // Tables and trigger for updating scrobbles based on rules. + db.execSQL(pre_cmd + DATABASE_CREATE_CORRECTION_RULES); + db.execSQL(pre_cmd + DATABASE_CREATE_RULE_CHANGES); + db.execSQL(pre_cmd + DATABASE_CREATE_HEARTS); + db.execSQL(pre_cmd_with_trigger + TRIGGGER_CREATE_CHECK_CORRECTION_RULES); + db.execSQL(pre_cmd_with_trigger + TRIGGGER_CREATE_CHECK_CORRECTION_RULES_HEARTS); + // check for primary key bug in CORENETAPP + repairCoreNetAppTable(db); + // alter database to add missing values if possible + // scrobbles table + verifyOrAddColumnInTable(scrobbles_heart_only_strings, str_opt, TABLENAME_SCROBBLES, db); + verifyOrAddColumnInTable(scrobbles_strings, str_opt, TABLENAME_SCROBBLES, db); + verifyOrAddColumnInTable(scrobbles_ints, int_opt, TABLENAME_SCROBBLES, db); + // netapp table + verifyOrAddColumnInTable(scrobbles_netapp_strings, str_opt, TABLENAME_CORRNETAPP_REPAIRED, db); + // hearts table + verifyOrAddColumnInTable(scrobbles_heart_only_strings, str_opt, TABLENAME_HEARTS, db); + } } @Override @@ -233,6 +313,20 @@ public long insertTrack(Track track) { return mDb.insert(TABLENAME_SCROBBLES, null, vals); } + /** + * Return the new rowId for that heart, otherwise return a -1 to indicate + * failure. + * + * @return rowId or -1 if failed + */ + public long insertHeart(Track track, NetApp netApp){ + ContentValues vals = new ContentValues(); + vals.put("artist", track.getArtist()); + vals.put("track", track.getTrack()); + vals.put("netapp", netApp.getValue()); + return mDb.insert(TABLENAME_HEARTS, null, vals); + } + /** * * @param napp @@ -246,7 +340,31 @@ public boolean insertScrobble(NetApp napp, long trackid) { iVals.put("netappid", napp.getValue()); iVals.put("trackid", trackid); - return mDb.insert(TABLENAME_CORRNETAPP, null, iVals) > 0; + return mDb.insert(TABLENAME_CORRNETAPP_REPAIRED, null, iVals) > 0; + } + + public long verifyOrUpdateScrobblesAlreadyInCache(NetApp napp){ + open(); + Cursor c; + String sql = "select * from scrobbles"; + c = mDb.rawQuery(sql, null); + c.moveToFirst(); + long count = 0; + long temp = 0; + while (!c.isAfterLast()) { + ContentValues iVals = new ContentValues(); + iVals.put("netappid", napp.getValue()); + iVals.put("trackid", c.getInt(c.getColumnIndex("_id"))); + Cursor c2 = mDb.rawQuery("SELECT * FROM " + TABLENAME_CORRNETAPP_REPAIRED + " WHERE " + scrobbles_netapp_strings[2] + " =? " + scrobbles_netapp_strings[0] + " =? " + " AND " + scrobbles_netapp_strings[1] + " =? ", new String[] { "", Integer.toString(napp.getValue()), Integer.toString(c.getInt(c.getColumnIndex("_id")))}); + if (c2.moveToFirst()){ + // do nothing + } else { + temp = mDb.insert(TABLENAME_CORRNETAPP_REPAIRED, null, iVals); + count += temp < 0 ? 1 : 0; + } + c.moveToNext(); + } + return count; } public int deleteScrobble(NetApp napp, int trackId) { @@ -254,10 +372,26 @@ public int deleteScrobble(NetApp napp, int trackId) { Log.e(TAG, "Trying to delete scrobble with trackId == -1"); return -2; } - return mDb.delete(TABLENAME_CORRNETAPP, "netappid = ? and trackid = ?", + return mDb.delete(TABLENAME_CORRNETAPP_REPAIRED, "netappid = ? and trackid = ?", + new String[]{"" + napp.getValue(), "" + trackId}); + } + + public int setSentField(NetApp napp, int trackId) { + if (trackId == -1) { + Log.e(TAG, "Trying to delete scrobble with trackId == -1"); + return -2; + } + ContentValues contentValues = new ContentValues(); + contentValues.put(scrobbles_netapp_strings[2], "sent"); + return mDb.update(TABLENAME_CORRNETAPP_REPAIRED, contentValues,"netappid = ? and trackid = ?", new String[]{"" + napp.getValue(), "" + trackId}); } + public int deleteHeart(String[] s) { + return mDb.delete(TABLENAME_HEARTS, scrobbles_heart_only_strings[0] + " = ? and " + scrobbles_heart_only_strings[1] + " = ? and " + scrobbles_heart_only_strings[2] + " = ?", + new String[]{"" + s[0], "" + s[1], "" + s[2]}); + } + public void setAlbum(String album, int trackId) { ContentValues values = new ContentValues(); values.put("album", album); @@ -294,13 +428,13 @@ public void setTrack(String track, int trackId) { * @return the number of rows affected */ public int deleteAllScrobbles(NetApp napp) { - return mDb.delete(TABLENAME_CORRNETAPP, "netappid = ?", + return mDb.delete(TABLENAME_CORRNETAPP_REPAIRED, "netappid = ?", new String[]{"" + napp.getValue()}); } public boolean cleanUpTracks() { mDb.execSQL("delete from scrobbles where _id not in " - + "(select trackid as _id from scrobbles_netapp)"); + + "(select trackid as _id from " + TABLENAME_CORRNETAPP_REPAIRED + ")"); return true; } @@ -327,8 +461,8 @@ private Track readTrack(Cursor c) { public Track[] fetchTracksArray(NetApp napp, int maxFetch) { Cursor c; // try { - String sql = "select * from scrobbles, scrobbles_netapp " - + "where _id = trackid and netappid = " + napp.getValue(); + String sql = "select * from scrobbles, " + TABLENAME_CORRNETAPP_REPAIRED + + " where scrobbles._id = trackid and netappid = " + napp.getValue(); c = mDb.rawQuery(sql, null); /* * } catch (SQLiteException e) { Log.e(TAG, @@ -349,10 +483,29 @@ public Track[] fetchTracksArray(NetApp napp, int maxFetch) { return tracks; } + public String[][] fetchHeartsArray(){ + Cursor c; + // try { + String sql = "select * from " + TABLENAME_HEARTS ; + c = mDb.rawQuery(sql, null); + + int count = c.getCount(); + c.moveToFirst(); + String[][] tracks = new String[count][3]; + for (int i = 0; i < count; i++) { + tracks[i][0] = c.getString(c.getColumnIndex(scrobbles_heart_only_strings[0])); + tracks[i][1] = c.getString(c.getColumnIndex(scrobbles_heart_only_strings[1])); + tracks[i][2] = c.getString(c.getColumnIndex(scrobbles_heart_only_strings[2])); + c.moveToNext(); + } + c.close(); + return tracks; + } + public Cursor fetchTracksCursor(NetApp napp, SortField sf) { Cursor c; - String sql = "select * from scrobbles, scrobbles_netapp " - + "where _id = trackid and netappid = " + napp.getValue() + String sql = "select * from scrobbles, " + TABLENAME_CORRNETAPP_REPAIRED + + " where scrobbles._id = trackid and netappid = " + napp.getValue() + " order by " + sf.getSql(); c = mDb.rawQuery(sql, null); return c; @@ -378,21 +531,6 @@ public Track fetchTrack(int trackId) { return track; } - public void loveRecentTrack() { - String sql = "select * from scrobbles order by rowid desc limit 1"; - Cursor c = mDb.rawQuery(sql, null); - - if (c.getCount() == 0) - return; - - c.moveToFirst(); - long trackId = c.getLong(c.getColumnIndex("_id")); - ContentValues values = new ContentValues(); - values.put("rating", "L"); - mDb.update("scrobbles", values, "_id=" + trackId, null); - c.close(); - } - public Track fetchRecentTrack() { String sql = "select * from scrobbles order by rowid desc limit 1"; Cursor c = mDb.rawQuery(sql, null); @@ -407,7 +545,7 @@ public Track fetchRecentTrack() { } public NetApp[] fetchNetAppsForScrobble(int trackId) { - String sql = "select netappid from scrobbles_netapp where trackid = " + String sql = "select netappid from " + TABLENAME_CORRNETAPP_REPAIRED + " where trackid = " + trackId; Cursor c = mDb.rawQuery(sql, null); @@ -441,7 +579,7 @@ public int queryNumberOfTracks() { public int queryNumberOfScrobbles(NetApp napp) { Cursor c; c = mDb.rawQuery( - "select count(trackid) from scrobbles_netapp where netappid = " + "select count(trackid) from " + TABLENAME_CORRNETAPP_REPAIRED + " where netappid = " + napp.getValue(), null); int count = c.getCount(); if (count != 0) { @@ -503,30 +641,4 @@ public CorrectionRule fetchCorrectioneRule(int id) { c.close(); return rule; } - - public void rebuildCoreNetappDatabaseOnce(){ - Log.d(TAG, "dropping sql corenetapp "); - mDb.execSQL("DROP TABLE IF EXISTS " + TABLENAME_CORRNETAPP); - Log.d(TAG, "create sql corrnetapp: " + DATABASE_CREATE_CORRNETAPP); - mDb.execSQL(DATABASE_CREATE_CORRNETAPP); - } - - public void rebuildCorrectionsDatabaseOnce(){ - Log.d(TAG, "dropping sql corrections "); - mDb.execSQL("DROP TABLE IF EXISTS " + TABLENAME_CORRECTION_RULES); - mDb.execSQL("DROP TABLE IF EXISTS " + TABLENAME_RULE_CHANGES); - mDb.execSQL("DROP TRIGGER IF EXISTS " + TRIGGER_NAME_CHECK_CORRECTION_RULES); - Log.d(TAG, "create sql corrections: " + DATABASE_CREATE_CORRECTION_RULES); - mDb.execSQL(DATABASE_CREATE_CORRECTION_RULES); - mDb.execSQL(DATABASE_CREATE_RULE_CHANGES); - mDb.execSQL(TRIGGGER_CREATE_CHECK_CORRECTION_RULES); - } - - - public void rebuildScrobblesDatabaseOnce(){ - Log.d(TAG, "dropping sql scrobbles "); - mDb.execSQL("DROP TABLE IF EXISTS " + TABLENAME_SCROBBLES); - Log.d(TAG, "create sql scrobbles: " + DATABASE_CREATE_SCROBBLES); - mDb.execSQL(DATABASE_CREATE_SCROBBLES); - } } 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 19335bf2..71b79e77 100644 --- a/app/src/main/java/com/adam/aslfms/util/Util.java +++ b/app/src/main/java/com/adam/aslfms/util/Util.java @@ -613,7 +613,7 @@ public static boolean isMyServiceRunning(Context context, Class serviceClass) { return false; } - public static void runServices(Context context) { + public static void runServices(Context context) { if (!isMyServiceRunning(context, ScrobblingService.class)) { Log.d(TAG, "(re)starting scrobbleservice"); Intent i = new Intent(context, ScrobblingService.class); From a9868a78e7f1f68f36680f0736b2c752044c2da6 Mon Sep 17 00:00:00 2001 From: Austin Hogan Date: Sat, 21 Sep 2019 14:55:13 -0400 Subject: [PATCH 2/5] Database Migration * Database problems fixed * Database migration * Offline Heart Track * A grey record of sent tracks is kept now * Back button in permissions fixed * Privacy information in permissions * Russian thanks to alexesprit --- .../adam/aslfms/receiver/MusicAPITest.java | 4 +- app/src/main/assets/changelog.txt | 5 +- .../com/adam/aslfms/MusicAppsActivity.java | 17 ++++++- .../com/adam/aslfms/SettingsActivity.java | 4 +- .../java/com/adam/aslfms/StatusActivity.java | 2 +- .../aslfms/ViewScrobbleCacheActivity.java | 23 +++++++++ .../receiver/AbstractPlayStatusReceiver.java | 7 ++- .../receiver/GenericControllerReceiver.java | 4 +- .../com/adam/aslfms/receiver/MusicAPI.java | 30 ++++++++---- .../com/adam/aslfms/service/Handshaker.java | 2 + .../com/adam/aslfms/service/Scrobbler.java | 2 +- .../aslfms/service/ScrobblingService.java | 19 ++++---- .../adam/aslfms/util/ScrobblesDatabase.java | 41 ++++++++++++---- .../main/java/com/adam/aslfms/util/Util.java | 48 +++++++++++++++++++ app/src/main/res/menu/view_scrobble_cache.xml | 4 ++ app/src/main/res/values/strings.xml | 3 ++ 16 files changed, 177 insertions(+), 38 deletions(-) diff --git a/app/src/androidTest/java/com/adam/aslfms/receiver/MusicAPITest.java b/app/src/androidTest/java/com/adam/aslfms/receiver/MusicAPITest.java index 13ec3387..c3edf05e 100644 --- a/app/src/androidTest/java/com/adam/aslfms/receiver/MusicAPITest.java +++ b/app/src/androidTest/java/com/adam/aslfms/receiver/MusicAPITest.java @@ -129,11 +129,11 @@ public void testGettersFromDB() { public void testEnabling() { MusicAPI a = getMusicAPIA(); assertTrue(a.isEnabled()); - a.setEnabled(ctx, false); + a.setEnabled(ctx, 0); assertFalse(a.isEnabled()); MusicAPI b = MusicAPI.fromDatabase(ctx, a.getId()); assertFalse(b.isEnabled()); - b.setEnabled(ctx, true); + b.setEnabled(ctx, 1); assertTrue(b.isEnabled()); a = MusicAPI.fromDatabase(ctx, b.getId()); assertTrue(a.isEnabled()); diff --git a/app/src/main/assets/changelog.txt b/app/src/main/assets/changelog.txt index 105252ab..86daaf71 100644 --- a/app/src/main/assets/changelog.txt +++ b/app/src/main/assets/changelog.txt @@ -5,12 +5,13 @@ https://github.com/simple-last-fm-scrobbler/sls/wiki/Privacy-Concerns For privacy concerns. - 1.6.8 (2019-9-15) codename: kingus - * Database overwrite problem fixed + * Database problems fixed + * Database migration + * A grey record of sent tracks is kept now * Back button in permissions fixed * Privacy information in permissions * Russian thanks to alexesprit - - 1.6.7 (2019-9-15) codename: jingus * Fixed non-foreground service crash Bug * Show user permissions each update diff --git a/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java b/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java index fb1de407..69feb200 100644 --- a/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java +++ b/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java @@ -113,7 +113,7 @@ public boolean onPreferenceTreeClick(PreferenceScreen prefScreen, if (mapi != null) { CheckBoxPreference cbp = (CheckBoxPreference) pref; boolean checked = cbp.isChecked(); - mapi.setEnabled(this, checked); + mapi.setEnabled(this, checked ? 1 : 0); setSMASummary(pref, mapi); if (checked && mScrobbleDroidInstalled @@ -157,11 +157,26 @@ private void update() { MusicAPI[] mapis = MusicAPI.all(this); for (MusicAPI mapi : mapis) { + CheckBoxPreference appPref = new CheckBoxPreference(this, null); appPref.setTitle(mapi.getName()); appPref.setPersistent(false); appPref.setChecked(mapi.isEnabled()); + + switch (mapi.getEnabledValue()){ + case 0: + appPref.setIcon(android.R.drawable.checkbox_off_background); + break; + case 1: + appPref.setIcon(android.R.drawable.checkbox_on_background); + break; + case 2: + default: + appPref.setIcon(android.R.drawable.stat_sys_warning); + break; + } + mSupportedMusicAppsList.addPreference(appPref); mPrefsToMapisMap.put(appPref, mapi); mMapisToPrefsMap.put(mapi, appPref); diff --git a/app/src/main/java/com/adam/aslfms/SettingsActivity.java b/app/src/main/java/com/adam/aslfms/SettingsActivity.java index 99a3dda4..58b7548f 100644 --- a/app/src/main/java/com/adam/aslfms/SettingsActivity.java +++ b/app/src/main/java/com/adam/aslfms/SettingsActivity.java @@ -145,7 +145,7 @@ public boolean onPreferenceTreeClick(PreferenceScreen prefScreen, Preference pref) { if (pref == mScrobbleAllNow) { checkNetwork(); - int numInCache = mDb.queryNumberOfTracks(); + int numInCache = mDb.queryNumberOfUnscrobbledTracks(); Util.scrobbleAllIfPossible(this, numInCache); return true; } else if (pref == mViewScrobbleCache) { @@ -169,7 +169,7 @@ public boolean onPreferenceTreeClick(PreferenceScreen prefScreen, */ private void update() { mDb = new ScrobblesDatabase(this); - int numCache = mDb.queryNumberOfTracks(); + int numCache = mDb.queryNumberOfUnscrobbledTracks(); mScrobbleAllNow.setSummary(getString(R.string.scrobbles_cache).replace( "%1", Integer.toString(numCache))); mScrobbleAllNow.setEnabled(numCache > 0); diff --git a/app/src/main/java/com/adam/aslfms/StatusActivity.java b/app/src/main/java/com/adam/aslfms/StatusActivity.java index a3780957..bc8a3b22 100644 --- a/app/src/main/java/com/adam/aslfms/StatusActivity.java +++ b/app/src/main/java/com/adam/aslfms/StatusActivity.java @@ -110,7 +110,7 @@ public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection switch (item.getItemId()) { case MENU_SCROBBLE_NOW_ID: - int numInCache = mDb.queryNumberOfTracks(); + int numInCache = mDb.queryNumberOfUnscrobbledTracks(); Util.scrobbleAllIfPossible(this, numInCache); return true; case R.id.MENU_RESET_STATS_ID: diff --git a/app/src/main/java/com/adam/aslfms/ViewScrobbleCacheActivity.java b/app/src/main/java/com/adam/aslfms/ViewScrobbleCacheActivity.java index 65fbe5f0..107cb785 100644 --- a/app/src/main/java/com/adam/aslfms/ViewScrobbleCacheActivity.java +++ b/app/src/main/java/com/adam/aslfms/ViewScrobbleCacheActivity.java @@ -28,6 +28,7 @@ import android.content.IntentFilter; import android.content.res.Resources; import android.database.Cursor; +import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.support.v7.app.ActionBar; @@ -57,6 +58,8 @@ public class ViewScrobbleCacheActivity extends AppCompatActivity { private static final String TAG = "VSCacheActivity"; + private static final int disabledColor = Color.argb(25, 0,0,0); + private AppSettings settings; @@ -65,6 +68,7 @@ public class ViewScrobbleCacheActivity extends AppCompatActivity { * mNetApp == null means that we should view cache for all netapps */ private NetApp mNetApp; + private NetApp[] mNetApps; private Cursor mScrobblesCursor = null; @@ -178,6 +182,7 @@ private void refillData() { private void fillData() { SortField sf = settings.getCacheSortField(); + if (mNetApp == null) { mScrobblesCursor = mDb.fetchAllTracksCursor(sf); } else { @@ -218,6 +223,15 @@ public boolean onOptionsItemSelected(MenuItem item) { mScrobblesCursor); } return true; + case R.id.menu_clear_completed_cache: + if (mNetApp == null) { + Util.deleteAllScrobbledTracksFromAllCaches(this, mDb, + mScrobblesCursor); + } else { + Util.deleteAllScrobbledTracksFromCache(this, mDb, mNetApp, + mScrobblesCursor); + } + return true; case R.id.menu_change_sort_order: viewChangeSortOrder(); return true; @@ -318,6 +332,15 @@ public MyAdapter(Context context, Cursor c) { @Override public void bindView(View view, Context context, Cursor cursor) { + + if (mNetApp == null) { + mNetApps = mDb.fetchNetAppsForScrobble(cursor.getInt(cursor.getColumnIndex("_id"))); + } else { + mNetApps = null; + } + + if (mNetApps.length == 0) view.setBackgroundColor(disabledColor); + String track = cursor.getString(cursor.getColumnIndex("track")); TextView trackView = (TextView) view.findViewById(R.id.track); trackView.setText(track); diff --git a/app/src/main/java/com/adam/aslfms/receiver/AbstractPlayStatusReceiver.java b/app/src/main/java/com/adam/aslfms/receiver/AbstractPlayStatusReceiver.java index f2f0ac12..d7c3f60e 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/AbstractPlayStatusReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/AbstractPlayStatusReceiver.java @@ -27,6 +27,7 @@ import android.os.Bundle; import android.util.Log; +import com.adam.aslfms.MusicAppsActivity; import com.adam.aslfms.R; import com.adam.aslfms.UserCredActivity; import com.adam.aslfms.service.ScrobblingService; @@ -106,10 +107,14 @@ public final void onReceive(Context context, Intent intent) { } // check if the user wants to scrobble music from this MusicAPI - if (!mMusicAPI.isEnabled()) { + if (mMusicAPI.getEnabledValue() == 0) { Log.d(TAG, "App: " + mMusicAPI.getName() + " has been disabled, won't propagate"); return; + } else if (mMusicAPI.getEnabledValue() == 2) { + Util.myNotify(context, mMusicAPI.getName(), context.getString(R.string.new_music_app), 12473, MusicAppsActivity.class); + Log.d(TAG, "App: " + mMusicAPI.getName() + + " has been ignored, will propagate"); } // submit track for the ScrobblingService 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 ebbc40ce..f7a56e92 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java @@ -70,7 +70,7 @@ private void parseData(Context ctx, String action, Bundle bundle){ if (playerPackage != null && !playerPackage.isEmpty()) { PackageManager packageManager = ctx.getPackageManager(); playerName = packageManager.getApplicationLabel(packageManager.getApplicationInfo(playerPackage, PackageManager.GET_META_DATA)).toString(); - mMusicApi = MusicAPI.fromReceiver(ctx, playerName, playerPackage, null, false); + mMusicApi = MusicAPI.fromReceiver(ctx, playerName, playerPackage, "genericrcvr", false); setMusicAPI(mMusicApi); } } @@ -78,7 +78,7 @@ private void parseData(Context ctx, String action, Bundle bundle){ Log.w(TAG, e.toString()); } if (mMusicApi == null) { - mMusicApi = MusicAPI.fromReceiver(ctx, ctx.getResources().getString(R.string.notification_controller), ctx.getPackageName(), null, false); + mMusicApi = MusicAPI.fromReceiver(ctx, ctx.getResources().getString(R.string.notification_controller), ctx.getPackageName(), "genericrcvr", false); setMusicAPI(mMusicApi); } if (bundle.containsKey("track")) { diff --git a/app/src/main/java/com/adam/aslfms/receiver/MusicAPI.java b/app/src/main/java/com/adam/aslfms/receiver/MusicAPI.java index 03b2c401..33eec041 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/MusicAPI.java +++ b/app/src/main/java/com/adam/aslfms/receiver/MusicAPI.java @@ -58,7 +58,7 @@ public class MusicAPI { int enabled; MusicAPI(long id, String name, String pkg, String msg, - boolean clashWithScrobbleDroid, boolean enabled) { + boolean clashWithScrobbleDroid, int enabled) { super(); if (name == null) @@ -71,7 +71,7 @@ public class MusicAPI { this.pkg = pkg; this.msg = msg; this.clashWithScrobbleDroid = clashWithScrobbleDroid ? 1 : 0; - this.enabled = enabled ? 1 : 0; + this.enabled = enabled; } /** @@ -138,6 +138,17 @@ public boolean isEnabled() { return enabled == 1; } + /** + * Returns int if the user has not enabled or disabled scrobbling through this API / music + * app. Default is true. + * + * @return int of scrobbling from this API / music app + * @see MusicAppsActivity + */ + public int getEnabledValue() { + return enabled; + } + /** * Enables / disables scrobbling from this API / music app. * @@ -145,8 +156,8 @@ public boolean isEnabled() { * @param enabled whether this API / app should be enabled or disabled * @see MusicAppsActivity */ - public void setEnabled(Context ctx, boolean enabled) { - int en = enabled ? 1 : 0; + public void setEnabled(Context ctx, int enabled) { + int en = enabled; if (en == this.enabled) return; @@ -285,7 +296,8 @@ public static MusicAPI fromReceiver(Context ctx, String name, String pkg, vals.put("pkg", pkg); vals.put("msg", msg); vals.put("sdclash", clashWithScrobbleDroid ? 1 : 0); - vals.put("enabled", 1); + if (msg.equals("genericrcvr")) vals.put("enabled", 2); + else vals.put("enabled", 1); long id = db.insert("music_api", null, vals); @@ -296,8 +308,8 @@ public static MusicAPI fromReceiver(Context ctx, String name, String pkg, Log.d(TAG, "new mapiinserted into db"); } - mapi = new MusicAPI(id, name, pkg, msg, clashWithScrobbleDroid, - true); + if (msg.equals("genericrcvr")) mapi = new MusicAPI(id, name, pkg, msg, clashWithScrobbleDroid, 2); + else mapi = new MusicAPI(id, name, pkg, msg, clashWithScrobbleDroid, 1); Log.d(TAG, mapi.toString()); } DatabaseHelper.closeDatabase(); @@ -329,7 +341,7 @@ public static MusicAPI fromDatabase(Context ctx, long id) { // track // hasn't been played after the upgrade to v1.2.3 mapi = new MusicAPI(-1, ctx.getString(R.string.unknown_mapi), - NOT_AN_APPLICATION_PACKAGE + "pre_1_2_3", null, false, true); + NOT_AN_APPLICATION_PACKAGE + "pre_1_2_3", null, false, 1); } c.close(); DatabaseHelper.closeDatabase(); @@ -366,7 +378,7 @@ private static MusicAPI readMusicAPI(Cursor c) { c.getString(c.getColumnIndex("pkg")), // c.getString(c.getColumnIndex("msg")), // c.getInt(c.getColumnIndex("sdclash")) == 1, // - c.getInt(c.getColumnIndex("enabled")) == 1); + c.getInt(c.getColumnIndex("enabled"))); } static final String DATABASE_NAME = "music_apis"; 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 e7921cdd..78e15ddf 100644 --- a/app/src/main/java/com/adam/aslfms/service/Handshaker.java +++ b/app/src/main/java/com/adam/aslfms/service/Handshaker.java @@ -136,6 +136,8 @@ public void run() { ScrobblesDatabase db = new ScrobblesDatabase(mCtx); + db.verifyOrUpdateScrobblesAlreadyInCache(getNetApp()); + notifyAuthStatusUpdate(AuthStatus.AUTHSTATUS_OK); // launch services after login 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 7eb5cda8..bb596c17 100644 --- a/app/src/main/java/com/adam/aslfms/service/Scrobbler.java +++ b/app/src/main/java/com/adam/aslfms/service/Scrobbler.java @@ -108,7 +108,7 @@ public boolean doRun(HandshakeResult hInfo) { // delete scrobbles (not tracks) from db (not array) for (Track track : tracks) { - mDb.setSentField(netApp, track.getRowId()); + if ( mDb.setSentField(netApp, track.getRowId()) <= 0) Log.e(TAG, "failed to set sent field for trackid: " + track.getRowId() + " netapp: " + netApp.getValue()); } // clean up tracks if no one else wants to scrobble them 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 ae5b4e89..9cf0aa65 100644 --- a/app/src/main/java/com/adam/aslfms/service/ScrobblingService.java +++ b/app/src/main/java/com/adam/aslfms/service/ScrobblingService.java @@ -215,11 +215,11 @@ private void handleCommand(Intent i, int startId) { if (sdk < Build.VERSION_CODES.HONEYCOMB) { @SuppressWarnings("deprecation") android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(tempTrack.getTrack() + " by " + tempTrack.getArtist() + ", " + tempTrack.getAlbum() + ", on " + tempTrack.getMusicAPI().getName()); + clipboard.setText(tempTrack.getTrack() + R.string.by + tempTrack.getArtist() + ", " + tempTrack.getAlbum() + "; " + tempTrack.getMusicAPI().getName()); } else { @SuppressWarnings("deprecation") android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("Track", tempTrack.getTrack() + " by " + tempTrack.getArtist() + ", " + tempTrack.getAlbum() + ", on " + tempTrack.getMusicAPI().getName()); + android.content.ClipData clip = android.content.ClipData.newPlainText("Track", tempTrack.getTrack() + R.string.by + tempTrack.getArtist() + ", " + tempTrack.getAlbum() + "; " + tempTrack.getMusicAPI().getName()); clipboard.setPrimaryClip(clip); } Log.d(TAG, "Copy Track!"); @@ -234,11 +234,11 @@ private void handleCommand(Intent i, int startId) { if (sdk < Build.VERSION_CODES.HONEYCOMB) { @SuppressWarnings("deprecation") android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(mCurrentTrack.getTrack() + " by " + mCurrentTrack.getArtist() + ", " + mCurrentTrack.getAlbum() + ", on " + mCurrentTrack.getMusicAPI().getName()); + clipboard.setText(mCurrentTrack.getTrack() + R.string.by + mCurrentTrack.getArtist() + ", " + mCurrentTrack.getAlbum() + "; " + mCurrentTrack.getMusicAPI().getName()); } else { @SuppressWarnings("deprecation") android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("Track", mCurrentTrack.getTrack() + " by " + mCurrentTrack.getArtist() + ", " + mCurrentTrack.getAlbum() + ", on " + mCurrentTrack.getMusicAPI().getName()); + android.content.ClipData clip = android.content.ClipData.newPlainText("Track", mCurrentTrack.getTrack() + R.string.by + mCurrentTrack.getArtist() + ", " + mCurrentTrack.getAlbum() + "; " + mCurrentTrack.getMusicAPI().getName()); clipboard.setPrimaryClip(clip); } Log.d(TAG, "Copy Track!"); @@ -431,11 +431,12 @@ private void queue(Track track) { // now set up scrobbling rels for (NetApp napp : NetApp.values()) { Log.d(TAG, "inserting scrobble: " + napp.getName()); - if (mDb.insertScrobble(napp, rowId)){ - Log.d(TAG, "inserting scrobble successful"); - mDb.verifyOrUpdateScrobblesAlreadyInCache(napp); - } else { - Log.d(TAG, "inserting scrobble failure"); + if (settings.isAuthenticated(napp)) { + if (mDb.insertScrobble(napp, rowId)) { + Log.d(TAG, "inserting scrobble successful"); + } else { + Log.d(TAG, "inserting scrobble failure"); + } } // tell interested parties Intent i = new Intent( 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 f9d20c13..37591d0c 100644 --- a/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java +++ b/app/src/main/java/com/adam/aslfms/util/ScrobblesDatabase.java @@ -355,7 +355,7 @@ public long verifyOrUpdateScrobblesAlreadyInCache(NetApp napp){ ContentValues iVals = new ContentValues(); iVals.put("netappid", napp.getValue()); iVals.put("trackid", c.getInt(c.getColumnIndex("_id"))); - Cursor c2 = mDb.rawQuery("SELECT * FROM " + TABLENAME_CORRNETAPP_REPAIRED + " WHERE " + scrobbles_netapp_strings[2] + " =? " + scrobbles_netapp_strings[0] + " =? " + " AND " + scrobbles_netapp_strings[1] + " =? ", new String[] { "", Integer.toString(napp.getValue()), Integer.toString(c.getInt(c.getColumnIndex("_id")))}); + Cursor c2 = mDb.rawQuery("SELECT * FROM " + TABLENAME_CORRNETAPP_REPAIRED + " WHERE " + scrobbles_netapp_strings[0] + " =? AND " + scrobbles_netapp_strings[1] + " =? ", new String[] { Integer.toString(napp.getValue()), Integer.toString(c.getInt(c.getColumnIndex("_id")))}); if (c2.moveToFirst()){ // do nothing } else { @@ -378,13 +378,13 @@ public int deleteScrobble(NetApp napp, int trackId) { public int setSentField(NetApp napp, int trackId) { if (trackId == -1) { - Log.e(TAG, "Trying to delete scrobble with trackId == -1"); + Log.e(TAG, "Failed to set sent field"); return -2; } + Log.d(TAG, "Trying to set sent field"); ContentValues contentValues = new ContentValues(); - contentValues.put(scrobbles_netapp_strings[2], "sent"); - return mDb.update(TABLENAME_CORRNETAPP_REPAIRED, contentValues,"netappid = ? and trackid = ?", - new String[]{"" + napp.getValue(), "" + trackId}); + contentValues.put("sentstatus", "sent"); + return mDb.update(TABLENAME_CORRNETAPP_REPAIRED, contentValues,"netappid = " + napp.getValue() +" and _id = " + trackId, null); } public int deleteHeart(String[] s) { @@ -432,12 +432,23 @@ public int deleteAllScrobbles(NetApp napp) { new String[]{"" + napp.getValue()}); } + public int deleteAllScrobbledTracks(NetApp napp) { + return mDb.delete(TABLENAME_CORRNETAPP_REPAIRED, "netappid = ? AND sentstatus = ?", + new String[]{"" + napp.getValue(), "sent"}); + } + public boolean cleanUpTracks() { - mDb.execSQL("delete from scrobbles where _id not in " + mDb.execSQL("delete from scrobbles where scrobbles._id not in " + "(select trackid as _id from " + TABLENAME_CORRNETAPP_REPAIRED + ")"); return true; } + public boolean cleanUpScrobbledTracks() { + mDb.execSQL("delete from scrobbles where scrobbles._id not in " + + "(select trackid as _id from " + TABLENAME_CORRNETAPP_REPAIRED + " WHERE " + TABLENAME_CORRNETAPP_REPAIRED + ".sentstatus = 'sent')"); + return true; + } + private Track readTrack(Cursor c) { Track.Builder b = new Track.Builder(); b.setMusicAPI(MusicAPI.fromDatabase(mCtx, c.getLong(c @@ -546,7 +557,7 @@ public Track fetchRecentTrack() { public NetApp[] fetchNetAppsForScrobble(int trackId) { String sql = "select netappid from " + TABLENAME_CORRNETAPP_REPAIRED + " where trackid = " - + trackId; + + trackId + " and sentstatus != 'sent'"; Cursor c = mDb.rawQuery(sql, null); if (c.getCount() == 0) @@ -576,11 +587,25 @@ public int queryNumberOfTracks() { return count; } + public int queryNumberOfUnscrobbledTracks() { + if (mDb == null || !mDb.isOpen()) { + open(); + } + Cursor c = mDb.rawQuery("select count(distinct trackid) from " + TABLENAME_CORRNETAPP_REPAIRED + " where sentstatus = ''", null); + int count = c.getCount(); + if (count != 0) { + c.moveToFirst(); + count = c.getInt(0); + } + c.close(); + return count; + } + public int queryNumberOfScrobbles(NetApp napp) { Cursor c; c = mDb.rawQuery( "select count(trackid) from " + TABLENAME_CORRNETAPP_REPAIRED + " where netappid = " - + napp.getValue(), null); + + napp.getValue() + " and sentstatus != 'sent'" , null); int count = c.getCount(); if (count != 0) { c.moveToFirst(); 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 71b79e77..98d920e6 100644 --- a/app/src/main/java/com/adam/aslfms/util/Util.java +++ b/app/src/main/java/com/adam/aslfms/util/Util.java @@ -373,6 +373,54 @@ public static void deleteAllScrobblesFromAllCaches(Context ctx, } } + public static void deleteAllScrobbledTracksFromCache(Context ctx, + final ScrobblesDatabase db, final NetApp napp, final Cursor cursor) { + int numInCache = db.queryNumberOfScrobbles(napp); + if (numInCache > 0) { + Util.confirmDialog(ctx, ctx.getString( + R.string.confirm_delete_all_scd_tr).replaceAll("%1", + napp.getName()), R.string.clear_cache, android.R.string.cancel, + (dialog, which) -> { + Log.d(TAG, "Will remove all scrobbles from cache: " + + napp.getName()); + db.deleteAllScrobbledTracks(napp); + db.cleanUpScrobbledTracks(); + // need to refill data, otherwise the screen won't + // update + if (cursor != null) + cursor.requery(); + }); + } else { + Toast.makeText(ctx, ctx.getString(R.string.no_scrobbles_in_cache), + Toast.LENGTH_LONG).show(); + } + } + + public static void deleteAllScrobbledTracksFromAllCaches(Context ctx, + final ScrobblesDatabase db, final Cursor cursor) { + int numInCache = db.queryNumberOfTracks(); + if (numInCache > 0) { + Util.confirmDialog(ctx, ctx + .getString(R.string.confirm_delete_all_scd_tr_from_all), + R.string.clear_cache, android.R.string.cancel, + (dialog, which) -> { + Log + .d(TAG, + "Will remove scrobbled tracks from cache for all netapps"); + for (NetApp napp : NetApp.values()) + db.deleteAllScrobbledTracks(napp); + db.cleanUpScrobbledTracks(); + // need to refill data, otherwise the screen won't + // update + if (cursor != null) + cursor.requery(); + }); + } else { + Toast.makeText(ctx, ctx.getString(R.string.no_scrobbles_in_cache), + Toast.LENGTH_LONG).show(); + } + } + public static String getStatusSummary(Context ctx, AppSettings settings, NetApp napp) { return getStatusSummary(ctx, settings, napp, true); diff --git a/app/src/main/res/menu/view_scrobble_cache.xml b/app/src/main/res/menu/view_scrobble_cache.xml index d90f0f4d..575c5845 100644 --- a/app/src/main/res/menu/view_scrobble_cache.xml +++ b/app/src/main/res/menu/view_scrobble_cache.xml @@ -8,6 +8,10 @@ android:id="@+id/menu_clear_cache" android:icon="@android:drawable/ic_menu_close_clear_cancel" android:title="@string/clear_cache" /> + Are you sure you don\'t want to scrobble this track? This operation cannot be undone. Are you sure you want to clear all tracks in the cache for %1? This operation cannot be undone. Are you sure you want to clear all tracks in the cache? This operation cannot be undone. + Are you sure you want to clear all scrobbled tracks in the cache for %1? This operation cannot be undone. + Are you sure you want to clear all scrobbled tracks in the cache? This operation cannot be undone. There are no cached scrobbles View scrobble cache View details Remove from cache Clear cache + Clear completed cache Track info Scrobble cache for %1 View and edit the list of unsubmitted scrobbles From c06561fb2174f5fb3fb1c423b3d19852fa8fadea Mon Sep 17 00:00:00 2001 From: Austin Hogan Date: Sat, 21 Sep 2019 14:55:25 -0400 Subject: [PATCH 3/5] Changelog Changelog --- app/src/main/assets/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/changelog.txt b/app/src/main/assets/changelog.txt index 86daaf71..e948a0e8 100644 --- a/app/src/main/assets/changelog.txt +++ b/app/src/main/assets/changelog.txt @@ -7,6 +7,7 @@ For privacy concerns. - 1.6.8 (2019-9-15) codename: kingus * Database problems fixed * Database migration + * Offline Heart Track * A grey record of sent tracks is kept now * Back button in permissions fixed * Privacy information in permissions From 690e6c715b4e94290a6e20db04e911f1dd0e8b68 Mon Sep 17 00:00:00 2001 From: Austin Hogan Date: Sat, 21 Sep 2019 15:18:45 -0400 Subject: [PATCH 4/5] generic receiver music api Warning fix. --- app/src/main/assets/changelog.txt | 1 + app/src/main/java/com/adam/aslfms/MusicAppsActivity.java | 3 ++- .../com/adam/aslfms/receiver/GenericControllerReceiver.java | 4 ++-- app/src/main/java/com/adam/aslfms/receiver/MusicAPI.java | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/assets/changelog.txt b/app/src/main/assets/changelog.txt index e948a0e8..b14c8714 100644 --- a/app/src/main/assets/changelog.txt +++ b/app/src/main/assets/changelog.txt @@ -7,6 +7,7 @@ For privacy concerns. - 1.6.8 (2019-9-15) codename: kingus * Database problems fixed * Database migration + * Stop automatic app adding, so user must manually add music apps Android 5.0+ * Offline Heart Track * A grey record of sent tracks is kept now * Back button in permissions fixed diff --git a/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java b/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java index 69feb200..ab9ca2b7 100644 --- a/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java +++ b/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java @@ -212,7 +212,8 @@ private void setSMASummary(Preference pref, MusicAPI mapi) { pref.setSummary(getString(R.string.incompatability_short) .replaceAll("%1", mScrobbleDroidLabel)); } else { - pref.setSummary(mapi.getMessage()); + if (!mapi.getMessage().equals("generic receiver")) pref.setSummary(mapi.getMessage()); + else pref.setSummary(""); } } } 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 f7a56e92..4e1fdf5e 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java +++ b/app/src/main/java/com/adam/aslfms/receiver/GenericControllerReceiver.java @@ -70,7 +70,7 @@ private void parseData(Context ctx, String action, Bundle bundle){ if (playerPackage != null && !playerPackage.isEmpty()) { PackageManager packageManager = ctx.getPackageManager(); playerName = packageManager.getApplicationLabel(packageManager.getApplicationInfo(playerPackage, PackageManager.GET_META_DATA)).toString(); - mMusicApi = MusicAPI.fromReceiver(ctx, playerName, playerPackage, "genericrcvr", false); + mMusicApi = MusicAPI.fromReceiver(ctx, playerName, playerPackage, "generic receiver", false); setMusicAPI(mMusicApi); } } @@ -78,7 +78,7 @@ private void parseData(Context ctx, String action, Bundle bundle){ Log.w(TAG, e.toString()); } if (mMusicApi == null) { - mMusicApi = MusicAPI.fromReceiver(ctx, ctx.getResources().getString(R.string.notification_controller), ctx.getPackageName(), "genericrcvr", false); + mMusicApi = MusicAPI.fromReceiver(ctx, ctx.getResources().getString(R.string.notification_controller), ctx.getPackageName(), "generic receiver", false); setMusicAPI(mMusicApi); } if (bundle.containsKey("track")) { diff --git a/app/src/main/java/com/adam/aslfms/receiver/MusicAPI.java b/app/src/main/java/com/adam/aslfms/receiver/MusicAPI.java index 33eec041..117eb394 100644 --- a/app/src/main/java/com/adam/aslfms/receiver/MusicAPI.java +++ b/app/src/main/java/com/adam/aslfms/receiver/MusicAPI.java @@ -296,7 +296,7 @@ public static MusicAPI fromReceiver(Context ctx, String name, String pkg, vals.put("pkg", pkg); vals.put("msg", msg); vals.put("sdclash", clashWithScrobbleDroid ? 1 : 0); - if (msg.equals("genericrcvr")) vals.put("enabled", 2); + if (msg.equals("generic receiver")) vals.put("enabled", 2); else vals.put("enabled", 1); long id = db.insert("music_api", null, vals); @@ -308,7 +308,7 @@ public static MusicAPI fromReceiver(Context ctx, String name, String pkg, Log.d(TAG, "new mapiinserted into db"); } - if (msg.equals("genericrcvr")) mapi = new MusicAPI(id, name, pkg, msg, clashWithScrobbleDroid, 2); + if (msg.equals("generic receiver")) mapi = new MusicAPI(id, name, pkg, msg, clashWithScrobbleDroid, 2); else mapi = new MusicAPI(id, name, pkg, msg, clashWithScrobbleDroid, 1); Log.d(TAG, mapi.toString()); } From 89d1c9d03f3b895e3049f8aceb434074730e0b4f Mon Sep 17 00:00:00 2001 From: Austin Hogan Date: Sat, 21 Sep 2019 15:19:02 -0400 Subject: [PATCH 5/5] Music Apps Activity --- .../java/com/adam/aslfms/MusicAppsActivity.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java b/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java index ab9ca2b7..dcf00d5c 100644 --- a/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java +++ b/app/src/main/java/com/adam/aslfms/MusicAppsActivity.java @@ -116,6 +116,19 @@ public boolean onPreferenceTreeClick(PreferenceScreen prefScreen, mapi.setEnabled(this, checked ? 1 : 0); setSMASummary(pref, mapi); + switch (mapi.getEnabledValue()){ + case 0: + pref.setIcon(android.R.drawable.checkbox_off_background); + break; + case 1: + pref.setIcon(android.R.drawable.checkbox_on_background); + break; + case 2: + default: + pref.setIcon(android.R.drawable.stat_sys_warning); + break; + } + if (checked && mScrobbleDroidInstalled && mapi.clashesWithScrobbleDroid()) { Util.warningDialog(this, getString(