Numerous layout changes, unpin, new widgets

PullToRefresh no longer in debug
Add 4x2, 4x3 and 4x4 widgets
Move track title on Now Playing screen above artist
Add playlist current / total count on Now Playing screen
Add total playlist time on Now Playing Screen
Enable fast scroll on all ListViews
Add unpin to most context menus
Scroll playlist to current track on track change
This commit is contained in:
Joshua Bahnsen 2013-05-25 22:19:28 -07:00
parent 0d98f1edd9
commit dc5e49212c
44 changed files with 1610 additions and 729 deletions

View File

@ -46,7 +46,7 @@ public abstract class PullToRefreshBase<T extends View> extends LinearLayout imp
// Constants
// ===========================================================
static final boolean DEBUG = true;
static final boolean DEBUG = false;
static final boolean USE_HW_LAYERS = false;

View File

@ -137,6 +137,39 @@
a:name="android.appwidget.provider"
a:resource="@xml/appwidget_info_4x1" />
</receiver>
<receiver
a:name=".provider.UltraSonicAppWidgetProvider4x2"
a:label="UltraSonic (4x2)" >
<intent-filter>
<action a:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
a:name="android.appwidget.provider"
a:resource="@xml/appwidget_info_4x2" />
</receiver>
<receiver
a:name=".provider.UltraSonicAppWidgetProvider4x3"
a:label="UltraSonic (4x3)" >
<intent-filter>
<action a:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
a:name="android.appwidget.provider"
a:resource="@xml/appwidget_info_4x3" />
</receiver>
<receiver
a:name=".provider.UltraSonicAppWidgetProvider4x4"
a:label="UltraSonic (4x4)" >
<intent-filter>
<action a:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
a:name="android.appwidget.provider"
a:resource="@xml/appwidget_info_4x4" />
</receiver>
<provider
a:name=".provider.SearchSuggestionProvider"

View File

@ -42,16 +42,16 @@ public final class R {
public static final int indicator_right_padding = 0x7f070000;
}
public static final class drawable {
public static final int default_ptr_flip = 0x7f02000c;
public static final int default_ptr_rotate = 0x7f02000d;
public static final int indicator_arrow = 0x7f020048;
public static final int indicator_bg_bottom = 0x7f020049;
public static final int indicator_bg_top = 0x7f02004a;
public static final int default_ptr_flip = 0x7f02000e;
public static final int default_ptr_rotate = 0x7f02000f;
public static final int indicator_arrow = 0x7f02004a;
public static final int indicator_bg_bottom = 0x7f02004b;
public static final int indicator_bg_top = 0x7f02004c;
}
public static final class id {
public static final int both = 0x7f060003;
public static final int disabled = 0x7f060000;
public static final int fl_inner = 0x7f060086;
public static final int fl_inner = 0x7f060089;
public static final int flip = 0x7f060008;
public static final int gridview = 0x7f060009;
public static final int manualOnly = 0x7f060004;
@ -59,17 +59,17 @@ public final class R {
public static final int pullFromEnd = 0x7f060002;
public static final int pullFromStart = 0x7f060001;
public static final int pullUpFromBottom = 0x7f060006;
public static final int pull_to_refresh_image = 0x7f060087;
public static final int pull_to_refresh_progress = 0x7f060088;
public static final int pull_to_refresh_sub_text = 0x7f06008a;
public static final int pull_to_refresh_text = 0x7f060089;
public static final int pull_to_refresh_image = 0x7f06008a;
public static final int pull_to_refresh_progress = 0x7f06008b;
public static final int pull_to_refresh_sub_text = 0x7f06008d;
public static final int pull_to_refresh_text = 0x7f06008c;
public static final int rotate = 0x7f060007;
public static final int scrollview = 0x7f06000b;
public static final int webview = 0x7f06000a;
}
public static final class layout {
public static final int pull_to_refresh_header_horizontal = 0x7f03001c;
public static final int pull_to_refresh_header_vertical = 0x7f03001d;
public static final int pull_to_refresh_header_horizontal = 0x7f03001f;
public static final int pull_to_refresh_header_vertical = 0x7f030020;
}
public static final class string {
public static final int pull_to_refresh_from_bottom_pull_label = 0x7f080003;

View File

@ -453,255 +453,262 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
public static final int album_art_background=0x7f020001;
public static final int appwidget_art_default=0x7f020002;
public static final int appwidget_bg=0x7f020003;
public static final int bg_separator=0x7f020004;
public static final int bkgd_tile_black=0x7f020005;
public static final int border=0x7f020006;
public static final int btn_bg=0x7f020007;
public static final int btn_check_buttonless_off=0x7f020008;
public static final int btn_check_buttonless_on=0x7f020009;
public static final int btn_check_custom=0x7f02000a;
public static final int buttonbar_selector=0x7f02000b;
public static final int default_ptr_flip=0x7f02000c;
public static final int default_ptr_rotate=0x7f02000d;
public static final int drop_shadow=0x7f02000e;
public static final int ic_appwidget_music_next=0x7f02000f;
public static final int ic_appwidget_music_pause=0x7f020010;
public static final int ic_appwidget_music_play=0x7f020011;
public static final int ic_appwidget_music_previous=0x7f020012;
public static final int ic_launcher=0x7f020013;
public static final int ic_menu_about_dark=0x7f020014;
public static final int ic_menu_about_light=0x7f020015;
public static final int ic_menu_add_to_queue_dark=0x7f020016;
public static final int ic_menu_add_to_queue_light=0x7f020017;
public static final int ic_menu_backward_dark=0x7f020018;
public static final int ic_menu_backward_light=0x7f020019;
public static final int ic_menu_browse_dark=0x7f02001a;
public static final int ic_menu_browse_light=0x7f02001b;
public static final int ic_menu_chat_dark=0x7f02001c;
public static final int ic_menu_chat_light=0x7f02001d;
public static final int ic_menu_chat_send_dark=0x7f02001e;
public static final int ic_menu_chat_send_light=0x7f02001f;
public static final int ic_menu_exit_dark=0x7f020020;
public static final int ic_menu_exit_light=0x7f020021;
public static final int ic_menu_forward_dark=0x7f020022;
public static final int ic_menu_forward_light=0x7f020023;
public static final int ic_menu_help_dark=0x7f020024;
public static final int ic_menu_help_light=0x7f020025;
public static final int ic_menu_home_dark=0x7f020026;
public static final int ic_menu_home_light=0x7f020027;
public static final int ic_menu_pin=0x7f020028;
public static final int ic_menu_playlists_dark=0x7f020029;
public static final int ic_menu_playlists_light=0x7f02002a;
public static final int ic_menu_remove_all_dark=0x7f02002b;
public static final int ic_menu_remove_all_light=0x7f02002c;
public static final int ic_menu_save_dark=0x7f02002d;
public static final int ic_menu_save_light=0x7f02002e;
public static final int ic_menu_screen_on_off_dark=0x7f02002f;
public static final int ic_menu_screen_on_off_light=0x7f020030;
public static final int ic_menu_search_dark=0x7f020031;
public static final int ic_menu_search_light=0x7f020032;
public static final int ic_menu_select_all_dark=0x7f020033;
public static final int ic_menu_select_all_light=0x7f020034;
public static final int ic_menu_select_folder_dark=0x7f020035;
public static final int ic_menu_select_folder_light=0x7f020036;
public static final int ic_menu_settings_dark=0x7f020037;
public static final int ic_menu_settings_light=0x7f020038;
public static final int ic_menu_share_dark=0x7f020039;
public static final int ic_menu_share_light=0x7f02003a;
public static final int ic_menu_unpin_dark=0x7f02003b;
public static final int ic_menu_unpin_light=0x7f02003c;
public static final int ic_star_full_dark=0x7f02003d;
public static final int ic_star_full_light=0x7f02003e;
public static final int ic_star_hollow_dark=0x7f02003f;
public static final int ic_star_hollow_light=0x7f020040;
public static final int ic_stat_downloaded_dark=0x7f020041;
public static final int ic_stat_downloaded_light=0x7f020042;
public static final int ic_stat_downloading_dark=0x7f020043;
public static final int ic_stat_downloading_light=0x7f020044;
public static final int ic_stat_play_dark=0x7f020045;
public static final int ic_stat_play_light=0x7f020046;
public static final int ic_stat_ultrasonic=0x7f020047;
public static final int indicator_arrow=0x7f020048;
public static final int indicator_bg_bottom=0x7f020049;
public static final int indicator_bg_top=0x7f02004a;
public static final int list_background=0x7f02004b;
public static final int list_focused_holo=0x7f02004c;
public static final int list_longpressed_holo=0x7f02004d;
public static final int list_pressed_holo_dark=0x7f02004e;
public static final int list_pressed_holo_light=0x7f02004f;
public static final int list_selector_background_transition_holo_dark=0x7f020050;
public static final int list_selector_background_transition_holo_light=0x7f020051;
public static final int list_selector_disabled_holo_dark=0x7f020052;
public static final int list_selector_disabled_holo_light=0x7f020053;
public static final int list_selector_holo_dark=0x7f020054;
public static final int list_selector_holo_light=0x7f020055;
public static final int main_header_icon=0x7f020056;
public static final int md__category_background=0x7f020057;
public static final int md__list_focused_holo=0x7f020058;
public static final int md__list_longpressed_holo=0x7f020059;
public static final int md__list_pressed_holo_dark=0x7f02005a;
public static final int md__list_selector_background_transition_holo_dark=0x7f02005b;
public static final int md__list_selector_disabled_holo_dark=0x7f02005c;
public static final int md__list_selector_holo_dark=0x7f02005d;
public static final int media_backward_normal=0x7f02005e;
public static final int media_backward_normal_dark=0x7f02005f;
public static final int media_backward_normal_light=0x7f020060;
public static final int media_forward_normal=0x7f020061;
public static final int media_forward_normal_dark=0x7f020062;
public static final int media_forward_normal_light=0x7f020063;
public static final int media_pause_normal=0x7f020064;
public static final int media_pause_normal_dark=0x7f020065;
public static final int media_pause_normal_light=0x7f020066;
public static final int media_play_next=0x7f020067;
public static final int media_play_next_dark=0x7f020068;
public static final int media_play_next_light=0x7f020069;
public static final int media_play_now_dark=0x7f02006a;
public static final int media_play_now_light=0x7f02006b;
public static final int media_repeat_all=0x7f02006c;
public static final int media_repeat_off=0x7f02006d;
public static final int media_repeat_off_dark=0x7f02006e;
public static final int media_repeat_off_light=0x7f02006f;
public static final int media_repeat_single=0x7f020070;
public static final int media_shuffle_normal=0x7f020071;
public static final int media_shuffle_normal_dark=0x7f020072;
public static final int media_shuffle_normal_light=0x7f020073;
public static final int media_start_normal=0x7f020074;
public static final int media_start_normal_dark=0x7f020075;
public static final int media_start_normal_light=0x7f020076;
public static final int media_start_pressed=0x7f020077;
public static final int media_stop_normal=0x7f020078;
public static final int media_stop_normal_dark=0x7f020079;
public static final int media_stop_normal_light=0x7f02007a;
public static final int media_toggle_list_normal=0x7f02007b;
public static final int media_toggle_list_normal_dark=0x7f02007c;
public static final int media_toggle_list_normal_light=0x7f02007d;
public static final int menu_arrow=0x7f02007e;
public static final int menu_arrow_bottom=0x7f02007f;
public static final int menu_arrow_right=0x7f020080;
public static final int menu_arrow_top=0x7f020081;
public static final int menubar_button_disabled=0x7f020082;
public static final int menubar_button_normal=0x7f020083;
public static final int notify_panel_notification_icon_bg=0x7f020084;
public static final int pinstripe_tile=0x7f020085;
public static final int preview=0x7f020086;
public static final int preview_two=0x7f020087;
public static final int progress_bg_holo_dark=0x7f020088;
public static final int progress_horizontal_holo_dark=0x7f020089;
public static final int progress_primary_holo_dark=0x7f02008a;
public static final int progress_secondary_holo_dark=0x7f02008b;
public static final int select_album_play_all=0x7f02008c;
public static final int select_album_play_all_normal=0x7f02008d;
public static final int select_album_play_all_pressed=0x7f02008e;
public static final int status_bg=0x7f02008f;
public static final int title_bar_shadow=0x7f020090;
public static final int unknown_album=0x7f020091;
public static final int unknown_album_large=0x7f020092;
public static final int appwidget_dark_bg=0x7f020004;
public static final int appwidget_dark_bg_trans=0x7f020005;
public static final int bg_separator=0x7f020006;
public static final int bkgd_tile_black=0x7f020007;
public static final int border=0x7f020008;
public static final int btn_bg=0x7f020009;
public static final int btn_check_buttonless_off=0x7f02000a;
public static final int btn_check_buttonless_on=0x7f02000b;
public static final int btn_check_custom=0x7f02000c;
public static final int buttonbar_selector=0x7f02000d;
public static final int default_ptr_flip=0x7f02000e;
public static final int default_ptr_rotate=0x7f02000f;
public static final int drop_shadow=0x7f020010;
public static final int ic_appwidget_music_next=0x7f020011;
public static final int ic_appwidget_music_pause=0x7f020012;
public static final int ic_appwidget_music_play=0x7f020013;
public static final int ic_appwidget_music_previous=0x7f020014;
public static final int ic_launcher=0x7f020015;
public static final int ic_menu_about_dark=0x7f020016;
public static final int ic_menu_about_light=0x7f020017;
public static final int ic_menu_add_to_queue_dark=0x7f020018;
public static final int ic_menu_add_to_queue_light=0x7f020019;
public static final int ic_menu_backward_dark=0x7f02001a;
public static final int ic_menu_backward_light=0x7f02001b;
public static final int ic_menu_browse_dark=0x7f02001c;
public static final int ic_menu_browse_light=0x7f02001d;
public static final int ic_menu_chat_dark=0x7f02001e;
public static final int ic_menu_chat_light=0x7f02001f;
public static final int ic_menu_chat_send_dark=0x7f020020;
public static final int ic_menu_chat_send_light=0x7f020021;
public static final int ic_menu_exit_dark=0x7f020022;
public static final int ic_menu_exit_light=0x7f020023;
public static final int ic_menu_forward_dark=0x7f020024;
public static final int ic_menu_forward_light=0x7f020025;
public static final int ic_menu_help_dark=0x7f020026;
public static final int ic_menu_help_light=0x7f020027;
public static final int ic_menu_home_dark=0x7f020028;
public static final int ic_menu_home_light=0x7f020029;
public static final int ic_menu_pin=0x7f02002a;
public static final int ic_menu_playlists_dark=0x7f02002b;
public static final int ic_menu_playlists_light=0x7f02002c;
public static final int ic_menu_remove_all_dark=0x7f02002d;
public static final int ic_menu_remove_all_light=0x7f02002e;
public static final int ic_menu_save_dark=0x7f02002f;
public static final int ic_menu_save_light=0x7f020030;
public static final int ic_menu_screen_on_off_dark=0x7f020031;
public static final int ic_menu_screen_on_off_light=0x7f020032;
public static final int ic_menu_search_dark=0x7f020033;
public static final int ic_menu_search_light=0x7f020034;
public static final int ic_menu_select_all_dark=0x7f020035;
public static final int ic_menu_select_all_light=0x7f020036;
public static final int ic_menu_select_folder_dark=0x7f020037;
public static final int ic_menu_select_folder_light=0x7f020038;
public static final int ic_menu_settings_dark=0x7f020039;
public static final int ic_menu_settings_light=0x7f02003a;
public static final int ic_menu_share_dark=0x7f02003b;
public static final int ic_menu_share_light=0x7f02003c;
public static final int ic_menu_unpin_dark=0x7f02003d;
public static final int ic_menu_unpin_light=0x7f02003e;
public static final int ic_star_full_dark=0x7f02003f;
public static final int ic_star_full_light=0x7f020040;
public static final int ic_star_hollow_dark=0x7f020041;
public static final int ic_star_hollow_light=0x7f020042;
public static final int ic_stat_downloaded_dark=0x7f020043;
public static final int ic_stat_downloaded_light=0x7f020044;
public static final int ic_stat_downloading_dark=0x7f020045;
public static final int ic_stat_downloading_light=0x7f020046;
public static final int ic_stat_play_dark=0x7f020047;
public static final int ic_stat_play_light=0x7f020048;
public static final int ic_stat_ultrasonic=0x7f020049;
public static final int indicator_arrow=0x7f02004a;
public static final int indicator_bg_bottom=0x7f02004b;
public static final int indicator_bg_top=0x7f02004c;
public static final int list_background=0x7f02004d;
public static final int list_focused_holo=0x7f02004e;
public static final int list_longpressed_holo=0x7f02004f;
public static final int list_pressed_holo_dark=0x7f020050;
public static final int list_pressed_holo_light=0x7f020051;
public static final int list_selector_background_transition_holo_dark=0x7f020052;
public static final int list_selector_background_transition_holo_light=0x7f020053;
public static final int list_selector_disabled_holo_dark=0x7f020054;
public static final int list_selector_disabled_holo_light=0x7f020055;
public static final int list_selector_holo_dark=0x7f020056;
public static final int list_selector_holo_light=0x7f020057;
public static final int main_header_icon=0x7f020058;
public static final int md__category_background=0x7f020059;
public static final int md__list_focused_holo=0x7f02005a;
public static final int md__list_longpressed_holo=0x7f02005b;
public static final int md__list_pressed_holo_dark=0x7f02005c;
public static final int md__list_selector_background_transition_holo_dark=0x7f02005d;
public static final int md__list_selector_disabled_holo_dark=0x7f02005e;
public static final int md__list_selector_holo_dark=0x7f02005f;
public static final int media_backward_normal=0x7f020060;
public static final int media_backward_normal_dark=0x7f020061;
public static final int media_backward_normal_light=0x7f020062;
public static final int media_forward_normal=0x7f020063;
public static final int media_forward_normal_dark=0x7f020064;
public static final int media_forward_normal_light=0x7f020065;
public static final int media_pause_normal=0x7f020066;
public static final int media_pause_normal_dark=0x7f020067;
public static final int media_pause_normal_light=0x7f020068;
public static final int media_play_next=0x7f020069;
public static final int media_play_next_dark=0x7f02006a;
public static final int media_play_next_light=0x7f02006b;
public static final int media_play_now_dark=0x7f02006c;
public static final int media_play_now_light=0x7f02006d;
public static final int media_repeat_all=0x7f02006e;
public static final int media_repeat_off=0x7f02006f;
public static final int media_repeat_off_dark=0x7f020070;
public static final int media_repeat_off_light=0x7f020071;
public static final int media_repeat_single=0x7f020072;
public static final int media_shuffle_normal=0x7f020073;
public static final int media_shuffle_normal_dark=0x7f020074;
public static final int media_shuffle_normal_light=0x7f020075;
public static final int media_start_normal=0x7f020076;
public static final int media_start_normal_dark=0x7f020077;
public static final int media_start_normal_light=0x7f020078;
public static final int media_start_pressed=0x7f020079;
public static final int media_stop_normal=0x7f02007a;
public static final int media_stop_normal_dark=0x7f02007b;
public static final int media_stop_normal_light=0x7f02007c;
public static final int media_toggle_list_normal=0x7f02007d;
public static final int media_toggle_list_normal_dark=0x7f02007e;
public static final int media_toggle_list_normal_light=0x7f02007f;
public static final int menu_arrow=0x7f020080;
public static final int menu_arrow_bottom=0x7f020081;
public static final int menu_arrow_right=0x7f020082;
public static final int menu_arrow_top=0x7f020083;
public static final int menubar_button_disabled=0x7f020084;
public static final int menubar_button_normal=0x7f020085;
public static final int notify_panel_notification_icon_bg=0x7f020086;
public static final int pinstripe_tile=0x7f020087;
public static final int preview=0x7f020088;
public static final int preview_two=0x7f020089;
public static final int progress_bg_holo_dark=0x7f02008a;
public static final int progress_horizontal_holo_dark=0x7f02008b;
public static final int progress_primary_holo_dark=0x7f02008c;
public static final int progress_secondary_holo_dark=0x7f02008d;
public static final int select_album_play_all=0x7f02008e;
public static final int select_album_play_all_normal=0x7f02008f;
public static final int select_album_play_all_pressed=0x7f020090;
public static final int status_bg=0x7f020091;
public static final int title_bar_shadow=0x7f020092;
public static final int unknown_album=0x7f020093;
public static final int unknown_album_large=0x7f020094;
}
public static final class id {
public static final int album=0x7f06007b;
public static final int album=0x7f060027;
public static final int album_artist=0x7f06001d;
public static final int album_coverart=0x7f06001b;
public static final int album_menu_pin=0x7f0600c3;
public static final int album_menu_play_last=0x7f0600c2;
public static final int album_menu_play_next=0x7f0600c1;
public static final int album_menu_play_now=0x7f0600c0;
public static final int album_menu_pin=0x7f0600c6;
public static final int album_menu_play_last=0x7f0600c5;
public static final int album_menu_play_next=0x7f0600c4;
public static final int album_menu_play_now=0x7f0600c3;
public static final int album_menu_unpin=0x7f0600c7;
public static final int album_star=0x7f06001e;
public static final int album_title=0x7f06001c;
public static final int appwidget_coverart=0x7f06001f;
public static final int appwidget_top=0x7f060021;
public static final int artist=0x7f060023;
public static final int artist_menu_pin=0x7f0600c7;
public static final int artist_menu_play_last=0x7f0600c6;
public static final int artist_menu_play_next=0x7f0600c5;
public static final int artist_menu_play_now=0x7f0600c4;
public static final int artist_menu_pin=0x7f0600cb;
public static final int artist_menu_play_last=0x7f0600ca;
public static final int artist_menu_play_next=0x7f0600c9;
public static final int artist_menu_play_now=0x7f0600c8;
public static final int artist_menu_unpin=0x7f0600cc;
public static final int both=0x7f060003;
public static final int chat_edittext=0x7f060028;
public static final int chat_entries=0x7f060027;
public static final int chat_message=0x7f06002d;
public static final int chat_message_layout=0x7f06002b;
public static final int chat_send=0x7f060029;
public static final int chat_time=0x7f06002c;
public static final int chat_username=0x7f06002a;
public static final int chat_edittext=0x7f060029;
public static final int chat_entries=0x7f060028;
public static final int chat_message=0x7f06002e;
public static final int chat_message_layout=0x7f06002c;
public static final int chat_send=0x7f06002a;
public static final int chat_time=0x7f06002d;
public static final int chat_username=0x7f06002b;
public static final int control_next=0x7f060026;
public static final int control_play=0x7f060025;
public static final int control_previous=0x7f060024;
public static final int control_stop=0x7f06007c;
public static final int control_stop=0x7f06007f;
public static final int disabled=0x7f060000;
public static final int download_album=0x7f060039;
public static final int download_album=0x7f06003d;
public static final int download_album_art_image=0x7f060033;
public static final int download_album_art_layout=0x7f060032;
public static final int download_artist=0x7f060038;
public static final int download_artist=0x7f06003c;
public static final int download_button_bar_flipper=0x7f060035;
public static final int download_control_layout=0x7f06002e;
public static final int download_duration=0x7f060037;
public static final int download_empty=0x7f06003a;
public static final int download_equalizer=0x7f0600b5;
public static final int download_jukebox=0x7f0600b7;
public static final int download_list=0x7f06003b;
public static final int download_next=0x7f060069;
public static final int download_pause=0x7f060067;
public static final int download_control_layout=0x7f06002f;
public static final int download_duration=0x7f06003a;
public static final int download_empty=0x7f06003e;
public static final int download_equalizer=0x7f0600b8;
public static final int download_items=0x7f060037;
public static final int download_jukebox=0x7f0600ba;
public static final int download_list=0x7f06003f;
public static final int download_next=0x7f06006d;
public static final int download_pause=0x7f06006b;
public static final int download_playlist_flipper=0x7f060031;
public static final int download_position=0x7f060036;
public static final int download_previous=0x7f060065;
public static final int download_progress_bar=0x7f06003c;
public static final int download_repeat=0x7f06006a;
public static final int download_shuffle=0x7f060064;
public static final int download_song_title=0x7f060030;
public static final int download_star=0x7f06006b;
public static final int download_start=0x7f060066;
public static final int download_status=0x7f06002f;
public static final int download_stop=0x7f060068;
public static final int download_toggle_list=0x7f060063;
public static final int download_visualizer=0x7f0600b6;
public static final int download_position=0x7f060038;
public static final int download_previous=0x7f060069;
public static final int download_progress_bar=0x7f060040;
public static final int download_repeat=0x7f06006e;
public static final int download_shuffle=0x7f060068;
public static final int download_song_title=0x7f060036;
public static final int download_star=0x7f06006f;
public static final int download_start=0x7f06006a;
public static final int download_status=0x7f060030;
public static final int download_stop=0x7f06006c;
public static final int download_toggle_list=0x7f060067;
public static final int download_total_duration=0x7f06003b;
public static final int download_track=0x7f060039;
public static final int download_visualizer=0x7f0600b9;
public static final int download_visualizer_view_layout=0x7f060034;
public static final int equalizer_bar=0x7f060042;
public static final int equalizer_frequency=0x7f060040;
public static final int equalizer_level=0x7f060041;
public static final int equalizer_enabled=0x7f06003d;
public static final int equalizer_layout=0x7f06003e;
public static final int equalizer_preset=0x7f06003f;
public static final int fl_inner=0x7f060086;
public static final int equalizer_bar=0x7f060046;
public static final int equalizer_frequency=0x7f060044;
public static final int equalizer_level=0x7f060045;
public static final int equalizer_enabled=0x7f060041;
public static final int equalizer_layout=0x7f060042;
public static final int equalizer_preset=0x7f060043;
public static final int fl_inner=0x7f060089;
public static final int flip=0x7f060008;
public static final int get_playlist_comment=0x7f0600b1;
public static final int get_playlist_comment_label=0x7f0600b0;
public static final int get_playlist_name=0x7f0600af;
public static final int get_playlist_name_label=0x7f0600ae;
public static final int get_playlist_public=0x7f0600b3;
public static final int get_playlist_public_label=0x7f0600b2;
public static final int get_playlist_comment=0x7f0600b4;
public static final int get_playlist_comment_label=0x7f0600b3;
public static final int get_playlist_name=0x7f0600b2;
public static final int get_playlist_name_label=0x7f0600b1;
public static final int get_playlist_public=0x7f0600b6;
public static final int get_playlist_public_label=0x7f0600b5;
public static final int gridview=0x7f060009;
public static final int help_back=0x7f060044;
public static final int help_buttons=0x7f060043;
public static final int help_contents=0x7f060047;
public static final int help_forward=0x7f060046;
public static final int help_stop=0x7f060045;
public static final int jukebox_volume_progress_bar=0x7f060049;
public static final int help_back=0x7f060048;
public static final int help_buttons=0x7f060047;
public static final int help_contents=0x7f06004b;
public static final int help_forward=0x7f06004a;
public static final int help_stop=0x7f060049;
public static final int jukebox_volume_progress_bar=0x7f06004d;
public static final int linearLayout1=0x7f060020;
public static final int lyrics_artist=0x7f06004b;
public static final int lyrics_scrollview=0x7f06004a;
public static final int lyrics_text=0x7f06004d;
public static final int lyrics_title=0x7f06004c;
public static final int main_select_server_1=0x7f060051;
public static final int main_select_server_2=0x7f060052;
public static final int main_albums=0x7f06005a;
public static final int main_albums_alphaByArtist=0x7f060062;
public static final int main_albums_alphaByName=0x7f060061;
public static final int main_albums_button=0x7f060055;
public static final int main_albums_frequent=0x7f06005d;
public static final int main_albums_highest=0x7f06005e;
public static final int main_albums_newest=0x7f06005b;
public static final int main_albums_random=0x7f06005f;
public static final int main_albums_recent=0x7f06005c;
public static final int main_albums_starred=0x7f060060;
public static final int main_artists_button=0x7f060054;
public static final int main_dummy=0x7f06004f;
public static final int main_genres_button=0x7f060056;
public static final int main_list=0x7f06004e;
public static final int main_music=0x7f060053;
public static final int main_select_server=0x7f060050;
public static final int main_shuffle=0x7f0600b4;
public static final int main_songs=0x7f060057;
public static final int main_songs_button=0x7f060058;
public static final int main_songs_starred=0x7f060059;
public static final int lyrics_artist=0x7f06004f;
public static final int lyrics_scrollview=0x7f06004e;
public static final int lyrics_text=0x7f060051;
public static final int lyrics_title=0x7f060050;
public static final int main_select_server_1=0x7f060055;
public static final int main_select_server_2=0x7f060056;
public static final int main_albums=0x7f06005e;
public static final int main_albums_alphaByArtist=0x7f060066;
public static final int main_albums_alphaByName=0x7f060065;
public static final int main_albums_button=0x7f060059;
public static final int main_albums_frequent=0x7f060061;
public static final int main_albums_highest=0x7f060062;
public static final int main_albums_newest=0x7f06005f;
public static final int main_albums_random=0x7f060063;
public static final int main_albums_recent=0x7f060060;
public static final int main_albums_starred=0x7f060064;
public static final int main_artists_button=0x7f060058;
public static final int main_dummy=0x7f060053;
public static final int main_genres_button=0x7f06005a;
public static final int main_list=0x7f060052;
public static final int main_music=0x7f060057;
public static final int main_select_server=0x7f060054;
public static final int main_shuffle=0x7f0600b7;
public static final int main_songs=0x7f06005b;
public static final int main_songs_button=0x7f06005c;
public static final int main_songs_starred=0x7f06005d;
public static final int manualOnly=0x7f060004;
/** Used with View#setTag(int) to specify a position for the active view.
*/
@ -721,105 +728,106 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
/** The ID of the menu container.
*/
public static final int md__menu=0x7f06000f;
public static final int menu_about=0x7f060076;
public static final int menu_about=0x7f06007a;
public static final int menu_album=0x7f060012;
public static final int menu_browse=0x7f06006f;
public static final int menu_chat=0x7f060072;
public static final int menu_common=0x7f060074;
public static final int menu_exit=0x7f060077;
public static final int menu_home=0x7f06006e;
public static final int menu_lyrics=0x7f0600bc;
public static final int menu_main=0x7f06006c;
public static final int menu_navigation=0x7f06006d;
public static final int menu_now_playing=0x7f060073;
public static final int menu_playlists=0x7f060071;
public static final int menu_remove=0x7f0600bd;
public static final int menu_remove_all=0x7f0600b9;
public static final int menu_save_playlist=0x7f0600b8;
public static final int menu_screen_on_off=0x7f0600ba;
public static final int menu_search=0x7f060070;
public static final int menu_settings=0x7f060075;
public static final int menu_show_album=0x7f0600bb;
public static final int menu_shuffle=0x7f0600be;
public static final int notification_image=0x7f060079;
public static final int now_playing=0x7f06007d;
public static final int now_playing_artist=0x7f060081;
public static final int now_playing_control_play=0x7f060082;
public static final int now_playing_image=0x7f06007f;
public static final int now_playing_trackname=0x7f060080;
public static final int now_playing_view=0x7f06007e;
public static final int play_video_contents=0x7f060083;
public static final int playlist_info=0x7f0600c8;
public static final int playlist_menu_delete=0x7f0600cd;
public static final int playlist_menu_pin=0x7f0600cb;
public static final int playlist_menu_play_now=0x7f0600c9;
public static final int playlist_menu_play_shuffled=0x7f0600ca;
public static final int playlist_name=0x7f060084;
public static final int playlist_update_info=0x7f0600cc;
public static final int progress_message=0x7f060085;
public static final int menu_browse=0x7f060073;
public static final int menu_chat=0x7f060076;
public static final int menu_common=0x7f060078;
public static final int menu_exit=0x7f06007b;
public static final int menu_home=0x7f060072;
public static final int menu_lyrics=0x7f0600bf;
public static final int menu_main=0x7f060070;
public static final int menu_navigation=0x7f060071;
public static final int menu_now_playing=0x7f060077;
public static final int menu_playlists=0x7f060075;
public static final int menu_remove=0x7f0600c0;
public static final int menu_remove_all=0x7f0600bc;
public static final int menu_save_playlist=0x7f0600bb;
public static final int menu_screen_on_off=0x7f0600bd;
public static final int menu_search=0x7f060074;
public static final int menu_settings=0x7f060079;
public static final int menu_show_album=0x7f0600be;
public static final int menu_shuffle=0x7f0600c1;
public static final int notification_image=0x7f06007d;
public static final int now_playing=0x7f060080;
public static final int now_playing_artist=0x7f060084;
public static final int now_playing_control_play=0x7f060085;
public static final int now_playing_image=0x7f060082;
public static final int now_playing_trackname=0x7f060083;
public static final int now_playing_view=0x7f060081;
public static final int play_video_contents=0x7f060086;
public static final int playlist_info=0x7f0600cd;
public static final int playlist_menu_delete=0x7f0600d3;
public static final int playlist_menu_pin=0x7f0600d0;
public static final int playlist_menu_play_now=0x7f0600ce;
public static final int playlist_menu_play_shuffled=0x7f0600cf;
public static final int playlist_menu_unpin=0x7f0600d1;
public static final int playlist_name=0x7f060087;
public static final int playlist_update_info=0x7f0600d2;
public static final int progress_message=0x7f060088;
public static final int pullDownFromTop=0x7f060005;
public static final int pullFromEnd=0x7f060002;
public static final int pullFromStart=0x7f060001;
public static final int pullUpFromBottom=0x7f060006;
public static final int pull_to_refresh_image=0x7f060087;
public static final int pull_to_refresh_progress=0x7f060088;
public static final int pull_to_refresh_sub_text=0x7f06008a;
public static final int pull_to_refresh_text=0x7f060089;
public static final int pull_to_refresh_image=0x7f06008a;
public static final int pull_to_refresh_progress=0x7f06008b;
public static final int pull_to_refresh_sub_text=0x7f06008d;
public static final int pull_to_refresh_text=0x7f06008c;
public static final int rotate=0x7f060007;
public static final int save_playlist_name=0x7f06008c;
public static final int save_playlist_root=0x7f06008b;
public static final int save_playlist_name=0x7f06008f;
public static final int save_playlist_root=0x7f06008e;
public static final int scrollview=0x7f06000b;
public static final int search_albums=0x7f060090;
public static final int search_artists=0x7f06008f;
public static final int search_list=0x7f06008d;
public static final int search_more_albums=0x7f060093;
public static final int search_more_artists=0x7f060092;
public static final int search_more_songs=0x7f060094;
public static final int search_search=0x7f06008e;
public static final int search_songs=0x7f060091;
public static final int select_album_art=0x7f060097;
public static final int select_album_artist=0x7f060099;
public static final int search_albums=0x7f060093;
public static final int search_artists=0x7f060092;
public static final int search_list=0x7f060090;
public static final int search_more_albums=0x7f060096;
public static final int search_more_artists=0x7f060095;
public static final int search_more_songs=0x7f060097;
public static final int search_search=0x7f060091;
public static final int search_songs=0x7f060094;
public static final int select_album_art=0x7f06009a;
public static final int select_album_artist=0x7f06009c;
public static final int select_album_delete=0x7f060019;
public static final int select_album_duration=0x7f06009c;
public static final int select_album_empty=0x7f060095;
public static final int select_album_entries=0x7f060096;
public static final int select_album_genre=0x7f06009a;
public static final int select_album_duration=0x7f06009f;
public static final int select_album_empty=0x7f060098;
public static final int select_album_entries=0x7f060099;
public static final int select_album_genre=0x7f06009d;
public static final int select_album_more=0x7f06001a;
public static final int select_album_pin=0x7f060017;
public static final int select_album_play_all=0x7f0600bf;
public static final int select_album_play_all=0x7f0600c2;
public static final int select_album_play_last=0x7f060016;
public static final int select_album_play_next=0x7f060015;
public static final int select_album_play_now=0x7f060014;
public static final int select_album_select=0x7f060013;
public static final int select_album_song_count=0x7f06009b;
public static final int select_album_title=0x7f060098;
public static final int select_album_song_count=0x7f06009e;
public static final int select_album_title=0x7f06009b;
public static final int select_album_unpin=0x7f060018;
public static final int select_artist_folder=0x7f06009e;
public static final int select_artist_folder_1=0x7f06009f;
public static final int select_artist_folder_2=0x7f0600a0;
public static final int select_artist_list=0x7f06009d;
public static final int select_genre_empty=0x7f0600a1;
public static final int select_genre_list=0x7f0600a2;
public static final int select_playlist_empty=0x7f0600a3;
public static final int select_playlist_list=0x7f0600a4;
public static final int song_artist=0x7f0600a9;
public static final int song_check=0x7f0600a5;
public static final int song_duration=0x7f0600aa;
public static final int song_menu_pin=0x7f0600d1;
public static final int song_menu_play_last=0x7f0600d0;
public static final int song_menu_play_next=0x7f0600cf;
public static final int song_menu_play_now=0x7f0600ce;
public static final int song_menu_unpin=0x7f0600d2;
public static final int song_star=0x7f0600ab;
public static final int song_status=0x7f0600a8;
public static final int song_title=0x7f0600a7;
public static final int song_track=0x7f0600a6;
public static final int statusbar=0x7f060078;
public static final int tab_progress=0x7f0600ac;
public static final int tab_progress_message=0x7f0600ad;
public static final int select_artist_folder=0x7f0600a1;
public static final int select_artist_folder_1=0x7f0600a2;
public static final int select_artist_folder_2=0x7f0600a3;
public static final int select_artist_list=0x7f0600a0;
public static final int select_genre_empty=0x7f0600a4;
public static final int select_genre_list=0x7f0600a5;
public static final int select_playlist_empty=0x7f0600a6;
public static final int select_playlist_list=0x7f0600a7;
public static final int song_artist=0x7f0600ac;
public static final int song_check=0x7f0600a8;
public static final int song_duration=0x7f0600ad;
public static final int song_menu_pin=0x7f0600d7;
public static final int song_menu_play_last=0x7f0600d6;
public static final int song_menu_play_next=0x7f0600d5;
public static final int song_menu_play_now=0x7f0600d4;
public static final int song_menu_unpin=0x7f0600d8;
public static final int song_star=0x7f0600ae;
public static final int song_status=0x7f0600ab;
public static final int song_title=0x7f0600aa;
public static final int song_track=0x7f0600a9;
public static final int statusbar=0x7f06007c;
public static final int tab_progress=0x7f0600af;
public static final int tab_progress_message=0x7f0600b0;
public static final int title=0x7f060022;
public static final int toast_layout_root=0x7f060048;
public static final int trackname=0x7f06007a;
public static final int toast_layout_root=0x7f06004c;
public static final int trackname=0x7f06007e;
public static final int webview=0x7f06000a;
}
public static final class integer {
@ -830,45 +838,48 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
public static final int album_buttons=0x7f030000;
public static final int album_list_item=0x7f030001;
public static final int appwidget4x1=0x7f030002;
public static final int artist_list_item=0x7f030003;
public static final int chat=0x7f030004;
public static final int chat_item=0x7f030005;
public static final int chat_item_reverse=0x7f030006;
public static final int download=0x7f030007;
public static final int download_button_bar_flipper=0x7f030008;
public static final int download_playlist=0x7f030009;
public static final int download_slider=0x7f03000a;
public static final int equalizer=0x7f03000b;
public static final int equalizer_bar=0x7f03000c;
public static final int help=0x7f03000d;
public static final int jukebox_volume=0x7f03000e;
public static final int lyrics=0x7f03000f;
public static final int main=0x7f030010;
public static final int main_buttons=0x7f030011;
public static final int media_buttons=0x7f030012;
public static final int menu_main=0x7f030013;
public static final int menu_row_category=0x7f030014;
public static final int menu_row_item=0x7f030015;
public static final int notification=0x7f030016;
public static final int notification_large=0x7f030017;
public static final int now_playing=0x7f030018;
public static final int play_video=0x7f030019;
public static final int playlist_list_item=0x7f03001a;
public static final int progress=0x7f03001b;
public static final int pull_to_refresh_header_horizontal=0x7f03001c;
public static final int pull_to_refresh_header_vertical=0x7f03001d;
public static final int save_playlist=0x7f03001e;
public static final int search=0x7f03001f;
public static final int search_buttons=0x7f030020;
public static final int select_album=0x7f030021;
public static final int select_album_header=0x7f030022;
public static final int select_artist=0x7f030023;
public static final int select_artist_header=0x7f030024;
public static final int select_genre=0x7f030025;
public static final int select_playlist=0x7f030026;
public static final int song_list_item=0x7f030027;
public static final int tab_progress=0x7f030028;
public static final int update_playlist=0x7f030029;
public static final int appwidget4x2=0x7f030003;
public static final int appwidget4x3=0x7f030004;
public static final int appwidget4x4=0x7f030005;
public static final int artist_list_item=0x7f030006;
public static final int chat=0x7f030007;
public static final int chat_item=0x7f030008;
public static final int chat_item_reverse=0x7f030009;
public static final int download=0x7f03000a;
public static final int download_button_bar_flipper=0x7f03000b;
public static final int download_playlist=0x7f03000c;
public static final int download_slider=0x7f03000d;
public static final int equalizer=0x7f03000e;
public static final int equalizer_bar=0x7f03000f;
public static final int help=0x7f030010;
public static final int jukebox_volume=0x7f030011;
public static final int lyrics=0x7f030012;
public static final int main=0x7f030013;
public static final int main_buttons=0x7f030014;
public static final int media_buttons=0x7f030015;
public static final int menu_main=0x7f030016;
public static final int menu_row_category=0x7f030017;
public static final int menu_row_item=0x7f030018;
public static final int notification=0x7f030019;
public static final int notification_large=0x7f03001a;
public static final int now_playing=0x7f03001b;
public static final int play_video=0x7f03001c;
public static final int playlist_list_item=0x7f03001d;
public static final int progress=0x7f03001e;
public static final int pull_to_refresh_header_horizontal=0x7f03001f;
public static final int pull_to_refresh_header_vertical=0x7f030020;
public static final int save_playlist=0x7f030021;
public static final int search=0x7f030022;
public static final int search_buttons=0x7f030023;
public static final int select_album=0x7f030024;
public static final int select_album_header=0x7f030025;
public static final int select_artist=0x7f030026;
public static final int select_artist_header=0x7f030027;
public static final int select_genre=0x7f030028;
public static final int select_playlist=0x7f030029;
public static final int song_list_item=0x7f03002a;
public static final int tab_progress=0x7f03002b;
public static final int update_playlist=0x7f03002c;
}
public static final class menu {
public static final int main=0x7f0e0000;
@ -1234,8 +1245,11 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
}
public static final class xml {
public static final int appwidget_info_4x1=0x7f050000;
public static final int searchable=0x7f050001;
public static final int settings=0x7f050002;
public static final int appwidget_info_4x2=0x7f050001;
public static final int appwidget_info_4x3=0x7f050002;
public static final int appwidget_info_4x4=0x7f050003;
public static final int searchable=0x7f050004;
public static final int settings=0x7f050005;
}
public static final class styleable {
/** Styleables used for styling the menu drawer.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -34,24 +34,15 @@
a:id="@+id/download_status"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_above="@+id/download_song_title"
a:layout_centerHorizontal="true"
a:layout_alignParentBottom="true"
a:layout_marginBottom="8dip"
a:ellipsize="end"
a:gravity="center_horizontal"
a:singleLine="true"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_song_title"
a:layout_width="150dip"
a:layout_height="wrap_content"
a:layout_above="@+id/linearLayout1"
a:layout_centerHorizontal="true"
a:ellipsize="end"
a:gravity="center_horizontal"
a:maxLines="2"
a:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<com.thejoshwa.ultrasonic.androidapp.util.MyViewFlipper

View File

@ -36,26 +36,11 @@
a:singleLine="true"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_song_title"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_above="@+id/download_status"
a:layout_centerHorizontal="true"
a:layout_gravity="center_horizontal"
a:layout_marginLeft="16dip"
a:layout_marginRight="16dip"
a:layout_marginTop="16dip"
a:ellipsize="end"
a:singleLine="true"
a:textSize="18sp"
a:textStyle="bold" />
<LinearLayout
a:id="@+id/download_visualizer_view_layout"
a:layout_width="fill_parent"
a:layout_height="60dip"
a:layout_above="@+id/download_song_title"
a:layout_alignParentBottom="true"
a:layout_gravity="center_horizontal"
a:layout_marginLeft="80dip"
a:layout_marginRight="80dip"

View File

@ -2,14 +2,16 @@
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:background="@color/opaque"
a:minWidth="250dp"
a:minHeight="40dp"
a:background="@drawable/appwidget_dark_bg_trans"
a:orientation="horizontal" >
<ImageView
a:id="@+id/appwidget_coverart"
a:layout_width="81dip"
a:layout_height="fill_parent"
a:background="@drawable/list_selector_holo_dark"
a:layout_width="80dp"
a:layout_height="80dp"
a:layout_gravity="center_vertical"
a:clickable="true"
a:focusable="true"
a:src="@drawable/ic_launcher" />
@ -24,7 +26,6 @@
a:id="@+id/appwidget_top"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:background="@drawable/list_selector_holo_dark"
a:clickable="true"
a:focusable="true"
a:orientation="vertical" >
@ -37,9 +38,12 @@
a:fadingEdge="horizontal"
a:fadingEdgeLength="20dip"
a:minHeight="16sp"
a:paddingLeft="5dip"
a:paddingRight="5dip"
a:paddingLeft="4dip"
a:paddingRight="4dip"
a:paddingTop="4dip"
a:singleLine="true"
a:gravity="center_horizontal"
a:text="Title"
a:textColor="@color/appwidget_text"
a:textSize="16sp"
a:textStyle="bold" />
@ -52,9 +56,12 @@
a:fadingEdge="horizontal"
a:fadingEdgeLength="10dip"
a:minHeight="12sp"
a:paddingBottom="2dip"
a:paddingLeft="5dip"
a:paddingBottom="4dip"
a:paddingLeft="4dip"
a:paddingRight="4dip"
a:singleLine="true"
a:gravity="center_horizontal"
a:text="Artist"
a:textColor="@color/appwidget_text"
a:textSize="12sp" />
</LinearLayout>
@ -62,15 +69,16 @@
<LinearLayout
a:layout_width="fill_parent"
a:layout_height="fill_parent"
a:layout_marginTop="3dp"
a:orientation="horizontal" >
a:orientation="horizontal"
a:paddingBottom="4dip"
a:paddingTop="4dip" >
<ImageButton
a:id="@+id/control_previous"
a:layout_width="0dip"
a:layout_height="fill_parent"
a:layout_weight="1"
a:background="@drawable/list_selector_holo_dark"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_backward_normal_dark" />
@ -79,7 +87,7 @@
a:layout_width="0dip"
a:layout_height="fill_parent"
a:layout_weight="1"
a:background="@drawable/list_selector_holo_dark"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_start_normal_dark" />
@ -88,7 +96,7 @@
a:layout_width="0dip"
a:layout_height="fill_parent"
a:layout_weight="1"
a:background="@drawable/list_selector_holo_dark"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_forward_normal_dark" />
</LinearLayout>

126
res/layout/appwidget4x2.xml Normal file
View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:minWidth="250dp"
a:minHeight="110dp"
a:background="@drawable/appwidget_dark_bg_trans"
a:orientation="horizontal" >
<ImageView
a:id="@+id/appwidget_coverart"
a:layout_width="110dp"
a:layout_height="110dp"
a:layout_gravity="center_vertical"
a:clickable="true"
a:focusable="true"
a:src="@drawable/ic_launcher" />
<LinearLayout
a:id="@+id/linearLayout1"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:orientation="vertical" >
<LinearLayout
a:id="@+id/appwidget_top"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:clickable="true"
a:focusable="true"
a:orientation="vertical"
a:paddingTop="4dip"
a:paddingBottom="4dip" >
<TextView
a:id="@+id/title"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:ellipsize="none"
a:fadingEdge="horizontal"
a:fadingEdgeLength="20dip"
a:minHeight="16sp"
a:paddingLeft="4dip"
a:paddingRight="4dip"
a:paddingTop="4dip"
a:singleLine="true"
a:gravity="center_horizontal"
a:text="Title"
a:textColor="@color/appwidget_text"
a:textSize="16sp"
a:textStyle="bold" />
<TextView
a:id="@+id/artist"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:ellipsize="none"
a:fadingEdge="horizontal"
a:fadingEdgeLength="10dip"
a:minHeight="12sp"
a:paddingLeft="4dip"
a:paddingRight="4dip"
a:singleLine="true"
a:gravity="center_horizontal"
a:text="Artist"
a:textColor="@color/appwidget_text"
a:textSize="12sp" />
<TextView
a:id="@+id/album"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:ellipsize="none"
a:fadingEdge="horizontal"
a:fadingEdgeLength="10dip"
a:minHeight="12sp"
a:paddingBottom="4dip"
a:paddingLeft="4dip"
a:paddingRight="4dip"
a:singleLine="true"
a:gravity="center_horizontal"
a:text="Album"
a:textColor="@color/appwidget_text"
a:textSize="12sp" />
</LinearLayout>
<LinearLayout
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:orientation="horizontal"
a:layout_gravity="bottom"
a:gravity="bottom"
a:paddingBottom="4dip"
a:paddingTop="4dip" >"
<ImageButton
a:id="@+id/control_previous"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_weight="1"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_backward_normal_dark" />
<ImageButton
a:id="@+id/control_play"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_weight="1"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_start_normal_dark" />
<ImageButton
a:id="@+id/control_next"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_weight="1"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_forward_normal_dark" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

112
res/layout/appwidget4x3.xml Normal file
View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:minWidth="250dp"
a:minHeight="180dp"
a:background="@drawable/appwidget_dark_bg_trans"
a:orientation="vertical" >
<ImageView
a:id="@+id/appwidget_coverart"
a:layout_width="170dp"
a:layout_height="170dp"
a:layout_gravity="center_horizontal"
a:clickable="true"
a:focusable="true"
a:paddingTop="6dip"
a:paddingBottom="6dip"
a:src="@drawable/ic_launcher" />
<LinearLayout
a:id="@+id/linearLayout1"
a:layout_width="match_parent"
a:layout_height="wrap_content"
a:orientation="vertical" >
<LinearLayout
a:id="@+id/appwidget_top"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:clickable="true"
a:focusable="true"
a:orientation="vertical"
a:paddingBottom="4dip"
a:paddingTop="4dip" >
<TextView
a:id="@+id/title"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:ellipsize="none"
a:fadingEdge="horizontal"
a:fadingEdgeLength="20dip"
a:minHeight="16sp"
a:paddingLeft="5dip"
a:paddingRight="5dip"
a:singleLine="true"
a:textColor="@color/appwidget_text"
a:textSize="16sp"
a:text="Title"
a:layout_gravity="center_horizontal"
a:gravity="center"
a:textStyle="bold" />
<TextView
a:id="@+id/artist"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:ellipsize="none"
a:fadingEdge="horizontal"
a:fadingEdgeLength="10dip"
a:minHeight="12sp"
a:paddingBottom="2dip"
a:paddingLeft="5dip"
a:singleLine="true"
a:text="Artist"
a:layout_gravity="center_horizontal"
a:gravity="center"
a:textColor="@color/appwidget_text"
a:textSize="12sp" />
</LinearLayout>
<LinearLayout
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:layout_gravity="bottom"
a:gravity="bottom"
a:orientation="horizontal"
a:paddingBottom="4dip"
a:paddingTop="4dip" >
<ImageButton
a:id="@+id/control_previous"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_weight="1"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_backward_normal_dark" />
<ImageButton
a:id="@+id/control_play"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_weight="1"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_start_normal_dark" />
<ImageButton
a:id="@+id/control_next"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_weight="1"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_forward_normal_dark" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

113
res/layout/appwidget4x4.xml Normal file
View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:minWidth="250dp"
a:minHeight="250dp"
a:orientation="vertical"
a:background="@drawable/appwidget_dark_bg_trans" >"
<ImageView
a:id="@+id/appwidget_coverart"
a:layout_width="234dp"
a:layout_height="234dp"
a:layout_gravity="center_horizontal"
a:clickable="true"
a:focusable="true"
a:layout_margin="6dip"
a:paddingTop="6dip"
a:paddingBottom="6dip"
a:src="@drawable/ic_launcher" />
<LinearLayout
a:id="@+id/linearLayout1"
a:layout_width="match_parent"
a:layout_height="wrap_content"
a:orientation="vertical" >
<LinearLayout
a:id="@+id/appwidget_top"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:clickable="true"
a:focusable="true"
a:orientation="vertical"
a:paddingTop="4dip"
a:paddingBottom="4dip" >
<TextView
a:id="@+id/title"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:ellipsize="none"
a:fadingEdge="horizontal"
a:fadingEdgeLength="20dip"
a:minHeight="16sp"
a:paddingLeft="5dip"
a:paddingRight="5dip"
a:singleLine="true"
a:textColor="@color/appwidget_text"
a:textSize="16sp"
a:text="Title"
a:layout_gravity="center_horizontal"
a:gravity="center"
a:textStyle="bold" />
<TextView
a:id="@+id/artist"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:ellipsize="none"
a:fadingEdge="horizontal"
a:fadingEdgeLength="10dip"
a:minHeight="12sp"
a:paddingBottom="2dip"
a:paddingLeft="5dip"
a:singleLine="true"
a:text="Artist"
a:layout_gravity="center_horizontal"
a:gravity="center"
a:textColor="@color/appwidget_text"
a:textSize="12sp" />
</LinearLayout>
<LinearLayout
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:layout_gravity="bottom"
a:gravity="bottom"
a:orientation="horizontal"
a:paddingBottom="4dip"
a:paddingTop="4dip" >
<ImageButton
a:id="@+id/control_previous"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_weight="1"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_backward_normal_dark" />
<ImageButton
a:id="@+id/control_play"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_weight="1"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_start_normal_dark" />
<ImageButton
a:id="@+id/control_next"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_weight="1"
a:background="@color/transparent"
a:scaleType="center"
a:src="@drawable/media_forward_normal_dark" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -1,60 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<com.thejoshwa.ultrasonic.androidapp.util.MyViewFlipper
xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/download_button_bar_flipper"
a:layout_width="fill_parent"
a:layout_height="wrap_content" >
<RelativeLayout
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:paddingLeft="8dip"
a:paddingRight="8dip"
a:paddingBottom="8dip" >
<TextView
a:id="@+id/download_position"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_alignParentLeft="true"
a:layout_alignParentTop="true"
a:layout_marginRight="6dip"
a:text="@string/util.zero_time"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_duration"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_alignParentRight="true"
a:layout_alignParentTop="true"
a:layout_marginLeft="6dip"
a:text="@string/util.no_time"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_artist"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_toRightOf="@+id/download_position"
a:layout_toLeftOf="@+id/download_duration"
a:layout_centerHorizontal="true"
a:layout_alignParentTop="true"
a:singleLine="true"
a:ellipsize="end"
a:gravity="center_horizontal"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_album"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_centerHorizontal="true"
a:layout_below="@+id/download_artist"
a:singleLine="true"
a:ellipsize="end"
a:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
<RelativeLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/download_button_bar_flipper"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:paddingBottom="8dip"
a:paddingLeft="8dip"
a:paddingRight="8dip" >
</com.thejoshwa.ultrasonic.androidapp.util.MyViewFlipper>
<TextView
a:id="@+id/download_song_title"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:layout_alignParentTop="true"
a:layout_centerHorizontal="true"
a:gravity="center"
a:ellipsize="end"
a:singleLine="true"
a:textAppearance="?android:attr/textAppearanceMedium"
a:text="Title" />
<RelativeLayout
a:id="@+id/download_items"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:layout_below="@id/download_song_title" >
<TextView
a:id="@+id/download_position"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_alignParentLeft="true"
a:layout_marginRight="6dip"
a:text="@string/util.no_time"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_track"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_alignParentLeft="true"
a:layout_below="@id/download_position"
a:layout_marginRight="6dip"
a:text="0 / 0"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_duration"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_alignParentRight="true"
a:layout_marginLeft="6dip"
a:text="@string/util.no_time"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_total_duration"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_alignParentRight="true"
a:layout_below="@id/download_duration"
a:layout_marginLeft="6dip"
a:text="@string/util.no_time"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_artist"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_centerHorizontal="true"
a:layout_toLeftOf="@+id/download_duration"
a:layout_toRightOf="@+id/download_position"
a:ellipsize="end"
a:gravity="center_horizontal"
a:singleLine="true"
a:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
a:id="@+id/download_album"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_below="@+id/download_artist"
a:layout_centerHorizontal="true"
a:ellipsize="end"
a:singleLine="true"
a:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</RelativeLayout>

View File

@ -19,6 +19,7 @@
a:layout_width="fill_parent"
a:layout_height="0dip"
a:layout_weight="1"
a:cacheColorHint="#00000000"/>
a:fastScrollEnabled="true"
a:textFilterEnabled="true" />
</LinearLayout>

View File

@ -24,6 +24,7 @@
a:layout_width="fill_parent"
a:layout_height="0dip"
a:layout_weight="1.0"
a:fastScrollEnabled="true"
a:textFilterEnabled="true" />
<include layout="@layout/album_buttons" />

View File

@ -18,7 +18,9 @@
a:id="@+id/select_playlist_list"
a:layout_width="fill_parent"
a:layout_height="0dip"
a:layout_weight="1.0" />
a:layout_weight="1.0"
a:fastScrollEnabled="true"
a:textFilterEnabled="true" />
<include layout="@layout/now_playing" />

View File

@ -20,5 +20,10 @@
a:id="@+id/album_menu_pin"
a:title="@string/common.pin"
/>
<item
a:id="@+id/album_menu_unpin"
a:title="@string/common.unpin"
/>
</menu>

View File

@ -20,5 +20,11 @@
a:id="@+id/artist_menu_pin"
a:title="@string/common.pin"
/>
<item
a:id="@+id/artist_menu_unpin"
a:title="@string/common.unpin"
/>
</menu>

View File

@ -13,6 +13,9 @@
<item
android:id="@+id/playlist_menu_pin"
android:title="@string/common.pin"/>
<item
android:id="@+id/playlist_menu_unpin"
android:title="@string/common.unpin"/>
<item
android:id="@+id/playlist_update_info"
android:title="@string/playlist.update_info"/>

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
a:minWidth="272dp"
a:minHeight="56dp"
a:minWidth="250dp"
a:minHeight="40dp"
a:updatePeriodMillis="0"
a:resizeMode="horizontal|vertical"
a:resizeMode="none"
a:previewImage="@drawable/preview"
a:widgetCategory="home_screen|keyguard"
a:initialLayout="@layout/appwidget4x1"/>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
a:minWidth="250dp"
a:minHeight="110dp"
a:updatePeriodMillis="0"
a:resizeMode="none"
a:previewImage="@drawable/preview"
a:widgetCategory="home_screen|keyguard"
a:initialLayout="@layout/appwidget4x2"/>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
a:minWidth="250dp"
a:minHeight="180dp"
a:updatePeriodMillis="0"
a:resizeMode="none"
a:previewImage="@drawable/preview"
a:widgetCategory="home_screen|keyguard"
a:initialLayout="@layout/appwidget4x3"/>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
a:minWidth="250dp"
a:minHeight="250dp"
a:updatePeriodMillis="0"
a:resizeMode="none"
a:previewImage="@drawable/preview"
a:widgetCategory="home_screen|keyguard"
a:initialLayout="@layout/appwidget4x4" />

View File

@ -30,7 +30,9 @@ import android.view.*;
import android.view.GestureDetector.OnGestureListener;
import android.view.animation.AnimationUtils;
import android.widget.*;
import com.thejoshwa.ultrasonic.androidapp.R;
import com.thejoshwa.ultrasonic.androidapp.domain.Bookmark;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry;
import com.thejoshwa.ultrasonic.androidapp.domain.PlayerState;
@ -70,6 +72,8 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
private ImageView albumArtImageView;
private ListView playlistView;
private TextView positionTextView;
private TextView downloadTrackTextView;
private TextView downloadTotalDurationTextView;
private TextView durationTextView;
private TextView statusTextView;
private static SeekBar progressBar;
@ -90,6 +94,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
private boolean visualizerAvailable;
private boolean equalizerAvailable;
private SilentBackgroundTask<Void> onProgressChangedTask;
//private volatile List<Bookmark> bookmarks;
/**
* Called when the activity is first created.
@ -112,6 +117,8 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
artistTextView = (TextView) findViewById(R.id.download_artist);
albumArtImageView = (ImageView) findViewById(R.id.download_album_art_image);
positionTextView = (TextView) findViewById(R.id.download_position);
downloadTrackTextView = (TextView) findViewById(R.id.download_track);
downloadTotalDurationTextView = (TextView) findViewById(R.id.download_total_duration);
durationTextView = (TextView) findViewById(R.id.download_duration);
statusTextView = (TextView) findViewById(R.id.download_status);
progressBar = (SeekBar) findViewById(R.id.download_progress_bar);
@ -376,13 +383,13 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
new Thread(new Runnable() {
public void run() {
final MusicService musicService = MusicServiceFactory.getMusicService(getBaseContext());
final MusicService musicService = MusicServiceFactory.getMusicService(DownloadActivity.this);
try {
if (isStarred) {
musicService.unstar(id, null, null, getBaseContext(), null);
musicService.unstar(id, null, null, DownloadActivity.this, null);
} else {
musicService.star(id, null, null, getBaseContext(), null);
musicService.star(id, null, null, DownloadActivity.this, null);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
@ -392,6 +399,19 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
}
});
// TODO: Add bookmark support
// new Thread(new Runnable() {
// public void run() {
// final MusicService musicService = MusicServiceFactory.getMusicService(DownloadActivity.this);
//
// try {
// bookmarks = musicService.getBookmarks(DownloadActivity.this, null);
// } catch (Exception e) {
// Log.e(TAG, e.getMessage(), e);
// }
// }
// }).start();
visualizerAvailable = downloadService != null && downloadService.getVisualizerController() != null;
equalizerAvailable = downloadService != null && downloadService.getEqualizerController() != null;
@ -407,7 +427,6 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
public boolean onTouch(final View view, final MotionEvent motionEvent) {
visualizerView.setActive(!visualizerView.isActive());
getDownloadService().setShowVisualization(visualizerView.isActive());
//updateButtons();
return true;
}
});
@ -442,7 +461,6 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
onDownloadListChanged();
onCurrentChanged();
onSliderProgressChanged();
scrollToCurrent();
if (downloadService != null && downloadService.getKeepScreenOn()) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
@ -454,7 +472,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
visualizerView.setActive(downloadService != null && downloadService.getShowVisualization());
}
}
// Scroll to current playing/downloading.
private void scrollToCurrent() {
if (getDownloadService() == null) {
@ -463,14 +481,15 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
for (int i = 0; i < playlistView.getAdapter().getCount(); i++) {
if (currentPlaying == playlistView.getItemAtPosition(i)) {
playlistView.setSelectionFromTop(i, 40);
playlistView.smoothScrollToPositionFromTop(i, 40);
return;
}
}
final DownloadFile currentDownloading = getDownloadService().getCurrentDownloading();
for (int i = 0; i < playlistView.getAdapter().getCount(); i++) {
if (currentDownloading == playlistView.getItemAtPosition(i)) {
playlistView.setSelectionFromTop(i, 40);
playlistView.smoothScrollToPositionFromTop(i, 40);
return;
}
}
@ -792,19 +811,36 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
currentPlaying = getDownloadService().getCurrentPlaying();
scrollToCurrent();
long totalDuration = getDownloadService().getDownloadListDuration();
long totalSongs = getDownloadService().getSongs().size();
int currentSongIndex = getDownloadService().getCurrentPlayingIndex() + 1;
String duration = Util.formatTotalDuration(totalDuration);
String trackFormat = String.format("%d / %d",
currentSongIndex,
totalSongs
);
if (currentPlaying != null) {
currentSong = currentPlaying.getSong();
currentSong = currentPlaying.getSong();
final Drawable starDrawable = currentSong.getStarred() ? Util.getDrawableFromAttribute(SubsonicTabActivity.getInstance(), R.attr.star_full) : Util.getDrawableFromAttribute(SubsonicTabActivity.getInstance(), R.attr.star_hollow);
starImageView.setImageDrawable(starDrawable);
songTitleTextView.setText(currentSong.getTitle());
albumTextView.setText(currentSong.getAlbum());
artistTextView.setText(currentSong.getArtist());
downloadTrackTextView.setText(trackFormat);
downloadTotalDurationTextView.setText(duration);
getImageLoader().loadImage(albumArtImageView, currentSong, true, 0, false, true);
} else {
currentSong = null;
songTitleTextView.setText(null);
albumTextView.setText(null);
artistTextView.setText(null);
downloadTrackTextView.setText(null);
downloadTotalDurationTextView.setText(null);
getImageLoader().loadImage(albumArtImageView, null, true, 0, false, false);
}
}

View File

@ -192,17 +192,20 @@ public class SearchActivity extends SubsonicTabActivity {
switch (menuItem.getItemId()) {
case R.id.album_menu_play_now:
downloadRecursively(id, false, false, true, false, false, false);
downloadRecursively(id, false, false, true, false, false, false, false);
break;
case R.id.album_menu_play_next:
downloadRecursively(id, false, true, false, true, false, true);
downloadRecursively(id, false, true, false, true, false, true, false);
break;
case R.id.album_menu_play_last:
downloadRecursively(id, false, true, false, false, false, false);
downloadRecursively(id, false, true, false, false, false, false, false);
break;
case R.id.album_menu_pin:
downloadRecursively(id, true, true, false, false, false, false);
downloadRecursively(id, true, true, false, false, false, false, false);
break;
case R.id.album_menu_unpin:
downloadRecursively(id, false, false, false, false, false, false, true);
break;
case R.id.song_menu_play_now:
if (entry != null) {
songs = new ArrayList<MusicDirectory.Entry>(1);
@ -392,7 +395,7 @@ public class SearchActivity extends SubsonicTabActivity {
private void onSongSelected(MusicDirectory.Entry song, boolean save, boolean append, boolean autoplay, boolean playNext) {
DownloadService downloadService = getDownloadService();
if (downloadService != null) {
if (!append) {
if (!append && !playNext) {
downloadService.clear();
}

View File

@ -19,7 +19,6 @@
package com.thejoshwa.ultrasonic.androidapp.activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@ -60,8 +59,6 @@ import com.handmark.pulltorefresh.library.PullToRefreshListView;
public class SelectAlbumActivity extends SubsonicTabActivity {
private static final String TAG = SelectAlbumActivity.class.getSimpleName();
private PullToRefreshListView refreshAlbumListView;
private ListView albumListView;
private View header;
@ -268,7 +265,7 @@ public class SelectAlbumActivity extends SubsonicTabActivity {
String id = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ID);
if (hasSubFolders && id != null) {
downloadRecursively(id, false, append, !append, shuffle, false, false);
downloadRecursively(id, false, append, !append, shuffle, false, false, false);
} else {
selectAll(true, false);
download(append, false, !append, false, shuffle, getSelectedSongs(albumListView));
@ -319,17 +316,20 @@ public class SelectAlbumActivity extends SubsonicTabActivity {
switch (menuItem.getItemId()) {
case R.id.album_menu_play_now:
downloadRecursively(entry.getId(), false, false, true, false, false, false);
downloadRecursively(entry.getId(), false, false, true, false, false, false, false);
break;
case R.id.album_menu_play_next:
downloadRecursively(entry.getId(), false, false, false, false, false, true);
downloadRecursively(entry.getId(), false, false, false, false, false, true, false);
break;
case R.id.album_menu_play_last:
downloadRecursively(entry.getId(), false, true, false, false, false, false);
downloadRecursively(entry.getId(), false, true, false, false, false, false, false);
break;
case R.id.album_menu_pin:
downloadRecursively(entry.getId(), true, true, false, false, false, false);
downloadRecursively(entry.getId(), true, true, false, false, false, false, false);
break;
case R.id.album_menu_unpin:
downloadRecursively(entry.getId(), false, false, false, false, false, false, true);
break;
case R.id.select_album_play_all:
playAll();
break;
@ -816,15 +816,7 @@ public class SelectAlbumActivity extends SubsonicTabActivity {
String songs = getResources().getQuantityString(R.plurals.select_album_n_songs, songCount, songCount);
songCountView.setText(songs);
long millis = totalDuration * 1000;
String duration = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);
String duration = Util.formatTotalDuration(totalDuration);
TextView durationView = (TextView) header.findViewById(R.id.select_album_duration);
durationView.setText(duration);

View File

@ -223,16 +223,19 @@ public class SelectArtistActivity extends SubsonicTabActivity implements Adapter
if (artist != null) {
switch (menuItem.getItemId()) {
case R.id.artist_menu_play_now:
downloadRecursively(artist.getId(), false, false, true, false, false, false);
downloadRecursively(artist.getId(), false, false, true, false, false, false, false);
break;
case R.id.artist_menu_play_next:
downloadRecursively(artist.getId(), false, false, true, true, false, true);
downloadRecursively(artist.getId(), false, false, true, true, false, true, false);
break;
case R.id.artist_menu_play_last:
downloadRecursively(artist.getId(), false, true, false, false, false, false);
downloadRecursively(artist.getId(), false, true, false, false, false, false, false);
break;
case R.id.artist_menu_pin:
downloadRecursively(artist.getId(), true, true, false, false, false, false);
downloadRecursively(artist.getId(), true, true, false, false, false, false, false);
break;
case R.id.artist_menu_unpin:
downloadRecursively(artist.getId(), false, false, false, false, false, false, true);
break;
default:
return super.onContextItemSelected(menuItem);

View File

@ -142,8 +142,11 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt
Intent intent;
switch (menuItem.getItemId()) {
case R.id.playlist_menu_pin:
downloadPlaylist(playlist.getId(), playlist.getName(), true, true, false, false, true, false);
downloadPlaylist(playlist.getId(), playlist.getName(), true, true, false, false, true, false, false);
break;
case R.id.playlist_menu_unpin:
downloadPlaylist(playlist.getId(), playlist.getName(), false, false, false, false, true, false, true);
break;
case R.id.playlist_menu_play_now:
intent = new Intent(SelectPlaylistActivity.this, SelectAlbumActivity.class);
intent.putExtra(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId());

View File

@ -609,13 +609,16 @@ public class SubsonicTabActivity extends Activity implements OnClickListener{
// If service is not available, request it to start and wait for it.
for (int i = 0; i < 5; i++) {
DownloadService downloadService = DownloadServiceImpl.getInstance();
if (downloadService != null) {
return downloadService;
}
Log.w(TAG, "DownloadService not running. Attempting to start it.");
startService(new Intent(this, DownloadServiceImpl.class));
Util.sleepQuietly(50L);
}
return DownloadServiceImpl.getInstance();
}
@ -649,7 +652,7 @@ public class SubsonicTabActivity extends Activity implements OnClickListener{
Runnable onValid = new Runnable() {
@Override
public void run() {
if (!append) {
if (!append && !playNext) {
getDownloadService().clear();
}
@ -678,13 +681,13 @@ public class SubsonicTabActivity extends Activity implements OnClickListener{
}
protected void downloadRecursively(final String id, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext) {
downloadRecursively(id, "", true, save, append, autoplay, shuffle, background, playNext);
protected void downloadRecursively(final String id, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext, final boolean unpin) {
downloadRecursively(id, "", true, save, append, autoplay, shuffle, background, playNext, unpin);
}
protected void downloadPlaylist(final String id, final String name, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext) {
downloadRecursively(id, name, false, save, append, autoplay, shuffle, background, playNext);
protected void downloadPlaylist(final String id, final String name, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext, final boolean unpin) {
downloadRecursively(id, name, false, save, append, autoplay, shuffle, background, playNext, unpin);
}
protected void downloadRecursively(final String id, final String name, final boolean isDirectory, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext) {
protected void downloadRecursively(final String id, final String name, final boolean isDirectory, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext, final boolean unpin) {
ModalBackgroundTask<List<MusicDirectory.Entry>> task = new ModalBackgroundTask<List<MusicDirectory.Entry>>(this, false) {
private static final int MAX_SONGS = 500;
@ -737,18 +740,26 @@ public class SubsonicTabActivity extends Activity implements OnClickListener{
protected void done(List<MusicDirectory.Entry> songs) {
DownloadService downloadService = getDownloadService();
if (!songs.isEmpty() && downloadService != null) {
if (!append && !playNext) {
if (!append && !playNext && !unpin) {
downloadService.clear();
}
warnIfNetworkOrStorageUnavailable();
if(!background) {
downloadService.download(songs, save, autoplay, playNext, shuffle);
if (!append && Util.getShouldTransitionOnPlaybackPreference(SubsonicTabActivity.this)) {
Util.startActivityWithoutTransition(SubsonicTabActivity.this, DownloadActivity.class);
if (unpin) {
downloadService.unpin(songs);
} else {
downloadService.download(songs, save, autoplay, playNext, shuffle);
if (!append && Util.getShouldTransitionOnPlaybackPreference(SubsonicTabActivity.this)) {
Util.startActivityWithoutTransition(SubsonicTabActivity.this, DownloadActivity.class);
}
}
}
else {
downloadService.downloadBackground(songs, save);
if (unpin) {
downloadService.unpin(songs);
} else {
downloadService.downloadBackground(songs, save);
}
}
}
}

View File

@ -0,0 +1,87 @@
package com.thejoshwa.ultrasonic.androidapp.domain;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry;
public class Bookmark implements Serializable {
/**
*
*/
private static final long serialVersionUID = 8988990025189807803L;
private Long position;
private String username;
private String comment;
private Date created;
private Date changed;
private List<Entry> entries;
public Long getPosition() {
return position;
}
public void setPosition(Long position) {
this.position = position;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Date getCreated() {
return created;
}
public void setCreated(String created) {
if (created != null) {
try {
this.created = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(created);
} catch (ParseException e) {
this.created = null;
}
} else {
this.created = null;
}
}
public Date getChanged() {
return changed;
}
public void setChanged(String changed) {
if (changed != null) {
try {
this.changed = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(changed);
} catch (ParseException e) {
this.changed = null;
}
} else {
this.changed = null;
}
}
public List<Entry> getEntries() {
return this.entries;
}
public void addEntry(Entry entry) {
entries.add(entry);
}
}

View File

@ -0,0 +1,180 @@
package com.thejoshwa.ultrasonic.androidapp.provider;
import com.thejoshwa.ultrasonic.androidapp.R;
import com.thejoshwa.ultrasonic.androidapp.activity.DownloadActivity;
import com.thejoshwa.ultrasonic.androidapp.activity.MainActivity;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
import com.thejoshwa.ultrasonic.androidapp.service.DownloadService;
import com.thejoshwa.ultrasonic.androidapp.service.DownloadServiceImpl;
import com.thejoshwa.ultrasonic.androidapp.util.FileUtil;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.RemoteViews;
public class UltraSonicAppWidgetProvider extends AppWidgetProvider {
private final static String TAG = UltraSonicAppWidgetProvider.class.getSimpleName();
protected int layoutId;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
defaultAppWidget(context, appWidgetIds);
}
/**
* Initialize given widgets to default state, where we launch UltraSonic on default click
* and hide actions if service not running.
*/
private void defaultAppWidget(Context context, int[] appWidgetIds) {
final Resources res = context.getResources();
final RemoteViews views = new RemoteViews(context.getPackageName(), this.layoutId);
views.setTextViewText(R.id.artist, res.getText(R.string.widget_initial_text));
linkButtons(context, views, false);
pushUpdate(context, appWidgetIds, views);
}
private void pushUpdate(Context context, int[] appWidgetIds, RemoteViews views) {
// Update specific list of appWidgetIds if given, otherwise default to all
final AppWidgetManager manager = AppWidgetManager.getInstance(context);
if (appWidgetIds != null) {
manager.updateAppWidget(appWidgetIds, views);
} else {
manager.updateAppWidget(new ComponentName(context, this.getClass()), views);
}
}
/**
* Handle a change notification coming over from {@link DownloadService}
*/
public void notifyChange(Context context, DownloadService service, boolean playing, boolean setAlbum) {
if (hasInstances(context)) {
performUpdate(context, service, null, playing, setAlbum);
}
}
/**
* Check against {@link AppWidgetManager} if there are any instances of this widget.
*/
private boolean hasInstances(Context context) {
AppWidgetManager manager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(context, getClass()));
return (appWidgetIds.length > 0);
}
/**
* Update all active widget instances by pushing changes
*/
private void performUpdate(Context context, DownloadService service, int[] appWidgetIds, boolean playing, boolean setAlbum) {
final Resources res = context.getResources();
final RemoteViews views = new RemoteViews(context.getPackageName(), this.layoutId);
MusicDirectory.Entry currentPlaying = service.getCurrentPlaying() == null ? null : service.getCurrentPlaying().getSong();
String title = currentPlaying == null ? null : currentPlaying.getTitle();
String artist = currentPlaying == null ? null : currentPlaying.getArtist();
String album = currentPlaying == null ? null : currentPlaying.getAlbum();
CharSequence errorState = null;
// Show error message?
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_SHARED) ||
status.equals(Environment.MEDIA_UNMOUNTED)) {
errorState = res.getText(R.string.widget_sdcard_busy);
} else if (status.equals(Environment.MEDIA_REMOVED)) {
errorState = res.getText(R.string.widget_sdcard_missing);
} else if (currentPlaying == null) {
errorState = res.getText(R.string.widget_initial_text);
}
if (errorState != null) {
// Show error state to user
views.setTextViewText(R.id.title, null);
views.setTextViewText(R.id.artist, errorState);
if (setAlbum) {
views.setTextViewText(R.id.album, null);
}
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.appwidget_art_default);
} else {
// No error, so show normal titles
views.setTextViewText(R.id.title, title);
views.setTextViewText(R.id.artist, artist);
if (setAlbum) {
views.setTextViewText(R.id.album, album);
}
}
// Set correct drawable for pause state
if (playing) {
views.setImageViewResource(R.id.control_play, R.drawable.media_pause_normal_dark);
} else {
views.setImageViewResource(R.id.control_play, R.drawable.media_start_normal_dark);
}
// Set the cover art
try {
int size = context.getResources().getDrawable(R.drawable.appwidget_art_default).getIntrinsicHeight();
Bitmap bitmap = currentPlaying == null ? null : FileUtil.getAlbumArtBitmap(context, currentPlaying, size, true);
if (bitmap == null) {
// Set default cover art
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.appwidget_art_default);
} else {
//bitmap = getRoundedCornerBitmap(bitmap);
views.setImageViewBitmap(R.id.appwidget_coverart, bitmap);
}
} catch (Exception x) {
Log.e(TAG, "Failed to load cover art", x);
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.appwidget_art_default);
}
// Link actions buttons to intents
linkButtons(context, views, currentPlaying != null);
pushUpdate(context, appWidgetIds, views);
}
/**
* Link up various button actions using {@link PendingIntent}.
*
* @param playerActive True if player is active in background, which means
* widget click will launch {@link DownloadActivity},
* otherwise we launch {@link MainActivity}.
*/
private void linkButtons(Context context, RemoteViews views, boolean playerActive) {
Intent intent = new Intent(context, playerActive ? DownloadActivity.class : MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.appwidget_coverart, pendingIntent);
views.setOnClickPendingIntent(R.id.appwidget_top, pendingIntent);
// Emulate media button clicks.
intent = new Intent("1");
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.control_play, pendingIntent);
intent = new Intent("2"); // Use a unique action name to ensure a different PendingIntent to be created.
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT));
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.control_next, pendingIntent);
intent = new Intent("3"); // Use a unique action name to ensure a different PendingIntent to be created.
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS));
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.control_previous, pendingIntent);
}
}

View File

@ -18,45 +18,16 @@
*/
package com.thejoshwa.ultrasonic.androidapp.provider;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.RemoteViews;
import com.thejoshwa.ultrasonic.androidapp.R;
import com.thejoshwa.ultrasonic.androidapp.activity.DownloadActivity;
import com.thejoshwa.ultrasonic.androidapp.activity.MainActivity;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
import com.thejoshwa.ultrasonic.androidapp.service.DownloadService;
import com.thejoshwa.ultrasonic.androidapp.service.DownloadServiceImpl;
import com.thejoshwa.ultrasonic.androidapp.util.FileUtil;
/**
* Simple widget to show currently playing album art along
* with play/pause and next track buttons.
* <p/>
* Based on source code from the stock Android Music app.
*
* @author Sindre Mehus
*/
public class UltraSonicAppWidgetProvider4x1 extends AppWidgetProvider {
public class UltraSonicAppWidgetProvider4x1 extends UltraSonicAppWidgetProvider {
private static UltraSonicAppWidgetProvider4x1 instance;
private static final String TAG = UltraSonicAppWidgetProvider4x1.class.getSimpleName();
public UltraSonicAppWidgetProvider4x1() {
super();
this.layoutId = R.layout.appwidget4x1;
}
private static UltraSonicAppWidgetProvider4x1 instance;
public static synchronized UltraSonicAppWidgetProvider4x1 getInstance() {
if (instance == null) {
@ -64,175 +35,4 @@ public class UltraSonicAppWidgetProvider4x1 extends AppWidgetProvider {
}
return instance;
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
defaultAppWidget(context, appWidgetIds);
}
/**
* Initialize given widgets to default state, where we launch UltraSonic on default click
* and hide actions if service not running.
*/
private void defaultAppWidget(Context context, int[] appWidgetIds) {
final Resources res = context.getResources();
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget4x1);
views.setTextViewText(R.id.artist, res.getText(R.string.widget_initial_text));
linkButtons(context, views, false);
pushUpdate(context, appWidgetIds, views);
}
private void pushUpdate(Context context, int[] appWidgetIds, RemoteViews views) {
// Update specific list of appWidgetIds if given, otherwise default to all
final AppWidgetManager manager = AppWidgetManager.getInstance(context);
if (appWidgetIds != null) {
manager.updateAppWidget(appWidgetIds, views);
} else {
manager.updateAppWidget(new ComponentName(context, this.getClass()), views);
}
}
/**
* Handle a change notification coming over from {@link DownloadService}
*/
public void notifyChange(Context context, DownloadService service, boolean playing) {
if (hasInstances(context)) {
performUpdate(context, service, null, playing);
}
}
/**
* Check against {@link AppWidgetManager} if there are any instances of this widget.
*/
private boolean hasInstances(Context context) {
AppWidgetManager manager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(context, getClass()));
return (appWidgetIds.length > 0);
}
/**
* Update all active widget instances by pushing changes
*/
private void performUpdate(Context context, DownloadService service, int[] appWidgetIds, boolean playing) {
final Resources res = context.getResources();
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget4x1);
MusicDirectory.Entry currentPlaying = service.getCurrentPlaying() == null ? null : service.getCurrentPlaying().getSong();
String title = currentPlaying == null ? null : currentPlaying.getTitle();
CharSequence artist = currentPlaying == null ? null : currentPlaying.getArtist();
CharSequence errorState = null;
// Show error message?
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_SHARED) ||
status.equals(Environment.MEDIA_UNMOUNTED)) {
errorState = res.getText(R.string.widget_sdcard_busy);
} else if (status.equals(Environment.MEDIA_REMOVED)) {
errorState = res.getText(R.string.widget_sdcard_missing);
} else if (currentPlaying == null) {
errorState = res.getText(R.string.widget_initial_text);
}
if (errorState != null) {
// Show error state to user
views.setTextViewText(R.id.title,null);
views.setTextViewText(R.id.artist, errorState);
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.appwidget_art_default);
} else {
// No error, so show normal titles
views.setTextViewText(R.id.title, title);
views.setTextViewText(R.id.artist, artist);
}
// Set correct drawable for pause state
if (playing) {
views.setImageViewResource(R.id.control_play, R.drawable.media_pause_normal_dark);
} else {
views.setImageViewResource(R.id.control_play, R.drawable.media_start_normal_dark);
}
// Set the cover art
try {
int size = context.getResources().getDrawable(R.drawable.appwidget_art_default).getIntrinsicHeight();
Bitmap bitmap = currentPlaying == null ? null : FileUtil.getAlbumArtBitmap(context, currentPlaying, size, true);
if (bitmap == null) {
// Set default cover art
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.appwidget_art_default);
} else {
bitmap = getRoundedCornerBitmap(bitmap);
views.setImageViewBitmap(R.id.appwidget_coverart, bitmap);
}
} catch (Exception x) {
Log.e(TAG, "Failed to load cover art", x);
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.appwidget_art_default);
}
// Link actions buttons to intents
linkButtons(context, views, currentPlaying != null);
pushUpdate(context, appWidgetIds, views);
}
/**
* Round the corners of a bitmap for the cover art image
*/
private static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final float roundPx = 10;
// Add extra width to the rect so the right side wont be rounded.
final Rect rect = new Rect(0, 0, bitmap.getWidth() + (int) roundPx, bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
/**
* Link up various button actions using {@link PendingIntent}.
*
* @param playerActive True if player is active in background, which means
* widget click will launch {@link DownloadActivity},
* otherwise we launch {@link MainActivity}.
*/
private void linkButtons(Context context, RemoteViews views, boolean playerActive) {
Intent intent = new Intent(context, playerActive ? DownloadActivity.class : MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.appwidget_coverart, pendingIntent);
views.setOnClickPendingIntent(R.id.appwidget_top, pendingIntent);
// Emulate media button clicks.
intent = new Intent("1");
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.control_play, pendingIntent);
intent = new Intent("2"); // Use a unique action name to ensure a different PendingIntent to be created.
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT));
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.control_next, pendingIntent);
intent = new Intent("3"); // Use a unique action name to ensure a different PendingIntent to be created.
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS));
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.control_previous, pendingIntent);
}
}

View File

@ -0,0 +1,38 @@
/*
This file is part of Subsonic.
Subsonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Subsonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 (C) Sindre Mehus
*/
package com.thejoshwa.ultrasonic.androidapp.provider;
import com.thejoshwa.ultrasonic.androidapp.R;
public class UltraSonicAppWidgetProvider4x2 extends UltraSonicAppWidgetProvider {
public UltraSonicAppWidgetProvider4x2() {
super();
this.layoutId = R.layout.appwidget4x2;
}
private static UltraSonicAppWidgetProvider4x2 instance;
public static synchronized UltraSonicAppWidgetProvider4x2 getInstance() {
if (instance == null) {
instance = new UltraSonicAppWidgetProvider4x2();
}
return instance;
}
}

View File

@ -0,0 +1,38 @@
/*
This file is part of Subsonic.
Subsonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Subsonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 (C) Sindre Mehus
*/
package com.thejoshwa.ultrasonic.androidapp.provider;
import com.thejoshwa.ultrasonic.androidapp.R;
public class UltraSonicAppWidgetProvider4x3 extends UltraSonicAppWidgetProvider {
public UltraSonicAppWidgetProvider4x3() {
super();
this.layoutId = R.layout.appwidget4x3;
}
private static UltraSonicAppWidgetProvider4x3 instance;
public static synchronized UltraSonicAppWidgetProvider4x3 getInstance() {
if (instance == null) {
instance = new UltraSonicAppWidgetProvider4x3();
}
return instance;
}
}

View File

@ -0,0 +1,38 @@
/*
This file is part of Subsonic.
Subsonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Subsonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 (C) Sindre Mehus
*/
package com.thejoshwa.ultrasonic.androidapp.provider;
import com.thejoshwa.ultrasonic.androidapp.R;
public class UltraSonicAppWidgetProvider4x4 extends UltraSonicAppWidgetProvider {
public UltraSonicAppWidgetProvider4x4() {
super();
this.layoutId = R.layout.appwidget4x4;
}
private static UltraSonicAppWidgetProvider4x4 instance;
public static synchronized UltraSonicAppWidgetProvider4x4 getInstance() {
if (instance == null) {
instance = new UltraSonicAppWidgetProvider4x4();
}
return instance;
}
}

View File

@ -26,6 +26,7 @@ import org.apache.http.HttpResponse;
import android.content.Context;
import android.graphics.Bitmap;
import com.thejoshwa.ultrasonic.androidapp.domain.Bookmark;
import com.thejoshwa.ultrasonic.androidapp.domain.ChatMessage;
import com.thejoshwa.ultrasonic.androidapp.domain.Genre;
import com.thejoshwa.ultrasonic.androidapp.domain.Indexes;
@ -372,4 +373,19 @@ public class CachedMusicService implements MusicService {
public void addChatMessage(String message, Context context, ProgressListener progressListener) throws Exception {
musicService.addChatMessage(message, context, progressListener);
}
@Override
public List<Bookmark> getBookmarks(Context context, ProgressListener progressListener) throws Exception {
return musicService.getBookmarks(context, progressListener);
}
@Override
public void deleteBookmark(String id, Context context, ProgressListener progressListener) throws Exception {
musicService.deleteBookmark(id, context, progressListener);
}
@Override
public void createBookmark(String id, Long position, Context context, ProgressListener progressListener) throws Exception {
musicService.createBookmark(id, position, context, progressListener);
}
}

View File

@ -70,6 +70,8 @@ public interface DownloadService {
void remove(DownloadFile downloadFile);
long getDownloadListDuration();
List<DownloadFile> getSongs();
List<DownloadFile> getDownloads();

View File

@ -45,9 +45,13 @@ import com.thejoshwa.ultrasonic.androidapp.activity.SubsonicTabActivity;
import com.thejoshwa.ultrasonic.androidapp.audiofx.EqualizerController;
import com.thejoshwa.ultrasonic.androidapp.audiofx.VisualizerController;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry;
import com.thejoshwa.ultrasonic.androidapp.domain.PlayerState;
import com.thejoshwa.ultrasonic.androidapp.domain.RepeatMode;
import com.thejoshwa.ultrasonic.androidapp.provider.UltraSonicAppWidgetProvider4x1;
import com.thejoshwa.ultrasonic.androidapp.provider.UltraSonicAppWidgetProvider4x2;
import com.thejoshwa.ultrasonic.androidapp.provider.UltraSonicAppWidgetProvider4x3;
import com.thejoshwa.ultrasonic.androidapp.provider.UltraSonicAppWidgetProvider4x4;
import com.thejoshwa.ultrasonic.androidapp.receiver.MediaButtonIntentReceiver;
import com.thejoshwa.ultrasonic.androidapp.util.CancellableTask;
import com.thejoshwa.ultrasonic.androidapp.util.Constants;
@ -552,7 +556,10 @@ public class DownloadServiceImpl extends Service implements DownloadService {
updateRemoteControl();
// Update widget
UltraSonicAppWidgetProvider4x1.getInstance().notifyChange(this, this, playerState == PlayerState.STARTED);
UltraSonicAppWidgetProvider4x1.getInstance().notifyChange(this, this, playerState == PlayerState.STARTED, false);
UltraSonicAppWidgetProvider4x2.getInstance().notifyChange(this, this, playerState == PlayerState.STARTED, true);
UltraSonicAppWidgetProvider4x3.getInstance().notifyChange(this, this, playerState == PlayerState.STARTED, false);
UltraSonicAppWidgetProvider4x4.getInstance().notifyChange(this, this, playerState == PlayerState.STARTED, false);
SubsonicTabActivity tabInstance = SubsonicTabActivity.getInstance();
if (currentPlaying != null) {
@ -623,6 +630,27 @@ public class DownloadServiceImpl extends Service implements DownloadService {
public List<DownloadFile> getSongs() {
return downloadList;
}
@Override
public long getDownloadListDuration() {
long totalDuration = 0;
for (DownloadFile downloadFile : downloadList) {
Entry entry = downloadFile.getSong();
if (!entry.isDirectory()) {
if (entry.getArtist() != null) {
Integer duration = entry.getDuration();
if (duration != null) {
totalDuration += duration;
}
}
}
}
return totalDuration;
}
@Override
public synchronized List<DownloadFile> getDownloads() {
@ -659,11 +687,13 @@ public class DownloadServiceImpl extends Service implements DownloadService {
setCurrentPlaying(null, false);
lifecycleSupport.serializeDownloadQueue();
} else {
if(nextPlayingTask != null) {
if (nextPlayingTask != null) {
nextPlayingTask.cancel();
nextPlayingTask = null;
}
setCurrentPlaying(index, start);
if (start) {
if (jukeboxEnabled) {
jukeboxService.skip(getCurrentPlayingIndex(), 0);
@ -672,6 +702,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
bufferAndPlay();
}
}
checkDownloads();
setNextPlaying();
}
@ -894,7 +925,10 @@ public class DownloadServiceImpl extends Service implements DownloadService {
updateRemoteControl();
// Update widget
UltraSonicAppWidgetProvider4x1.getInstance().notifyChange(this, this, this.playerState == PlayerState.STARTED);
UltraSonicAppWidgetProvider4x1.getInstance().notifyChange(this, this, this.playerState == PlayerState.STARTED, false);
UltraSonicAppWidgetProvider4x2.getInstance().notifyChange(this, this, this.playerState == PlayerState.STARTED, true);
UltraSonicAppWidgetProvider4x3.getInstance().notifyChange(this, this, this.playerState == PlayerState.STARTED, false);
UltraSonicAppWidgetProvider4x4.getInstance().notifyChange(this, this, this.playerState == PlayerState.STARTED, false);
SubsonicTabActivity tabInstance = SubsonicTabActivity.getInstance();
if (show) {

View File

@ -25,6 +25,7 @@ import org.apache.http.HttpResponse;
import android.content.Context;
import android.graphics.Bitmap;
import com.thejoshwa.ultrasonic.androidapp.domain.Bookmark;
import com.thejoshwa.ultrasonic.androidapp.domain.ChatMessage;
import com.thejoshwa.ultrasonic.androidapp.domain.Genre;
import com.thejoshwa.ultrasonic.androidapp.domain.Indexes;
@ -129,4 +130,10 @@ public interface MusicService {
List<ChatMessage> getChatMessages(Long since, Context context, ProgressListener progressListener) throws Exception;
void addChatMessage(String message, Context context, ProgressListener progressListener) throws Exception;
List<Bookmark> getBookmarks(Context context, ProgressListener progressListener) throws Exception;
void deleteBookmark(String id, Context context, ProgressListener progressListener) throws Exception;
void createBookmark(String id, Long position, Context context, ProgressListener progressListener) throws Exception;
}

View File

@ -20,9 +20,7 @@ package com.thejoshwa.ultrasonic.androidapp.service;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
@ -36,7 +34,6 @@ import java.util.concurrent.TimeUnit;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.util.Log;
import com.thejoshwa.ultrasonic.androidapp.domain.Artist;

View File

@ -70,6 +70,7 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import com.thejoshwa.ultrasonic.androidapp.R;
import com.thejoshwa.ultrasonic.androidapp.domain.Bookmark;
import com.thejoshwa.ultrasonic.androidapp.domain.ChatMessage;
import com.thejoshwa.ultrasonic.androidapp.domain.Genre;
import com.thejoshwa.ultrasonic.androidapp.domain.Indexes;
@ -85,6 +86,7 @@ import com.thejoshwa.ultrasonic.androidapp.domain.ServerInfo;
import com.thejoshwa.ultrasonic.androidapp.domain.Share;
import com.thejoshwa.ultrasonic.androidapp.domain.Version;
import com.thejoshwa.ultrasonic.androidapp.service.parser.AlbumListParser;
import com.thejoshwa.ultrasonic.androidapp.service.parser.BookmarkParser;
import com.thejoshwa.ultrasonic.androidapp.service.parser.ChatMessageParser;
import com.thejoshwa.ultrasonic.androidapp.service.parser.ErrorParser;
import com.thejoshwa.ultrasonic.androidapp.service.parser.GenreParser;
@ -1205,4 +1207,62 @@ public class RESTMusicService implements MusicService {
}
}
@Override
public List<Bookmark> getBookmarks(Context context, ProgressListener progressListener) throws Exception {
checkServerVersion(context, "1.9", "Bookmarks not supported.");
Reader reader = getReader(context, progressListener, "getBookmarks", null);
try {
return new BookmarkParser(context).parse(reader, progressListener);
} finally {
Util.close(reader);
}
}
@Override
public void createBookmark(String id, Long position, Context context, ProgressListener progressListener) throws Exception {
checkServerVersion(context, "1.9", "Bookmarks not supported.");
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setSoTimeout(params, SOCKET_READ_TIMEOUT_GET_RANDOM_SONGS);
List<String> parameterNames = new ArrayList<String>();
List<Object> parameterValues = new ArrayList<Object>();
parameterNames.add("id");
parameterValues.add(id);
parameterNames.add("position");
parameterValues.add(position);
Reader reader = getReader(context, progressListener, "createBookmark", params, parameterNames, parameterValues);
try {
new ErrorParser(context).parse(reader);
} finally {
Util.close(reader);
}
}
@Override
public void deleteBookmark(String id, Context context, ProgressListener progressListener) throws Exception {
checkServerVersion(context, "1.9", "Bookmarks not supported.");
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setSoTimeout(params, SOCKET_READ_TIMEOUT_GET_RANDOM_SONGS);
List<String> parameterNames = new ArrayList<String>();
List<Object> parameterValues = new ArrayList<Object>();
parameterNames.add("id");
parameterValues.add(id);
Reader reader = getReader(context, progressListener, "deleteBookmark", params, parameterNames, parameterValues);
try {
new ErrorParser(context).parse(reader);
} finally {
Util.close(reader);
}
}
}

View File

@ -0,0 +1,56 @@
package com.thejoshwa.ultrasonic.androidapp.service.parser;
import android.content.Context;
import com.thejoshwa.ultrasonic.androidapp.R;
import com.thejoshwa.ultrasonic.androidapp.domain.Bookmark;
import com.thejoshwa.ultrasonic.androidapp.util.ProgressListener;
import org.xmlpull.v1.XmlPullParser;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* @author Joshua Bahnsen
*/
public class BookmarkParser extends MusicDirectoryEntryParser {
public BookmarkParser(Context context) {
super(context);
}
public List<Bookmark> parse(Reader reader, ProgressListener progressListener) throws Exception {
updateProgress(progressListener, R.string.parser_reading);
init(reader);
List<Bookmark> dir = new ArrayList<Bookmark>();
Bookmark bookmark = null;
int eventType;
do {
eventType = nextParseEvent();
if (eventType == XmlPullParser.START_TAG) {
String name = getElementName();
if ("bookmark".equals(name)) {
bookmark = new Bookmark();
bookmark.setChanged(get("changed"));
bookmark.setCreated(get("created"));
bookmark.setComment(get("comment"));
bookmark.setPosition(getLong("position"));
bookmark.setUsername(get("username"));
} else if ("entry".equals(name)) {
bookmark.addEntry(parseEntry(null, false));
} else if ("error".equals(name)) {
handleError();
}
}
} while (eventType != XmlPullParser.END_DOCUMENT);
validate();
updateProgress(progressListener, R.string.parser_reading_done);
return dir;
}
}

View File

@ -74,8 +74,10 @@ import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* @author Sindre Mehus
@ -1243,4 +1245,24 @@ public class Util extends DownloadActivity {
public static boolean isNullOrWhiteSpace(String string) {
return string == null || string.isEmpty() || string.trim().isEmpty();
}
public static String formatTotalDuration(long totalDuration) {
long millis = totalDuration * 1000;
long hours = TimeUnit.MILLISECONDS.toHours(millis);
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(hours);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(hours * 60 + minutes);
if (hours >= 10) {
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
} else if (hours > 0) {
return String.format("%d:%02d:%02d", hours, minutes, seconds);
} else if (minutes >= 10) {
return String.format("%02d:%02d", minutes, seconds);
} else if (minutes > 0) {
return String.format("%d:%02d", minutes, seconds);
} else {
return String.format("0:%02d", seconds);
}
}
}

View File

@ -19,25 +19,25 @@
package com.thejoshwa.ultrasonic.androidapp.view;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import com.thejoshwa.ultrasonic.androidapp.activity.SubsonicTabActivity;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry;
import com.thejoshwa.ultrasonic.androidapp.util.ImageLoader;
/**
* @author Sindre Mehus
*/
public class EntryAdapter extends ArrayAdapter<MusicDirectory.Entry> {
public class EntryAdapter extends ArrayAdapter<Entry> {
private final SubsonicTabActivity activity;
private final ImageLoader imageLoader;
private final boolean checkable;
public EntryAdapter(SubsonicTabActivity activity, ImageLoader imageLoader, List<MusicDirectory.Entry> entries, boolean checkable) {
public EntryAdapter(SubsonicTabActivity activity, ImageLoader imageLoader, List<Entry> entries, boolean checkable) {
super(activity, android.R.layout.simple_list_item_1, entries);
this.activity = activity;
this.imageLoader = imageLoader;
this.checkable = checkable;
@ -45,7 +45,7 @@ public class EntryAdapter extends ArrayAdapter<MusicDirectory.Entry> {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MusicDirectory.Entry entry = getItem(position);
Entry entry = getItem(position);
if (entry.isDirectory()) {
AlbumView view;