<div dir="ltr">Thing is, MediaDatabase.java aggregates all db accesses.<div><br></div><div>I'd rather split different db helpers, so I'm not against this idea but for now all is done in this class.</div><div><br></div><div>Thus, I use already present playlistDelete, playlistExists, playlistInsertItem and playlistAdd mathods in this very class.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Mar 23, 2015 at 6:37 PM, Edward Wang <span dir="ltr"><<a href="mailto:edward.c.wang@compdigitec.com" target="_blank">edward.c.wang@compdigitec.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This shouldn't be using MediaDatabase directly; it should be using<br>
them through PlaylistDatabase.<br>
<br>
Regards,<br>
Edward<br>
<div class="HOEnZb"><div class="h5"><br>
On Mon, Mar 23, 2015 at 9:00 AM, Jean-Baptiste Kempf <<a href="mailto:jb@videolan.org">jb@videolan.org</a>> wrote:<br>
> OK.<br>
><br>
><br>
> On 23 Mar, Geoffrey Métais wrote :<br>
>> ---<br>
>>  .../res/drawable-hdpi/ic_save_grey600_24dp.png     | Bin 0 -> 344 bytes<br>
>>  .../res/drawable-hdpi/ic_save_white_24dp.png       | Bin 0 -> 341 bytes<br>
>>  .../res/drawable-mdpi/ic_save_grey600_24dp.png     | Bin 0 -> 259 bytes<br>
>>  .../res/drawable-mdpi/ic_save_white_24dp.png       | Bin 0 -> 257 bytes<br>
>>  .../res/drawable-xhdpi/ic_save_grey600_24dp.png    | Bin 0 -> 440 bytes<br>
>>  .../res/drawable-xhdpi/ic_save_white_24dp.png      | Bin 0 -> 359 bytes<br>
>>  .../res/drawable-xxhdpi/ic_save_grey600_24dp.png   | Bin 0 -> 493 bytes<br>
>>  .../res/drawable-xxhdpi/ic_save_white_24dp.png     | Bin 0 -> 489 bytes<br>
>>  .../res/drawable-xxxhdpi/ic_save_grey600_24dp.png  | Bin 0 -> 747 bytes<br>
>>  .../res/drawable-xxxhdpi/ic_save_white_24dp.png    | Bin 0 -> 747 bytes<br>
>>  vlc-android/res/layout/audio_player.xml            |  13 +++<br>
>>  vlc-android/res/layout/dialog_playlist.xml         |  37 +++++++<br>
>>  vlc-android/res/menu/audio_list_browser.xml        |   6 +-<br>
>>  vlc-android/res/values/attrs.xml                   |   1 +<br>
>>  vlc-android/res/values/strings.xml                 |   2 +<br>
>>  vlc-android/res/values/styles.xml                  |   2 +<br>
>>  vlc-android/src/org/videolan/vlc/MediaLibrary.java |  20 +++-<br>
>>  .../src/org/videolan/vlc/gui/CommonDialogs.java    |   7 ++<br>
>>  .../vlc/gui/audio/AudioBrowserFragment.java        |  62 ++++++++---<br>
>>  .../vlc/gui/audio/AudioBrowserListAdapter.java     |  35 ++++--<br>
>>  .../org/videolan/vlc/gui/audio/AudioPlayer.java    |  23 +++-<br>
>>  .../vlc/gui/audio/AudioPlaylistAdapter.java        |   4 +<br>
>>  .../org/videolan/vlc/gui/dialogs/SavePlaylist.java | 120 +++++++++++++++++++++<br>
>>  23 files changed, 303 insertions(+), 29 deletions(-)<br>
>>  create mode 100644 vlc-android/res/drawable-hdpi/ic_save_grey600_24dp.png<br>
>>  create mode 100644 vlc-android/res/drawable-hdpi/ic_save_white_24dp.png<br>
>>  create mode 100644 vlc-android/res/drawable-mdpi/ic_save_grey600_24dp.png<br>
>>  create mode 100644 vlc-android/res/drawable-mdpi/ic_save_white_24dp.png<br>
>>  create mode 100644 vlc-android/res/drawable-xhdpi/ic_save_grey600_24dp.png<br>
>>  create mode 100644 vlc-android/res/drawable-xhdpi/ic_save_white_24dp.png<br>
>>  create mode 100644 vlc-android/res/drawable-xxhdpi/ic_save_grey600_24dp.png<br>
>>  create mode 100644 vlc-android/res/drawable-xxhdpi/ic_save_white_24dp.png<br>
>>  create mode 100644 vlc-android/res/drawable-xxxhdpi/ic_save_grey600_24dp.png<br>
>>  create mode 100644 vlc-android/res/drawable-xxxhdpi/ic_save_white_24dp.png<br>
>>  create mode 100644 vlc-android/res/layout/dialog_playlist.xml<br>
>>  create mode 100644 vlc-android/src/org/videolan/vlc/gui/dialogs/SavePlaylist.java<br>
>><br>
>> diff --git a/vlc-android/res/drawable-hdpi/ic_save_grey600_24dp.png b/vlc-android/res/drawable-hdpi/ic_save_grey600_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..3ead270a02dbe60f07f722d4c58caadff02f361f<br>
>> GIT binary patch<br>
>> literal 344<br>
>> zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;Lb6AYF9SoB8UsT^3j@P1pisjL<br>
>> z28L1t28LG&3=CE?7#PG0=Ijcz0ZK3>dAqwX{BQ3+vmeOgEbxddW?<k3n!+v2$S`Y;<br>
>> z1W@pTr;B5V$MLt<e7Twp1Xv#&+1wc<P~95$NH=&BuiVnva*hFSa<lR$=q*{6S=ZCK<br>
>> zl>78;79M#uV<VvnxlZ30Q&${3AYS~*S#sTk#)oz*_|n!)i8Au=*mBQ#Yo3?x&euyn<br>
>> z?mX_b)Zx}U6OUC~%bfna4yd>)wqWZ|=h;rOEG)lFUi8(}#U=E#7p;{&9kIgLs=A}O<br>
>> zh0)Z$t%`Zq(YUgOhV4IA^=jOo;Vw~9w&hL(Tkq3=;2E5<i|r<!YI)Jc`12I&6|+s5<br>
>> m4^GTG6rh=AzTecdk}0CI%&h3-WD}s@7(8A5T-G@yGywqLjDB7K<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/drawable-hdpi/ic_save_white_24dp.png b/vlc-android/res/drawable-hdpi/ic_save_white_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..8c9e9cec086bc0b7d2e1a07185c395e13a5e1175<br>
>> GIT binary patch<br>
>> literal 341<br>
>> zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;Lb6AYF9SoB8UsT^3j@P1pisjL<br>
>> z28L1t28LG&3=CE?7#PG0=Ijcz0ZK3>dAqwX{BQ3+vmeOgEbxddW?<k3n!+v2$S`Y;<br>
>> z1W@p-r;B5V$MLt<yt$eU1lS%N+1wc<P~94*qI!G6;*!hC99?^T-}3&`Thf~;_bl<{<br>
>> zp>sJbhuaI)d^k>+d46LQ%{X`<{PUA`t{6e7JM3FKIN!BNFf90-x2ib!)x_O)QuDLd<br>
>> zgzzm{d#-tb)(q~C>zyBlMmHus=FjE&Dj*>7X@T{r@4vZ%twOTiMl5&Qd+}znlnRf><br>
>> zKM5(G7t?-i*6y`j5}xa{H$g7(!p)0C$|_4zgNqG>t<+>E9&5=s(ol1h^@`c1%m*jt<br>
>> jO<ovyCU2c-<WH8uP(x<v=yq42#~3_a{an^LB{Ts5)j@m(<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/drawable-mdpi/ic_save_grey600_24dp.png b/vlc-android/res/drawable-mdpi/ic_save_grey600_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..e72945d9e59915a028a9add8e4e488125fe40146<br>
>> GIT binary patch<br>
>> literal 259<br>
>> zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1g=CK)Uj~LMH3o);76yi2K%s^g<br>
>> z3=E|P3=FRl7#OT(FffQ0%-I!a1C(G&@^*J&_}|`tW<QX}S>O=~G=W<fgc%uT%>kKR<br>
>> z?djqeVsZNFWnZoa1p(Fs{RiidHd(c4?5O(PmmRAReREZ#S7DRDquew@c^+nehdtdd<br>
>> z*wl1ROg*C-5Wjz7@re^hh2>hfJ3cu6W7zUZeZxT~r-O<g8<xsf%1vM~;n!elW0z?><br>
>> wz|1Kp#l~1IyXNfjW7-nZy&V!&<+J88U*h=PQ0~0yFwhwcp00i_>zopr0I>;C<p2Nx<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/drawable-mdpi/ic_save_white_24dp.png b/vlc-android/res/drawable-mdpi/ic_save_white_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..bb26bc075dc41e7b30c7413a109940b7b302d945<br>
>> GIT binary patch<br>
>> literal 257<br>
>> zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1g=CK)Uj~LMH3o);76yi2K%s^g<br>
>> z3=E|P3=FRl7#OT(FffQ0%-I!a1C(G&@^*J&_}|`tW<QX}S>O=~G=W<fgc%uT%>kKR<br>
>> z>FMGaVsZNF<+Gd(20U#K^)9?hYU&Hr+0pbkOnk$<IDfW3n!O55KlLo1GzxSawCVoI<br>
>> zQ{wX^YY+3!kHR;lAC$FnUu06OI>5akq@Iaeu6wci%ZBOFtg;)Jv}6mIvSeSd@>osa<br>
>> u2)V+urqV#XU#fqBZjH;5pTCx0y~%J?&PdMil4K>&5e%NLelF{r5}E+b<x-0P<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/drawable-xhdpi/ic_save_grey600_24dp.png b/vlc-android/res/drawable-xhdpi/ic_save_grey600_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..fad94a7fc2a1d0439af37920e916886006a36ce2<br>
>> GIT binary patch<br>
>> literal 440<br>
>> zcmV;p0Z0CcP)<h;3K|Lk000e1NJLTq001xm001xu1ONa4{R=S+0000WV@Og>004R><br>
>> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN<br>
>> zS#tmY3ljhU3ljkVnw%H_00A&bL_t(o!|m5UOG053$MLUA85QpK1{_iZuh8tK5aC{P<br>
>> zIEX|@t8KM}IEXJmcL}1U7m!H}g-fe63nAg1bWyyIKG#3D<DfogyFa++^KiHv?&Hg|<br>
>> z+VUA-`+yL4Bsg5M%Pob)fDo?)JRQ`PP=PvUo@e1gsKD>i!<kE{K!21j*s?#LkOee^<br>
>> zG%!WT0~5q50OfrHcm)2v;S6Aa4F!6XsnG(CIVZ!eEYK!N%kdoMnIk!%ho!U!h|pw5<br>
>> z3V7gJlNQNI0Wm%_sYO!?@MCMzJ^t1Puz1&`ao(hWB3GKUL{<v0iSsp)MQO-=rtm|G<br>
>> zPo@16LD^MdQ=vLs6&GB(o_;3KWnW;`b)CP^D)7ju08l3_e*qa+hZDYMU7_wtaNv13<br>
>> iFWflWn`^8ABx(Sl*>NFF2Q9h)0000<MNUMnLSTYP9jbQ#<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/drawable-xhdpi/ic_save_white_24dp.png b/vlc-android/res/drawable-xhdpi/ic_save_white_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..aa0332092a831d643dc16620ff8741c3ec9ccc7c<br>
>> GIT binary patch<br>
>> literal 359<br>
>> zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}tg=CK)Uj~LMH3o);76yi2K%s^g<br>
>> z3=E|}g|8AA7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+;1OBOz`!jG!i)^F=12eq<br>
>> z?|Zs9hD02Gd)<+%$wB1U$D5tvoeEtBd*_RD9PZAL)y$G!=(z3I_O1(RGhY=4p8X!i<br>
>> z{Hd<_RCBt);b|Wa{AWz|(u(ta#nof^DK5x-!IQsB^c+~T7S--K`c>FUAnJhAibi%P<br>
>> z{*n$w1{(ziyIyvi533K%R25`o<TjEr-H>{zs_2v-=N#*|yls-=vKzMeEt<;LvBqHy<br>
>> zGn2MJo#2KIOr3lu);O$VmRiRD_W7y%B4uZ+-hO`-cyWW0nu?0z`<=D=1(SMq{j%IJ<br>
>> zk>RKS_X%5ex4+s~X8mfO9=zrDZ_{hcUAve*?KrXY(x;;hK(8`*y85}Sb4q9e0E^az<br>
>> A761SM<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/drawable-xxhdpi/ic_save_grey600_24dp.png b/vlc-android/res/drawable-xxhdpi/ic_save_grey600_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..6ecab92a7d4f604f08f24fcda65789486ca9722a<br>
>> GIT binary patch<br>
>> literal 493<br>
>> zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw6p}rHd>I(3)EF2VS{N990fib~<br>
>> zFff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9;eUJonf*W>XMsm#F#`j)FbFd;%$g&?<br>
>> zz`&U5>EalYaqsQT^I3-+1lT^rn6$p)7ODDhURy*^-u0roK<2~U-<P^*x>n^b5xFJs<br>
>> z!7^%z`rC!#ndzHn&pPwugW>kZR{5KE->?fSt_pW$5p)r7G-W*+@jz1EVp_=e=Z)(=<br>
>> zhDj||@cd`>w7AJLs5p>QeS(VV<WmleDl30RDxUD3G;8_k^E(gySBh*X@-$l@GfDJ><br>
>> z=O$)Lk7)`MQ@E{!fW}P~cLW>D64}fbk<`N{m9eOsGi=)e5%c;m{t1zda)p}5`ozq{<br>
>> z7F;>_Q!(|{g60j8%T2Ga>F%v8T+1z0?HC*zaGd+q%O<I~fHmA%*LbgdZThuqL8rLM<br>
>> zW!ANO7O=my|Ee(E_)@)<(Uv)L%*w?2UmtVKdVEr=E=7WC_SVh5J=s1NoqHr|&oK2D<br>
>> zIbN6^)o{1HG46_kr^E|CUK4)iScTAsd%W})Wgq#u?!ZnhGnRcv#eR476*cYD)-TBO<br>
>> g7XZ5b%j$iM)8ub3n}nB00b_x|)78&qol`;+0DIfJD*ylh<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/drawable-xxhdpi/ic_save_white_24dp.png b/vlc-android/res/drawable-xxhdpi/ic_save_white_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..6c87e1358816aaec842a21e215d2a70a3f0f2035<br>
>> GIT binary patch<br>
>> literal 489<br>
>> zcmV<F0T%v=P)<h;3K|Lk000e1NJLTq002k;002k`1ONa4|Kxkj0000WV@Og>004R><br>
>> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN<br>
>> zS#tmY3ljhU3ljkVnw%H_00Ci1L_t(&-tF1XO2a@92Jl?k6>MKX@X$Z6Af@;yE$tJO<br>
>> zqEC>QDlH<#s}T`21o|9G@zl?Qm!iAbP1>Ew;hVV)B>Z4EnSn`=G%FK=2qK7}hJp;1<br>
>> zc*ZBr73pc9YrNy!k=6&92%KP&t++(2Nb7+zK#ycAegS$UTk$wf`GjkcG(e>!9Z(5L<br>
>> z3*;o}fgB`Fkd>qh0zm{36g>zch#-OpB1ju_zzP%e&_Wx1OtIDl<+%Cx^azC(=n<FJ<br>
>> zv7>{n1}JxMeo2Ki=wLal;~YzaR^EAWBMX{%K{HuU&kGvJf?8gXkp;Dz2I_l3Ls`(&<br>
>> z3!2M<)?Uzq^q+cE%DI(q9R)g0P8U0k=DKx|x_HtWKMIU3hqbHlh6oem1~Uv`U@*iy<br>
>> z@G4gXeTxmS`!LX}7$^$^-HU-1VW11-BAho{M|7<?KLj{e)t10_c)>o>RnD+*%?sSy<br>
>> f6GRX}1pUb$u{XmgXM?Q~00000NkvXXu0mjfr`^33<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/drawable-xxxhdpi/ic_save_grey600_24dp.png b/vlc-android/res/drawable-xxxhdpi/ic_save_grey600_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..6c8f219e8664bdc64931df96c55ec25e78ad1e6b<br>
>> GIT binary patch<br>
>> literal 747<br>
>> zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcg6p}rHd>I(3)EF2VS{N990fib~<br>
>> zFff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9;eUJonf*W>XMsm#F#`j)FbFd;%$g$s<br>
>> zRFUlI;uunK>+S8+*};w?$3Nza<Z!+63STQG8oR~mg}j0j%f-Dn#Me!^(%QA+=y9*`<br>
>> zuZ<EPI{SM)W?!>+aNY91QSVBZURLta-ghAznvShiIdk?*ZqfUlpR7+mX_<4rAkC<F<br>
>> z=96P5%AT+YI504RiCdg6(x)iduE{7?eQt5P%0WH+=KLE8$CO+cttt;~bNQ{vrpQ%b<br>
>> ze(++yZvpeK%894e@Tlxy+%DmpnaHWMgYo^%Ik#>}I2168-QHKQt>ppRl~=~mF-dDp<br>
>> zS#~q{H>Ea+A2d7AoFIE)N`m}_mI<s5DvHt#98O^j=iZBh9iX7-a7(d)fr&!_Mx?MB<br>
>> zoL4d4^H6(3n_U;r#mS-$QzzRz@xQzJw8R6Z*Ke5BG(H~wc+cydL56g}OkrQ6bp==S<br>
>> z5}E}2owVL;<y>*;dCt80WYNtf(JVYhPiI;lVy<qeG&5aevo7MC%<Hv`$1H^>)J`<a<br>
>> zZkTJsd*a?v<?IGMJNA_F%?Z304z6GDW<Jx3)_<ElYvx^Myg7Z=yO~1lAvYyHIDb>D<br>
>> zNS=EjENO=4`7^b5w(k&+S}^^+T;=MSOHV&5+jVGyyW-_H8><&+7VCVPY<Ws%W9^bT<br>
>> z&lv8{Ia{oM?S*>HivLG6wf^KqRJKX>U;M3U8}{>r$oa~%;t9IZHxC{Vn&)wZX-W0R<br>
>> zts7_6XgrXO=3%^dNt$cNNk`{~Y#BaQk&2t2ehU^Zc54h@*kGdn;QH}WKFjB2EDGn7<br>
>> zw@GW%x82n_#^^B5XlaP_%458JyH9`rDIL}*<Z5<d;*Ud?$BpxLSKXISut7xkG=X|X<br>
>> YkM<{y8w5O<foYJz)78&qol`;+0GBp3)&Kwi<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/drawable-xxxhdpi/ic_save_white_24dp.png b/vlc-android/res/drawable-xxxhdpi/ic_save_white_24dp.png<br>
>> new file mode 100644<br>
>> index 0000000000000000000000000000000000000000..51998492cb52124ca6e6990966998dff0f116c0e<br>
>> GIT binary patch<br>
>> literal 747<br>
>> zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcg6p}rHd>I(3)EF2VS{N990fib~<br>
>> zFff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9;eUJonf*W>XMsm#F#`j)FbFd;%$g$s<br>
>> zRFUlI;uunK>+S8+*}{P$$3Nza<Z!+63STQG8oR~mg}j0j%f-Dn#Me!^(%SXoz;U2N<br>
>> zm&Aw8{$7vS*X$i!xBPF^yV9kXm3*}KUC4%}V{29JoZNdk<yp_4b4JBZ=bjh6J3IHG<br>
>> z-#WK#%IXaaOdJXz;)0)p{bG@qiLSG?Ezj?~#%#6o)W0Ka#$t+G7fuRqQ@zD+$Pw7E<br>
>> zo3pPjr%C$4`R<UkRE2}QJC0^}aeE6K<gGaW?8>!c3{BD-ZhULqtjc1(;GfgFqpH`U<br>
>> zoHuZPP>Eox5X@n=;kd@=%lVDbmm`wFMQ9Uahe8VLgFm&5ECLP;j6zIHWT7qrJ4eAG<br>
>> zjN!A7(P8O*OxZ6MpAfK(WDK!9>iq9Y?XDh1y$$E=5}JhUWv+)6wL9K!I6Wt0Qeo@j<br>
>> zGDhK^3X!11^}Y^M?b1L0kzPGx>20Ni37Y562+G}HKC^jc;?u&TMb9Ggc@2);Y<SZ><br>
>> zXA9enlb0Lb#M*3Pd-15)q0F578iVW~u2cUs8=_v=&pz^a4(Ew|S4z%Lu~=~GScCm0<br>
>> z{)5u5S+)rs_NhvH_jupYy%(7F)_gw^eO4#dZ2M)=HXE*)Y5jMlXBiz=+COvg8Nu7z<br>
>> zr(BkKFne?5yQ5NnTk>Do7tZ3^FC8{7@mSKAI<NjvJENn;ai3WuPKT8lY-mvz+Q{%y<br>
>> zt|oVlnmkv<aWUtH?O)oM@`^49JdkR4W@L@q_NT_>&WgYXp&ANjnSXpOoa=mUr!3=%<br>
>> z&okb#otmF$-d)HrVY!dyRku}z&5z%Gs*O9W6|m?8o0U+!#q)||x#91BGxxN^Vq4*W<br>
>> b&?Ehw%@P7vCQFq9(;$PVtDnm{r-UW|xDGfS<br>
>><br>
>> literal 0<br>
>> HcmV?d00001<br>
>><br>
>> diff --git a/vlc-android/res/layout/audio_player.xml b/vlc-android/res/layout/audio_player.xml<br>
>> index 836ca00..49b13b4 100644<br>
>> --- a/vlc-android/res/layout/audio_player.xml<br>
>> +++ b/vlc-android/res/layout/audio_player.xml<br>
>> @@ -33,6 +33,18 @@<br>
>>              android:layout_weight="1" /><br>
>><br>
>>          <ImageButton<br>
>> +            android:id="@+id/playlist_save"<br>
>> +            android:layout_width="40dp"<br>
>> +            android:layout_height="40dp"<br>
>> +            android:layout_gravity="center"<br>
>> +            android:layout_weight="0"<br>
>> +            android:background="#00000000"<br>
>> +            android:focusable="true"<br>
>> +            android:scaleType="fitXY"<br>
>> +            android:contentDescription="@string/playlist_save"<br>
>> +            android:src="?attr/ic_save" /><br>
>> +<br>
>> +        <ImageButton<br>
>>              android:id="@+id/playlist_switch"<br>
>>              android:layout_width="40dp"<br>
>>              android:layout_height="40dp"<br>
>> @@ -58,6 +70,7 @@<br>
>>              android:layout_width="wrap_content"<br>
>>              android:layout_height="wrap_content"<br>
>>              android:layout_gravity="center|left"<br>
>> +            android:layout_marginLeft="15dp"<br>
>>              android:layout_marginRight="15dp"<br>
>>              android:layout_weight="0"<br>
>>              android:clickable="true"<br>
>> diff --git a/vlc-android/res/layout/dialog_playlist.xml b/vlc-android/res/layout/dialog_playlist.xml<br>
>> new file mode 100644<br>
>> index 0000000..8783a11<br>
>> --- /dev/null<br>
>> +++ b/vlc-android/res/layout/dialog_playlist.xml<br>
>> @@ -0,0 +1,37 @@<br>
>> +<?xml version="1.0" encoding="utf-8"?><br>
>> +<RelativeLayout xmlns:android="<a href="http://schemas.android.com/apk/res/android" target="_blank">http://schemas.android.com/apk/res/android</a>"<br>
>> +    xmlns:tools="<a href="http://schemas.android.com/tools" target="_blank">http://schemas.android.com/tools</a>"<br>
>> +    android:layout_width="match_parent" android:layout_height="match_parent"><br>
>> +<br>
>> +    <EditText<br>
>> +        android:id="@+id/dialog_playlist_name"<br>
>> +        android:layout_width="match_parent"<br>
>> +        android:layout_height="wrap_content"<br>
>> +        android:layout_alignParentTop="true"<br>
>> +        android:hint="@string/playlist_name_hint"<br>
>> +        android:inputType="text"<br>
>> +        android:imeOptions="actionSend"/><br>
>> +    <FrameLayout<br>
>> +        android:id="@+id/dialog_list_container"<br>
>> +        android:layout_width="match_parent"<br>
>> +        android:layout_height="wrap_content"<br>
>> +        android:layout_below="@+id/dialog_playlist_name"><br>
>> +        <ListView<br>
>> +            android:id="@android:id/list"<br>
>> +            android:layout_width="match_parent"<br>
>> +            android:layout_height="wrap_content"/><br>
>> +        <TextView<br>
>> +            android:id="@android:id/empty"<br>
>> +            android:layout_width="match_parent"<br>
>> +            android:layout_height="wrap_content"<br>
>> +            android:text="@string/noplaylist"/><br>
>> +    </FrameLayout><br>
>> +    <Button<br>
>> +        android:id="@+id/dialog_playlist_save"<br>
>> +        android:layout_width="match_parent"<br>
>> +        android:layout_height="wrap_content"<br>
>> +        android:text="@string/playlist_save"<br>
>> +        android:layout_below="@id/dialog_list_container"<br>
>> +        tools:targetApi="11"<br>
>> +        style="?android:attr/borderlessButtonStyle"/><br>
>> +</RelativeLayout><br>
>> \ No newline at end of file<br>
>> diff --git a/vlc-android/res/menu/audio_list_browser.xml b/vlc-android/res/menu/audio_list_browser.xml<br>
>> index 6bda46a..f838a5a 100644<br>
>> --- a/vlc-android/res/menu/audio_list_browser.xml<br>
>> +++ b/vlc-android/res/menu/audio_list_browser.xml<br>
>> @@ -11,10 +11,10 @@<br>
>>           <item<br>
>>               android:id="@+id/audio_list_browser_play_all"<br>
>>               android:title="@string/play_all" /><br>
>> -        <item<br>
>> -           android:id="@+id/audio_list_browser_delete"<br>
>> -           android:title="@string/delete"/><br>
>>      </group><br>
>> +    <item<br>
>> +        android:id="@+id/audio_list_browser_delete"<br>
>> +        android:title="@string/delete"/><br>
>>      <group android:id="@+id/phone_only" ><br>
>>           <item<br>
>>               android:id="@+id/audio_list_browser_set_song"<br>
>> diff --git a/vlc-android/res/values/attrs.xml b/vlc-android/res/values/attrs.xml<br>
>> index 93cd223..13f36aa 100644<br>
>> --- a/vlc-android/res/values/attrs.xml<br>
>> +++ b/vlc-android/res/values/attrs.xml<br>
>> @@ -56,6 +56,7 @@<br>
>>      <attr name="ic_menu_preferences" format="reference" /><br>
>>      <attr name="ic_menu_cone" format="reference" /><br>
>>      <attr name="ic_move_media" format="reference" /><br>
>> +    <attr name="ic_save" format="reference" /><br>
>>      <attr name="ic_trash_small_normal" format="reference" /><br>
>>      <attr name="gridview_progressbar" format="reference" /><br>
>>      <attr name="toolbar_popup_style" format="reference" /><br>
>> diff --git a/vlc-android/res/values/strings.xml b/vlc-android/res/values/strings.xml<br>
>> index 1675b38..9ef83ec 100644<br>
>> --- a/vlc-android/res/values/strings.xml<br>
>> +++ b/vlc-android/res/values/strings.xml<br>
>> @@ -322,6 +322,8 @@<br>
>>      <string name="search_hint">Search media</string><br>
>>      <string name="directory_show_medialib">Show in MediaLib</string><br>
>>      <string name="directory_hide_medialib">Hide from MediaLib</string><br>
>> +    <string name="playlist_save">Save Playlist</string><br>
>> +    <string name="playlist_name_hint">playlist name</string><br>
>><br>
>>      <string-array name="hardware_acceleration_list"><br>
>>          <item>@string/automatic</item><br>
>> diff --git a/vlc-android/res/values/styles.xml b/vlc-android/res/values/styles.xml<br>
>> index 09c767b..3913689 100644<br>
>> --- a/vlc-android/res/values/styles.xml<br>
>> +++ b/vlc-android/res/values/styles.xml<br>
>> @@ -67,6 +67,7 @@<br>
>>          <item name="ic_menu_preferences">@drawable/ic_menu_preferences</item><br>
>>          <item name="ic_menu_cone">@drawable/ic_menu_cone</item><br>
>>          <item name="ic_move_media">@drawable/ic_move_media</item><br>
>> +        <item name="ic_save">@drawable/ic_save_grey600_24dp</item><br>
>>          <item name="ic_trash_small_normal">@drawable/ic_trash_small_normal</item><br>
>>          <item name="gridview_progressbar">@drawable/gridview_progressbar_w</item><br>
>>          <item name="advanced_options_style">@style/Theme.VLC.AdvancedOptionsLight</item><br>
>> @@ -138,6 +139,7 @@<br>
>>          <item name="ic_menu_preferences">@drawable/ic_menu_preferences_w</item><br>
>>          <item name="ic_menu_cone">@drawable/ic_menu_cone_w</item><br>
>>          <item name="ic_move_media">@drawable/ic_move_media_w</item><br>
>> +        <item name="ic_save">@drawable/ic_save_white_24dp</item><br>
>>          <item name="ic_trash_small_normal">@drawable/ic_trash_small_normal_w</item><br>
>>          <item name="gridview_progressbar">@drawable/gridview_progressbar</item><br>
>>          <item name="advanced_options_style">@style/Theme.VLC.AdvancedOptionsBlack</item><br>
>> diff --git a/vlc-android/src/org/videolan/vlc/MediaLibrary.java b/vlc-android/src/org/videolan/vlc/MediaLibrary.java<br>
>> index 6d3ce3b..7ee3bb7 100644<br>
>> --- a/vlc-android/src/org/videolan/vlc/MediaLibrary.java<br>
>> +++ b/vlc-android/src/org/videolan/vlc/MediaLibrary.java<br>
>> @@ -39,11 +39,13 @@ import org.videolan.libvlc.LibVlcException;<br>
>>  import org.videolan.libvlc.Media;<br>
>>  import org.videolan.libvlc.util.Extensions;<br>
>>  import org.videolan.vlc.gui.MainActivity;<br>
>> +import org.videolan.vlc.gui.audio.AudioBrowserListAdapter;<br>
>>  import org.videolan.vlc.util.AndroidDevices;<br>
>>  import org.videolan.vlc.util.Util;<br>
>>  import org.videolan.vlc.util.VLCInstance;<br>
>>  import org.videolan.vlc.util.WeakHandler;<br>
>><br>
>> +import android.app.LauncherActivity;<br>
>>  import android.content.Context;<br>
>>  import android.os.Environment;<br>
>>  import android.os.Handler;<br>
>> @@ -172,7 +174,7 @@ public class MediaLibrary {<br>
>>          return audioItems;<br>
>>      }<br>
>><br>
>> -    public ArrayList<MediaWrapper> getPlaylistItems() {<br>
>> +    public ArrayList<MediaWrapper> getPlaylistFilesItems() {<br>
>>          ArrayList<MediaWrapper> playlistItems = new ArrayList<MediaWrapper>();<br>
>>          mItemListLock.readLock().lock();<br>
>>          for (int i = 0; i < mItemList.size(); i++) {<br>
>> @@ -185,6 +187,22 @@ public class MediaLibrary {<br>
>>          return playlistItems;<br>
>>      }<br>
>><br>
>> +    public ArrayList<AudioBrowserListAdapter.ListItem> getPlaylistDbItems() {<br>
>> +        ArrayList<AudioBrowserListAdapter.ListItem> playlistItems = new ArrayList<AudioBrowserListAdapter.ListItem>();<br>
>> +        AudioBrowserListAdapter.ListItem playList;<br>
>> +        MediaDatabase db = MediaDatabase.getInstance();<br>
>> +        String[] items, playlistNames = db.getPlaylists();<br>
>> +        for (String playlistName : playlistNames){<br>
>> +            items = db.playlistGetItems(playlistName);<br>
>> +            playList = new AudioBrowserListAdapter.ListItem(playlistName, null, null, false);<br>
>> +            for (String track : items){<br>
>> +                playList.mMediaList.add(new MediaWrapper(track));<br>
>> +            }<br>
>> +            playlistItems.add(playList);<br>
>> +        }<br>
>> +        return playlistItems;<br>
>> +    }<br>
>> +<br>
>>      public ArrayList<MediaWrapper> getMediaItems() {<br>
>>          return mItemList;<br>
>>      }<br>
>> diff --git a/vlc-android/src/org/videolan/vlc/gui/CommonDialogs.java b/vlc-android/src/org/videolan/vlc/gui/CommonDialogs.java<br>
>> index c8d93c3..6f725e4 100644<br>
>> --- a/vlc-android/src/org/videolan/vlc/gui/CommonDialogs.java<br>
>> +++ b/vlc-android/src/org/videolan/vlc/gui/CommonDialogs.java<br>
>> @@ -60,6 +60,13 @@ public class CommonDialogs {<br>
>>                                            final String addressMedia,<br>
>>                                            final VLCRunnable runnable) {<br>
>>          final String name = Uri.decode(addressMedia.substring(addressMedia.lastIndexOf('/')+1));<br>
>> +        return  deleteMedia(context, addressMedia, name, runnable);<br>
>> +    }<br>
>> +<br>
>> +    public static AlertDialog deleteMedia(final Context context,<br>
>> +                                          final String addressMedia,<br>
>> +                                          final String name,<br>
>> +                                          final VLCRunnable runnable) {<br>
>><br>
>>          return confirmDialog(<br>
>>                  context,<br>
>> diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java<br>
>> index ab1bb53..663c62e 100644<br>
>> --- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java<br>
>> +++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java<br>
>> @@ -56,6 +56,7 @@ import org.videolan.libvlc.LibVLC;<br>
>>  import org.videolan.libvlc.LibVlcUtil;<br>
>>  import org.videolan.libvlc.Media;<br>
>>  import org.videolan.libvlc.util.MediaBrowser;<br>
>> +import org.videolan.vlc.MediaDatabase;<br>
>>  import org.videolan.vlc.MediaLibrary;<br>
>>  import org.videolan.vlc.MediaWrapper;<br>
>>  import org.videolan.vlc.R;<br>
>> @@ -66,6 +67,7 @@ import org.videolan.vlc.gui.MainActivity;<br>
>>  import org.videolan.vlc.gui.SecondaryActivity;<br>
>>  import org.videolan.vlc.util.AndroidDevices;<br>
>>  import org.videolan.vlc.util.Util;<br>
>> +import org.videolan.vlc.util.VLCInstance;<br>
>>  import org.videolan.vlc.util.VLCRunnable;<br>
>>  import org.videolan.vlc.util.WeakHandler;<br>
>>  import org.videolan.vlc.widget.SwipeRefreshLayout;<br>
>> @@ -352,8 +354,14 @@ public class AudioBrowserFragment extends BrowserFragment implements SwipeRefres<br>
>>      OnItemClickListener playlistListener = new OnItemClickListener() {<br>
>>          @Override<br>
>>          public void onItemClick(AdapterView<?> av, View v, int p, long id) {<br>
>> -            String mediaLocation = mPlaylistAdapter.getItem(p).mMediaList.get(0).getLocation();<br>
>> -            mAudioController.load(mediaLocation, true);<br>
>> +            ArrayList<MediaWrapper> mediaList = mPlaylistAdapter.getItem(p).mMediaList;<br>
>> +            if (mediaList.size() == 1) {<br>
>> +                String mediaLocation = mediaList.get(0).getLocation();<br>
>> +                mAudioController.load(mediaLocation, true);<br>
>> +            } else {<br>
>> +                ArrayList<String> mediaLocations = mPlaylistAdapter.getLocations(p);<br>
>> +                mAudioController.load(mediaLocations, 0, true);<br>
>> +            }<br>
>>          }<br>
>>      };<br>
>><br>
>> @@ -374,6 +382,8 @@ public class AudioBrowserFragment extends BrowserFragment implements SwipeRefres<br>
>>              MenuItem play = menu.findItem(R.id.audio_list_browser_play);<br>
>>              play.setVisible(true);<br>
>>          }<br>
>> +        if (pos != MODE_SONG && pos != MODE_PLAYLIST)<br>
>> +            menu.findItem(R.id.audio_list_browser_delete).setVisible(false);<br>
>>          if (!AndroidDevices.isPhone())<br>
>>              menu.setGroupVisible(R.id.phone_only, false);<br>
>>      }<br>
>> @@ -394,6 +404,7 @@ public class AudioBrowserFragment extends BrowserFragment implements SwipeRefres<br>
>><br>
>>          int startPosition;<br>
>>          int groupPosition;<br>
>> +        int mode = mViewPager.getCurrentItem();<br>
>>          List<String> medias;<br>
>>          int id = item.getItemId();<br>
>><br>
>> @@ -408,17 +419,29 @@ public class AudioBrowserFragment extends BrowserFragment implements SwipeRefres<br>
>>              groupPosition = position;<br>
>><br>
>>          if (id == R.id.audio_list_browser_delete) {<br>
>> +            AudioBrowserListAdapter adapter;<br>
>> +            if (mode == MODE_SONG){<br>
>> +                adapter = mSongsAdapter;<br>
>> +            } else if (mode == MODE_PLAYLIST) {<br>
>> +                adapter = mPlaylistAdapter;<br>
>> +            } else<br>
>> +                return false;<br>
>>              AlertDialog alertDialog = CommonDialogs.deleteMedia(<br>
>>                      getActivity(),<br>
>> -                    mSongsAdapter.getLocations(groupPosition).get(0),<br>
>> -                    new VLCRunnable(mSongsAdapter.getItem(groupPosition)) {<br>
>> +                    adapter.getLocations(groupPosition).get(0),<br>
>> +                    adapter.getItem(groupPosition).mTitle,<br>
>> +                    new VLCRunnable(adapter.getItem(groupPosition)) {<br>
>>                          @Override<br>
>>                          public void run(Object o) {<br>
>>                              AudioBrowserListAdapter.ListItem listItem = (AudioBrowserListAdapter.ListItem)o;<br>
>> -                            MediaWrapper media = listItem.mMediaList.get(0);<br>
>> -                            mMediaLibrary.getMediaItems().remove(media);<br>
>> -                            if (mAudioController.getMediaLocations().contains(media.getLocation()))<br>
>> -                                mAudioController.removeLocation(media.getLocation());<br>
>> +                            if (!MediaDatabase.getInstance().playlistExists(listItem.mTitle)) {<br>
>> +                                MediaWrapper media = listItem.mMediaList.get(0);<br>
>> +                                mMediaLibrary.getMediaItems().remove(media);<br>
>> +                                if (mAudioController.getMediaLocations().contains(media.getLocation()))<br>
>> +                                    mAudioController.removeLocation(media.getLocation());<br>
>> +                            } else {<br>
>> +                                MediaDatabase.getInstance().playlistDelete(listItem.mTitle);<br>
>> +                            }<br>
>>                              updateLists();<br>
>>                          }<br>
>>                      });<br>
>> @@ -437,7 +460,7 @@ public class AudioBrowserFragment extends BrowserFragment implements SwipeRefres<br>
>>          }<br>
>>          else {<br>
>>              startPosition = 0;<br>
>> -            switch (mViewPager.getCurrentItem())<br>
>> +            switch (mode)<br>
>>              {<br>
>>                  case MODE_SONG:<br>
>>                      medias = mSongsAdapter.getLocations(groupPosition);<br>
>> @@ -451,11 +474,15 @@ public class AudioBrowserFragment extends BrowserFragment implements SwipeRefres<br>
>>                  case MODE_GENRE:<br>
>>                      medias = mGenresAdapter.getLocations(groupPosition);<br>
>>                      break;<br>
>> -                case MODE_PLAYLIST: //For playlist, we browse tracks with mediabrowser, and add them in callbacks onMediaAdded and onBrowseEnd<br>
>> -                    if (mMediaBrowser == null)<br>
>> -                        mMediaBrowser = new MediaBrowser(LibVLC.getInstance(), this);<br>
>> -                    mMediaBrowser.browse(mPlaylistAdapter.getMedia(groupPosition).get(0).getLocation());<br>
>> -                    return true;<br>
>> +                case MODE_PLAYLIST: //For file playlist, we browse tracks with mediabrowser, and add them in callbacks onMediaAdded and onBrowseEnd<br>
>> +                    medias = mPlaylistAdapter.getLocations(groupPosition);<br>
>> +                    if (medias.size() <2) {<br>
>> +                        if (mMediaBrowser == null)<br>
>> +                            mMediaBrowser = new MediaBrowser(VLCInstance.get(), this);<br>
>> +                        mMediaBrowser.browse(mPlaylistAdapter.getMedia(groupPosition).get(0).getLocation());<br>
>> +                        return true;<br>
>> +                    }<br>
>> +                    break;<br>
>>                  default:<br>
>>                      return true;<br>
>>              }<br>
>> @@ -678,8 +705,13 @@ public class AudioBrowserFragment extends BrowserFragment implements SwipeRefres<br>
>>      Runnable updatePlaylists = new Runnable() {<br>
>>          @Override<br>
>>          public void run() {<br>
>> -            ArrayList<MediaWrapper> playlists = mMediaLibrary.getPlaylistItems();<br>
>> +            //File playlists<br>
>> +            ArrayList<MediaWrapper> playlists = mMediaLibrary.getPlaylistFilesItems();<br>
>>              mPlaylistAdapter.addAll(playlists, AudioBrowserListAdapter.TYPE_PLAYLISTS);<br>
>> +            //DB playlists<br>
>> +            ArrayList<AudioBrowserListAdapter.ListItem> dbPlaylists = mMediaLibrary.getPlaylistDbItems();<br>
>> +            mPlaylistAdapter.addAll(dbPlaylists);<br>
>> +<br>
>>              mAdaptersToNotify.add(mPlaylistAdapter);<br>
>>              if (mReadyToDisplay && !mDisplaying)<br>
>>                  display();<br>
>> diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java<br>
>> index 33bc575..7f35b86 100644<br>
>> --- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java<br>
>> +++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java<br>
>> @@ -22,6 +22,7 @@ package org.videolan.vlc.gui.audio;<br>
>><br>
>>  import java.util.ArrayList;<br>
>>  import java.util.Collections;<br>
>> +import java.util.Comparator;<br>
>>  import java.util.HashMap;<br>
>>  import java.util.LinkedList;<br>
>>  import java.util.List;<br>
>> @@ -83,7 +84,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex<br>
>>      private ContextPopupMenuListener mContextPopupMenuListener;<br>
>><br>
>>      // An item of the list: a media or a separator.<br>
>> -    static class ListItem {<br>
>> +    public static class ListItem {<br>
>>          final public String mTitle;<br>
>>          final public String mSubTitle;<br>
>>          final public ArrayList<MediaWrapper> mMediaList;<br>
>> @@ -112,6 +113,14 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex<br>
>>          mAlignMode = Integer.valueOf(preferences.getString("audio_title_alignment", "0"));<br>
>>      }<br>
>><br>
>> +    public void addAll(List<ListItem> items) {<br>
>> +        for (ListItem item : items) {<br>
>> +            mMediaItemMap.put(item.mTitle, item);<br>
>> +            mItems.add(item);<br>
>> +        }<br>
>> +        Collections.sort(mItems, mItemsComparator);<br>
>> +    }<br>
>> +<br>
>>      public void add(String title, String subTitle, MediaWrapper media) {<br>
>>          if(title == null) return;<br>
>>          title = title.trim();<br>
>> @@ -338,13 +347,16 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex<br>
>>          holder.footer.setVisibility(isMediaItemAboveASeparator(position) ? View.GONE : View.VISIBLE);<br>
>><br>
>>          final int pos = position;<br>
>> -        holder.more.setOnClickListener(new OnClickListener() {<br>
>> -            @Override<br>
>> -            public void onClick(View v) {<br>
>> -                if (mContextPopupMenuListener != null)<br>
>> -                    mContextPopupMenuListener.onPopupMenu(v, pos);<br>
>> -            }<br>
>> -        });<br>
>> +        if (mContextPopupMenuListener != null)<br>
>> +            holder.more.setOnClickListener(new OnClickListener() {<br>
>> +                @Override<br>
>> +                public void onClick(View v) {<br>
>> +                    if (mContextPopupMenuListener != null)<br>
>> +                        mContextPopupMenuListener.onPopupMenu(v, pos);<br>
>> +                }<br>
>> +            });<br>
>> +        else<br>
>> +            holder.more.setVisibility(View.GONE);<br>
>><br>
>>          return v;<br>
>>      }<br>
>> @@ -544,4 +556,11 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex<br>
>>          if (observer != null)<br>
>>              super.unregisterDataSetObserver(observer);<br>
>>      }<br>
>> +<br>
>> +    private Comparator<ListItem> mItemsComparator = new Comparator<ListItem>() {<br>
>> +        @Override<br>
>> +        public int compare(ListItem lhs, ListItem rhs) {<br>
>> +            return String.CASE_INSENSITIVE_ORDER.compare(lhs.mTitle, rhs.mTitle);<br>
>> +        }<br>
>> +    };<br>
>>  }<br>
>> diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java<br>
>> index d3655a6..34bb0df 100644<br>
>> --- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java<br>
>> +++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java<br>
>> @@ -34,6 +34,7 @@ import org.videolan.vlc.gui.MainActivity;<br>
>>  import org.videolan.vlc.gui.CommonDialogs.MenuType;<br>
>>  import org.videolan.vlc.gui.audio.widget.CoverMediaSwitcher;<br>
>>  import org.videolan.vlc.gui.audio.widget.HeaderMediaSwitcher;<br>
>> +import org.videolan.vlc.gui.dialogs.SavePlaylist;<br>
>>  import org.videolan.vlc.interfaces.IAudioPlayer;<br>
>>  import org.videolan.vlc.util.Strings;<br>
>>  import org.videolan.vlc.util.Util;<br>
>> @@ -42,9 +43,11 @@ import org.videolan.vlc.widget.AudioMediaSwitcher.AudioMediaSwitcherListener;<br>
>>  import android.media.AudioManager;<br>
>>  import android.os.Bundle;<br>
>>  import android.os.Handler;<br>
>> +import android.os.Parcelable;<br>
>>  import android.preference.PreferenceManager;<br>
>>  import android.support.v4.app.Fragment;<br>
>>  import android.support.v4.app.FragmentActivity;<br>
>> +import android.support.v4.app.FragmentManager;<br>
>>  import android.util.Log;<br>
>>  import android.view.ContextMenu;<br>
>>  import android.view.LayoutInflater;<br>
>> @@ -65,7 +68,7 @@ import android.widget.ViewSwitcher;<br>
>>  import android.widget.AdapterView.OnItemClickListener;<br>
>>  import android.widget.SeekBar.OnSeekBarChangeListener;<br>
>><br>
>> -public class AudioPlayer extends Fragment implements IAudioPlayer {<br>
>> +public class AudioPlayer extends Fragment implements IAudioPlayer, View.OnClickListener {<br>
>>      public static final String TAG = "VLC/AudioPlayer";<br>
>><br>
>>      private ProgressBar mProgressBar;<br>
>> @@ -81,7 +84,7 @@ public class AudioPlayer extends Fragment implements IAudioPlayer {<br>
>>      private ImageButton mShuffle;<br>
>>      private ImageButton mRepeat;<br>
>>      private ImageButton mAdvFunc;<br>
>> -    private ImageButton mPlaylistSwitch;<br>
>> +    private ImageButton mPlaylistSwitch, mPlaylistSave;<br>
>>      private SeekBar mTimeline;<br>
>>      private AudioPlaylistView mSongsList;<br>
>><br>
>> @@ -134,6 +137,7 @@ public class AudioPlayer extends Fragment implements IAudioPlayer {<br>
>>          mRepeat = (ImageButton) v.findViewById(R.id.repeat);<br>
>>          mAdvFunc = (ImageButton) v.findViewById(R.id.adv_function);<br>
>>          mPlaylistSwitch = (ImageButton) v.findViewById(R.id.playlist_switch);<br>
>> +        mPlaylistSave = (ImageButton) v.findViewById(R.id.playlist_save);<br>
>>          mTimeline = (SeekBar) v.findViewById(R.id.timeline);<br>
>><br>
>>          mSongsList = (AudioPlaylistView) v.findViewById(R.id.songs_list);<br>
>> @@ -212,6 +216,7 @@ public class AudioPlayer extends Fragment implements IAudioPlayer {<br>
>>                  showAdvancedOptions(v);<br>
>>              }<br>
>>          });<br>
>> +        mPlaylistSave.setOnClickListener(this);<br>
>>          mPlaylistSwitch.setOnClickListener(new View.OnClickListener() {<br>
>>              @Override<br>
>>              public void onClick(View v) {<br>
>> @@ -577,6 +582,20 @@ public class AudioPlayer extends Fragment implements IAudioPlayer {<br>
>>          public void onTouchClick() {}<br>
>>      };<br>
>><br>
>> +    @Override<br>
>> +    public void onClick(View v) {<br>
>> +        switch (v.getId()){<br>
>> +            case R.id.playlist_save:<br>
>> +                FragmentManager fm = getActivity().getSupportFragmentManager();<br>
>> +                SavePlaylist savePlaylistDialog = new SavePlaylist();<br>
>> +                Bundle args = new Bundle();<br>
>> +                args.putParcelableArrayList(SavePlaylist.KEY_TRACKS, mSongsListAdapter.getItems());<br>
>> +                savePlaylistDialog.setArguments(args);<br>
>> +                savePlaylistDialog.show(fm, "fragment_save_playlist");<br>
>> +                break;<br>
>> +        }<br>
>> +    }<br>
>> +<br>
>>      class LongSeekListener implements View.OnTouchListener {<br>
>>          boolean forward;<br>
>>          int normal, pressed;<br>
>> diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlaylistAdapter.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlaylistAdapter.java<br>
>> index e0f5fd6..5ebfb50 100644<br>
>> --- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlaylistAdapter.java<br>
>> +++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlaylistAdapter.java<br>
>> @@ -174,6 +174,10 @@ public class AudioPlaylistAdapter extends ArrayAdapter<MediaWrapper> {<br>
>>          return locations;<br>
>>      }<br>
>><br>
>> +    public ArrayList<MediaWrapper> getItems(){<br>
>> +        return mMediaList;<br>
>> +    }<br>
>> +<br>
>>      static class ViewHolder {<br>
>>          int position;<br>
>>          TextView title;<br>
>> diff --git a/vlc-android/src/org/videolan/vlc/gui/dialogs/SavePlaylist.java b/vlc-android/src/org/videolan/vlc/gui/dialogs/SavePlaylist.java<br>
>> new file mode 100644<br>
>> index 0000000..73f39bf<br>
>> --- /dev/null<br>
>> +++ b/vlc-android/src/org/videolan/vlc/gui/dialogs/SavePlaylist.java<br>
>> @@ -0,0 +1,120 @@<br>
>> +/*<br>
>> + * *************************************************************************<br>
>> + *  SavePlaylist.java<br>
>> + * **************************************************************************<br>
>> + *  Copyright © 2015 VLC authors and VideoLAN<br>
>> + *<br>
>> + *  This program is free software; you can redistribute it and/or modify<br>
>> + *  it under the terms of the GNU General Public License as published by<br>
>> + *  the Free Software Foundation; either version 2 of the License, or<br>
>> + *  (at your option) any later version.<br>
>> + *<br>
>> + *  This program is distributed in the hope that it will be useful,<br>
>> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
>> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
>> + *  GNU General Public License for more details.<br>
>> + *<br>
>> + *  You should have received a copy of the GNU General Public License<br>
>> + *  along with this program; if not, write to the Free Software<br>
>> + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.<br>
>> + *  ***************************************************************************<br>
>> + */<br>
>> +<br>
>> +package org.videolan.vlc.gui.dialogs;<br>
>> +<br>
>> +import android.os.Bundle;<br>
>> +import android.support.annotation.Nullable;<br>
>> +import android.support.v4.app.DialogFragment;<br>
>> +import android.view.KeyEvent;<br>
>> +import android.view.LayoutInflater;<br>
>> +import android.view.View;<br>
>> +import android.view.ViewGroup;<br>
>> +import android.view.Window;<br>
>> +import android.view.inputmethod.EditorInfo;<br>
>> +import android.widget.AdapterView;<br>
>> +import android.widget.Button;<br>
>> +import android.widget.EditText;<br>
>> +import android.widget.ListView;<br>
>> +import android.widget.TextView;<br>
>> +<br>
>> +import org.videolan.vlc.MediaDatabase;<br>
>> +import org.videolan.vlc.MediaLibrary;<br>
>> +import org.videolan.vlc.MediaWrapper;<br>
>> +import org.videolan.vlc.R;<br>
>> +import org.videolan.vlc.gui.audio.AudioBrowserListAdapter;<br>
>> +<br>
>> +import java.util.ArrayList;<br>
>> +<br>
>> +public class SavePlaylist extends DialogFragment implements AdapterView.OnItemClickListener, View.OnClickListener, TextView.OnEditorActionListener {<br>
>> +<br>
>> +    public final static String TAG = "VLC/SavePlaylist";<br>
>> +<br>
>> +    public static final String KEY_TRACKS = "PLAYLIST_TRACKS";<br>
>> +<br>
>> +    EditText mEditText;<br>
>> +    ListView mListView;<br>
>> +    TextView mEmptyView;<br>
>> +    Button mSaveButton;<br>
>> +    AudioBrowserListAdapter mAdapter;<br>
>> +    ArrayList<MediaWrapper> mTracks;<br>
>> +<br>
>> +    public SavePlaylist(){}<br>
>> +<br>
>> +    @Override<br>
>> +    public void onCreate(Bundle savedInstanceState) {<br>
>> +        super.onCreate(savedInstanceState);<br>
>> +        mAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITHOUT_COVER);<br>
>> +        mAdapter.addAll(MediaLibrary.getInstance().getPlaylistDbItems());<br>
>> +        mTracks = getArguments().getParcelableArrayList(KEY_TRACKS);<br>
>> +    }<br>
>> +<br>
>> +    @Override<br>
>> +    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {<br>
>> +        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);<br>
>> +        View view = inflater.inflate(R.layout.dialog_playlist, container);<br>
>> +<br>
>> +        mListView = (ListView) view.findViewById(android.R.id.list);<br>
>> +        mSaveButton = (Button) view.findViewById(R.id.dialog_playlist_save);<br>
>> +        mEmptyView = (TextView) view.findViewById(android.R.id.empty);<br>
>> +        mEditText = (EditText) view.findViewById(R.id.dialog_playlist_name);<br>
>> +        mListView.setOnItemClickListener(this);<br>
>> +        mSaveButton.setOnClickListener(this);<br>
>> +<br>
>> +        mEditText.setOnEditorActionListener(this);<br>
>> +        mListView.setEmptyView(mEmptyView);<br>
>> +        mListView.setAdapter(mAdapter);<br>
>> +        return view;<br>
>> +    }<br>
>> +<br>
>> +    @Override<br>
>> +    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {<br>
>> +        mEditText.setText(mAdapter.getItem(position).mTitle);<br>
>> +    }<br>
>> +<br>
>> +    @Override<br>
>> +    public void onClick(View v) {<br>
>> +        savePlaylist();<br>
>> +    }<br>
>> +<br>
>> +    @Override<br>
>> +    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {<br>
>> +        if (actionId == EditorInfo.IME_ACTION_SEND) {<br>
>> +            savePlaylist();<br>
>> +        }<br>
>> +        return false;<br>
>> +    }<br>
>> +<br>
>> +    private void savePlaylist() {<br>
>> +        final MediaDatabase db = MediaDatabase.getInstance();<br>
>> +        final String name = mEditText.getText().toString().trim();<br>
>> +        if (db.playlistExists(name))<br>
>> +            db.playlistDelete(name);<br>
>> +        db.playlistAdd(name);<br>
>> +        MediaWrapper mw;<br>
>> +        for (int i = 0 ; i< mTracks.size() ; ++i){<br>
>> +            mw = mTracks.get(i);<br>
>> +            db.playlistInsertItem(name, i, mw.getLocation());<br>
>> +        }<br>
>> +        dismiss();<br>
>> +    }<br>
>> +}<br>
>> --<br>
>> 2.1.0<br>
>><br>
>><br>
>> _______________________________________________<br>
>> Android mailing list<br>
>> <a href="mailto:Android@videolan.org">Android@videolan.org</a><br>
>> <a href="https://mailman.videolan.org/listinfo/android" target="_blank">https://mailman.videolan.org/listinfo/android</a><br>
><br>
> --<br>
> With my kindest regards,<br>
><br>
> --<br>
> Jean-Baptiste Kempf<br>
> <a href="http://www.jbkempf.com/" target="_blank">http://www.jbkempf.com/</a> - +33 672 704 734<br>
> Sent from my Electronic Device<br>
><br>
> _______________________________________________<br>
> Android mailing list<br>
> <a href="mailto:Android@videolan.org">Android@videolan.org</a><br>
> <a href="https://mailman.videolan.org/listinfo/android" target="_blank">https://mailman.videolan.org/listinfo/android</a><br>
><br>
<br>
_______________________________________________<br>
Android mailing list<br>
<a href="mailto:Android@videolan.org">Android@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/android" target="_blank">https://mailman.videolan.org/listinfo/android</a><br>
</div></div></blockquote></div><br></div>