android:name="android.app.default_searchable"
android:value=".QueryBrowserActivity"
/>
- <activity android:name="MusicBrowserActivity">
+ <activity android:name="MusicBrowserActivity"
+ android:theme="@android:style/Theme.NoTitleBar"
+ >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
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=""
<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" />
--- /dev/null
+<?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:color="#ffffff"/>
+ <item android:state_focused="true" android:color="#ffffff"/>
+ <item android:color="#808080"/> <!-- not selected -->
+</selector>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
+
--- /dev/null
+<?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>
+
--- /dev/null
+<?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>
+
--- /dev/null
+<?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>
+
--- /dev/null
+<?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>
+
--- /dev/null
+<?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:textColor="@color/tab_indicator_text"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="fill_parent"
+ 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:textColor="@color/tab_indicator_text"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="fill_parent"
+ 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:textColor="@color/tab_indicator_text"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="fill_parent"
+ 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:textColor="@color/tab_indicator_text"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="fill_parent"
+ android:layout_height="64dip" />
+
+</TabWidget>
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"
+ android:gravity="center_vertical" >
+
+ <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>
--- /dev/null
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"
+ android:gravity="center_vertical" >
+
+ <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>
--- /dev/null
+<?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>
+
--- /dev/null
+<?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:textColor="@color/tab_indicator_text"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="fill_parent"
+ 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:textColor="@color/tab_indicator_text"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="fill_parent"
+ 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:textColor="@color/tab_indicator_text"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="fill_parent"
+ 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:textColor="@color/tab_indicator_text"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="-3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="fill_parent"
+ 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:textColor="@color/tab_indicator_text"
+ android:paddingTop="7dip"
+ android:paddingBottom="2dip"
+ android:gravity="center"
+ android:layout_weight="1"
+ android:layout_marginLeft="3dip"
+ android:layout_marginRight="-3dip"
+ android:layout_width="fill_parent"
+ android:layout_height="64dip" />
+
+</TabWidget>
+
<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/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"
<string name="rename_playlist_menu" msgid="3133463747389494668">"Omdøb"</string>
<string name="playlist_deleted_message" msgid="9008053828193961455">"Afspilningsliste slettet."</string>
<string name="playlist_renamed_message" msgid="7187580192703005990">"Afspilningslisten er omdøbt."</string>
- <string name="recentlyadded" msgid="110978416756366953">"Tilføjet for nyligt"</string>
- <string name="recentlyadded_title" msgid="3153322287249901914">"Tilføjet for nyligt"</string>
+ <string name="recentlyadded" msgid="110978416756366953">"Tilføjet for nylig"</string>
+ <string name="recentlyadded_title" msgid="3153322287249901914">"Tilføjet for nylig"</string>
<string name="podcasts_listitem" msgid="8657809279717670634">"Podcasts"</string>
<string name="podcasts_title" msgid="4928414142496858304">"Podcasts"</string>
<string name="sdcard_missing_title" msgid="9008284946643270850">"Der er intet SD-kort"</string>
<string name="sdcard_error_message" msgid="4574563894036627855">"Der opstod en fejl på dit SD-kort."</string>
<string name="unknown_artist_name" msgid="5567811106415855219">"Ukendt kunstner"</string>
<string name="unknown_album_name" msgid="8525145988941244727">"Ukendt album"</string>
- <string name="shuffle_on_notif" msgid="5453708337808483943">"Bland er slået til."</string>
- <string name="shuffle_off_notif" msgid="4251189610017886263">"Bland er slået fra."</string>
+ <string name="shuffle_on_notif" msgid="5453708337808483943">"Blanding er slået til."</string>
+ <string name="shuffle_off_notif" msgid="4251189610017886263">"Blanding er slået fra."</string>
<string name="repeat_off_notif" msgid="1149406899083479716">"Gentagelse er slået fra."</string>
<string name="repeat_current_notif" msgid="1227153936360904196">"Den aktuelle sang gentages."</string>
<string name="repeat_all_notif" msgid="6443293055987316642">"Gentager alle sange."</string>
- <string name="ringtone_menu" msgid="2737472190159134599">"Brug som telefonringetone"</string>
+ <string name="ringtone_menu" msgid="2737472190159134599">"Brug som ringetone"</string>
<string name="ringtone_menu_short" msgid="3367622038867238133">"Brug som ringetone"</string>
<string name="ringtone_set" msgid="5325818347613843130">"\"<xliff:g id="NAME">%s</xliff:g>\" er indstillet som ringetone for telefonen."</string>
<string name="play_selection" msgid="2854921021814550018">"Afspil"</string>
<item msgid="2727959579637914171">"11 uger"</item>
<item msgid="8708754966127584739">"12 uger"</item>
</string-array>
- <string name="weekpicker_set" msgid="7636608790418067496">"Færdig"</string>
- <string name="weekpicker_title" msgid="699535378922101701">"Indstil tid"</string>
+ <string name="weekpicker_set" msgid="7636608790418067496">"Udfør"</string>
+ <string name="weekpicker_title" msgid="699535378922101701">"Angiv tid"</string>
<string name="save_as_playlist" msgid="5180413608901885255">"Gem som afspilningsliste"</string>
<string name="clear_playlist" msgid="4565515100924905315">"Ryd afspilningsliste"</string>
<string name="musicbrowserlabel" msgid="3162022214114562892">"Musik"</string>
<string name="goto_start" msgid="8979658707407220934">"Bibliothek"</string>
<string name="goto_playback" msgid="4885216161312176550">"Wiedergeben"</string>
<string name="party_shuffle" msgid="8213359225506006168">"Party-Shuffle"</string>
- <string name="party_shuffle_off" msgid="1828744483354711679">"Party-Shuffle deaktivieren"</string>
+ <string name="party_shuffle_off" msgid="1828744483354711679">"Party-Shuffle aus"</string>
<string name="delete_item" msgid="3363330144534750601">"Löschen"</string>
<string name="shuffle_all" msgid="1388193611787878773">"Alle zufällig wiedergeben"</string>
<string name="play_all" msgid="6309622568869321842">"Alle wiedergeben"</string>
<string name="repeat_off_notif" msgid="1149406899083479716">"Wiederholung ist deaktiviert."</string>
<string name="repeat_current_notif" msgid="1227153936360904196">"Aktueller Titel wird wiederholt."</string>
<string name="repeat_all_notif" msgid="6443293055987316642">"Alle Titel werden wiederholt."</string>
- <string name="ringtone_menu" msgid="2737472190159134599">"Als Telefonklingelton verwenden"</string>
+ <string name="ringtone_menu" msgid="2737472190159134599">"Als Klingelton verwenden"</string>
<string name="ringtone_menu_short" msgid="3367622038867238133">"Als Klingelton verwenden"</string>
<string name="ringtone_set" msgid="5325818347613843130">"\"<xliff:g id="NAME">%s</xliff:g>\" wurde als Telefonklingelton festgelegt."</string>
<string name="play_selection" msgid="2854921021814550018">"Wiedergeben"</string>
<item msgid="8708754966127584739">"12 Wochen"</item>
</string-array>
<string name="weekpicker_set" msgid="7636608790418067496">"Fertig"</string>
- <string name="weekpicker_title" msgid="699535378922101701">"Uhrzeit einstellen"</string>
+ <string name="weekpicker_title" msgid="699535378922101701">"Zeit einstellen"</string>
<string name="save_as_playlist" msgid="5180413608901885255">"Als Playlist speichern"</string>
<string name="clear_playlist" msgid="4565515100924905315">"Playlist löschen"</string>
<string name="musicbrowserlabel" msgid="3162022214114562892">"Musik"</string>
<string name="albums_title" msgid="8773880394961378035">"Álbumes"</string>
<string name="tracks_menu" msgid="6942246568246092330">"Canciones"</string>
<string name="tracks_title" msgid="3229389424532295124">"Canciones"</string>
- <string name="playlists_menu" msgid="5382792649771928849">"Listas de repr."</string>
+ <string name="playlists_menu" msgid="5382792649771928849">"Listas de rep."</string>
<string name="playlists_title" msgid="5094238486322957927">"Listas de reproducción"</string>
<string name="videos_title" msgid="2066741954354129115">"Videos"</string>
<string name="all_title" msgid="6880186414437237653">"Todos los medios"</string>
<string name="goto_start" msgid="8979658707407220934">"Bibliothèque"</string>
<string name="goto_playback" msgid="4885216161312176550">"Lecture"</string>
<string name="party_shuffle" msgid="8213359225506006168">"Lecture aléatoire"</string>
- <string name="party_shuffle_off" msgid="1828744483354711679">"La lecture aléatoire est désactivée."</string>
+ <string name="party_shuffle_off" msgid="1828744483354711679">"Désactiver la lecture aléatoire"</string>
<string name="delete_item" msgid="3363330144534750601">"Supprimer"</string>
<string name="shuffle_all" msgid="1388193611787878773">"Lecture aléatoire de toutes les chansons"</string>
<string name="play_all" msgid="6309622568869321842">"Tout lire"</string>
<string name="play_selection" msgid="2854921021814550018">"Lire"</string>
<string name="add_to_playlist" msgid="7110273488645072783">"Ajouter à la playlist"</string>
<string name="queue" msgid="2937629819482787704">"Playlist actuelle"</string>
- <string name="new_playlist" msgid="7588112979692632867">"Nouveau"</string>
+ <string name="new_playlist" msgid="7588112979692632867">"Nouvelle"</string>
<string name="new_playlist_name_template" msgid="905710296728900597">"Nouvelle playlist <xliff:g id="NUMBER">%d</xliff:g>"</string>
<plurals name="NNNtrackstoplaylist">
<item quantity="one" msgid="422388042993582235">"1 chanson a été ajoutée à la playlist."</item>
<string name="party_shuffle" msgid="8213359225506006168">"Party shuffle"</string>
<string name="party_shuffle_off" msgid="1828744483354711679">"Party shuffle non attiva"</string>
<string name="delete_item" msgid="3363330144534750601">"Elimina"</string>
- <string name="shuffle_all" msgid="1388193611787878773">"Ripr. casuale"</string>
+ <string name="shuffle_all" msgid="1388193611787878773">"Casuale"</string>
<string name="play_all" msgid="6309622568869321842">"Riprod. tutti"</string>
<string name="delete_artist_desc" msgid="1843750591006508005">"Tutti i brani di <xliff:g id="ARTIST">%s</xliff:g> verranno eliminati definitivamente dalla scheda SD."</string>
<string name="delete_album_desc" msgid="535515999268177079">"L\'intero album \"<xliff:g id="ALBUM">%s</xliff:g>\" verrà eliminato definitivamente dalla scheda SD."</string>
<string name="ringtone_menu" msgid="2737472190159134599">"Usa come suoneria"</string>
<string name="ringtone_menu_short" msgid="3367622038867238133">"Usa come suoneria"</string>
<string name="ringtone_set" msgid="5325818347613843130">"\"<xliff:g id="NAME">%s</xliff:g>\" impostato come suoneria del telefono."</string>
- <string name="play_selection" msgid="2854921021814550018">"Riprod."</string>
+ <string name="play_selection" msgid="2854921021814550018">"Riproduci"</string>
<string name="add_to_playlist" msgid="7110273488645072783">"Aggiungi a playlist"</string>
<string name="queue" msgid="2937629819482787704">"Playlist corrente"</string>
<string name="new_playlist" msgid="7588112979692632867">"Nuova"</string>
<string name="albums_title" msgid="8773880394961378035">"Álbuns"</string>
<string name="tracks_menu" msgid="6942246568246092330">"Músicas"</string>
<string name="tracks_title" msgid="3229389424532295124">"Músicas"</string>
- <string name="playlists_menu" msgid="5382792649771928849">"Listas de reprodução"</string>
+ <string name="playlists_menu" msgid="5382792649771928849">"Listas"</string>
<string name="playlists_title" msgid="5094238486322957927">"Listas de reprodução"</string>
<string name="videos_title" msgid="2066741954354129115">"Vídeos"</string>
<string name="all_title" msgid="6880186414437237653">"Todas as mídias"</string>
<string name="repeat_off_notif" msgid="1149406899083479716">"Режим повторного воспроизведения отключен."</string>
<string name="repeat_current_notif" msgid="1227153936360904196">"Повторение текущей композиции."</string>
<string name="repeat_all_notif" msgid="6443293055987316642">"Повтор всех композиций."</string>
- <string name="ringtone_menu" msgid="2737472190159134599">"СделаÑ\82Ñ\8c мелодией звонка"</string>
- <string name="ringtone_menu_short" msgid="3367622038867238133">"СделаÑ\82Ñ\8c мелодией звонка"</string>
+ <string name="ringtone_menu" msgid="2737472190159134599">"Ð\9fоÑ\81Ñ\82авиÑ\82Ñ\8c на звонок"</string>
+ <string name="ringtone_menu_short" msgid="3367622038867238133">"Ð\9fоÑ\81Ñ\82авиÑ\82Ñ\8c на звонок"</string>
<string name="ringtone_set" msgid="5325818347613843130">"Композиция \"<xliff:g id="NAME">%s</xliff:g>\" установлена в качестве мелодии звонка."</string>
<string name="play_selection" msgid="2854921021814550018">"Воспроизвести"</string>
<string name="add_to_playlist" msgid="7110273488645072783">"Добавить в плейлист"</string>
<string name="music_picker_title" msgid="1561623486324013570">"Выбрать музыкальную дорожку"</string>
<string name="gadget_track" msgid="3186569295893300114">"Трек <xliff:g id="TRACK_NUMBER">%d</xliff:g>"</string>
<string name="fail_to_start_stream" msgid="3605390187703912835">"Не удается выполнить совместный просмотр."</string>
- <string name="search_settings_description" msgid="6520975349259883368">"Ð\98Ñ\81полниÑ\82ели, алÑ\8cбомÑ\8b и доÑ\80ожки"</string>
+ <string name="search_settings_description" msgid="6520975349259883368">"Ð\98Ñ\81полниÑ\82ели, алÑ\8cбомÑ\8b и композиÑ\86ии"</string>
</resources>
<string name="goto_start" msgid="8979658707407220934">"Bibliotek"</string>
<string name="goto_playback" msgid="4885216161312176550">"Uppspelning"</string>
<string name="party_shuffle" msgid="8213359225506006168">"Blanda alla spår"</string>
- <string name="party_shuffle_off" msgid="1828744483354711679">"Blandar inte hela listan"</string>
+ <string name="party_shuffle_off" msgid="1828744483354711679">"Blanda inte hela listan"</string>
<string name="delete_item" msgid="3363330144534750601">"Ta bort"</string>
<string name="shuffle_all" msgid="1388193611787878773">"Blanda hela listan"</string>
<string name="play_all" msgid="6309622568869321842">"Spela alla"</string>
<string name="repeat_all_notif" msgid="6443293055987316642">"Tüm şarkılar tekrarlanıyor."</string>
<string name="ringtone_menu" msgid="2737472190159134599">"Telefon zil sesi olarak kullan"</string>
<string name="ringtone_menu_short" msgid="3367622038867238133">"Zil sesi olarak kullan"</string>
- <string name="ringtone_set" msgid="5325818347613843130">"\"<xliff:g id="NAME">%s</xliff:g>\" telefon zil sesi olarak ayarlanmış."</string>
+ <string name="ringtone_set" msgid="5325818347613843130">"<xliff:g id="NAME">%s</xliff:g> telefon zil sesi olarak ayarlandı."</string>
<string name="play_selection" msgid="2854921021814550018">"Yürüt"</string>
<string name="add_to_playlist" msgid="7110273488645072783">"Şarkı listesine ekle"</string>
<string name="queue" msgid="2937629819482787704">"Geçerli şarkı listesi"</string>
<string name="delete_item" msgid="3363330144534750601">"删除"</string>
<string name="shuffle_all" msgid="1388193611787878773">"全部随机播放"</string>
<string name="play_all" msgid="6309622568869321842">"全部播放"</string>
- <string name="delete_artist_desc" msgid="1843750591006508005">"将会从 SD 卡上永久删除<xliff:g id="ARTIST">%s</xliff:g>的所有歌曲。"</string>
- <string name="delete_album_desc" msgid="535515999268177079">"将会从 SD 卡上永久删除整张“<xliff:g id="ALBUM">%s</xliff:g>”专辑。"</string>
- <string name="delete_song_desc" msgid="1856800468541831408">"将会从 SD 卡上永久删除“<xliff:g id="SONG">%s</xliff:g>”。"</string>
+ <string name="delete_artist_desc" msgid="1843750591006508005">"<xliff:g id="ARTIST">%s</xliff:g>的所有歌曲会从 SD 卡中永久删除。"</string>
+ <string name="delete_album_desc" msgid="535515999268177079">"整张“<xliff:g id="ALBUM">%s</xliff:g>”专辑会从 SD 卡中永久删除。"</string>
+ <string name="delete_song_desc" msgid="1856800468541831408">"“<xliff:g id="SONG">%s</xliff:g>”会从 SD 卡中永久删除。"</string>
<string name="delete_confirm_button_text" msgid="7008121194944357274">"确定"</string>
<plurals name="NNNtracksdeleted">
<item quantity="one" msgid="8560276109508404217">"已删除 1 首歌曲。"</item>
- <item quantity="other" msgid="5156740163031225200">"<xliff:g id="SONGS_TO_DELETE">%d</xliff:g> 首歌曲已删除。"</item>
+ <item quantity="other" msgid="5156740163031225200">"已删除 <xliff:g id="SONGS_TO_DELETE">%d</xliff:g> 首歌曲。"</item>
</plurals>
<string name="scanning" msgid="3529383847223198502">"正在扫描 SD 卡..."</string>
- <string name="nowplaying_title" msgid="8342523844307751761">"当前播放列表"</string>
+ <string name="nowplaying_title" msgid="8342523844307751761">"正在播放"</string>
<string name="partyshuffle_title" msgid="6582413231529992125">"派对随机播放"</string>
<string name="artists_title" msgid="8490372367259160067">"艺术家"</string>
<string name="albums_menu" msgid="5807982055590211900">"专辑"</string>
<string name="rename_playlist_menu" msgid="3133463747389494668">"重命名"</string>
<string name="playlist_deleted_message" msgid="9008053828193961455">"播放列表已删除。"</string>
<string name="playlist_renamed_message" msgid="7187580192703005990">"播放列表已重命名。"</string>
- <string name="recentlyadded" msgid="110978416756366953">"æ\9c\80è¿\91æ·»å\8a ç\9a\84æ\96\87件"</string>
- <string name="recentlyadded_title" msgid="3153322287249901914">"æ\9c\80è¿\91æ·»å\8a ç\9a\84æ\96\87件"</string>
+ <string name="recentlyadded" msgid="110978416756366953">"æ\9c\80è¿\91æ·»å\8a ç\9a\84æ\8cæ\9b²"</string>
+ <string name="recentlyadded_title" msgid="3153322287249901914">"æ\96°å¢\9eæ\8cæ\9b²"</string>
<string name="podcasts_listitem" msgid="8657809279717670634">"播客"</string>
<string name="podcasts_title" msgid="4928414142496858304">"播客"</string>
<string name="sdcard_missing_title" msgid="9008284946643270850">"无 SD 卡"</string>
<string name="sdcard_busy_title" msgid="1162763571147174655">"SD 卡不可用"</string>
<string name="sdcard_busy_message" msgid="8071868348072728830">"抱歉,SD 卡正忙。"</string>
<string name="sdcard_error_title" msgid="165682155008600643">"SD 卡错误"</string>
- <string name="sdcard_error_message" msgid="4574563894036627855">"SD 卡上出现错误。"</string>
+ <string name="sdcard_error_message" msgid="4574563894036627855">"SD 卡出现错误。"</string>
<string name="unknown_artist_name" msgid="5567811106415855219">"未知艺术家"</string>
<string name="unknown_album_name" msgid="8525145988941244727">"未知专辑"</string>
<string name="shuffle_on_notif" msgid="5453708337808483943">"随机播放已打开。"</string>
<string name="repeat_all_notif" msgid="6443293055987316642">"重复播放所有歌曲。"</string>
<string name="ringtone_menu" msgid="2737472190159134599">"用作手机铃声"</string>
<string name="ringtone_menu_short" msgid="3367622038867238133">"用作铃声"</string>
- <string name="ringtone_set" msgid="5325818347613843130">"已将“<xliff:g id="NAME">%s</xliff:g>”设置为手机铃声。"</string>
+ <string name="ringtone_set" msgid="5325818347613843130">"已将“<xliff:g id="NAME">%s</xliff:g>”设为手机铃声。"</string>
<string name="play_selection" msgid="2854921021814550018">"播放"</string>
<string name="add_to_playlist" msgid="7110273488645072783">"添加到播放列表"</string>
- <string name="queue" msgid="2937629819482787704">"当前播放列表"</string>
- <string name="new_playlist" msgid="7588112979692632867">"新建"</string>
- <string name="new_playlist_name_template" msgid="905710296728900597">"新建播放列表 <xliff:g id="NUMBER">%d</xliff:g>"</string>
+ <string name="queue" msgid="2937629819482787704">"当前的播放列表"</string>
+ <string name="new_playlist" msgid="7588112979692632867">"新建播放列表"</string>
+ <string name="new_playlist_name_template" msgid="905710296728900597">"新播放列表 <xliff:g id="NUMBER">%d</xliff:g>"</string>
<plurals name="NNNtrackstoplaylist">
<item quantity="one" msgid="422388042993582235">"已将 1 首歌曲添加到播放列表。"</item>
<item quantity="other" msgid="7662771987109627255">"<xliff:g id="NUMBER">%d</xliff:g> 首歌曲已添加到播放列表。"</item>
</plurals>
- <string name="emptyplaylist" msgid="6711555673997896344">"选定的播放列表为空。"</string>
+ <string name="emptyplaylist" msgid="6711555673997896344">"您选的播放列表是空的。"</string>
<string name="create_playlist_create_text" msgid="8149755205483279143">"保存"</string>
<string name="create_playlist_overwrite_text" msgid="2007808383561024706">"覆盖"</string>
<string name="service_start_error_title" msgid="8649916852210198813">"播放问题"</string>
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;
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;
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;
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;
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()
{
}
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);
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);
@Override
public void onDestroy() {
+ ListView lv = getListView();
+ if (lv != null) {
+ mLastListPosCourse = lv.getFirstVisiblePosition();
+ View cv = lv.getChildAt(0);
+ if (cv != null) {
+ mLastListPosFine = cv.getTop();
+ }
+ }
MusicUtils.unbindFromService(this);
if (!mAdapterSent) {
Cursor c = mAdapter.getCursor();
@Override
public void onReceive(Context context, Intent intent) {
getListView().invalidateViews();
+ MusicUtils.updateNowPlaying(AlbumBrowserActivity.this);
}
};
private BroadcastReceiver mScanListener = new BroadcastReceiver() {
mReScanHandler.sendEmptyMessageDelayed(0, 1000);
return;
}
-
+
+ // restore previous position
+ if (mLastListPosCourse >= 0) {
+ getListView().setSelectionFromTop(mLastListPosCourse, mLastListPosFine);
+ mLastListPosCourse = -1;
+ }
+
MusicUtils.hideDatabaseError(this);
+ MusicUtils.updateButtonBar(this, R.id.albumtab);
setTitle();
}
@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);
}
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,
private Cursor mAlbumCursor;
private String mArtistId;
+
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ MusicUtils.updateNowPlaying(this);
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ finish();
+ }
}
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;
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;
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;
public class ArtistAlbumBrowserActivity extends ExpandableListActivity
- implements View.OnCreateContextMenuListener, MusicUtils.Defs
+ implements View.OnCreateContextMenuListener, MusicUtils.Defs, ServiceConnection
{
private String mCurrentArtistId;
private String mCurrentArtistName;
private ArtistAlbumListAdapter mAdapter;
private boolean mAdapterSent;
private final static int SEARCH = CHILD_MENU_BASE;
-
- public ArtistAlbumBrowserActivity()
- {
- }
+ private static int mLastListPosCourse = -1;
+ private static int mLastListPosFine = -1;
/** Called when the activity is first created. */
@Override
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");
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);
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);
@Override
public void onDestroy() {
+ ExpandableListView lv = getExpandableListView();
+ if (lv != null) {
+ mLastListPosCourse = lv.getFirstVisiblePosition();
+ View cv = lv.getChildAt(0);
+ if (cv != null) {
+ mLastListPosFine = cv.getTop();
+ }
+ }
+
MusicUtils.unbindFromService(this);
if (!mAdapterSent) {
Cursor c = mAdapter.getCursor();
@Override
public void onReceive(Context context, Intent intent) {
getExpandableListView().invalidateViews();
+ MusicUtils.updateNowPlaying(ArtistAlbumBrowserActivity.this);
}
};
private BroadcastReceiver mScanListener = new BroadcastReceiver() {
return;
}
+ // restore previous position
+ if (mLastListPosCourse >= 0) {
+ ExpandableListView elv = getExpandableListView();
+ elv.setSelectionFromTop(mLastListPosCourse, mLastListPosFine);
+ mLastListPosCourse = -1;
+ }
+
MusicUtils.hideDatabaseError(this);
+ MusicUtils.updateButtonBar(this, R.id.artisttab);
setTitle();
}
@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);
}
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,
}
private Cursor mArtistCursor;
+
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ MusicUtils.updateNowPlaying(this);
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ finish();
+ }
}
* Link up various button actions using {@link PendingIntents}.
*
* @param playerActive True if player is active in background, which means
- * widget click will launch {@link MediaPlaybackActivity},
+ * widget click will launch {@link MediaPlaybackActivityStarter},
* otherwise we launch {@link MusicBrowserActivity}.
*/
private void linkButtons(Context context, RemoteViews views, boolean playerActive) {
final ComponentName serviceName = new ComponentName(context, MediaPlaybackService.class);
if (playerActive) {
- intent = new Intent(context, MediaPlaybackActivity.class);
+ intent = new Intent(context, MediaPlaybackActivityStarter.class);
pendingIntent = PendingIntent.getActivity(context,
0 /* no requestCode */, intent, 0 /* no flags */);
views.setOnClickPendingIntent(R.id.album_appwidget, pendingIntent);
mAlbumArtHandler = new AlbumArtHandler(mAlbumArtWorker.getLooper());
requestWindowFeature(Window.FEATURE_NO_TITLE);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
setContentView(R.layout.audio_player);
mCurrentTime = (TextView) findViewById(R.id.currenttime);
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
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;
--- /dev/null
+/*
+ * 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(getIntent());
+ i.setClass(this, MediaPlaybackActivity.class);
+ startActivity(i);
+ finish();
+ }
+
+
+}
+
public void onDestroy() {
// Check that we're not being destroyed while something is still playing.
if (isPlaying()) {
- Log.e("MediaPlaybackService", "Service being destroyed while still playing.");
+ Log.e(LOGTAG, "Service being destroyed while still playing.");
}
// release all MediaPlayer resources, including the native player and wakelocks
mPlayer.release();
long seekpos = mPreferences.getLong("seekpos", 0);
seek(seekpos >= 0 && seekpos < duration() ? seekpos : 0);
+ Log.d(LOGTAG, "restored queue, currently at position "
+ + position() + "/" + duration()
+ + " (requested " + seekpos + ")");
int repmode = mPreferences.getInt("repeatmode", REPEAT_NONE);
if (repmode != REPEAT_ALL && repmode != REPEAT_CURRENT) {
if (CMDNEXT.equals(cmd) || NEXT_ACTION.equals(action)) {
next(true);
} else if (CMDPREVIOUS.equals(cmd) || PREVIOUS_ACTION.equals(action)) {
- prev();
+ if (position() < 2000) {
+ prev();
+ } else {
+ seek(0);
+ play();
+ }
} else if (CMDTOGGLEPAUSE.equals(cmd) || TOGGLEPAUSE_ACTION.equals(action)) {
if (isPlaying()) {
pause();
if (!mQuietMode) {
Toast.makeText(this, R.string.playback_failed, Toast.LENGTH_SHORT).show();
}
+ Log.d(LOGTAG, "Failed to open file for playback");
}
} else {
mOpenFailedCounter = 0;
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;
}
if (mPlayListLen <= 0) {
+ Log.d(LOGTAG, "No play queue");
return;
}
openCurrent();
play();
notifyChange(META_CHANGED);
+ if (mShuffleMode == SHUFFLE_AUTO) {
+ doAutoShuffleUpdate();
+ }
}
}
mHandler.sendMessageDelayed(mHandler.obtainMessage(SERVER_DIED), 2000);
return true;
default:
+ Log.d("MultiPlayer", "Error: " + what + "," + extra);
break;
}
return false;
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;
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() {
}
@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
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
if (serv != null) {
try {
serv.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO);
- updateMenu();
} catch (RemoteException ex) {
}
}
}
};
- 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();
- }
- };
}
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
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;
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.TabWidget;
import android.widget.TextView;
import android.widget.Toast;
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).
if (v != null) {
v.setVisibility(View.GONE);
}
+ v = a.findViewById(R.id.buttonbar);
+ if (v != null) {
+ v.setVisibility(View.GONE);
+ }
TextView tv = (TextView) a.findViewById(R.id.sd_message);
tv.setText(message);
}
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);
}
}
return null;
}
-
+
/** Get album art for specified album. You should not pass in the album id
* for the "unknown" album here (use -1 instead)
+ * This method always returns the default album art icon when no album art is found.
*/
public static Bitmap getArtwork(Context context, long song_id, long album_id) {
+ return getArtwork(context, song_id, album_id, true);
+ }
+
+ /** Get album art for specified album. You should not pass in the album id
+ * for the "unknown" album here (use -1 instead)
+ */
+ public static Bitmap getArtwork(Context context, long song_id, long album_id,
+ boolean allowdefault) {
if (album_id < 0) {
// This is something that is not in the database, so get the album art directly
return bm;
}
}
- return getDefaultArtwork(context);
+ if (allowdefault) {
+ return getDefaultArtwork(context);
+ }
+ return null;
}
ContentResolver res = context.getContentResolver();
if (bm != null) {
if (bm.getConfig() == null) {
bm = bm.copy(Bitmap.Config.RGB_565, false);
- if (bm == null) {
+ if (bm == null && allowdefault) {
return getDefaultArtwork(context);
}
}
- } else {
+ } else if (allowdefault) {
bm = getDefaultArtwork(context);
}
return bm;
}
}
}
+
+ static int sActiveTabIndex = -1;
+
+ static boolean 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 withtabs;
+ } 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.setTag(i);
+ v.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+
+ 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() {
+
+ public void onClick(View v) {
+ processTabClick((Activity)ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId());
+ }});
+ }
+ return withtabs;
+ }
+
+ static void processTabClick(Activity a, View v, int current) {
+ int id = v.getId();
+ if (id == current) {
+ return;
+ }
+
+ final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar);
+ ll.setCurrentTab((Integer) v.getTag());
+
+ 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() {
+
+ public void onClick(View v) {
+ Context c = v.getContext();
+ c.startActivity(new Intent(c, MediaPlaybackActivity.class));
+ }});
+ return;
+ }
+ } catch (RemoteException ex) {
+ }
+ nowPlayingView.setVisibility(View.GONE);
+ }
+
+ static void setBackground(View v, Bitmap bm) {
+
+ if (bm == null) {
+ v.setBackgroundResource(0);
+ return;
+ }
+
+ int vwidth = v.getWidth();
+ int vheight = v.getHeight();
+ int bwidth = bm.getWidth();
+ int bheight = bm.getHeight();
+ float scalex = (float) vwidth / bwidth;
+ float scaley = (float) vheight / bheight;
+ float scale = Math.max(scalex, scaley) * 1.3f;
+
+ Bitmap.Config config = Bitmap.Config.ARGB_8888;
+ Bitmap bg = Bitmap.createBitmap(vwidth, vheight, config);
+ Canvas c = new Canvas(bg);
+ Paint paint = new Paint();
+ paint.setAntiAlias(true);
+ paint.setFilterBitmap(true);
+ ColorMatrix greymatrix = new ColorMatrix();
+ greymatrix.setSaturation(0);
+ ColorMatrix darkmatrix = new ColorMatrix();
+ darkmatrix.setScale(.3f, .3f, .3f, 1.0f);
+ greymatrix.postConcat(darkmatrix);
+ ColorFilter filter = new ColorMatrixColorFilter(greymatrix);
+ paint.setColorFilter(filter);
+ Matrix matrix = new Matrix();
+ matrix.setTranslate(-bwidth/2, -bheight/2); // move bitmap center to origin
+ matrix.postRotate(10);
+ matrix.postScale(scale, scale);
+ matrix.postTranslate(vwidth/2, vheight/2); // Move bitmap center to view center
+ c.drawBitmap(bm, matrix, paint);
+ v.setBackgroundDrawable(new BitmapDrawable(bg));
+ }
+
}
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;
}
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) {
MusicUtils.playPlaylist(PlaylistBrowserActivity.this, id);
}
finish();
+ return;
}
+ MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this);
}
public void onServiceDisconnected(ComponentName classname) {
registerReceiver(mScanListener, f);
setContentView(R.layout.media_picker_activity);
+ MusicUtils.updateButtonBar(this, R.id.playlisttab);
ListView lv = getListView();
lv.setOnCreateContextMenuListener(this);
lv.setTextFilterEnabled(true);
@Override
public void onDestroy() {
+ ListView lv = getListView();
+ if (lv != null) {
+ mLastListPosCourse = lv.getFirstVisiblePosition();
+ View cv = lv.getChildAt(0);
+ if (cv != null) {
+ mLastListPosFine = cv.getTop();
+ }
+ }
MusicUtils.unbindFromService(this);
if (!mAdapterSent) {
Cursor c = mAdapter.getCursor();
super.onResume();
MusicUtils.setSpinnerState(this);
+ MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this);
}
@Override
public void onPause() {
return;
}
+ // restore previous position
+ if (mLastListPosCourse >= 0) {
+ getListView().setSelectionFromTop(mLastListPosCourse, mLastListPosFine);
+ mLastListPosCourse = -1;
+ }
MusicUtils.hideDatabaseError(this);
+ MusicUtils.updateButtonBar(this, R.id.playlisttab);
setTitle();
}
@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);
}
import android.database.AbstractCursor;
import android.database.CharArrayBuffer;
import android.database.Cursor;
+import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaFile;
import android.net.Uri;
private String mSortOrder;
private int mSelectedPosition;
private long mSelectedId;
+ private static int mLastListPosCourse = -1;
+ private static int mLastListPosFine = -1;
+ private boolean mUseLastListPos = false;
public TrackBrowserActivity()
{
{
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");
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");
};
setContentView(R.layout.media_picker_activity);
+ mUseLastListPos = MusicUtils.updateButtonBar(this, R.id.songtab);
mTrackList = getListView();
mTrackList.setOnCreateContextMenuListener(this);
if (mEditMode) {
setListAdapter(mAdapter);
}
MusicUtils.bindToService(this, this);
+
+ // don't set the album art until after the view has been layed out
+ mTrackList.post(new Runnable() {
+
+ public void run() {
+ setAlbumArtBackground();
+ }
+ });
}
public void onServiceConnected(ComponentName name, IBinder service)
// 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) {
@Override
public void onDestroy() {
+ ListView lv = getListView();
+ if (lv != null && mUseLastListPos) {
+ mLastListPosCourse = lv.getFirstVisiblePosition();
+ View cv = lv.getChildAt(0);
+ if (cv != null) {
+ mLastListPosFine = cv.getTop();
+ }
+ }
MusicUtils.unbindFromService(this);
try {
if ("nowplaying".equals(mPlaylist)) {
super.onSaveInstanceState(outcicle);
}
- public void init(Cursor newCursor) {
+ public void init(Cursor newCursor, boolean isLimited) {
if (mAdapter == null) {
return;
mReScanHandler.sendEmptyMessageDelayed(0, 1000);
return;
}
-
+
MusicUtils.hideDatabaseError(this);
+ mUseLastListPos = MusicUtils.updateButtonBar(this, R.id.songtab);
setTitle();
+ // Restore previous position
+ if (mLastListPosCourse >= 0 && mUseLastListPos) {
+ 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;
+ }
+ }
+
// When showing the queue, position the selection on the currently playing track
// Otherwise, position the selection on the first matching artist, if any
IntentFilter f = new IntentFilter();
}
}
+ private void setAlbumArtBackground() {
+ try {
+ long albumid = Long.valueOf(mAlbumId);
+ Bitmap bm = MusicUtils.getArtwork(TrackBrowserActivity.this, -1, albumid, false);
+ if (bm != null) {
+ MusicUtils.setBackground(mTrackList, bm);
+ mTrackList.setCacheColorHint(0);
+ return;
+ }
+ } catch (Exception ex) {
+ }
+ mTrackList.setBackgroundResource(0);
+ mTrackList.setCacheColorHint(0xff000000);
+ }
+
private void setTitle() {
CharSequence fancyName = null;
@Override
public void onReceive(Context context, Intent intent) {
getListView().invalidateViews();
+ if (!mEditMode) {
+ MusicUtils.updateNowPlaying(TrackBrowserActivity.this);
+ }
}
};
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);
}
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);
}
@Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MusicUtils.setPartyShuffleMenuIcon(menu);
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
Cursor cursor;
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?
// 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;
@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,