Music player UI refresh.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8b8bbfc..9dadb44 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -55,7 +55,7 @@
to it we want it back in its initial state. We exclude from
recents since this is accessible through a notification when
appropriate. -->
- <activity android:name="MediaPlaybackActivity"
+ <activity android:name="MediaPlaybackActivityStarter"
android:theme="@android:style/Theme.NoTitleBar"
android:label="@string/mediaplaybacklabel"
android:taskAffinity=""
@@ -77,6 +77,11 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
+ <activity android:name="MediaPlaybackActivity"
+ android:theme="@android:style/Theme.NoTitleBar"
+ android:label="@string/mediaplaybacklabel" >
+ </activity>
+
<activity android:name="StreamStarter" android:theme="@android:style/Theme.Dialog" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
diff --git a/res/drawable-finger/buttonbarbackground.xml b/res/drawable-finger/buttonbarbackground.xml
new file mode 100644
index 0000000..54f4181
--- /dev/null
+++ b/res/drawable-finger/buttonbarbackground.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/buttonbar_focused" />
+ <item
+ android:state_pressed="true"
+ android:drawable="@drawable/buttonbar_pressed" />
+ <item
+ android:state_selected="true"
+ android:drawable="@drawable/buttonbar_active" />
+ <item
+ android:state_selected="false"
+ android:drawable="@drawable/buttonbar_inactive" />
+</selector>
diff --git a/res/drawable-finger/ic_tab_albums.xml b/res/drawable-finger/ic_tab_albums.xml
new file mode 100644
index 0000000..72957df
--- /dev/null
+++ b/res/drawable-finger/ic_tab_albums.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_albums_selected" />
+ <item android:drawable="@drawable/ic_tab_albums_unselected" />
+</selector>
+
diff --git a/res/drawable-finger/ic_tab_artists.xml b/res/drawable-finger/ic_tab_artists.xml
new file mode 100644
index 0000000..e79766a
--- /dev/null
+++ b/res/drawable-finger/ic_tab_artists.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_artists_selected" />
+ <item android:drawable="@drawable/ic_tab_artists_unselected" />
+</selector>
+
diff --git a/res/drawable-finger/ic_tab_playback.xml b/res/drawable-finger/ic_tab_playback.xml
new file mode 100644
index 0000000..bcb8312
--- /dev/null
+++ b/res/drawable-finger/ic_tab_playback.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_playback_selected" />
+ <item android:drawable="@drawable/ic_tab_playback_unselected" />
+</selector>
+
diff --git a/res/drawable-finger/ic_tab_playlists.xml b/res/drawable-finger/ic_tab_playlists.xml
new file mode 100644
index 0000000..64e6353
--- /dev/null
+++ b/res/drawable-finger/ic_tab_playlists.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_playlists_selected" />
+ <item android:drawable="@drawable/ic_tab_playlists_unselected" />
+</selector>
+
diff --git a/res/drawable-finger/ic_tab_songs.xml b/res/drawable-finger/ic_tab_songs.xml
new file mode 100644
index 0000000..7642017
--- /dev/null
+++ b/res/drawable-finger/ic_tab_songs.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_songs_selected" />
+ <item android:drawable="@drawable/ic_tab_songs_unselected" />
+</selector>
+
diff --git a/res/drawable-hdpi-finger/buttonbar_active.9.png b/res/drawable-hdpi-finger/buttonbar_active.9.png
new file mode 100644
index 0000000..08a39ff
--- /dev/null
+++ b/res/drawable-hdpi-finger/buttonbar_active.9.png
Binary files differ
diff --git a/res/drawable-hdpi-finger/buttonbar_focused.9.png b/res/drawable-hdpi-finger/buttonbar_focused.9.png
new file mode 100644
index 0000000..a65b8f5
--- /dev/null
+++ b/res/drawable-hdpi-finger/buttonbar_focused.9.png
Binary files differ
diff --git a/res/drawable-hdpi-finger/buttonbar_inactive.9.png b/res/drawable-hdpi-finger/buttonbar_inactive.9.png
new file mode 100644
index 0000000..6150b5b
--- /dev/null
+++ b/res/drawable-hdpi-finger/buttonbar_inactive.9.png
Binary files differ
diff --git a/res/drawable-hdpi-finger/buttonbar_pressed.9.png b/res/drawable-hdpi-finger/buttonbar_pressed.9.png
new file mode 100644
index 0000000..0f90065
--- /dev/null
+++ b/res/drawable-hdpi-finger/buttonbar_pressed.9.png
Binary files differ
diff --git a/res/drawable-hdpi-finger/music_bottom_playback_bg.9.png b/res/drawable-hdpi-finger/music_bottom_playback_bg.9.png
new file mode 100644
index 0000000..df5bb44
--- /dev/null
+++ b/res/drawable-hdpi-finger/music_bottom_playback_bg.9.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_albums_selected.png b/res/drawable-hdpi/ic_tab_albums_selected.png
new file mode 100644
index 0000000..d12864c
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_albums_selected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_albums_unselected.png b/res/drawable-hdpi/ic_tab_albums_unselected.png
new file mode 100644
index 0000000..7e3a933
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_albums_unselected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_artists_selected.png b/res/drawable-hdpi/ic_tab_artists_selected.png
new file mode 100644
index 0000000..e6d3e99
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_artists_selected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_artists_unselected.png b/res/drawable-hdpi/ic_tab_artists_unselected.png
new file mode 100644
index 0000000..3139529
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_artists_unselected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_playback_selected.png b/res/drawable-hdpi/ic_tab_playback_selected.png
new file mode 100644
index 0000000..c23f761
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_playback_selected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_playback_unselected.png b/res/drawable-hdpi/ic_tab_playback_unselected.png
new file mode 100644
index 0000000..136da63
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_playback_unselected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_playlists_selected.png b/res/drawable-hdpi/ic_tab_playlists_selected.png
new file mode 100644
index 0000000..4588822
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_playlists_selected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_playlists_unselected.png b/res/drawable-hdpi/ic_tab_playlists_unselected.png
new file mode 100644
index 0000000..e42392e
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_playlists_unselected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_songs_selected.png b/res/drawable-hdpi/ic_tab_songs_selected.png
new file mode 100644
index 0000000..44e9cd1
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_songs_selected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_songs_unselected.png b/res/drawable-hdpi/ic_tab_songs_unselected.png
new file mode 100644
index 0000000..41edb5c
--- /dev/null
+++ b/res/drawable-hdpi/ic_tab_songs_unselected.png
Binary files differ
diff --git a/res/drawable-mdpi-finger/music_bottom_playback_bg.png b/res/drawable-mdpi-finger/music_bottom_playback_bg.png
new file mode 100644
index 0000000..3c59e90
--- /dev/null
+++ b/res/drawable-mdpi-finger/music_bottom_playback_bg.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_albums_selected.png b/res/drawable-mdpi/ic_tab_albums_selected.png
new file mode 100644
index 0000000..702436e
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_albums_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_albums_unselected.png b/res/drawable-mdpi/ic_tab_albums_unselected.png
new file mode 100644
index 0000000..f8083f6
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_albums_unselected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_artists_selected.png b/res/drawable-mdpi/ic_tab_artists_selected.png
new file mode 100644
index 0000000..3b010d5
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_artists_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_artists_unselected.png b/res/drawable-mdpi/ic_tab_artists_unselected.png
new file mode 100644
index 0000000..0737253
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_artists_unselected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_playback_selected.png b/res/drawable-mdpi/ic_tab_playback_selected.png
new file mode 100644
index 0000000..629516a
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_playback_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_playback_unselected.png b/res/drawable-mdpi/ic_tab_playback_unselected.png
new file mode 100644
index 0000000..8a924d9
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_playback_unselected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_playlists_selected.png b/res/drawable-mdpi/ic_tab_playlists_selected.png
new file mode 100644
index 0000000..78b128e
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_playlists_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_playlists_unselected.png b/res/drawable-mdpi/ic_tab_playlists_unselected.png
new file mode 100644
index 0000000..969366b
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_playlists_unselected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_songs_selected.png b/res/drawable-mdpi/ic_tab_songs_selected.png
new file mode 100644
index 0000000..fa3ad84
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_songs_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_songs_unselected.png b/res/drawable-mdpi/ic_tab_songs_unselected.png
new file mode 100644
index 0000000..48144f1
--- /dev/null
+++ b/res/drawable-mdpi/ic_tab_songs_unselected.png
Binary files differ
diff --git a/res/layout-finger/buttonbar.xml b/res/layout-finger/buttonbar.xml
new file mode 100644
index 0000000..4d31972
--- /dev/null
+++ b/res/layout-finger/buttonbar.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<TabWidget xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/buttonbar"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+
+ <TextView
+ android:id="@+id/artisttab"
+ android:focusable="true"
+ android:background="@drawable/buttonbarbackground"
+ android:drawableTop="@drawable/ic_tab_artists"
+ android:text="@string/browse_menu"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="wrap_content"
+ android:layout_height="64dip" />
+
+ <TextView
+ android:id="@+id/albumtab"
+ android:focusable="true"
+ android:background="@drawable/buttonbarbackground"
+ android:drawableTop="@drawable/ic_tab_albums"
+ android:text="@string/albums_menu"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="wrap_content"
+ android:layout_height="64dip" />
+
+ <TextView
+ android:id="@+id/songtab"
+ android:focusable="true"
+ android:background="@drawable/buttonbarbackground"
+ android:drawableTop="@drawable/ic_tab_songs"
+ android:text="@string/tracks_menu"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="wrap_content"
+ android:layout_height="64dip" />
+
+ <TextView
+ android:id="@+id/playlisttab"
+ android:focusable="true"
+ android:background="@drawable/buttonbarbackground"
+ android:drawableTop="@drawable/ic_tab_playlists"
+ android:text="@string/playlists_menu"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="wrap_content"
+ android:layout_height="64dip" />
+
+</TabWidget>
+
diff --git a/res/layout/media_picker_activity.xml b/res/layout-finger/media_picker_activity.xml
similarity index 90%
copy from res/layout/media_picker_activity.xml
copy to res/layout-finger/media_picker_activity.xml
index 79f080e..6513dcb 100644
--- a/res/layout/media_picker_activity.xml
+++ b/res/layout-finger/media_picker_activity.xml
@@ -22,12 +22,17 @@
<include layout="@layout/sd_error" />
+ <include layout="@layout/buttonbar" />
+
<com.android.music.TouchInterceptor
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
+ android:layout_weight="1"
android:textSize="18sp"
android:drawSelectorOnTop="false"
android:fastScrollEnabled="true" />
+ <include layout="@layout/nowplaying" />
+
</LinearLayout>
diff --git a/res/layout/media_picker_activity_expanding.xml b/res/layout-finger/media_picker_activity_expanding.xml
similarity index 91%
copy from res/layout/media_picker_activity_expanding.xml
copy to res/layout-finger/media_picker_activity_expanding.xml
index 888f909..17dde1a 100644
--- a/res/layout/media_picker_activity_expanding.xml
+++ b/res/layout-finger/media_picker_activity_expanding.xml
@@ -22,14 +22,19 @@
<include layout="@layout/sd_error" />
+ <include layout="@layout/buttonbar" />
+
<ExpandableListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
+ android:layout_weight="1"
android:textSize="18sp"
android:drawSelectorOnTop="false"
android:fastScrollEnabled="true"
android:indicatorLeft="8dip"
android:indicatorRight="52dip" />
+ <include layout="@layout/nowplaying" />
+
</LinearLayout>
diff --git a/res/layout-finger/nowplaying.xml b/res/layout-finger/nowplaying.xml
new file mode 100644
index 0000000..86dde1f
--- /dev/null
+++ b/res/layout-finger/nowplaying.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/nowplaying"
+ android:layout_width="fill_parent"
+ android:layout_height="64dip"
+ android:focusable="true"
+ android:visibility="gone"
+ android:background="@drawable/music_bottom_playback_bg"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="horizontal">
+
+ <LinearLayout
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/title"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+ <TextView
+ android:id="@+id/artist"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+ </LinearLayout>
+
+ <ImageView android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginLeft="16dip"
+ android:background="@drawable/indicator_ic_mp_playing_large"
+ />
+
+ </LinearLayout>
+</LinearLayout>
+
diff --git a/res/layout-land-finger/buttonbar.xml b/res/layout-land-finger/buttonbar.xml
new file mode 100644
index 0000000..0520ad0
--- /dev/null
+++ b/res/layout-land-finger/buttonbar.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<TabWidget xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/buttonbar"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+
+ <TextView
+ android:id="@+id/artisttab"
+ android:focusable="true"
+ android:background="@drawable/buttonbarbackground"
+ android:drawableTop="@drawable/ic_tab_artists"
+ android:text="@string/browse_menu"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="wrap_content"
+ android:layout_height="64dip" />
+
+ <TextView
+ android:id="@+id/albumtab"
+ android:focusable="true"
+ android:background="@drawable/buttonbarbackground"
+ android:drawableTop="@drawable/ic_tab_albums"
+ android:text="@string/albums_menu"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="wrap_content"
+ android:layout_height="64dip" />
+
+ <TextView
+ android:id="@+id/songtab"
+ android:focusable="true"
+ android:background="@drawable/buttonbarbackground"
+ android:drawableTop="@drawable/ic_tab_songs"
+ android:text="@string/tracks_menu"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="wrap_content"
+ android:layout_height="64dip" />
+
+ <TextView
+ android:id="@+id/playlisttab"
+ android:focusable="true"
+ android:background="@drawable/buttonbarbackground"
+ android:drawableTop="@drawable/ic_tab_playlists"
+ android:text="@string/playlists_menu"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="wrap_content"
+ android:layout_height="64dip" />
+
+ <TextView
+ android:id="@+id/nowplayingtab"
+ android:focusable="false"
+ android:background="@drawable/buttonbarbackground"
+ android:drawableTop="@drawable/ic_tab_playback"
+ android:text="@string/nowplaying_title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="wrap_content"
+ android:layout_height="64dip" />
+
+</TabWidget>
+
diff --git a/res/layout/media_picker_activity.xml b/res/layout-land-finger/media_picker_activity.xml
similarity index 93%
rename from res/layout/media_picker_activity.xml
rename to res/layout-land-finger/media_picker_activity.xml
index 79f080e..5277356 100644
--- a/res/layout/media_picker_activity.xml
+++ b/res/layout-land-finger/media_picker_activity.xml
@@ -22,10 +22,13 @@
<include layout="@layout/sd_error" />
+ <include layout="@layout/buttonbar" />
+
<com.android.music.TouchInterceptor
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
+ android:layout_weight="1"
android:textSize="18sp"
android:drawSelectorOnTop="false"
android:fastScrollEnabled="true" />
diff --git a/res/layout/media_picker_activity_expanding.xml b/res/layout-land-finger/media_picker_activity_expanding.xml
similarity index 94%
rename from res/layout/media_picker_activity_expanding.xml
rename to res/layout-land-finger/media_picker_activity_expanding.xml
index 888f909..ac8f220 100644
--- a/res/layout/media_picker_activity_expanding.xml
+++ b/res/layout-land-finger/media_picker_activity_expanding.xml
@@ -22,10 +22,13 @@
<include layout="@layout/sd_error" />
+ <include layout="@layout/buttonbar" />
+
<ExpandableListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
+ android:layout_weight="1"
android:textSize="18sp"
android:drawSelectorOnTop="false"
android:fastScrollEnabled="true"
diff --git a/src/com/android/music/AlbumBrowserActivity.java b/src/com/android/music/AlbumBrowserActivity.java
index 49a3893..4a2b6e6 100644
--- a/src/com/android/music/AlbumBrowserActivity.java
+++ b/src/com/android/music/AlbumBrowserActivity.java
@@ -20,10 +20,12 @@
import android.app.SearchManager;
import android.content.AsyncQueryHandler;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
@@ -35,6 +37,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;
@@ -49,6 +52,7 @@
import android.widget.Adapter;
import android.widget.AlphabetIndexer;
import android.widget.CursorAdapter;
+import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
@@ -60,7 +64,7 @@
import java.text.Collator;
public class AlbumBrowserActivity extends ListActivity
- implements View.OnCreateContextMenuListener, MusicUtils.Defs
+ implements View.OnCreateContextMenuListener, MusicUtils.Defs, ServiceConnection
{
private String mCurrentAlbumId;
private String mCurrentAlbumName;
@@ -70,6 +74,8 @@
private AlbumListAdapter mAdapter;
private boolean mAdapterSent;
private final static int SEARCH = CHILD_MENU_BASE;
+ private static int mLastListPosCourse = -1;
+ private static int mLastListPosFine = -1;
public AlbumBrowserActivity()
{
@@ -87,8 +93,9 @@
}
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
- MusicUtils.bindToService(this);
+ MusicUtils.bindToService(this, this);
IntentFilter f = new IntentFilter();
f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
@@ -98,8 +105,8 @@
registerReceiver(mScanListener, f);
setContentView(R.layout.media_picker_activity);
+ MusicUtils.updateButtonBar(this, R.id.albumtab);
ListView lv = getListView();
- lv.setFastScrollEnabled(true);
lv.setOnCreateContextMenuListener(this);
lv.setTextFilterEnabled(true);
@@ -146,6 +153,9 @@
@Override
public void onDestroy() {
+ ListView lv = getListView();
+ mLastListPosCourse = lv.getFirstVisiblePosition();
+ mLastListPosFine = lv.getChildAt(0).getTop();
MusicUtils.unbindFromService(this);
if (!mAdapterSent) {
Cursor c = mAdapter.getCursor();
@@ -178,6 +188,7 @@
@Override
public void onReceive(Context context, Intent intent) {
getListView().invalidateViews();
+ MusicUtils.updateNowPlaying(AlbumBrowserActivity.this);
}
};
private BroadcastReceiver mScanListener = new BroadcastReceiver() {
@@ -220,7 +231,13 @@
mReScanHandler.sendEmptyMessageDelayed(0, 1000);
return;
}
-
+
+ // restore previous position
+ if (mLastListPosCourse >= 0) {
+ getListView().setSelectionFromTop(mLastListPosCourse, mLastListPosFine);
+ mLastListPosCourse = -1;
+ }
+
MusicUtils.hideDatabaseError(this);
setTitle();
}
@@ -382,15 +399,14 @@
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
- menu.add(0, GOTO_START, 0, R.string.goto_start).setIcon(R.drawable.ic_menu_music_library);
- menu.add(0, GOTO_PLAYBACK, 0, R.string.goto_playback).setIcon(R.drawable.ic_menu_playback);
+ menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
menu.add(0, SHUFFLE_ALL, 0, R.string.shuffle_all).setIcon(R.drawable.ic_menu_shuffle);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
- menu.findItem(GOTO_PLAYBACK).setVisible(MusicUtils.isMusicLoaded());
+ MusicUtils.setPartyShuffleMenuIcon(menu);
return super.onPrepareOptionsMenu(menu);
}
@@ -399,17 +415,9 @@
Intent intent;
Cursor cursor;
switch (item.getItemId()) {
- case GOTO_START:
- intent = new Intent();
- intent.setClass(this, MusicBrowserActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- return true;
-
- case GOTO_PLAYBACK:
- intent = new Intent("com.android.music.PLAYBACK_VIEWER");
- startActivity(intent);
- return true;
+ case PARTY_SHUFFLE:
+ MusicUtils.togglePartyShuffle();
+ break;
case SHUFFLE_ALL:
cursor = MusicUtils.query(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
@@ -657,5 +665,15 @@
private Cursor mAlbumCursor;
private String mArtistId;
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ MusicUtils.updateNowPlaying(this);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ finish();
+ }
}
diff --git a/src/com/android/music/ArtistAlbumBrowserActivity.java b/src/com/android/music/ArtistAlbumBrowserActivity.java
index 9aa42b4..e4fd5c2 100644
--- a/src/com/android/music/ArtistAlbumBrowserActivity.java
+++ b/src/com/android/music/ArtistAlbumBrowserActivity.java
@@ -22,10 +22,12 @@
import android.app.SearchManager;
import android.content.AsyncQueryHandler;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.CursorWrapper;
@@ -36,9 +38,13 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.provider.MediaStore;
import android.util.Log;
+import android.util.SparseArray;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
@@ -47,9 +53,6 @@
import android.view.ViewGroup;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
-import android.widget.CursorAdapter;
-import android.widget.CursorTreeAdapter;
-import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.SectionIndexer;
@@ -61,7 +64,7 @@
public class ArtistAlbumBrowserActivity extends ExpandableListActivity
- implements View.OnCreateContextMenuListener, MusicUtils.Defs
+ implements View.OnCreateContextMenuListener, MusicUtils.Defs, ServiceConnection
{
private String mCurrentArtistId;
private String mCurrentArtistName;
@@ -73,9 +76,11 @@
private ArtistAlbumListAdapter mAdapter;
private boolean mAdapterSent;
private final static int SEARCH = CHILD_MENU_BASE;
+ private static int mLastListPosCourse = -1;
+ private static int mLastListPosFine = -1;
- public ArtistAlbumBrowserActivity()
- {
+ public void onTabClick(View v) {
+ MusicUtils.processTabClick(this, v, R.id.artisttab);
}
/** Called when the activity is first created. */
@@ -83,6 +88,7 @@
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
if (icicle != null) {
mCurrentAlbumId = icicle.getString("selectedalbum");
@@ -90,7 +96,7 @@
mCurrentArtistId = icicle.getString("selectedartist");
mCurrentArtistName = icicle.getString("selectedartistname");
}
- MusicUtils.bindToService(this);
+ MusicUtils.bindToService(this, this);
IntentFilter f = new IntentFilter();
f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
@@ -100,8 +106,8 @@
registerReceiver(mScanListener, f);
setContentView(R.layout.media_picker_activity_expanding);
+ MusicUtils.updateButtonBar(this, R.id.artisttab);
ExpandableListView lv = getExpandableListView();
- lv.setFastScrollEnabled(true);
lv.setOnCreateContextMenuListener(this);
lv.setTextFilterEnabled(true);
@@ -153,6 +159,10 @@
@Override
public void onDestroy() {
+ ExpandableListView lv = getExpandableListView();
+ mLastListPosCourse = lv.getFirstVisiblePosition();
+ mLastListPosFine = lv.getChildAt(0).getTop();
+
MusicUtils.unbindFromService(this);
if (!mAdapterSent) {
Cursor c = mAdapter.getCursor();
@@ -186,6 +196,7 @@
@Override
public void onReceive(Context context, Intent intent) {
getExpandableListView().invalidateViews();
+ MusicUtils.updateNowPlaying(ArtistAlbumBrowserActivity.this);
}
};
private BroadcastReceiver mScanListener = new BroadcastReceiver() {
@@ -229,6 +240,13 @@
return;
}
+ // restore previous position
+ if (mLastListPosCourse >= 0) {
+ ExpandableListView elv = getExpandableListView();
+ elv.setSelectionFromTop(mLastListPosCourse, mLastListPosFine);
+ mLastListPosCourse = -1;
+ }
+
MusicUtils.hideDatabaseError(this);
setTitle();
}
@@ -260,15 +278,14 @@
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
- menu.add(0, GOTO_START, 0, R.string.goto_start).setIcon(R.drawable.ic_menu_music_library);
- menu.add(0, GOTO_PLAYBACK, 0, R.string.goto_playback).setIcon(R.drawable.ic_menu_playback);
+ menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
menu.add(0, SHUFFLE_ALL, 0, R.string.shuffle_all).setIcon(R.drawable.ic_menu_shuffle);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
- menu.findItem(GOTO_PLAYBACK).setVisible(MusicUtils.isMusicLoaded());
+ MusicUtils.setPartyShuffleMenuIcon(menu);
return super.onPrepareOptionsMenu(menu);
}
@@ -277,17 +294,9 @@
Intent intent;
Cursor cursor;
switch (item.getItemId()) {
- case GOTO_START:
- intent = new Intent();
- intent.setClass(this, MusicBrowserActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- return true;
-
- case GOTO_PLAYBACK:
- intent = new Intent("com.android.music.PLAYBACK_VIEWER");
- startActivity(intent);
- return true;
+ case PARTY_SHUFFLE:
+ MusicUtils.togglePartyShuffle();
+ break;
case SHUFFLE_ALL:
cursor = MusicUtils.query(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
@@ -843,5 +852,15 @@
}
private Cursor mArtistCursor;
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ MusicUtils.updateNowPlaying(this);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ finish();
+ }
}
diff --git a/src/com/android/music/MediaPlaybackActivity.java b/src/com/android/music/MediaPlaybackActivity.java
index 8a040b8..021a199 100644
--- a/src/com/android/music/MediaPlaybackActivity.java
+++ b/src/com/android/music/MediaPlaybackActivity.java
@@ -573,9 +573,8 @@
case GOTO_START:
intent = new Intent();
intent.setClass(this, MusicBrowserActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
+ finish();
break;
case USE_AS_RINGTONE: {
// Set the system setting to make this the current ringtone
@@ -585,14 +584,7 @@
return true;
}
case PARTY_SHUFFLE:
- if (mService != null) {
- int shuffle = mService.getShuffleMode();
- if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) {
- mService.setShuffleMode(MediaPlaybackService.SHUFFLE_NONE);
- } else {
- mService.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO);
- }
- }
+ MusicUtils.togglePartyShuffle();
setShuffleButtonImage();
break;
diff --git a/src/com/android/music/MediaPlaybackActivityStarter.java b/src/com/android/music/MediaPlaybackActivityStarter.java
new file mode 100644
index 0000000..373c61c
--- /dev/null
+++ b/src/com/android/music/MediaPlaybackActivityStarter.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.music;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class MediaPlaybackActivityStarter extends Activity
+{
+ public MediaPlaybackActivityStarter()
+ {
+ }
+
+ @Override
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+ Intent i = new Intent(this, MediaPlaybackActivity.class);
+ startActivity(i);
+ finish();
+ }
+
+
+}
+
diff --git a/src/com/android/music/MediaPlaybackService.java b/src/com/android/music/MediaPlaybackService.java
index c26046a..85bb797 100644
--- a/src/com/android/music/MediaPlaybackService.java
+++ b/src/com/android/music/MediaPlaybackService.java
@@ -1072,7 +1072,8 @@
status.flags |= Notification.FLAG_ONGOING_EVENT;
status.icon = R.drawable.stat_notify_musicplayer;
status.contentIntent = PendingIntent.getActivity(this, 0,
- new Intent("com.android.music.PLAYBACK_VIEWER"), 0);
+ new Intent("com.android.music.PLAYBACK_VIEWER")
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0);
startForeground(PLAYBACKSERVICE_STATUS, status);
if (!mIsSupposedToBePlaying) {
mIsSupposedToBePlaying = true;
@@ -1553,6 +1554,9 @@
openCurrent();
play();
notifyChange(META_CHANGED);
+ if (mShuffleMode == SHUFFLE_AUTO) {
+ doAutoShuffleUpdate();
+ }
}
}
diff --git a/src/com/android/music/MusicBrowserActivity.java b/src/com/android/music/MusicBrowserActivity.java
index 8208771..3554234 100644
--- a/src/com/android/music/MusicBrowserActivity.java
+++ b/src/com/android/music/MusicBrowserActivity.java
@@ -24,6 +24,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.MediaFile;
@@ -42,12 +43,7 @@
import android.widget.TextView;
public class MusicBrowserActivity extends Activity
- implements MusicUtils.Defs, View.OnClickListener {
- private View mNowPlayingView;
- private TextView mTitle;
- private TextView mArtist;
- private boolean mAutoShuffle = false;
- private static final int SEARCH_MUSIC = CHILD_MENU_BASE;
+ implements MusicUtils.Defs {
public MusicBrowserActivity() {
}
@@ -58,23 +54,19 @@
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- setVolumeControlStream(AudioManager.STREAM_MUSIC);
+ int activeTab = MusicUtils.getIntPref(this, "activetab", R.id.artisttab);
+ if (activeTab != R.id.artisttab
+ && activeTab != R.id.albumtab
+ && activeTab != R.id.songtab
+ && activeTab != R.id.playlisttab) {
+ activeTab = R.id.artisttab;
+ }
+ MusicUtils.activateTab(this, activeTab);
+
String shuf = getIntent().getStringExtra("autoshuffle");
if ("true".equals(shuf)) {
- mAutoShuffle = true;
+ bindService((new Intent()).setClass(this, MediaPlaybackService.class), autoshuffle, 0);
}
- MusicUtils.bindToService(this, new ServiceConnection() {
- public void onServiceConnected(ComponentName classname, IBinder obj) {
- updateMenu();
- }
-
- public void onServiceDisconnected(ComponentName classname) {
- updateMenu();
- }
-
- });
- setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
- init();
}
@Override
@@ -83,138 +75,6 @@
super.onDestroy();
}
- public void init() {
- setContentView(R.layout.music_library);
- mNowPlayingView = findViewById(R.id.nowplaying);
- mTitle = (TextView) mNowPlayingView.findViewById(R.id.title);
- mArtist = (TextView) mNowPlayingView.findViewById(R.id.artist);
-
- View b = (View) findViewById(R.id.browse_button);
- b.setOnClickListener(this);
-
- b = (View) findViewById(R.id.albums_button);
- b.setOnClickListener(this);
-
- b = (View) findViewById(R.id.tracks_button);
- b.setOnClickListener(this);
-
- b = (View) findViewById(R.id.playlists_button);
- b.setOnClickListener(this);
- }
-
- private void updateMenu() {
- try {
- if (MusicUtils.sService != null && MusicUtils.sService.getAudioId() != -1) {
- makeNowPlayingView();
- mNowPlayingView.setVisibility(View.VISIBLE);
- return;
- }
- } catch (RemoteException ex) {
- }
- mNowPlayingView.setVisibility(View.INVISIBLE);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- IntentFilter f = new IntentFilter();
- f.addAction(MediaPlaybackService.META_CHANGED);
- registerReceiver(mStatusListener, new IntentFilter(f));
- updateMenu();
- if (mAutoShuffle) {
- mAutoShuffle = false;
- doAutoShuffle();
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- unregisterReceiver(mStatusListener);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
- menu.add(0, SEARCH_MUSIC, 0, R.string.search_title).setIcon(android.R.drawable.ic_menu_search);
- return true;
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- MenuItem item = menu.findItem(PARTY_SHUFFLE);
- if (item != null) {
- int shuffle = MusicUtils.getCurrentShuffleMode();
- if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) {
- item.setIcon(R.drawable.ic_menu_party_shuffle);
- item.setTitle(R.string.party_shuffle_off);
- } else {
- item.setIcon(R.drawable.ic_menu_party_shuffle);
- item.setTitle(R.string.party_shuffle);
- }
- }
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- Intent intent;
- try {
- switch (item.getItemId()) {
- case PARTY_SHUFFLE:
- int shuffle = MusicUtils.sService.getShuffleMode();
- if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) {
- MusicUtils.sService.setShuffleMode(MediaPlaybackService.SHUFFLE_NONE);
- } else {
- MusicUtils.sService.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO);
- }
- break;
-
- case SEARCH_MUSIC: {
- startSearch("", false, null, false);
- return true;
- }
- }
- } catch (RemoteException ex) {
- }
- return super.onOptionsItemSelected(item);
- }
-
- public void onClick(View v) {
- Intent intent;
- switch (v.getId()) {
- case R.id.browse_button:
- intent = new Intent(Intent.ACTION_PICK);
- intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/artistalbum");
- startActivity(intent);
- break;
- case R.id.albums_button:
- intent = new Intent(Intent.ACTION_PICK);
- intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/album");
- startActivity(intent);
- break;
- case R.id.tracks_button:
- intent = new Intent(Intent.ACTION_PICK);
- intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
- startActivity(intent);
- break;
- case R.id.playlists_button:
- intent = new Intent(Intent.ACTION_PICK);
- intent.setDataAndType(Uri.EMPTY, MediaStore.Audio.Playlists.CONTENT_TYPE);
- startActivity(intent);
- break;
- case R.id.nowplaying:
- intent = new Intent("com.android.music.PLAYBACK_VIEWER");
- startActivity(intent);
- break;
- }
- }
-
- private void doAutoShuffle() {
- bindService((new Intent()).setClass(this, MediaPlaybackService.class), autoshuffle, 0);
- }
-
private ServiceConnection autoshuffle = new ServiceConnection() {
public void onServiceConnected(ComponentName classname, IBinder obj) {
// we need to be able to bind again, so unbind
@@ -226,7 +86,6 @@
if (serv != null) {
try {
serv.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO);
- updateMenu();
} catch (RemoteException ex) {
}
}
@@ -236,46 +95,5 @@
}
};
- private void makeNowPlayingView() {
- try {
- mTitle.setText(MusicUtils.sService.getTrackName());
- String artistName = MusicUtils.sService.getArtistName();
- if (MediaFile.UNKNOWN_STRING.equals(artistName)) {
- artistName = getString(R.string.unknown_artist_name);
- }
- mArtist.setText(artistName);
- mNowPlayingView.setOnFocusChangeListener(mFocuser);
- mNowPlayingView.setOnClickListener(this);
- } catch (RemoteException ex) {
-
- }
- }
-
- View.OnFocusChangeListener mFocuser = new View.OnFocusChangeListener() {
- Drawable mBack;
-
- public void onFocusChange(View v, boolean hasFocus) {
- if (hasFocus) {
- if (mBack == null) {
- mBack = mNowPlayingView.getBackground();
- }
- Drawable dr = getResources().getDrawable(android.R.drawable.menuitem_background);
- dr.setState(new int[] { android.R.attr.state_focused});
- mNowPlayingView.setBackgroundDrawable(dr);
- mNowPlayingView.setSelected(true);
- } else {
- mNowPlayingView.setBackgroundDrawable(mBack);
- mNowPlayingView.setSelected(false);
- }
- }
- };
-
- private BroadcastReceiver mStatusListener = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // this receiver is only used for META_CHANGED events
- updateMenu();
- }
- };
}
diff --git a/src/com/android/music/MusicUtils.java b/src/com/android/music/MusicUtils.java
index cdc7251..67597eb 100644
--- a/src/com/android/music/MusicUtils.java
+++ b/src/com/android/music/MusicUtils.java
@@ -35,6 +35,7 @@
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.media.MediaFile;
import android.net.Uri;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
@@ -43,9 +44,14 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
+import android.view.ViewGroup;
import android.view.Window;
+import android.widget.LinearLayout;
+import android.widget.TabWidget;
import android.widget.TextView;
import android.widget.Toast;
@@ -231,6 +237,34 @@
return mode;
}
+ public static void togglePartyShuffle() {
+ if (sService != null) {
+ int shuffle = getCurrentShuffleMode();
+ try {
+ if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) {
+ sService.setShuffleMode(MediaPlaybackService.SHUFFLE_NONE);
+ } else {
+ sService.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO);
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ public static void setPartyShuffleMenuIcon(Menu menu) {
+ MenuItem item = menu.findItem(Defs.PARTY_SHUFFLE);
+ if (item != null) {
+ int shuffle = MusicUtils.getCurrentShuffleMode();
+ if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) {
+ item.setIcon(R.drawable.ic_menu_party_shuffle);
+ item.setTitle(R.string.party_shuffle_off);
+ } else {
+ item.setIcon(R.drawable.ic_menu_party_shuffle);
+ item.setTitle(R.string.party_shuffle);
+ }
+ }
+ }
+
/*
* Returns true if a file is currently opened for playback (regardless
* of whether it's playing or paused).
@@ -709,7 +743,7 @@
sService.play();
} catch (RemoteException ex) {
} finally {
- Intent intent = new Intent("com.android.music.PLAYBACK_VIEWER")
+ Intent intent = new Intent(context, MediaPlaybackActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
@@ -1014,4 +1048,131 @@
}
}
}
+
+ static int sActiveTabIndex = -1;
+
+ static void updateButtonBar(Activity a, int highlight) {
+ final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar);
+ boolean withtabs = false;
+ Intent intent = a.getIntent();
+ if (intent != null) {
+ withtabs = intent.getBooleanExtra("withtabs", false);
+ }
+
+ if (highlight == 0 || !withtabs) {
+ ll.setVisibility(View.GONE);
+ return;
+ } else if (withtabs) {
+ ll.setVisibility(View.VISIBLE);
+ }
+ for (int i = ll.getChildCount() - 1; i >= 0; i--) {
+
+ View v = ll.getChildAt(i);
+ boolean isActive = (v.getId() == highlight);
+ if (isActive) {
+ ll.setCurrentTab(i);
+ sActiveTabIndex = i;
+ }
+ v.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (hasFocus) {
+ for (int i = 0; i < ll.getTabCount(); i++) {
+ if (ll.getChildTabViewAt(i) == v) {
+ ll.setCurrentTab(i);
+ processTabClick((Activity)ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId());
+ break;
+ }
+ }
+ }
+ }});
+
+ v.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ processTabClick((Activity)ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId());
+
+ }});
+ }
+ }
+
+ static void processTabClick(Activity a, View v, int current) {
+ int id = v.getId();
+ if (id == current) {
+ return;
+ }
+ activateTab(a, id);
+ if (id != R.id.nowplayingtab) {
+ setIntPref(a, "activetab", id);
+ }
+ }
+
+ static void activateTab(Activity a, int id) {
+ Intent intent = new Intent(Intent.ACTION_PICK);
+ switch (id) {
+ case R.id.artisttab:
+ intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/artistalbum");
+ break;
+ case R.id.albumtab:
+ intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/album");
+ break;
+ case R.id.songtab:
+ intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
+ break;
+ case R.id.playlisttab:
+ intent.setDataAndType(Uri.EMPTY, MediaStore.Audio.Playlists.CONTENT_TYPE);
+ break;
+ case R.id.nowplayingtab:
+ intent = new Intent(a, MediaPlaybackActivity.class);
+ a.startActivity(intent);
+ // fall through and return
+ default:
+ return;
+ }
+ intent.putExtra("withtabs", true);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ a.startActivity(intent);
+ a.finish();
+ a.overridePendingTransition(0, 0);
+ }
+
+ static void updateNowPlaying(Activity a) {
+ View nowPlayingView = a.findViewById(R.id.nowplaying);
+ if (nowPlayingView == null) {
+ return;
+ }
+ try {
+ boolean withtabs = false;
+ Intent intent = a.getIntent();
+ if (intent != null) {
+ withtabs = intent.getBooleanExtra("withtabs", false);
+ }
+ if (true && MusicUtils.sService != null && MusicUtils.sService.getAudioId() != -1) {
+ TextView title = (TextView) nowPlayingView.findViewById(R.id.title);
+ TextView artist = (TextView) nowPlayingView.findViewById(R.id.artist);
+ title.setText(MusicUtils.sService.getTrackName());
+ String artistName = MusicUtils.sService.getArtistName();
+ if (MediaFile.UNKNOWN_STRING.equals(artistName)) {
+ artistName = a.getString(R.string.unknown_artist_name);
+ }
+ artist.setText(artistName);
+ //mNowPlayingView.setOnFocusChangeListener(mFocuser);
+ //mNowPlayingView.setOnClickListener(this);
+ nowPlayingView.setVisibility(View.VISIBLE);
+ nowPlayingView.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Context c = v.getContext();
+ c.startActivity(new Intent(c, MediaPlaybackActivity.class));
+ }});
+ return;
+ }
+ } catch (RemoteException ex) {
+ }
+ nowPlayingView.setVisibility(View.GONE);
+ }
+
}
diff --git a/src/com/android/music/PlaylistBrowserActivity.java b/src/com/android/music/PlaylistBrowserActivity.java
index ccdb529..fb719b2 100644
--- a/src/com/android/music/PlaylistBrowserActivity.java
+++ b/src/com/android/music/PlaylistBrowserActivity.java
@@ -70,6 +70,8 @@
private static final long PODCASTS_PLAYLIST = -3;
private PlaylistListAdapter mAdapter;
boolean mAdapterSent;
+ private static int mLastListPosCourse = -1;
+ private static int mLastListPosFine = -1;
private boolean mCreateShortcut;
@@ -90,6 +92,7 @@
}
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
MusicUtils.bindToService(this, new ServiceConnection() {
public void onServiceConnected(ComponentName classname, IBinder obj) {
@@ -108,7 +111,9 @@
MusicUtils.playPlaylist(PlaylistBrowserActivity.this, id);
}
finish();
+ return;
}
+ MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this);
}
public void onServiceDisconnected(ComponentName classname) {
@@ -123,6 +128,7 @@
registerReceiver(mScanListener, f);
setContentView(R.layout.media_picker_activity);
+ MusicUtils.updateButtonBar(this, R.id.playlisttab);
ListView lv = getListView();
lv.setOnCreateContextMenuListener(this);
lv.setTextFilterEnabled(true);
@@ -168,6 +174,9 @@
@Override
public void onDestroy() {
+ ListView lv = getListView();
+ mLastListPosCourse = lv.getFirstVisiblePosition();
+ mLastListPosFine = lv.getChildAt(0).getTop();
MusicUtils.unbindFromService(this);
if (!mAdapterSent) {
Cursor c = mAdapter.getCursor();
@@ -189,6 +198,7 @@
super.onResume();
MusicUtils.setSpinnerState(this);
+ MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this);
}
@Override
public void onPause() {
@@ -225,6 +235,11 @@
return;
}
+ // restore previous position
+ if (mLastListPosCourse >= 0) {
+ getListView().setSelectionFromTop(mLastListPosCourse, mLastListPosFine);
+ mLastListPosCourse = -1;
+ }
MusicUtils.hideDatabaseError(this);
setTitle();
}
@@ -236,29 +251,24 @@
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mCreateShortcut) {
- menu.add(0, GOTO_START, 0, R.string.goto_start).setIcon(
- R.drawable.ic_menu_music_library);
- menu.add(0, GOTO_PLAYBACK, 0, R.string.goto_playback).setIcon(
- R.drawable.ic_menu_playback).setVisible(MusicUtils.isMusicLoaded());
+ menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
}
return super.onCreateOptionsMenu(menu);
}
@Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MusicUtils.setPartyShuffleMenuIcon(menu);
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
switch (item.getItemId()) {
- case GOTO_START:
- intent = new Intent();
- intent.setClass(this, MusicBrowserActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- return true;
-
- case GOTO_PLAYBACK:
- intent = new Intent("com.android.music.PLAYBACK_VIEWER");
- startActivity(intent);
- return true;
+ case PARTY_SHUFFLE:
+ MusicUtils.togglePartyShuffle();
+ break;
}
return super.onOptionsItemSelected(item);
}
diff --git a/src/com/android/music/TrackBrowserActivity.java b/src/com/android/music/TrackBrowserActivity.java
index 078b17c..52559cf 100644
--- a/src/com/android/music/TrackBrowserActivity.java
+++ b/src/com/android/music/TrackBrowserActivity.java
@@ -94,6 +94,8 @@
private String mSortOrder;
private int mSelectedPosition;
private long mSelectedId;
+ private static int mLastListPosCourse = -1;
+ private static int mLastListPosFine = -1;
public TrackBrowserActivity()
{
@@ -105,6 +107,12 @@
{
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ Intent intent = getIntent();
+ if (intent != null) {
+ if (intent.getBooleanExtra("withtabs", false)) {
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ }
+ }
setVolumeControlStream(AudioManager.STREAM_MUSIC);
if (icicle != null) {
mSelectedId = icicle.getLong("selectedtrack");
@@ -114,10 +122,9 @@
mGenre = icicle.getString("genre");
mEditMode = icicle.getBoolean("editmode", false);
} else {
- mAlbumId = getIntent().getStringExtra("album");
+ mAlbumId = intent.getStringExtra("album");
// If we have an album, show everything on the album, not just stuff
// by a particular artist.
- Intent intent = getIntent();
mArtistId = intent.getStringExtra("artist");
mPlaylist = intent.getStringExtra("playlist");
mGenre = intent.getStringExtra("genre");
@@ -149,6 +156,7 @@
};
setContentView(R.layout.media_picker_activity);
+ MusicUtils.updateButtonBar(this, R.id.songtab);
mTrackList = getListView();
mTrackList.setOnCreateContextMenuListener(this);
if (mEditMode) {
@@ -200,12 +208,15 @@
// first case, simply retry the query when the cursor is null.
// Worst case, we end up doing the same query twice.
if (mTrackCursor != null) {
- init(mTrackCursor);
+ init(mTrackCursor, false);
} else {
setTitle(R.string.working_songs);
getTrackCursor(mAdapter.getQueryHandler(), null, true);
}
}
+ if (!mEditMode) {
+ MusicUtils.updateNowPlaying(this);
+ }
}
public void onServiceDisconnected(ComponentName name) {
@@ -222,6 +233,9 @@
@Override
public void onDestroy() {
+ ListView lv = getListView();
+ mLastListPosCourse = lv.getFirstVisiblePosition();
+ mLastListPosFine = lv.getChildAt(0).getTop();
MusicUtils.unbindFromService(this);
try {
if ("nowplaying".equals(mPlaylist)) {
@@ -319,7 +333,7 @@
super.onSaveInstanceState(outcicle);
}
- public void init(Cursor newCursor) {
+ public void init(Cursor newCursor, boolean isLimited) {
if (mAdapter == null) {
return;
@@ -332,7 +346,19 @@
mReScanHandler.sendEmptyMessageDelayed(0, 1000);
return;
}
-
+
+ // Restore previous position
+ if (mLastListPosCourse >= 0) {
+ ListView lv = getListView();
+ // this hack is needed because otherwise the position doesn't change
+ // for the 2nd (non-limited) cursor
+ lv.setAdapter(lv.getAdapter());
+ lv.setSelectionFromTop(mLastListPosCourse, mLastListPosFine);
+ if (!isLimited) {
+ mLastListPosCourse = -1;
+ }
+ }
+
MusicUtils.hideDatabaseError(this);
setTitle();
@@ -543,6 +569,9 @@
@Override
public void onReceive(Context context, Intent intent) {
getListView().invalidateViews();
+ if (!mEditMode) {
+ MusicUtils.updateNowPlaying(TrackBrowserActivity.this);
+ }
}
};
@@ -833,6 +862,18 @@
if (mTrackCursor.getCount() == 0) {
return;
}
+ // When selecting a track from the queue, just jump there instead of
+ // reloading the queue. This is both faster, and prevents accidentally
+ // dropping out of party shuffle.
+ if (mTrackCursor instanceof NowPlayingCursor) {
+ if (MusicUtils.sService != null) {
+ try {
+ MusicUtils.sService.setQueuePosition(position);
+ return;
+ } catch (RemoteException ex) {
+ }
+ }
+ }
MusicUtils.playAll(this, mTrackCursor, position);
}
@@ -847,9 +888,7 @@
if (mPlaylist == null) {
menu.add(0, PLAY_ALL, 0, R.string.play_all).setIcon(com.android.internal.R.drawable.ic_menu_play_clip);
}
- menu.add(0, GOTO_START, 0, R.string.goto_start).setIcon(R.drawable.ic_menu_music_library);
- menu.add(0, GOTO_PLAYBACK, 0, R.string.goto_playback).setIcon(R.drawable.ic_menu_playback)
- .setVisible(MusicUtils.isMusicLoaded());
+ menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
menu.add(0, SHUFFLE_ALL, 0, R.string.shuffle_all).setIcon(R.drawable.ic_menu_shuffle);
if (mPlaylist != null) {
menu.add(0, SAVE_AS_PLAYLIST, 0, R.string.save_as_playlist).setIcon(android.R.drawable.ic_menu_save);
@@ -861,6 +900,12 @@
}
@Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MusicUtils.setPartyShuffleMenuIcon(menu);
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
Cursor cursor;
@@ -870,18 +915,9 @@
return true;
}
- case GOTO_START:
- intent = new Intent();
- intent.setClass(this, MusicBrowserActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- return true;
-
- case GOTO_PLAYBACK:
- intent = new Intent("com.android.music.PLAYBACK_VIEWER");
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- return true;
+ case PARTY_SHUFFLE:
+ MusicUtils.togglePartyShuffle();
+ break;
case SHUFFLE_ALL:
// Should 'shuffle all' shuffle ALL, or only the tracks shown?
@@ -1022,7 +1058,7 @@
// This special case is for the "nowplaying" cursor, which cannot be handled
// asynchronously using AsyncQueryHandler, so we do some extra initialization here.
if (ret != null && async) {
- init(ret);
+ init(ret, false);
setTitle();
}
return ret;
@@ -1325,7 +1361,7 @@
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
//Log.i("@@@", "query complete: " + cursor.getCount() + " " + mActivity);
- mActivity.init(cursor);
+ mActivity.init(cursor, cookie != null);
if (token == 0 && cookie != null && cursor != null && cursor.getCount() >= 100) {
QueryArgs args = (QueryArgs) cookie;
startQuery(1, null, args.uri, args.projection, args.selection,