From 1da0d4554261ba18e8e4818f2e4186c6cfd1c3ad Mon Sep 17 00:00:00 2001 From: Joshua Bahnsen <archrival@gmail.com> Date: Wed, 17 Apr 2013 23:18:59 -0700 Subject: [PATCH] Add AVRCP and resume playback between sessions --- AndroidManifest.xml | 199 ++++++++++-------- .../receiver/A2dpIntentReceiver.java | 47 +++++ .../service/DownloadServiceImpl.java | 100 ++++++--- .../ultrasonic/androidapp/util/FileUtil.java | 11 +- .../ultrasonic/androidapp/util/Util.java | 89 ++++++++ 5 files changed, 329 insertions(+), 117 deletions(-) create mode 100644 src/com/thejoshwa/ultrasonic/androidapp/receiver/A2dpIntentReceiver.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 91a25d98..58fbf74d 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,91 +1,108 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:a="http://schemas.android.com/apk/res/android" - package="com.thejoshwa.ultrasonic.androidapp" - a:versionCode="4" - a:versionName="1.0.0.28" a:installLocation="auto"> + package="com.thejoshwa.ultrasonic.androidapp" + a:installLocation="auto" + a:versionCode="4" + a:versionName="1.0.0.28" > - <uses-permission a:name="android.permission.INTERNET"/> - <uses-permission a:name="android.permission.READ_PHONE_STATE"/> - <uses-permission a:name="android.permission.ACCESS_NETWORK_STATE"/> - <uses-permission a:name="android.permission.WAKE_LOCK"/> - <uses-permission a:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - <uses-permission a:name="android.permission.RECORD_AUDIO"/> - <uses-permission a:name="android.permission.MODIFY_AUDIO_SETTINGS"/> + <uses-permission a:name="android.permission.INTERNET" /> + <uses-permission a:name="android.permission.READ_PHONE_STATE" /> + <uses-permission a:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission a:name="android.permission.WAKE_LOCK" /> + <uses-permission a:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission a:name="android.permission.RECORD_AUDIO" /> + <uses-permission a:name="android.permission.MODIFY_AUDIO_SETTINGS" /> - <uses-sdk a:minSdkVersion="14" a:targetSdkVersion="17"/> + <uses-sdk + a:minSdkVersion="14" + a:targetSdkVersion="17" /> - <supports-screens a:anyDensity="true" a:xlargeScreens="true" a:largeScreens="true" a:normalScreens="true" a:smallScreens="true"/> + <supports-screens + a:anyDensity="true" + a:largeScreens="true" + a:normalScreens="true" + a:smallScreens="true" + a:xlargeScreens="true" /> - <application a:label="@string/common.appname" a:icon="@drawable/ic_launcher" a:allowBackup="false"> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.MainActivity" - a:label="UltraSonic" - a:configChanges="orientation|keyboardHidden" - a:launchMode="standard"> + <application + a:allowBackup="false" + a:icon="@drawable/ic_launcher" + a:label="@string/common.appname" > + <activity + a:name=".activity.MainActivity" + a:configChanges="orientation|keyboardHidden" + a:label="UltraSonic" + a:launchMode="standard" > <intent-filter> - <action a:name="android.intent.action.MAIN"/> - <category a:name="android.intent.category.LAUNCHER"/> + <action a:name="android.intent.action.MAIN" /> + + <category a:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.SelectArtistActivity" - a:configChanges="orientation|keyboardHidden" - a:launchMode="standard"/> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.SelectAlbumActivity" - a:configChanges="orientation|keyboardHidden"/> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.SearchActivity" - a:label="@string/search.label" - a:configChanges="orientation|keyboardHidden" - a:launchMode="singleTask" - /> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.SelectPlaylistActivity" - a:label="@string/playlist.label" - a:configChanges="orientation|keyboardHidden" - a:launchMode="standard"/> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.DownloadActivity" - a:configChanges="keyboardHidden" - a:launchMode="singleTask" - a:theme="@android:style/Theme.NoTitleBar.Fullscreen" - /> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.SettingsActivity" - a:configChanges="orientation|keyboardHidden" - a:launchMode="singleTask"/> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.HelpActivity" - a:label="@string/help.label" - a:launchMode="singleTask"/> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.LyricsActivity" - a:configChanges="orientation|keyboardHidden" - a:launchMode="singleTask"/> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.EqualizerActivity" - a:label="@string/equalizer.label" - a:configChanges="orientation|keyboardHidden" - a:launchMode="singleTask"/> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.VoiceQueryReceiverActivity" - a:launchMode="singleTask"> + <activity + a:name=".activity.SelectArtistActivity" + a:configChanges="orientation|keyboardHidden" + a:launchMode="standard" /> + <activity + a:name=".activity.SelectAlbumActivity" + a:configChanges="orientation|keyboardHidden" /> + <activity + a:name=".activity.SearchActivity" + a:configChanges="orientation|keyboardHidden" + a:label="@string/search.label" + a:launchMode="singleTask" /> + <activity + a:name=".activity.SelectPlaylistActivity" + a:configChanges="orientation|keyboardHidden" + a:label="@string/playlist.label" + a:launchMode="standard" /> + <activity + a:name=".activity.DownloadActivity" + a:configChanges="keyboardHidden" + a:launchMode="singleTask" + a:theme="@android:style/Theme.NoTitleBar.Fullscreen" /> + <activity + a:name=".activity.SettingsActivity" + a:configChanges="orientation|keyboardHidden" + a:launchMode="singleTask" /> + <activity + a:name=".activity.HelpActivity" + a:label="@string/help.label" + a:launchMode="singleTask" /> + <activity + a:name=".activity.LyricsActivity" + a:configChanges="orientation|keyboardHidden" + a:launchMode="singleTask" /> + <activity + a:name=".activity.EqualizerActivity" + a:configChanges="orientation|keyboardHidden" + a:label="@string/equalizer.label" + a:launchMode="singleTask" /> + <activity + a:name=".activity.VoiceQueryReceiverActivity" + a:launchMode="singleTask" > <intent-filter> <action a:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" /> + <category a:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> - - <activity a:name="com.thejoshwa.ultrasonic.androidapp.activity.QueryReceiverActivity" - a:launchMode="singleTask"> + <activity + a:name=".activity.QueryReceiverActivity" + a:launchMode="singleTask" > <intent-filter> - <action a:name="android.intent.action.SEARCH"/> + <action a:name="android.intent.action.SEARCH" /> </intent-filter> - <meta-data a:name="android.app.searchable" a:resource="@xml/searchable"/> + + <meta-data + a:name="android.app.searchable" + a:resource="@xml/searchable" /> </activity> - - <service a:name="com.thejoshwa.ultrasonic.androidapp.service.DownloadServiceImpl" a:label="UltraSonic Download Service"> + + <service + a:name=".service.DownloadServiceImpl" + a:label="UltraSonic Download Service" + a:exported="false" > <intent-filter> <action a:name="com.thejoshwa.ultrasonic.androidapp.CMD_TOGGLEPAUSE" /> <action a:name="com.thejoshwa.ultrasonic.androidapp.CMD_PLAY" /> @@ -96,31 +113,43 @@ </intent-filter> </service> - <receiver a:name="com.thejoshwa.ultrasonic.androidapp.receiver.MediaButtonIntentReceiver"> - <intent-filter a:priority="2147483647"> + <receiver a:name=".receiver.MediaButtonIntentReceiver" > + <intent-filter a:priority="2147483647" > <action a:name="android.intent.action.MEDIA_BUTTON" /> </intent-filter> </receiver> - - <receiver a:name="com.thejoshwa.ultrasonic.androidapp.receiver.BluetoothIntentReceiver"> + <receiver a:name=".receiver.BluetoothIntentReceiver" > <intent-filter> - <action a:name="android.bluetooth.a2dp.action.SINK_STATE_CHANGED"/> + <action a:name="android.bluetooth.a2dp.action.SINK_STATE_CHANGED" /> </intent-filter> </receiver> - - <receiver a:name="com.thejoshwa.ultrasonic.androidapp.provider.UltraSonicAppWidgetProvider4x1" a:label="UltraSonic (4x1)" > + <receiver + a:name=".provider.UltraSonicAppWidgetProvider4x1" + a:label="UltraSonic (4x1)" > <intent-filter> - <action a:name="android.appwidget.action.APPWIDGET_UPDATE"/> + <action a:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> - <meta-data a:name="android.appwidget.provider" a:resource="@xml/appwidget_info_4x1"/> + + <meta-data + a:name="android.appwidget.provider" + a:resource="@xml/appwidget_info_4x1" /> </receiver> - <provider a:name="com.thejoshwa.ultrasonic.androidapp.provider.SearchSuggestionProvider" - a:authorities="com.thejoshwa.ultrasonic.androidapp.provider.SearchSuggestionProvider"/> + <provider + a:name=".provider.SearchSuggestionProvider" + a:authorities="com.thejoshwa.ultrasonic.androidapp.provider.SearchSuggestionProvider" /> - <meta-data a:name="android.app.default_searchable" - a:value="com.thejoshwa.ultrasonic.androidapp.activity.QueryReceiverActivity"/> + <meta-data + a:name="android.app.default_searchable" + a:value="com.thejoshwa.ultrasonic.androidapp.activity.QueryReceiverActivity" /> + <receiver + a:name=".receiver.A2dpIntentReceiver" + a:exported="false" > + <intent-filter> + <action a:name="com.android.music.playstatusrequest" /> + </intent-filter> + </receiver> </application> -</manifest> +</manifest> \ No newline at end of file diff --git a/src/com/thejoshwa/ultrasonic/androidapp/receiver/A2dpIntentReceiver.java b/src/com/thejoshwa/ultrasonic/androidapp/receiver/A2dpIntentReceiver.java new file mode 100644 index 00000000..2a762b9f --- /dev/null +++ b/src/com/thejoshwa/ultrasonic/androidapp/receiver/A2dpIntentReceiver.java @@ -0,0 +1,47 @@ +package com.thejoshwa.ultrasonic.androidapp.receiver; + +import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry; +import com.thejoshwa.ultrasonic.androidapp.service.DownloadService; +import com.thejoshwa.ultrasonic.androidapp.service.DownloadServiceImpl; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class A2dpIntentReceiver extends BroadcastReceiver { + + private static final String PLAYSTATUS_REQUEST = "com.android.music.playstatusrequest"; + private static final String PLAYSTATUS_RESPONSE = "com.android.music.playstatusresponse"; + + @Override + public void onReceive(Context context, Intent intent) { + + DownloadService downloadService = DownloadServiceImpl.getInstance(); + + if (downloadService != null){ + Intent avrcpIntent = new Intent(PLAYSTATUS_RESPONSE); + + avrcpIntent.putExtra("duration", (long) downloadService.getCurrentPlaying().getSong().getDuration()); + avrcpIntent.putExtra("position", (long) downloadService.getPlayerPosition()); + avrcpIntent.putExtra("ListSize", (long) downloadService.getDownloads().size()); + + switch (downloadService.getPlayerState()){ + case STARTED: + avrcpIntent.putExtra("playing", true); + break; + case STOPPED: + avrcpIntent.putExtra("playing", false); + break; + case PAUSED: + avrcpIntent.putExtra("playing", false); + break; + case COMPLETED: + avrcpIntent.putExtra("playing", false); + break; + default: + return; + } + + context.sendBroadcast(avrcpIntent); + } + } +} \ No newline at end of file diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java index f4b5ea74..8c139e0e 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java @@ -74,6 +74,9 @@ public class DownloadServiceImpl extends Service implements DownloadService { public static final String CMD_STOP = "com.thejoshwa.ultrasonic.androidapp.CMD_STOP"; public static final String CMD_PREVIOUS = "com.thejoshwa.ultrasonic.androidapp.CMD_PREVIOUS"; public static final String CMD_NEXT = "com.thejoshwa.ultrasonic.androidapp.CMD_NEXT"; + + public static final String PLAYSTATUS_REQUEST = "com.android.music.playstatusrequest"; + public static final String PLAYSTATUS_RESPONSE = "com.android.music.playstatusresponse"; private final IBinder binder = new SimpleServiceBinder<DownloadService>(this); private MediaPlayer mediaPlayer; @@ -433,11 +436,12 @@ public class DownloadServiceImpl extends Service implements DownloadService { if (currentPlaying != null) { Util.broadcastNewTrackInfo(this, currentPlaying.getSong()); + Util.broadcastA2dpMetaDataChange(this, getInstance()); } else { Util.broadcastNewTrackInfo(this, null); } - setRemoteControl(); + updateRemoteControl(); // Update widget UltraSonicAppWidgetProvider4x1.getInstance().notifyChange(this, this, playerState == PlayerState.STARTED); @@ -474,6 +478,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { { int current = getCurrentPlayingIndex(); if (current == -1) { + resetProgressBar(); play(0); } else { play(current); @@ -538,8 +543,10 @@ public class DownloadServiceImpl extends Service implements DownloadService { // Restart song if played more than five seconds. if (getPlayerPosition() > 5000 || index == 0) { + resetProgressBar(); play(index); } else { + resetProgressBar(); play(index - 1); } } @@ -548,12 +555,24 @@ public class DownloadServiceImpl extends Service implements DownloadService { public synchronized void next() { int index = getCurrentPlayingIndex(); if (index != -1) { + resetProgressBar(); play(index + 1); } } + + private void resetProgressBar() + { + SeekBar progressBar = DownloadActivity.getProgressBar(); + if (progressBar != null) { + progressBar.setProgress(0); + } + secondaryProgress = -1; + } private void onSongCompleted() { + resetProgressBar(); int index = getCurrentPlayingIndex(); + if (index != -1) { switch (getRepeatMode()) { case OFF: @@ -593,6 +612,8 @@ public class DownloadServiceImpl extends Service implements DownloadService { try { if (playerState == STARTED) { + resetProgressBar(); + if (jukeboxEnabled) { jukeboxService.stop(); } else { @@ -643,7 +664,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { if (jukeboxEnabled) { return jukeboxService.getPositionSeconds() * 1000; } else { - return mediaPlayer.getCurrentPosition(); + return mediaPlayer.getCurrentPosition(); } } catch (Exception x) { handleError(x); @@ -677,35 +698,40 @@ public class DownloadServiceImpl extends Service implements DownloadService { synchronized void setPlayerState(PlayerState playerState) { Log.i(TAG, this.playerState.name() + " -> " + playerState.name() + " (" + currentPlaying + ")"); - if (playerState == PAUSED) { + this.playerState = playerState; + + if (this.playerState == PAUSED) { lifecycleSupport.serializeDownloadQueue(); } - boolean showWhenPaused = (playerState == PlayerState.PAUSED && Util.isNotificationAlwaysEnabled(this)); - - boolean show = playerState == PlayerState.STARTED || showWhenPaused; - boolean hide = playerState == PlayerState.IDLE || playerState == PlayerState.STOPPED || !showWhenPaused; - Util.broadcastPlaybackStatusChange(this, playerState); - - this.playerState = playerState; if (this.playerState == PlayerState.STARTED) { audioManager.requestAudioFocus(_afChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); } - setRemoteControl(); + boolean showWhenPaused = (this.playerState == PlayerState.PAUSED && Util.isNotificationAlwaysEnabled(this)); + + boolean show = this.playerState == PlayerState.STARTED || showWhenPaused; + boolean hide = this.playerState == PlayerState.IDLE || this.playerState == PlayerState.STOPPED || !showWhenPaused; + Util.broadcastPlaybackStatusChange(this, this.playerState); + Util.broadcastA2dpPlayStatusChange(this, this.playerState, getInstance()); + + // Set remote control + updateRemoteControl(); // Update widget - UltraSonicAppWidgetProvider4x1.getInstance().notifyChange(this, this, playerState == PlayerState.STARTED); + UltraSonicAppWidgetProvider4x1.getInstance().notifyChange(this, this, this.playerState == PlayerState.STARTED); if (show) { - Util.showPlayingNotification(this, this, handler, currentPlaying.getSong(), this.notification, this.playerState); + if (currentPlaying != null) { + Util.showPlayingNotification(this, this, handler, currentPlaying.getSong(), this.notification, this.playerState); + } } else if (hide) { Util.hidePlayingNotification(this, this, handler); } - if (playerState == STARTED) { + if (this.playerState == STARTED) { scrobbler.scrobble(this, currentPlaying, false); - } else if (playerState == COMPLETED) { + } else if (this.playerState == COMPLETED) { scrobbler.scrobble(this, currentPlaying, true); } } @@ -754,7 +780,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { jukeboxService.adjustVolume(up); } - private void setRemoteControl() { + private void updateRemoteControl() { if (Util.isLockScreenEnabled(this)) { if (remoteControlClient == null) { Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); @@ -828,7 +854,14 @@ public class DownloadServiceImpl extends Service implements DownloadService { private synchronized void bufferAndPlay() { reset(); - bufferTask = new BufferTask(currentPlaying, 0); + int progressBarProgress = 0; + SeekBar progressBar = DownloadActivity.getProgressBar(); + + if (progressBar != null) { + progressBarProgress = progressBar.getProgress(); + } + + bufferTask = new BufferTask(currentPlaying, progressBarProgress); bufferTask.start(); } @@ -1083,21 +1116,27 @@ public class DownloadServiceImpl extends Service implements DownloadService { private final File partialFile; public BufferTask(DownloadFile downloadFile, int position) { - this.downloadFile = downloadFile; - this.position = position; - partialFile = downloadFile.getPartialFile(); - int bufferLength = downloadFile.getBufferLength(); + this.downloadFile = downloadFile; + this.position = position; + partialFile = downloadFile.getPartialFile(); - // Calculate roughly how many bytes buffer length corresponds to. - int bitRate = downloadFile.getBitRate(); - long byteCount = Math.max(100000, bitRate * 1024 / 8 * bufferLength); + if (!Util.isStreamProxyEnabled(getBaseContext())) { + int bufferLength = downloadFile.getBufferLength(); - // Find out how large the file should grow before resuming playback. - if (position == 0) { - expectedFileSize = byteCount; - } else { - expectedFileSize = partialFile.length() + byteCount; - } + // Calculate roughly how many bytes buffer length corresponds to. + int bitRate = downloadFile.getBitRate(); + long byteCount = Math.max(100000, bitRate * 1024 / 8 * bufferLength); + + // Find out how large the file should grow before resuming playback. + if (position == 0) { + expectedFileSize = byteCount; + } else { + expectedFileSize = partialFile.length() + byteCount; + } + } else { + Log.i(TAG, "StreamProxy is enabled, will let media player control buffer size"); + expectedFileSize = 0; + } } @Override @@ -1111,7 +1150,6 @@ public class DownloadServiceImpl extends Service implements DownloadService { return; } } - } doPlay(downloadFile, position, true); diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/FileUtil.java b/src/com/thejoshwa/ultrasonic/androidapp/util/FileUtil.java index 87bc32e9..eeb73882 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/FileUtil.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/FileUtil.java @@ -88,7 +88,16 @@ public class FileUtil { if (albumArtFile.exists()) { Bitmap bitmap = BitmapFactory.decodeFile(albumArtFile.getPath()); Log.i("getAlbumArtBitmap", String.valueOf(size)); - return bitmap == null ? null : Util.scaleBitmap(bitmap, size); + if (bitmap == null) { + return null; + } + else { + if (size > 0) { + return Util.scaleBitmap(bitmap, size); + } + + return bitmap; + } } return null; diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/Util.java b/src/com/thejoshwa/ultrasonic/androidapp/util/Util.java index 8a4c8586..01b5d6a7 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/Util.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/Util.java @@ -38,6 +38,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Environment; import android.os.Handler; +import android.os.Parcelable; import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; @@ -54,6 +55,7 @@ import com.thejoshwa.ultrasonic.androidapp.domain.Version; import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry; import com.thejoshwa.ultrasonic.androidapp.provider.UltraSonicAppWidgetProvider4x1; import com.thejoshwa.ultrasonic.androidapp.receiver.MediaButtonIntentReceiver; +import com.thejoshwa.ultrasonic.androidapp.service.DownloadService; import com.thejoshwa.ultrasonic.androidapp.service.DownloadServiceImpl; import org.apache.http.HttpEntity; @@ -93,6 +95,9 @@ public class Util extends DownloadActivity { public static final String EVENT_META_CHANGED = "com.thejoshwa.ultrasonic.androidapp.EVENT_META_CHANGED"; public static final String EVENT_PLAYSTATE_CHANGED = "com.thejoshwa.ultrasonic.androidapp.EVENT_PLAYSTATE_CHANGED"; + + public static final String CM_AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged"; + public static final String CM_AVRCP_METADATA_CHANGED = "com.android.music.metachanged"; private static final Map<Integer, Version> SERVER_REST_VERSIONS = new ConcurrentHashMap<Integer, Version>(); @@ -817,6 +822,90 @@ public class Util extends DownloadActivity { context.sendBroadcast(intent); } + + public static void broadcastA2dpMetaDataChange(Context context, DownloadService downloadService) { + if (downloadService != null) { + MusicDirectory.Entry song = downloadService.getCurrentPlaying().getSong(); + + Intent avrcpIntent = new Intent(CM_AVRCP_METADATA_CHANGED); + + if (song != null) { + Bitmap bitmap = FileUtil.getAlbumArtBitmap(context, song, 0); + + avrcpIntent.putExtra("track", song.getTitle()); + avrcpIntent.putExtra("track_name", song.getTitle()); + avrcpIntent.putExtra("artist", song.getArtist()); + avrcpIntent.putExtra("artist_name", song.getArtist()); + avrcpIntent.putExtra("album", song.getAlbum()); + avrcpIntent.putExtra("album_name", song.getAlbum()); + avrcpIntent.putExtra("cover", (Parcelable) bitmap); + avrcpIntent.putExtra("coverart", (Parcelable) bitmap); + avrcpIntent.putExtra("ListSize", (long) downloadService.getDownloads().size()); + avrcpIntent.putExtra("id", (long) downloadService.getCurrentPlayingIndex() + 1); + avrcpIntent.putExtra("duration", (long) song.getDuration()); + avrcpIntent.putExtra("position", (long) downloadService.getPlayerPosition()); + + } else { + avrcpIntent.putExtra("track", ""); + avrcpIntent.putExtra("track_name", ""); + avrcpIntent.putExtra("artist", ""); + avrcpIntent.putExtra("artist_name", ""); + avrcpIntent.putExtra("album", ""); + avrcpIntent.putExtra("album_name", ""); + avrcpIntent.putExtra("cover", (Parcelable) null); + avrcpIntent.putExtra("coverart", (Parcelable) null); + avrcpIntent.putExtra("ListSize", (long) 0); + avrcpIntent.putExtra("id", (long) 0); + avrcpIntent.putExtra("duration", (long) 0); + avrcpIntent.putExtra("position", (long) 0); + } + + context.sendBroadcast(avrcpIntent); + } + + } + + public static void broadcastA2dpPlayStatusChange(Context context, PlayerState state, DownloadService downloadService) { + + if (downloadService.getCurrentPlaying() != null) { + Intent avrcpIntent = new Intent(CM_AVRCP_PLAYSTATE_CHANGED); + + MusicDirectory.Entry song = downloadService.getCurrentPlaying().getSong(); + Bitmap bitmap = FileUtil.getAlbumArtBitmap(context, song, 0); + + avrcpIntent.putExtra("track", song.getTitle()); + avrcpIntent.putExtra("track_name", song.getTitle()); + avrcpIntent.putExtra("artist", song.getArtist()); + avrcpIntent.putExtra("artist_name", song.getArtist()); + avrcpIntent.putExtra("album", song.getAlbum()); + avrcpIntent.putExtra("album_name", song.getAlbum()); + avrcpIntent.putExtra("cover", (Parcelable) bitmap); + avrcpIntent.putExtra("coverart", (Parcelable) bitmap); + avrcpIntent.putExtra("ListSize", (long) downloadService.getDownloads().size()); + avrcpIntent.putExtra("id", (long) downloadService.getCurrentPlayingIndex() + 1); + avrcpIntent.putExtra("duration", (long) song.getDuration()); + avrcpIntent.putExtra("position", (long) downloadService.getPlayerPosition()); + + switch (state) { + case STARTED: + avrcpIntent.putExtra("playing", true); + break; + case STOPPED: + avrcpIntent.putExtra("playing", false); + break; + case PAUSED: + avrcpIntent.putExtra("playing", false); + break; + case COMPLETED: + avrcpIntent.putExtra("playing", false); + break; + default: + return; // No need to broadcast. + } + + context.sendBroadcast(avrcpIntent); + } + } /** * <p>Broadcasts the given player state as the one being set.</p>