Ubuntu One Music for Android

Merge lp:~scottwferg/ubuntuone-android-music/last-fm-scrobbling into lp:ubuntuone-android-music

Proposed by Scott Ferguson on 2010-10-06
Status: Merged
Approved by: Chad Miller on 2010-10-07
Approved revision: 448
Merged at revision: 452
Proposed branch: lp:~scottwferg/ubuntuone-android-music/last-fm-scrobbling
Merge into: lp:ubuntuone-android-music
Diff against target: 202 lines (+80/-2) 6 files modified
To merge this branch: bzr merge lp:~scottwferg/ubuntuone-android-music/last-fm-scrobbling
Reviewer Review Type Date Requested Status
Chad Miller (community) 2010-10-06 Approve on 2010-10-06
Review via email: mp+37765@code.launchpad.net

Description of the Change

Adds Last.fm scrobbling support via the official Last.fm app or Simple Last.fm Scrobbler. The SLS API was used for it's simplicity, and implicit support in the official app. The changes also include a settings option to enable/disable scrobbling (defaulting to off). The user is not required to login in any way within the app, it simply broadcasts an intent with the song information at relevant playstate changes.

To post a comment you must log in.
Chad Miller (cmiller) wrote :

Nice! Thank you.

Approving, but I'm emailing last.fm about their plans for future support of the SLS API.

review: Approve
Scott Ferguson (scottwferg) wrote :

> Nice! Thank you.
>
> Approving, but I'm emailing last.fm about their plans for future support of
> the SLS API.

Sounds good!

Scott Ferguson (scottwferg) wrote :

Just pushed up a small commit to address sending the STATE_COMPLETE intent when currentPlaying is null. Caused a crash when exiting the app or finishing a playlist.

447. By Scott Ferguson <scott@scott-laptop> on 2010-10-06

Only set song information if it's available, otherwise just mark the scrobble as complete

448. By Scott Ferguson on 2010-10-07

Merge lp:~cmiller/ubuntuone-android-music/last-fm-scrobbling

Chad Miller (cmiller) wrote :

Okay. I'm happy with this.

Preview Diff

1=== modified file 'assets/html/en/index.html'
2--- assets/html/en/index.html 2010-09-01 14:23:38 +0000
3+++ assets/html/en/index.html 2010-10-07 03:11:04 +0000
4@@ -30,5 +30,17 @@
5 <li>Includes photos and contacts sync for iPhone and Android devices.</li><!-- May need to alter depending on the delivery date of photos sync -->
6 </ul>
7
8+ <h2>Scrobbling</h2>
9+
10+ <p>If you use <a href="http://last.fm/">Last.fm</a> to track your music and get recommendations, then you can install an "scrobbling" app to to send playlist events. Ubuntu One Mobile Music Streaming supports a number of apps:</a></p>
11+
12+ <ul>
13+ <li><i><disableda href="http://market.android.com/details?id=com.adam.aslfms">Simple Last.fm Scrobbler</disableda></i></li>
14+ <li>official <i><disableda href="http://market.android.com/search?q=fm.last.android">Last.fm</disableda></i></li>
15+ </ul>
16+
17+ <p>To use, enable scrobbling in the Ubuntu One Mobile Music Streaming settings, after you install and set up a scrobbling app.</p>
18+
19+
20 </body>
21 </html>
22
23=== modified file 'res/values/strings.xml'
24--- res/values/strings.xml 2010-10-01 12:16:53 +0000
25+++ res/values/strings.xml 2010-10-07 03:11:04 +0000
26@@ -137,6 +137,9 @@
27 <string name="settings.cache_size_10000">10 GB</string>
28 <string name="settings.cache_size_20000">20 GB</string>
29 <string name="settings.cache_size_unlimited">Unlimited</string>
30+ <string name="settings.lastfm_title">Last.fm</string>
31+ <string name="settings.lastfm_scrobble">Scrobbling Support</string>
32+ <string name="settings.lastfm_description">Report plays to Last.fm app (see Help)</string>
33
34 <string name="music_service.retry">A network error occurred. Retrying %d of %d.</string>
35
36
37=== modified file 'res/xml/settings.xml'
38--- res/xml/settings.xml 2010-09-07 09:14:31 +0000
39+++ res/xml/settings.xml 2010-10-07 03:11:04 +0000
40@@ -34,4 +34,14 @@
41
42 </PreferenceCategory>
43
44+ <PreferenceCategory
45+ a:title="@string/settings.lastfm_title">
46+ <CheckBoxPreference
47+ a:title="@string/settings.lastfm_scrobble"
48+ a:key="lastfmScrobbling"
49+ a:defaultValue="false"
50+ a:summary="@string/settings.lastfm_description"
51+ />
52+ </PreferenceCategory>
53+
54 </PreferenceScreen>
55
56=== modified file 'src/net/sourceforge/subsonic/androidapp/activity/SettingsActivity.java'
57--- src/net/sourceforge/subsonic/androidapp/activity/SettingsActivity.java 2010-08-23 06:27:00 +0000
58+++ src/net/sourceforge/subsonic/androidapp/activity/SettingsActivity.java 2010-10-07 03:11:04 +0000
59@@ -20,6 +20,7 @@
60
61 import android.content.SharedPreferences;
62 import android.os.Bundle;
63+import android.preference.CheckBoxPreference;
64 import android.preference.ListPreference;
65 import android.preference.PreferenceActivity;
66 import android.util.Log;
67@@ -33,6 +34,7 @@
68 private ListPreference theme;
69 private ListPreference cacheSize;
70 private ListPreference preloadCount;
71+ private CheckBoxPreference lastfmScrobbling;
72
73 @Override
74 public void onCreate(Bundle savedInstanceState) {
75@@ -42,6 +44,7 @@
76 theme = (ListPreference) findPreference(Constants.PREFERENCES_KEY_THEME);
77 cacheSize = (ListPreference) findPreference(Constants.PREFERENCES_KEY_CACHE_SIZE);
78 preloadCount = (ListPreference) findPreference(Constants.PREFERENCES_KEY_PRELOAD_COUNT);
79+ lastfmScrobbling = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_LASTFM_SCROBBLING);
80
81 SharedPreferences prefs = Util.getPreferences(this);
82 prefs.registerOnSharedPreferenceChangeListener(this);
83@@ -69,4 +72,4 @@
84 preloadCount.setSummary(preloadCount.getEntry());
85 }
86
87-}
88\ No newline at end of file
89+}
90
91=== modified file 'src/net/sourceforge/subsonic/androidapp/service/DownloadServiceImpl.java'
92--- src/net/sourceforge/subsonic/androidapp/service/DownloadServiceImpl.java 2010-09-07 09:14:31 +0000
93+++ src/net/sourceforge/subsonic/androidapp/service/DownloadServiceImpl.java 2010-10-07 03:11:04 +0000
94@@ -28,6 +28,7 @@
95 import android.app.Service;
96 import android.content.Context;
97 import android.content.Intent;
98+import android.content.SharedPreferences;
99 import android.media.AudioManager;
100 import android.media.MediaPlayer;
101 import android.os.Handler;
102@@ -38,6 +39,7 @@
103 import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
104 import net.sourceforge.subsonic.androidapp.domain.PlayerState;
105 import net.sourceforge.subsonic.androidapp.util.CancellableTask;
106+import net.sourceforge.subsonic.androidapp.util.Constants;
107 import net.sourceforge.subsonic.androidapp.util.ShufflePlayBuffer;
108 import net.sourceforge.subsonic.androidapp.util.SimpleServiceBinder;
109 import net.sourceforge.subsonic.androidapp.util.Util;
110@@ -226,8 +228,10 @@
111
112 if (currentPlaying != null && showNotification) {
113 Util.showPlayingNotification(this, handler, currentPlaying.getSong());
114+ scrobbleLastfm(Constants.LASTFM_STATE_START);
115 } else {
116 Util.hidePlayingNotification(this, handler);
117+ scrobbleLastfm(Constants.LASTFM_STATE_COMPLETE);
118 }
119 }
120
121@@ -380,8 +384,10 @@
122
123 if (this.playerState == PAUSED && playerState == PlayerState.STARTED) {
124 Util.showPlayingNotification(this, handler, currentPlaying.getSong());
125+ scrobbleLastfm(Constants.LASTFM_STATE_START);
126 } else if (this.playerState == STARTED && playerState == PlayerState.PAUSED) {
127 Util.hidePlayingNotification(this, handler);
128+ scrobbleLastfm(Constants.LASTFM_STATE_PAUSE);
129 }
130
131 this.playerState = playerState;
132@@ -572,6 +578,31 @@
133 return revision;
134 }
135
136+ private void scrobbleLastfm(final int aState) {
137+ SharedPreferences prefs = Util.getPreferences(this);
138+
139+ if (prefs.getBoolean(Constants.PREFERENCES_KEY_LASTFM_SCROBBLING, false)) {
140+ // Launch Last.fm intent here
141+ Intent lastfm = new Intent();
142+
143+ lastfm.setAction(Constants.INTENT_SCROBBLE_LASTFM);
144+ lastfm.putExtra(Constants.INTENT_EXTRA_LASTFM_APP_NAME, Constants.LASTFM_APP_NAME);
145+ lastfm.putExtra(Constants.INTENT_EXTRA_LASTFM_APP_PACKAGE, Constants.LASTFM_APP_PACKAGE);
146+
147+ if (currentPlaying != null && currentPlaying.getSong() != null) {
148+ lastfm.putExtra(Constants.INTENT_EXTRA_LASTFM_TRACK, currentPlaying.getSong().getTitle());
149+ lastfm.putExtra(Constants.INTENT_EXTRA_LASTFM_ARTIST, currentPlaying.getSong().getArtist());
150+ lastfm.putExtra(Constants.INTENT_EXTRA_LASTFM_ALBUM, currentPlaying.getSong().getAlbum());
151+ // lastfm.putExtra(Constants.INTENT_EXTRA_LASTFM_PLAYER, Constants.LASTFM_APP_NAME);
152+ lastfm.putExtra(Constants.INTENT_EXTRA_LASTFM_DURATION, currentPlaying.getSong().getDuration());
153+ }
154+
155+ lastfm.putExtra(Constants.INTENT_EXTRA_LASTFM_STATE, aState);
156+
157+ sendBroadcast(lastfm);
158+ }
159+ }
160+
161 private synchronized void cleanup() {
162 Iterator<DownloadFile> iterator = cleanupCandidates.iterator();
163 while (iterator.hasNext()) {
164
165=== modified file 'src/net/sourceforge/subsonic/androidapp/util/Constants.java'
166--- src/net/sourceforge/subsonic/androidapp/util/Constants.java 2010-09-29 21:08:46 +0000
167+++ src/net/sourceforge/subsonic/androidapp/util/Constants.java 2010-10-07 03:11:04 +0000
168@@ -44,7 +44,25 @@
169 public static final String INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET = "subsonic.albumlistoffset";
170 public static final String INTENT_EXTRA_NAME_SHUFFLE = "subsonic.shuffle";
171 public static final String INTENT_EXTRA_NAME_REFRESH = "subsonic.refresh";
172-
173+ public static final String INTENT_EXTRA_LASTFM_APP_NAME = "app-name";
174+ public static final String INTENT_EXTRA_LASTFM_APP_PACKAGE = "app-package";
175+ public static final String INTENT_EXTRA_LASTFM_TRACK = "track";
176+ public static final String INTENT_EXTRA_LASTFM_ARTIST = "artist";
177+ public static final String INTENT_EXTRA_LASTFM_ALBUM = "album";
178+ public static final String INTENT_EXTRA_LASTFM_PLAYER = "player";
179+ public static final String INTENT_EXTRA_LASTFM_DURATION = "duration";
180+ public static final String INTENT_EXTRA_LASTFM_STATE = "state";
181+
182+ // Names for external intents
183+ public static final String INTENT_SCROBBLE_LASTFM = "com.adam.aslfms.notify.playstatechanged";
184+
185+ // Last.fm scrobbling values
186+ public static final String LASTFM_APP_NAME = "Ubuntu One Music";
187+ public static final String LASTFM_APP_PACKAGE = "net.sourceforge.subsonic.androidapp";
188+ public static final int LASTFM_STATE_START = 0;
189+ public static final int LASTFM_STATE_RESUME = 1;
190+ public static final int LASTFM_STATE_PAUSE = 2;
191+ public static final int LASTFM_STATE_COMPLETE = 3;
192
193 // Notification IDs.
194 public static final int NOTIFICATION_ID_PLAYING = 100;
195@@ -62,6 +80,7 @@
196 public static final String PREFERENCES_KEY_MAX_BITRATE_MOBILE = "maxBitrateMobile";
197 public static final String PREFERENCES_KEY_CACHE_SIZE = "cacheSize";
198 public static final String PREFERENCES_KEY_PRELOAD_COUNT = "preloadCount";
199+ public static final String PREFERENCES_KEY_LASTFM_SCROBBLING = "lastfmScrobbling";
200
201 // Name of the preferences file.
202 public static final String PREFERENCES_FILE_NAME = "net.sourceforge.subsonic.u1m_preferences";

Subscribers

People subscribed via source and target branches

to status/vote changes: