From 569ed22476c24644c86de528c65be2d7f86fed84 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Fri, 2 Dec 2011 13:49:44 -0800 Subject: [PATCH 1/8] docs: add Android U class for "Improving Performance of Layouts" Change-Id: I3981223b7219179e1d68f982491effe655734c1e --- .../images/training/hierarchy-layouttimes.png | Bin 0 -> 19536 bytes .../training/hierarchy-linearlayout.png | Bin 0 -> 48561 bytes .../training/hierarchy-relativelayout.png | Bin 0 -> 46020 bytes docs/html/images/training/import-progress.png | Bin 0 -> 9199 bytes docs/html/images/training/layout-listitem.png | Bin 0 -> 3554 bytes docs/html/training/improving-layouts/index.jd | 58 +++++++ .../improving-layouts/loading-ondemand.jd | 86 ++++++++++ .../improving-layouts/optimizing-layout.jd | 156 ++++++++++++++++++ .../improving-layouts/reusing-layouts.jd | 150 +++++++++++++++++ .../improving-layouts/smooth-scrolling.jd | 124 ++++++++++++++ 10 files changed, 574 insertions(+) create mode 100644 docs/html/images/training/hierarchy-layouttimes.png create mode 100644 docs/html/images/training/hierarchy-linearlayout.png create mode 100644 docs/html/images/training/hierarchy-relativelayout.png create mode 100644 docs/html/images/training/import-progress.png create mode 100644 docs/html/images/training/layout-listitem.png create mode 100644 docs/html/training/improving-layouts/index.jd create mode 100644 docs/html/training/improving-layouts/loading-ondemand.jd create mode 100644 docs/html/training/improving-layouts/optimizing-layout.jd create mode 100644 docs/html/training/improving-layouts/reusing-layouts.jd create mode 100644 docs/html/training/improving-layouts/smooth-scrolling.jd diff --git a/docs/html/images/training/hierarchy-layouttimes.png b/docs/html/images/training/hierarchy-layouttimes.png new file mode 100644 index 0000000000000000000000000000000000000000..423f1af5150bd0adcd88b4551a65994c64d3473e GIT binary patch literal 19536 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 EA6!2R1poj5 literal 0 HcmV?d00001 diff --git a/docs/html/images/training/hierarchy-relativelayout.png b/docs/html/images/training/hierarchy-relativelayout.png new file mode 100644 index 0000000000000000000000000000000000000000..b3408e58b9d8e5a433351c3415c9f7541807195c GIT binary patch literal 46020 zcmaHSW02@f*X`K0b;h=B+qP|6XKdTHea5zJ+nzhm`~APE>ZGbGolZKtcdwPK^;ce2 z3>FFt3IG5ARzh4@5dZ+t>$gxt0R7ffuLL9i9;lr~)SZPKO$?kZ>}&~?Eo@8xl+9fT z7#RtaOza65=@}RZ=vg_L89ABg325klH;1y1vEO#!&Jr>r;2V%=pwt{yb+AmoRgm`L z8cqNJ&`AFk!1*oT&)-TAGXWU^0D$^f=uZPs0Dwkp31Im}za=b>|F#}$rW5RxQG z{{ORkf-nEJ{XOeRQYaJ#lh@l_K|#TfjhHa@`Esq%=|r~rsdF^bJ}Wqe9gEp~woIWA z3?9#VRfaN|l9u-R294x!E(VvYqoV_6q3Q(pNQPZjPz(X{I6<~_VtiaQ2FKzx zrd?52fy1C5q!{5i4HDb0(NZ1??#rc8o3s|htC@fAxWE*|mre?)u61*7|BMc2%x;nfvhB-|QLgrr@8Oaju z{6TGP8Ujidi{=JCmNv&OO6J#8ZOG$@`R|OFJG`q_1gIt2c`IwXfTzlOCCXTrBL;Xc z9=}uf;6I@kZk8|CIvZY|fduAuR$H&b7vOL>^zLQ{!_l2?H@roqpW9@Tf{?gqoabeQ zF}&~Qf8UlH0k>=W*kC*FW0&^0J2=HRPENA=K8YOw%v_pa(KXf#{ULq%_0hfZs9mhG7N;m zW-?x_W~{#xk_Z*`tBX--?kP6nyPjK(k@4H3jBy)MB_M4)RioC@R5!KW-{(QPtGuZs zLX>#F=JB^=_HeuctH%TU0hv`l?x)5>CVE5xro2o_DZvjl%YLeYmfK4~Q3Y zm9@3GJs(f+4n|UwlB6?v3tMVpLK5SW)GZ^>U7C1_)*w$qW(rUcnC0WIMJN>q`yKH) zV`0gG=-(va$pUsQm$B5zq+7Ke=^A6G$_gn9W$9y$t`Sg+x*m7oWdNh4KT~j^G&;;_ z5dY-#tZ7E|M+!+w{!Wf|s}tFU)F8&}|GNnV1%uV-^jf7-8Th$qt*`rH>_2GA2-7G{ zJMM~-QHPF~D#_)y-8o?`hLO6e8f`c_yUY3H@(%`)mo)uwZWBf=AE#@*m#c_>L@`{IbhIL|)ZA8# zz&rx^o#zC+udEFD&$XJgI6r+;@4+&IHhq{yj|9M~+eLxcdF7hU^*2CDi=I$qcPRp( zwc|kz{4m4Clj(l13F|~a-7mzaoNE6^KcudCJHFqC*?(9A+83=^x~Wy16iu36)n z&&M;W_bKFvMA;5`;+V3kYRUL`i8PPv?Cw9%e6b!hpx!Rv^93yt#`?!QbiemaVLz_BO6?8lG?y>bGCMVkV%SreZIP(q0Ywr(}qs&f1I9g{t zlb*<)7tW0C@`;1?&w1E|v+HY5tB>b@LEvt#u4q*ZcldH;JLaQtgvUPWDmq;5qX
A44Vx+lTQN(fq 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 literal 0 HcmV?d00001 diff --git a/docs/html/images/training/import-progress.png b/docs/html/images/training/import-progress.png new file mode 100644 index 0000000000000000000000000000000000000000..bbb689b51d4e4af239f6b2c6804826060c4c7430 GIT binary patch literal 9199 zcmVOz@Z0f2-7z;ux~O9+4z06=<WDR*FRcSTFz- zW=q650N5=6FiBTtNC2?60Km==3$g$R3;-}uh=nNt1bYBr$Ri_o0EC$U6h`t_Jn<{8 z5a%iY0C<_QJh>z}MS)ugEpZ1|S1ukX&Pf+56gFW3VVXcL!g-k)GJ!M?;PcD?0HBc- z5#WRK{dmp}uFlRjj{U%*%WZ25jX z{P*?XzTzZ-GF^d31o+^>%=Ap99M6&ogks$0k4OBs3;+Bb(;~!4V!2o<6ys46agIcq zjPo+3B8fthDa9qy|77CdEc*jK-!%ZRYCZvbku9iQV*~a}ClFY4z~c7+0P?$U!PF=S z1Au6Q;m>#f??3%Vpd|o+W=WE9003S@Bra6Svp>fO002awfhw>;8}z{#EWidF!3EsG z3;bXU&9EIRU@z1_9W=mEXoiz;4lcq~xDGvV5BgyU zp1~-*fe8db$Osc*A=-!mVv1NJjtCc-h4>-CNCXm#Bp}I%6j35eku^v$Qi@a{RY)E3 zJ#qp$hg?Rwkvqr$GJ^buyhkyVfwECO)C{#lxu`c9ghrwZ&}4KmnvWKso6vH!8a<3Q zq36)6Xb;+tK10Vaz~~qUGsJ8#F2=(`u{bOVlVi)VBCHIn#u~6ztOL7=^<&SmcLWlF zMZgI*1b0FpVIDz9SWH+>*hr`#93(Um+6gxa1B6k+CnA%mOSC4s5&6UzVlpv@SV$}* z))J2sFA#f(L&P^E5{W}HC%KRUNwK6<(h|}}(r!{C=`5+6G)NjFlgZj-YqAG9lq?`C z$c5yc>d>VnA`E_*3F2Qp##d8RZb=H01_mm@+|Cqnc9PsG(F5HIG_C zt)aG3uTh7n6Et<2In9F>NlT@zqLtGcXcuVrX|L#Xx)I%#9!{6gSJKPrN9dR61N3(c z4Tcqi$B1Vr8Jidf7-t!G7_XR2rWwr)$3XQ?}=hpK0&Z&W{| zep&sA23f;Q!%st`QJ}G3cbou<7-yIK2z4nfCCCtN2-XOGSWo##{8Q{ATurxr~;I`ytDs%xbip}RzP zziy}Qn4Z2~fSycmr`~zJ=lUFdFa1>gZThG6M+{g7vkW8#+YHVaJjFF}Z#*3@$J_By zLtVo_L#1JrVVB{Ak-5=4qt!-@Mh}c>#$4kh<88)m#-k<%CLtzEP3leVno>={htGUuD;o7bD)w_sX$S}eAxwzy?UvgBH(S?;#HZiQMoS*2K2 zT3xe7t(~nU*1N5{rxB;QPLocnp4Ml>u<^FZwyC!nu;thW+pe~4wtZn|Vi#w(#jeBd zlf9FDx_yoPJqHbk*$%56S{;6Kv~mM9!g3B(KJ}#RZ#@)!hR|78Dq|Iq-afF%KE1Brn_fm;Im z_u$xr8UFki1L{Ox>G0o)(&RAZ;=|I=wN2l97;cLaHH6leTB-XXa*h%dBOEvi`+x zi?=Txl?TadvyiL>SuF~-LZ;|cS}4~l2eM~nS7yJ>iOM;atDY;(?aZ^v+mJV$@1Ote z62cPUlD4IWOIIx&SmwQ~YB{nzae3Pc;}r!fhE@iwJh+OsDs9zItL;~pu715HdQEGA zUct(O!LkCy1<%NCg+}G`0PgpNm-?d@-hMgNe6^V+j6x$b<6@S<$+<4_1hi}Ti zncS4LsjI}fWY1>OX6feMEuLErma3QLmkw?X+1j)X-&VBk_4Y;EFPF_I+q;9dL%E~B zJh;4Nr^(LEJ3myURP{Rblsw%57T)g973R8o)DE9*xN#~;4_o$q%o z4K@u`jhx2fBXC4{U8Qn{*%*B$Ge=nny$HAYq{=vy|sI0 z_vss+H_qMky?OB#|JK!>IX&II^LlUh#rO5!7TtbwC;iULyV-Xq?ybB}ykGP{?LpZ? z-G|jbTmIbG@7#ZCz;~eY(cDM(28Dyq{*m>M4?_iynUBkc4TkHUI6gT!;y-fz>HMcd z&t%Ugo)`Y2{>!cx7B7DI)$7;J(U{Spm-3gBzioV_{p!H$8L!*M!p0uH$#^p{Ui4P` z?ZJ24cOCDe-w#jZd?0@)|7iKK^;6KN`;!@ylm7$*nDhK&GcDTy000JJOGiWi00000 z0Qp0^e*gdg32;bRa{vGf6951U69E94oEQKA00(qQO+^RW3;e~M20gNJs6}1FVcb+&4EKYu!a^yFbyZ@4^ohO zsQy#cUER~8f3}q_Xuj#5{#*6cufBiv)v=L5e214L54i4@Y@}~Ulg3xsd?oQX|LoWF?XhY7Ed=qhqd;;U@p1g;M z-oRo&iOW7D-%}Qs2%JTA!TtACpJ{<4p9z3=Twu$Nc#B2Xy$Z!f3FW~GN&_X?mVaI| zbm4fX-4B{kcnp|G11{2;BB*p`!Gk9o5@`6_UKLIni z#?JMa{|pfWX;>icL4je}$pDlHzz%`$5WrjsfSkiCMPL}RxZ!=1|uv_k;rC><{Y{zw-NCBf*fe9M6_DC<#2 zdjY?F=D)P!_3SNjSVABnF$q>uLQ4m_5PDb)Y}NCacBZch$sthIt0xC;rhuS-o^g-` z?+LsfQ6w#feS#+kYlV+^MxP-AAMkw|oc5FdSb|Adk_I=8GgC;FkFuEDw=&K*F&U{; z5znNoo^O(vMaV9bC!}NcgNm)9RdLrH4lB^V-E};e2`OKw_ zyuq^wMs=7HqPdq4|FwU8JE0Yfx-6w3_gM`~y^cw>IcNzEk}4M|Dh@$PgCc43OWHGc z307&~mE(Nua(}=1&qGRQ6tTfsq_++CRbS2`9w8!-=;HnBO$?9JQG2^q7*_YObpG1G z`dS;eZp?;!-HZQB{pi@}iI?jHQ5jM-JUgNk8hI^dCDe+*5u$ZuX8HGvRAUKVp_Ncp zgz%)pB)EqLG{NZYs~JkwY40I2BtOxIy>OQ!p%YCRXw@z#|BLKzmgXq20Ok7NT+8Ehj^A0sEeUo5Fu4n%YJtbu|D#ZuzRGtoNDg za~S$@0e%Ns1TggDI%YnYPns)oD$;L20f($@{M~6RKI`I(zkP?+QwO!vL&$qAVgMw) zwa|cxbDzcx%|_4=z8%oF2L>bdNxE4{`>Sm;!!b_z|H#QZE4Nkjn5#eRlvT2rO^MTl(l8+-?`|-)^BXQb{-=cI9nj z8PZUObmS#8dI?UWXGXELy``zW?Ugn<&o(sBw3r1@1c)9})M=&yr5AU#}65G>zu!db>Z0z-YLsqg#ky~`6H*~f6OC;sc_dsMq0lg@@n z@(aA9((YP&yQajc7UdvI?d>76fDtQ!qnjAXm_Kq<}l`dHcq^j{6NU|Ohq3X>O`tyiIK6Fbv4s*aCOOeP-@4`|*Yp+o06KMTz9;0uSvG$~m*_#U>Kc=dAr-ka9RWyDvg{jL^DF0mc>hJYgFywu9T0_U*-IBnU*VbP)Qs@;68zpZ?6!Z8_^}ZFDxInz_2N3;EB=I_j7=*L5-)uK>> ztruHp-e{uzsEw{0i$WL33~OjVX=CH*2Ec&D2a6aS97L^FL+w-z)e}`L{b@7PVL49wP5Qi5*0*}Qk*K_u-C0G+o6f3 znz{3XqiX`m*mp+3&QV=cEDn#5A@vt!-yI=AfOak(^KG@3AO6L{U`F(&YP=OF>hSKC z6EQ&71redU?dpuk^v>ySIU#cr5nR_r<;^Nio*D+{9Gz#K@agTfHaO>~yF2bby!o4Iy*rgVW8j|7ag)6669$WwwJpeT}C) zo3vyCB&Yzt1GfF`x_((C5awp)Kmz0j5a6+EwP0IB=LB;E2Y*xzNA&86L6k}**nhLJ z{&W>YgyGY}u)nqe03)YIBtZRdCmFQN0E=;WfRmhN9py{L;5sIc>PE+y*#rbpCYJEhY#9?zYGxEkNf25EIB01czf_P zNmq~`w*~X8pm@hDRN;duOqZ~CGq0V6BW}FW4IRuANoGP!WzuAh;5y};;3bDgMlt&H zNpvz{H`rT=Cx4VD16Ddl?Y`wfW;i0O`w`22M8J-{UNStJGU9fJLDj{_zn1CyB4 zjEP@PWBS)k0KoE72Q$AI3mqS+Ga?K$P-ohY7SVWj7S+G6!T#Dt^V(F1sB^z+VD7gq zEPS*809fBx_a!kyCn8S<{Q_9{{Q~B1&SQ0@jeEaaz}$_dV))b@2qYv^drD{z3Bdiv z!T7~-j9(lNfpPZw92Wk#lqpf|Y9>c7$)}epomXv6fj2UwD+)Wk37l9?TV3ovSy_1U z@*jHGBKzXM9yZKSQ%Tbql#WM!YAFhN$P0N~@|9Nr)d7|;QAwJlpQd5?`^SckAJSZ4 zg~=CJHqm~(gnKvUk`kl;yNi+^eecf&=7H@+N@}FdJ`8!mpefm{T)RrMCnS#%eG0{0c%>_~7R|*tDsa z-^1=5DrwSlHj{(B{+!^d-yQCdefczn2@Ivx~ADU|J<)zabXmE<@M>ZgZM zeY*<#OB)#V0iQqm99vsk7#tkL#Kj3rU!8ubgU&&I zdzjjv_5WT$yRvvEIOtA6CJ7{AP}V<6OL`j5Z>Jse^W*txiBw5V?)zglkIP1K&TsQZ z6V2Z=vHEBcoO3u^4%#bgnEhZbk}$(-DSg!GSMp&g^(6erGNIZtxDm|qHu|duf-i&r zj5Z?EaYK7(eCgZ!Ldj3%M{#)Zf3E9d{Ngw&Cn~sg`xZ*aOK`Vcba%Q(dTa{4zx{HI zBABqaEvOV@LQ|A}8q@Zo0h3LfIhiy#i=+WM%N}M5-{CnO5uAC(bDZrhOuc(0A(h2b zm|MN@o-QdHY=D_6e3mUOO;XALRn5i-b12SX@E?$p z9M|wn@Q_BsjjpkNj>Y1mk zFQIhDJsH{)0FvP>@cIExrpd`Y>nL?)xV&+AEa&}A<_Z`bDld`$`WcwGL9L^l*B+P@ zM1-Y>OK9F`CRd2_OXYY4^Ec;F`C$c{&o^=9@)gua>L`_DV$kM|CKi_#QTbs7t@|xZ zU!6w#aT@?Ie|sJq&o0eqp2is14^E2aR7eFnD4R_0xx(223Oc zpnmX!ab_N&`)yEFouHJF87Y+d^b}gKVkxYo%`BM_)=K>L6e%uR5yY@INN~2WkbA;c z9w$f|2*v@F$D5Kz@1iknDfm z|LcNw2-P1|Q=e6Rs~Y|u9vTiO9n=P-l-GEtfpWPF5`_BMIzIf558-^{z_Kjd|MWf< zmljd2M)z=cTrB*40gL~=2tL439jIdb;y9KcE@OCTSgWgp{(gOl&;0xs+5po==ybh1 z!?uzle)gJ>&U-gh$Vwkl$VO00Dbz!Z{SlmB=>iesGl#x4wE>Jm_`Yykiko_>s?6y>NC z`*{azkCxDVVMo%WP?vP%N;E zqIq>of}c9diGmjNXwXWvipgKSkJ`wnE(Ho5NcvmB9*He{6-G)8M^4c;RoATFk=Og)uaL)5P5MIe-Js z*A9kH4`cGuq&)t?9Qc3?87mKzHCv&2-vhJ%1!bTFYp`rKcmxaA@7S<-34B0G&0GL) zV8?;Fc{>iQI3)*-v)xo3ypS9UdekTcQ2mFK@OB)44BL(a2%l1n3ir^!4*)7}R91pFhjH>a%=SpXtZoCP z0gf_@Y`KZKz+No*X{bw6IwgNG?t&Kd$kBcb@w>_1QeI050lewNYzk~$11uQ*YO>|Q4+af#6zInc5gU{I6I%*|@S6IQZ z)oqy#rp)6Kpt{0XiX$X7%Yx@mxhiNuk0On0Kz*!K7G^8?)+@koAB$F>8S96~am-YX zjhw)DS^%yg34sS-^?`YWoco{m3rV4%N0zRA`eEN4bbT9Ge!MD8Nd@p7yfny?5}+o$ zW!eDa3mj#|)0imv;R6LN=uxEo+N1IY{}yZd?rQztOfY2n;;<_Cc_}tomY9MSSBKSz z>Td!3K&K=~GD;8+SkQtVG1?ahD$^Dd(qG{a*%yb0mXhpSPhT}MZEC3kl9~!!Q&Qp^ zQyBTj*FQ7A*Lx4A3stG0N7o7R>Ak-571}Pays~PxQx#?3!(gl*SQtB3N41oFddD@S z#3urR%_YDU`bIuYRf7vvsh~%ghW*0d;`^qpSPA&>3yI$C5-fS(DfC!%AjhIe4EQQV z0=)8Is;K><9NE(TbV2t(rbS68#UY@rN`OT#J~nvE#bR7nR7SqoA259bh2oLq8!<> z_V9k+nWmi`VBwQim>8gt1P>7W0NA#Tsml$yET*A^?Lsnpjv5BTvNAQRbmK({LqBqj z>ahh29=w7U^vF;EuwQH@(yZs9oXPAfwOTFAs!}*Z_TTvdNR@W|**ZAW7p};g3H(^? zcs>cRex`)G|LU4;fQ7fPpht}Y*j!lzsk!qEnTAdMg-A*p3!k)5J5?(H>i|pVSqD>> z8z^zeDQ+3XRu)DNT8rf!;a1mN+&^8yx)|NcJer|a6f97WlCv7g&mU0cPy|N1ZlKW&-Z9(KWC?U`dkgE_pwN*NyF znE53~?M(@Uv!Bg?Kw(@>K@0ji)9#iHdt)8sZtbaqQY_?x3iWqiOJHiS7{GaQ=~|<- zsKx;@4ieNq0KQ5U&}&ic-R_ggdz53>-)!`WjxkuXR}WV5dp5&Fp35HmzIR^SUf% z?IV>Ec5$CwFK@~Ac>R9Yf5CqR{~aLzZI~p$krS_{1en@bX-wS@6PoUy_gw5#qxO&} z`EI}jeJ%>VR}lNYl!E_W3;x^iv%y#_0zmd!F;^BdiIn{`uib8$QlyV$$WU+c+@B+R zo#fmSjp_S^{vFiIK#Y9rIrn^S4%Z zEQnK$0CJq7&wR1uDS-meEtxYx@43)nVfhADr88{>h4+V-n|EY6={&!Hu^sfU{rJuD5< z2?pA1baZkXhbh|E*W+`q{&Y4D2WAICnzVIr?l~OV>_Cxk_g*lBhHSixDhnJcFPK{$ zc?45L?>>Bf!Tad(67^wiqsC zo^JY%cU-SY4H^PuTF~t!d?V&Rp$q=x<1+}LHdT076GD(hc z5@!O3Ml0g5uA|1PiY>}Boj>ng8Q7rmBgh~C9WCKLajpF9i6Um5bF<0@igR3d6%aYz1q=o z)9k_&Uv=70O_@ygs_2rpgtuRJrDu4vtk~bff83n6mG6Hk=DoVKh~AYG^N=oZ0UOrr z*z)bn(M@$1Iw_Co_%>h9chS?zG5(b$!kUA01u>94J3l4s_&FAX4g{lD?7Gaz@#!Dp zhDFlVX$5eKkHXdGBIwt8I`2x;${xhM>M+UlE_{zS$gkl|!AqlyY7y3E{PfzrQEQE} zCL{k$s|l&)`?+BrT`}SAzmhbpS+SAT!Sgl_s->X)9ZNDFOi&{yKs6N9zb}wlsrX)1 zR2s?kL#UJ-rkXc(_!W%2B&{Z_feDV)Gz~0!$5B}u?kk7!TMex2UwM-IWpCxW1I3Q#)0g(QVVM>tMIS76 zRFGcSel3v45TdBiMr0Q1>gV@O!{2rtGVTo24K>*Xro1WlpA9YldL1*DFPo zNeojPNE5{whAJ-T%4aFX=agP-Wz2*YhTUCUq5rCpTM)}pP9GHRDx{ClzVXy9_1vMP zQLjNWuYZ5u=PLe5uq#mYfW}qIT;>jBHcioKZQxcUqshb384t&tSxJ-b6O#em#t_DWcL(^NvHq2QR#iic z8zrNrgOY>G&h`~7W?tp5XK5`^!R|mmBHJNE42DC1Jv_M5Mwaq%>@xu<@4sQoZX94dsE&MVdxaCt<6RfP2 zz)h}*9WFFE9Z?`!ff|_7)B`;t=xU2H`b1%=1F`U6-ej|oDLG<%pL24gul@izBbR3h z_)3V#;zJNLOYTCVyGX&MLWMvIn_pj;Dpo=#(G`j2$Y5zl+pXA)kUUlS@y#L?&@6L0 zg#QB&S%&ppain^fxl8b~l$+X2fyKDRZ|B2hy=)7I>a$F4AlmXU?s!)=f(02a`=n1j zt)jqs#p_QQC72RTT?db1wZlyy&~y?W;q#Ao+s}?%B7#Z^Y|69~gAEi&;I5K`Al}dN zJ=SGH3dEg}_PI1jD9X+4JFj%&pY74;t~{bUSdR@w4xG{o=WKyyB--YwmzonF6ex$H zZW?}~o3tz#rb%l`eoG?wuDrx&5J;DPJ!Xjk4tQDQ$l24%3`!La_7EP^D{hK71A$yHOT_EU1< zU@Ov~yI|R)v?N;L(DZA93WTHpliz_>v?Mk0d!K;^;s)9pN@PcX9eHHgypnlv;&2TJ{A;zbdoU00GZy6cTtTZxeP)VUipciBb_DNm z!fn|zywBL@KbXhLiLqKJ>aIx-v0f8M3ZD)+2H3>^P2?1g{z=lxiYXtf($Hy z4zNsYfe>j024*-yiasxLInLHQ4GWTX;Bd}6-QAWoTYL(Fqz$8qx+6Ui8YrkU$v)5` zPlcaN<32l%z(%$^zrkD2S=4t}ZBZ(j%}GfUR2>0+M1`C#s(eaQEM@dXhxGYA=x{7@ zwyDs&*>i{ePjcmh?4A|sIGL3Ls z!O!X1uM4Qk=||eug7H5Qa`$HiBxZ}aO@cnl8|%3wDeORhTw?Eyv;LT+Tp@fVF|sB! zy20MY0>6d~%U88?c_{_XWU~skad
  • CDxwhOv~FPgpoH~nRbTjUr~wT04R<>Qf^nqqu{6L@n?FKoEXp;qp>pI@(vzt7Fm zne@FBYVq2on40%h{tTxZpO&OV40bF2{-NWsP;@X&=r7{-8OU)lSY9cm|7y`?bavJ5 z&gWE3|K@Jk+x7Pyt6t3Oy;GjQM?1CqV&lvcrIOmiOrM5>Pd+7I*ACC! zt6Ti}rtvs?ePXMAJ&HLH^Q+mfYVzc}{#xC##ly*<^?Kum^%KsJ)sg!7=EssFN6#Ni zoh-^2M+8qcv`fa!biU6C4`*upFxuaqf6Hv;zSOYO{qj~Aqp7ImcxgB0aQ+sv`yBJ| z=S}~{?KhKk`xA}*3&xStc`|>^#T;r_^mZACY|hNSz*Rd~-J#exGC>MCLy`2(ZhOb$ znz5})q4yO|jC}{j{$Ted>uxCtrDxZ&f~ap7C;xcQ+)^s8TUshAIrv#sT)$Vl>|ee4 zgE1L4n7Y<*loJsXIeE-y@Y!cS$B@scqUr*Z7L{sv(jsupXm{ttGbd`VCg%6Sc4H{% zkWIXR$ubc=KmKr10KCns7iy#_`NBCM^x5z5-F6jF;37SIvsWRzPC294` z<6lG8C$^_dBlb_`rr#QEb^MSV-yiZwb-HV;p>ovv^3Ov?_oc@BQ~iU{T17|M4<{p- zlQH{J%!B52=0-c;d+mE;6^nUKwf!f`?k*2Jy);p|O1yHhKKN))LO*1!Zl$cdbtzI# zipjJFuMd|oQ@&muRcCUNvaTjOk8JzkwS_Scm7O>f|yV2;lu+>4ssx*YV>JiPg) z5>zvLv$bbBLZ46A3qtj6da=g_&o zH%;c;gIITs>zof^Qwg1HMS4|n zZ}v8pV!@FAt@D2s{{!{w-Pm40Ek_f_|7#*Gi5mc5GT8vvhxynG5-t~>4gp|ke$}iP H=^p + + + + + +

    Layouts are a key part of Android applications that directly affect the user experience. If +implemented poorly, your layout can lead to a memory hungry application with slow UIs. The Android +SDK includes tools to help you identify problems in your layout performance, which when combined the +lessons here, you will be able to implement smooth scrolling interfaces with a minimum memory +footprint.

    + + + +

    Lessons

    + +
    +
    Optimizing Layout Hierarchies
    +
    In the same way a complex web page can slow down load time, your layout hierarchy +if too complex can also cause performance problems. This lesson shows how you can use SDK tools +to inspect your layout and discover performance bottlenecks.
    +
    Re-using Layouts with <include/>
    +
    If your application UI repeats certain layout constructs in multiple places, this lesson +shows you how to create efficient, re-usable layout constructs, then include them in the appropriate +UI layouts.
    +
    Loading Views On Demand
    +
    Beyond simply including one layout component within another layout, you might want to +make the included layout visible only when it's needed, sometime after the activity is running. +This lesson shows how you can improve your layout's initialization performance by loading +portions of your layout on demand.
    +
    Making ListView Scrolling Smooth
    +
    If you've built an instance of {@link android.widget.ListView} that contains complex or +data-heavy content in each list item, the scroll performance of the list might suffer. This +lesson provides some tips about how you can make your scrolling performance more smooth.
    +
    \ No newline at end of file diff --git a/docs/html/training/improving-layouts/loading-ondemand.jd b/docs/html/training/improving-layouts/loading-ondemand.jd new file mode 100644 index 0000000000000..659b1ec3cd7d3 --- /dev/null +++ b/docs/html/training/improving-layouts/loading-ondemand.jd @@ -0,0 +1,86 @@ +page.title=Loading Views On Demand +parent.title=Improving Performance of Layouts +parent.link=index.html + +trainingnavtop=true +previous.title=Re-using Layouts with <include/> +previous.link=reusing-layouts.html +next.title=Making ListView Scrolling Smooth +next.link=smooth-scrolling.html + +@jd:body + + +
    +
    + + +

    This lesson teaches you to

    +
      +
    1. Define a ViewStub
    2. +
    3. Load the ViewStub Layout
    4. +
    + + +

    You should also read

    + + +
    +
    + + +

    Sometimes your layout might require complex views that are rarely used. Whether +they are item details, progress indicators, or undo messages, you can reduce memory usage and speed +up rendering by loading the views only when they are needed.

    + + +

    Define a ViewStub

    + +

    {@link android.view.ViewStub} is a lightweight view with no dimension and doesn’t draw anything +or participate in the layout. As such, it's cheap to inflate and cheap to leave in a view hierarchy. +Each {@link android.view.ViewStub} simply needs to include the {@code android:layout} attribute to +specify the layout to inflate.

    + +

    The following {@link android.view.ViewStub} is for a translucent progress bar overlay. It should +be visible only when new items are being imported into the application.

    + +
    +<ViewStub
    +    android:id="@+id/stub_import"
    +    android:inflatedId="@+id/panel_import"
    +    android:layout="@layout/progress_overlay"
    +    android:layout_width="fill_parent"
    +    android:layout_height="wrap_content"
    +    android:layout_gravity="bottom" />
    +
    + + +

    Load the ViewStub Layout

    + +

    When you want to load the layout specified by the {@link android.view.ViewStub}, either set it +visible by calling {@link android.view.View#setVisibility setVisibility(View.VISIBLE)} or call +{@link android.view.ViewStub#inflate()}.

    + +
    +((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
    +// or
    +View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();
    +
    + +

    Note: The {@link android.view.ViewStub#inflate()} method returns +the inflated {@link android.view.View} once complete. so you don't need to call {@link +android.app.Activity#findViewById findViewById()} if you need to interact with the layout.

    + +

    Once visible/inflated, the {@link android.view.ViewStub} element is no longer part of the view +hierarchy. It is replaced by the inflated layout and the ID for the root view of that layout is +the one specified by the {@code android:inflatedId} attribute of the ViewStub. (The ID {@code +android:id} specified for the {@link android.view.ViewStub} is valid only until the {@link +android.view.ViewStub} layout is visible/inflated.)

    + +

    Note: One drawback of {@link android.view.ViewStub} is that it +doesn’t currently support the {@code <merge/>} tag in the layouts to be inflated.

    + + + diff --git a/docs/html/training/improving-layouts/optimizing-layout.jd b/docs/html/training/improving-layouts/optimizing-layout.jd new file mode 100644 index 0000000000000..3237780b88e59 --- /dev/null +++ b/docs/html/training/improving-layouts/optimizing-layout.jd @@ -0,0 +1,156 @@ +page.title=Optimizing Layout Hierarchies +parent.title=Improving Performance of Layouts +parent.link=index.html + +trainingnavtop=true +next.title=Re-using Layouts with <include/> +next.link=reusing-layouts.html + +@jd:body + + + +
    +
    + + +

    This lesson teaches you to

    +
      +
    1. Inspect Your Layout
    2. +
    3. Revise Your Layout
    4. +
    5. Use Layoutopt
    6. +
    + + +

    You should also read

    + + +
    +
    + + +

    It is a common misconception that using the basic layout structures leads to the most efficient +layouts. However, each widget and layout you add to your application requires initialization, +layout, and drawing. For example, using nested instances of {@link android.widget.LinearLayout} can +lead to an excessively deep view hierarchy. Furthermore, nesting several instances of {@link +android.widget.LinearLayout} that use the {@code layout_weight} parameter can be especially +expensive as each child needs to be measured twice. This is particularly important when the layout +is inflated repeatedly, such as when used in a {@link android.widget.ListView} or {@link +android.widget.GridView}.

    + +

    In this lesson you'll learn to use Heirachy Viewer and Layoutopt to examine and optimize your +layout.

    + + + +

    Inspect Your Layout

    + +

    The Android SDK tools include a tool called Heirachy Viewer that allows +you to analyze your layout while your application is running. Using this tool helps you discover +bottlenecks in the layout performance.

    + +

    Hierarchy Viewer works by allowing you to select running processes on a connected device or +emulator, then display the layout tree. The traffic lights on each block represent its Measure, +Layout and Draw performance, helping you identify potential issues.

    + +

    For example, figure 1 shows a layout that's used as an item in a {@link +android.widget.ListView}. This layout shows a small bitmap image on the left and two stacked items +of text on the right. It is especially important that layouts that will be inflated multiple +times—such as this one—are optimized as the performance +benefits will be multiplied.

    + + +

    Figure 1. Conceptual layout for an item in a {@link +android.widget.ListView}.

    + +

    The {@code hierarchyviewer} tool is available in {@code <sdk>/tools/}. When opened, +the Hierarchy Viewer shows a list of available devices and its running components. Click +Load View Hierarchy to view the layout hierarchy of the selected component. For +example, figure 2 shows the layout for the list item illustrated by figure 1.

    + +
    + +

    Figure 2. Layout hierarchy for the layout in figure 1, +using nested instances of {@link android.widget.LinearLayout}.

    +
    + +
    + +

    Figure 3. Clicking a hierarchy node shows its +performance times.

    +
    + +

    In figure 2, you can see there is a 3-level hierarchy with some problems +laying out the text items. Clicking on the items shows the time taken for each stage of the process +(figure 3). It becomes clear which items are taking the longest to measure, layout, and render, and +where you should spend time optimizing.

    + +

    The timings for rendering a complete list item using this layout are:

    +
      +
    • Measure: 0.977ms
    • +
    • Layout: 0.167ms
    • +
    • Draw: 2.717ms
    • +
    + + +

    Revise Your Layout

    + +

    Because the layout performance above slows down due to a nested {@link +android.widget.LinearLayout}, the performance might improve by flattening the layout—make +the layout shallow and wide, rather than narrow and deep. A {@link android.widget.RelativeLayout} as +the root node allows for such layouts. So, when this design is converted to use {@link +android.widget.RelativeLayout}, you can see that the layout becomes a 2-level hierarchy. Inspection +of the new layout looks like this:

    + + +

    Figure 4. Layout hierarchy for the layout in figure 1, +using {@link android.widget.RelativeLayout}.

    + +

    Now rendering a list item takes:

    +
      +
    • Measure: 0.598ms
    • +
    • Layout: 0.110ms
    • +
    • Draw: 2.146ms
    • +
    + +

    Might seem like a small improvement, but this time is multiplied several times because this +layout is used for every item in a list.

    + +

    Most of this time difference is due to the use of {@code layout_weight} in the {@link +android.widget.LinearLayout} design, which can slow down the speed of measurement. It is just one +example of how each layout has appropriate uses and you should carefully consider whether using +layout weight is necessary.

    + + +

    Use Layoutopt

    + +

    It is always good practice to also run the layoutopt tool on your final layout files +to search for places in your view hierarchy that may be optimized. Layoutopt is also in your SDK +{@code tools/} directory and takes a layout directory name or a space-separated list of layout files +that you'd like to inspect.

    + +

    When you run {@code layoutopt} on a layout file, it prints a line number for each issue found, a +description of the issue, and for some types of issues it also suggests a resolution. For +example:

    + +
    +$ layoutopt samples/
    +samples/compound.xml
    +   7:23 The root-level <FrameLayout/> can be replaced with <merge/>
    +   11:21 This LinearLayout layout or its FrameLayout parent is useless
    +samples/simple.xml
    +   7:7 The root-level <FrameLayout/> can be replaced with <merge/>
    +
    + +

    After you apply the suggested layout optimizations, run Hierarchy Viewer again to inspect the +performance changes.

    + diff --git a/docs/html/training/improving-layouts/reusing-layouts.jd b/docs/html/training/improving-layouts/reusing-layouts.jd new file mode 100644 index 0000000000000..8f9729ac7d68f --- /dev/null +++ b/docs/html/training/improving-layouts/reusing-layouts.jd @@ -0,0 +1,150 @@ +page.title=Re-using Layouts with <include/> +parent.title=Improving Performance of Layouts +parent.link=index.html + +trainingnavtop=true +previous.title=Optimizing Layout Hierarchies +previous.link=optimizing-layout.html +next.title=Loading Views On Demand +next.link=loading-ondemand.html + +@jd:body + + +
    +
    + + +

    This lesson teaches you to

    +
      +
    1. Create a Re-usable Layout
    2. +
    3. Use the <include> Tag
    4. +
    5. Use the <merge> Tag
    6. +
    + + +

    You should also read

    + + +
    +
    + + + +

    Although Android offers a variety of widgets to provide small and re-usable interactive elements, +you might also need to re-use larger components that require a special layout. To efficiently +re-use complete layouts, you can use the {@code <include/>} and {@code <merge/>} tags +to embed another layout inside the current layout.

    + +

    Reusing layouts is particularly powerful as it allows you create reusable complex layouts. For +example, a yes/no button panel, or custom progress bar with description text. +It also means that any elements of your application that are common across multiple layouts can be +extracted, managed separately, then included in each layout. So while +you can create individual UI components by writing a custom {@link android.view.View}, you can +do it even more easily by re-using a layout file.

    + + +

    Create a Re-usable Layout

    + +

    If you already know the layout that you want to re-use, create a new XML file and define the +layout. For example, here's a layout from the G-Kenya codelab that defines a title bar to be +included in each activity (titlebar.xml):

    + +
    +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    +    android:layout_width=”match_parent”
    +    android:layout_height="wrap_content"
    +    android:background="@color/titlebar_bg">
    +
    +    <ImageView android:layout_width="wrap_content"
    +               android:layout_height="wrap_content" 
    +               android:src="@drawable/gafricalogo" />
    +</FrameLayout>
    +
    + +

    The root {@link android.view.View} should be exactly how you'd like it to appear in each +layout to which you add this layout.

    + + +

    Use the <include> Tag

    + +

    Inside the layout to which you want to add the re-usable component, add the {@code +<include/>} tag. For example, here's a layout from the +G-Kenya codelab that includes the title bar from above:

    + +

    Here's the layout file:

    + +
    +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    +    android:orientation="vertical" 
    +    android:layout_width=”match_parent”
    +    android:layout_height=”match_parent”
    +    android:background="@color/app_bg"
    +    android:gravity="center_horizontal">
    +
    +    <include layout="@layout/titlebar"/>
    +
    +    <TextView android:layout_width=”match_parent”
    +              android:layout_height="wrap_content"
    +              android:text="@string/hello"
    +              android:padding="10dp" />
    +
    +    ...
    +
    +</LinearLayout>
    +
    + +

    You can also override all the layout parameters (any {@code android:layout_*} attributes) of the +included layout's root view by specifying them in the {@code <include/>} tag. For +example:

    + +
    +<include android:id=”@+id/news_title”
    +         android:layout_width=”match_parent”
    +         android:layout_height=”match_parent”
    +         layout=”@layout/title”/>
    +
    + + + +

    Use the <merge> Tag

    + +

    The {@code <merge />} tag helps eliminate redundant view groups in your view hierarchy +when including one layout within another. For example, if your main layout is a vertical {@link +android.widget.LinearLayout} in which two consecutive views can be +re-used in multiple layouts, then the re-usable layout in which you place the two views requires its +own root view. However, using another {@link android.widget.LinearLayout} as the root for the +re-usable layout would result in a vertical {@link android.widget.LinearLayout} inside a +vertical {@link android.widget.LinearLayout}. The nested {@link android.widget.LinearLayout} +serves no real purpose other than to slow down your UI performance.

    + +

    To avoid including such a redundant view group, you can instead use the +{@code <merge>} element as the root view for the re-usable layout. For example:

    + +
    +<merge xmlns:android="http://schemas.android.com/apk/res/android">
    +
    +    <Button
    +        android:layout_width="fill_parent" 
    +        android:layout_height="wrap_content"
    +        android:text="@string/add"/>
    +
    +    <Button
    +        android:layout_width="fill_parent" 
    +        android:layout_height="wrap_content"
    +        android:text="@string/delete"/>
    +
    +</merge>
    +
    + +

    Now, when you include this layout in another layout (using the {@code <include/>} tag), the +system ignores the {@code <merge>} element and places the two buttons directly in the +layout, in place of the {@code <include/>} tag.

    + diff --git a/docs/html/training/improving-layouts/smooth-scrolling.jd b/docs/html/training/improving-layouts/smooth-scrolling.jd new file mode 100644 index 0000000000000..bc90dd2fa415d --- /dev/null +++ b/docs/html/training/improving-layouts/smooth-scrolling.jd @@ -0,0 +1,124 @@ +page.title=Making ListView Scrolling Smooth +parent.title=Optimizing Performance of Layouts +parent.link=index.html + +trainingnavtop=true +previous.title=Loading Views On Demand +previous.link=loading-ondemand.html + +@jd:body + + +
    +
    + + +

    This lesson teaches you to

    +
      +
    1. Use a Background Thread
    2. +
    3. Hold View Objects in a View Holder
    4. +
    + + +

    You should also read

    + + +
    +
    + +

    The key to a smoothly scrolling {@link android.widget.ListView} is to keep the application’s main +thread (the UI thread) free from heavy processing. Ensure you do any disk access, network access, or +SQL access in a separate thread. To test the status of your app, you can enable {@link +android.os.StrictMode}.

    + + +

    Use a Background Thread

    + +

    Using a background thread ("worker thread") removes strain from the main thread so it can focus +on drawing the UI. In many cases, using {@link android.os.AsyncTask} provides a simple way to +perform your work outside the main thread. {@link android.os.AsyncTask} automatically queues up all +the {@link android.os.AsyncTask#execute execute()} requests and performs them serially. This +behavior is global to a particular process and means you don’t need to worry about creating your +own thread pool.

    + +

    In the sample code below, an {@link android.os.AsyncTask} is used to load +images in a background thread, then apply them to the UI once finished. It also shows a +progress spinner in place of the images while they are loading.

    + +
    +// Using an AsyncTask to load the slow images in a background thread
    +new AsyncTask<ViewHolder, Void, Bitmap>() {
    +    private ViewHolder v;
    +
    +    @Override
    +    protected Bitmap doInBackground(ViewHolder... params) {
    +        v = params[0];
    +        return mFakeImageLoader.getImage();
    +    }
    +
    +    @Override
    +    protected void onPostExecute(Bitmap result) {
    +        super.onPostExecute(result);
    +        if (v.position == position) {
    +            // If this item hasn't been recycled already, hide the
    +            // progress and set and show the image
    +            v.progress.setVisibility(View.GONE);
    +            v.icon.setVisibility(View.VISIBLE);
    +            v.icon.setImageBitmap(result);
    +        }
    +    }
    +}.execute(holder);
    +
    + +

    Beginning with Android 3.0 (API level 11), an extra feature is available in {@link +android.os.AsyncTask} so you can enable it to run across multiple processor cores. Instead of +calling {@link android.os.AsyncTask#execute execute()} you can specify {@link +android.os.AsyncTask#executeOnExecutor executeOnExecutor()} and multiple requests can be executed at +the same time depending on the number of cores available.

    + + +

    Hold View Objects in a View Holder

    + +

    Your code might call {@link android.app.Activity#findViewById findViewById()} frequently +during the scrolling of {@link android.widget.ListView}, which can slow down performance. Even when +the {@link +android.widget.Adapter} returns an inflated view for recycling, you still need to look up the +elements +and update them. A way around repeated use of {@link android.app.Activity#findViewById +findViewById()} is to use the "view holder" design pattern.

    + +

    A {@code ViewHolder} object stores each of the component views inside the tag field of the +Layout, so you can immediately access them without the need to look them up repeatedly. First, you +need to create a class to hold your exact set of views. For example:

    + +
    +static class ViewHolder {
    +  TextView text;
    +  TextView timestamp;
    +  ImageView icon;
    +  ProgressBar progress;
    +  int position;
    +}
    +
    + +

    Then populate the {@code ViewHolder} and store it inside the layout.

    + +
    +ViewHolder holder = new ViewHolder();
    +holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
    +holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
    +holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
    +holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);
    +convertView.setTag(holder);
    +
    + +

    Now you can easily access each view without the need for the look-up, saving valuable processor +cycles.

    + + + + + From 3030c8e1db747c95a9d2692ddbc51d0013f9064d Mon Sep 17 00:00:00 2001 From: Dirk Dougherty Date: Mon, 12 Dec 2011 18:49:17 -0800 Subject: [PATCH 2/8] Doc change: API diff report for 15. Change-Id: Ifbe3cf600d9397dd42d855c4a271d514b008d45b --- docs/html/sdk/api_diff/15/changes.html | 45 + .../15/changes/alldiffs_index_additions.html | 620 +++++++++++++ .../15/changes/alldiffs_index_all.html | 828 ++++++++++++++++++ .../15/changes/alldiffs_index_changes.html | 398 +++++++++ .../15/changes/alldiffs_index_removals.html | 61 ++ .../changes/android.Manifest.permission.html | 129 +++ .../15/changes/android.app.Fragment.html | 129 +++ .../android.appwidget.AppWidgetHostView.html | 122 +++ .../android.bluetooth.BluetoothDevice.html | 151 ++++ .../15/changes/android.content.Context.html | 124 +++ .../15/changes/android.content.Intent.html | 214 +++++ .../android.database.CursorWindow.html | 140 +++ .../android.graphics.SurfaceTexture.html | 122 +++ .../android.hardware.Camera.Parameters.html | 136 +++ .../android.media.CamcorderProfile.html | 129 +++ .../android.media.MediaMetadataRetriever.html | 122 +++ .../15/changes/android.opengl.GLES11Ext.html | 143 +++ .../android.os.Build.VERSION_CODES.html | 122 +++ .../15/changes/android.os.IBinder.html | 122 +++ .../changes/android.os.RemoteException.html | 122 +++ ...der.CalendarContract.AttendeesColumns.html | 122 +++ ...ider.CalendarContract.CalendarColumns.html | 136 +++ ...ovider.CalendarContract.EventsColumns.html | 129 +++ .../changes/android.provider.MediaStore.html | 124 +++ .../android.provider.Settings.Secure.html | 122 +++ ...xtservice.SpellCheckerService.Session.html | 122 +++ ...ice.wallpaper.WallpaperService.Engine.html | 122 +++ ...ndroid.speech.tts.TextToSpeech.Engine.html | 129 +++ .../android.speech.tts.TextToSpeech.html | 147 ++++ ...ndroid.speech.tts.TextToSpeechService.html | 122 +++ .../android.text.style.SuggestionSpan.html | 122 +++ .../15/changes/android.view.KeyEvent.html | 143 +++ .../15/changes/android.view.View.html | 129 +++ ...iew.accessibility.AccessibilityRecord.html | 143 +++ ....view.textservice.SpellCheckerSession.html | 122 +++ ...roid.view.textservice.SuggestionsInfo.html | 122 +++ ...id.webkit.WebSettings.LayoutAlgorithm.html | 108 +++ .../changes/android.webkit.WebSettings.html | 135 +++ .../changes/android.widget.RemoteViews.html | 122 +++ .../api_diff/15/changes/changes-summary.html | 275 ++++++ .../15/changes/classes_index_additions.html | 91 ++ .../15/changes/classes_index_all.html | 345 ++++++++ .../15/changes/classes_index_changes.html | 303 +++++++ .../15/changes/classes_index_removals.html | 61 ++ .../changes/constructors_index_additions.html | 75 ++ .../15/changes/constructors_index_all.html | 78 ++ .../changes/constructors_index_changes.html | 67 ++ .../changes/constructors_index_removals.html | 61 ++ .../15/changes/fields_index_additions.html | 345 ++++++++ .../api_diff/15/changes/fields_index_all.html | 379 ++++++++ .../15/changes/fields_index_changes.html | 75 ++ .../15/changes/fields_index_removals.html | 61 ++ .../sdk/api_diff/15/changes/jdiff_help.html | 134 +++ .../api_diff/15/changes/jdiff_statistics.html | 447 ++++++++++ .../15/changes/jdiff_topleftframe.html | 63 ++ .../15/changes/methods_index_additions.html | 199 +++++ .../15/changes/methods_index_all.html | 205 +++++ .../15/changes/methods_index_changes.html | 77 ++ .../15/changes/methods_index_removals.html | 61 ++ .../15/changes/packages_index_additions.html | 63 ++ .../15/changes/packages_index_all.html | 85 ++ .../15/changes/packages_index_changes.html | 85 ++ .../15/changes/packages_index_removals.html | 63 ++ .../api_diff/15/changes/pkg_android.app.html | 119 +++ .../15/changes/pkg_android.appwidget.html | 119 +++ .../15/changes/pkg_android.bluetooth.html | 119 +++ .../15/changes/pkg_android.content.html | 126 +++ .../15/changes/pkg_android.database.html | 134 +++ .../15/changes/pkg_android.graphics.html | 119 +++ .../15/changes/pkg_android.hardware.html | 119 +++ .../sdk/api_diff/15/changes/pkg_android.html | 119 +++ .../15/changes/pkg_android.media.html | 126 +++ .../15/changes/pkg_android.opengl.html | 119 +++ .../api_diff/15/changes/pkg_android.os.html | 148 ++++ .../15/changes/pkg_android.provider.html | 218 +++++ .../pkg_android.service.textservice.html | 119 +++ .../pkg_android.service.wallpaper.html | 119 +++ .../15/changes/pkg_android.speech.tts.html | 148 ++++ .../15/changes/pkg_android.text.style.html | 119 +++ .../pkg_android.view.accessibility.html | 119 +++ .../api_diff/15/changes/pkg_android.view.html | 126 +++ .../changes/pkg_android.view.textservice.html | 126 +++ .../15/changes/pkg_android.webkit.html | 126 +++ .../15/changes/pkg_android.widget.html | 119 +++ .../html/sdk/api_diff/15/stylesheet-jdiff.css | 44 + 85 files changed, 12848 insertions(+) create mode 100644 docs/html/sdk/api_diff/15/changes.html create mode 100644 docs/html/sdk/api_diff/15/changes/alldiffs_index_additions.html create mode 100644 docs/html/sdk/api_diff/15/changes/alldiffs_index_all.html create mode 100644 docs/html/sdk/api_diff/15/changes/alldiffs_index_changes.html create mode 100644 docs/html/sdk/api_diff/15/changes/alldiffs_index_removals.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.Manifest.permission.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.app.Fragment.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.appwidget.AppWidgetHostView.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.bluetooth.BluetoothDevice.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.content.Context.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.content.Intent.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.database.CursorWindow.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.graphics.SurfaceTexture.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.hardware.Camera.Parameters.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.media.CamcorderProfile.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.media.MediaMetadataRetriever.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.opengl.GLES11Ext.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.os.Build.VERSION_CODES.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.os.IBinder.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.os.RemoteException.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.AttendeesColumns.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.CalendarColumns.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.EventsColumns.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.provider.MediaStore.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.provider.Settings.Secure.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.service.textservice.SpellCheckerService.Session.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.service.wallpaper.WallpaperService.Engine.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeech.Engine.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeech.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeechService.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.text.style.SuggestionSpan.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.view.KeyEvent.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.view.View.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.view.accessibility.AccessibilityRecord.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.view.textservice.SpellCheckerSession.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.view.textservice.SuggestionsInfo.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.webkit.WebSettings.LayoutAlgorithm.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.webkit.WebSettings.html create mode 100644 docs/html/sdk/api_diff/15/changes/android.widget.RemoteViews.html create mode 100644 docs/html/sdk/api_diff/15/changes/changes-summary.html create mode 100644 docs/html/sdk/api_diff/15/changes/classes_index_additions.html create mode 100644 docs/html/sdk/api_diff/15/changes/classes_index_all.html create mode 100644 docs/html/sdk/api_diff/15/changes/classes_index_changes.html create mode 100644 docs/html/sdk/api_diff/15/changes/classes_index_removals.html create mode 100644 docs/html/sdk/api_diff/15/changes/constructors_index_additions.html create mode 100644 docs/html/sdk/api_diff/15/changes/constructors_index_all.html create mode 100644 docs/html/sdk/api_diff/15/changes/constructors_index_changes.html create mode 100644 docs/html/sdk/api_diff/15/changes/constructors_index_removals.html create mode 100644 docs/html/sdk/api_diff/15/changes/fields_index_additions.html create mode 100644 docs/html/sdk/api_diff/15/changes/fields_index_all.html create mode 100644 docs/html/sdk/api_diff/15/changes/fields_index_changes.html create mode 100644 docs/html/sdk/api_diff/15/changes/fields_index_removals.html create mode 100644 docs/html/sdk/api_diff/15/changes/jdiff_help.html create mode 100644 docs/html/sdk/api_diff/15/changes/jdiff_statistics.html create mode 100644 docs/html/sdk/api_diff/15/changes/jdiff_topleftframe.html create mode 100644 docs/html/sdk/api_diff/15/changes/methods_index_additions.html create mode 100644 docs/html/sdk/api_diff/15/changes/methods_index_all.html create mode 100644 docs/html/sdk/api_diff/15/changes/methods_index_changes.html create mode 100644 docs/html/sdk/api_diff/15/changes/methods_index_removals.html create mode 100644 docs/html/sdk/api_diff/15/changes/packages_index_additions.html create mode 100644 docs/html/sdk/api_diff/15/changes/packages_index_all.html create mode 100644 docs/html/sdk/api_diff/15/changes/packages_index_changes.html create mode 100644 docs/html/sdk/api_diff/15/changes/packages_index_removals.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.app.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.appwidget.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.bluetooth.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.content.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.database.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.graphics.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.hardware.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.media.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.opengl.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.os.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.provider.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.service.textservice.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.service.wallpaper.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.speech.tts.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.text.style.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.view.accessibility.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.view.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.view.textservice.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.webkit.html create mode 100644 docs/html/sdk/api_diff/15/changes/pkg_android.widget.html create mode 100644 docs/html/sdk/api_diff/15/stylesheet-jdiff.css diff --git a/docs/html/sdk/api_diff/15/changes.html b/docs/html/sdk/api_diff/15/changes.html new file mode 100644 index 0000000000000..6fe88e8c48ca1 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes.html @@ -0,0 +1,45 @@ + + + + + + + + + + +API Differences between 14 and 15 + + + + + + + + + + + + + + +<h2> +Frame Alert +</h2> + +<p> +This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. +<br> +Link to <a href="changes/changes-summary.html" target="_top">Non-frame version.</A> + + diff --git a/docs/html/sdk/api_diff/15/changes/alldiffs_index_additions.html b/docs/html/sdk/api_diff/15/changes/alldiffs_index_additions.html new file mode 100644 index 0000000000000..25c2b0af5a92f --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/alldiffs_index_additions.html @@ -0,0 +1,620 @@ + + + + + + + + + +All Additions Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Differences +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + + +
    A  +C +E +F +G +H +I +K +L +M +O +Q +R +S +T +U +W + TOP +

    +ACCESSIBILITY_SPEAK_PASSWORD +
    + +ACTION_UUID +
    + +ALLOWED_ATTENDEE_TYPES +
    + +ALLOWED_AVAILABILITY +
    + +AVAILABILITY_TENTATIVE +
    + + +
    C  +A +E +F +G +H +I +K +L +M +O +Q +R +S +T +U +W + TOP +

    +CALENDAR_COLOR_KEY +
    + +CalendarContract.Colors
    + +CalendarContract.ColorsColumns
    + +callOnClick +()
    + +cancel +()
    + +CATEGORY_APP_BROWSER +
    + +CATEGORY_APP_CALCULATOR +
    + +CATEGORY_APP_CALENDAR +
    + +CATEGORY_APP_CONTACTS +
    + +CATEGORY_APP_EMAIL +
    + +CATEGORY_APP_GALLERY +
    + +CATEGORY_APP_MAPS +
    + +CATEGORY_APP_MESSAGING +
    + +CATEGORY_APP_MUSIC +
    + +ContactsContract.Contacts.StreamItems
    + +ContactsContract.RawContacts.StreamItems
    + +ContactsContract.StreamItemPhotos
    + +ContactsContract.StreamItemPhotosColumns
    + +ContactsContract.StreamItems
    + +ContactsContract.StreamItems.StreamItemPhotos
    + +ContactsContract.StreamItemsColumns
    + +CrossProcessCursorWrapper
    + +CursorWindow +(String) constructor
    + + +
    E  +A +C +F +G +H +I +K +L +M +O +Q +R +S +T +U +W + TOP +

    +EVENT_COLOR_KEY +
    + +EXTRA_UUID +
    + + +
    F  +A +C +E +G +H +I +K +L +M +O +Q +R +S +T +U +W + TOP +

    +fetchUuidsWithSdp +()
    + +FILL_IN_SELECTOR +
    + +FLAG_AUTO_CORRECTION +
    + + +
    G  +A +C +E +F +H +I +K +L +M +O +Q +R +S +T +U +W + TOP +

    +getDefaultPaddingForWidget +(Context, ComponentName, Rect)
    + +getFeatures +(Locale)
    + +getMaxScrollX +()
    + +getMaxScrollY +()
    + +getSelector +()
    + +getUserVisibleHint +()
    + +getUuids +()
    + +getVideoStabilization +()
    + +GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES +
    + +GL_SAMPLER_EXTERNAL_OES +
    + +GL_TEXTURE_BINDING_EXTERNAL_OES +
    + +GL_TEXTURE_EXTERNAL_OES +
    + + +
    H  +A +C +E +F +G +I +K +L +M +O +Q +R +S +T +U +W + TOP +

    +hasOnClickListeners +()
    + + +
    I  +A +C +E +F +G +H +K +L +M +O +Q +R +S +T +U +W + TOP +

    +ICE_CREAM_SANDWICH_MR1 +
    + +isVideoStabilizationSupported +()
    + + +
    K  +A +C +E +F +G +H +I +L +M +O +Q +R +S +T +U +W + TOP +

    +KEY_FEATURE_EMBEDDED_SYNTHESIS +
    + +KEY_FEATURE_NETWORK_SYNTHESIS +
    + +KEYCODE_CALCULATOR +
    + +KEYCODE_CALENDAR +
    + +KEYCODE_CONTACTS +
    + +KEYCODE_MUSIC +
    + + +
    L  +A +C +E +F +G +H +I +K +M +O +Q +R +S +T +U +W + TOP +

    +LIKE_TRANSACTION +
    + + +
    M  +A +C +E +F +G +H +I +K +L +O +Q +R +S +T +U +W + TOP +

    +makeMainSelectorActivity +(String, String)
    + +METADATA_KEY_LOCATION +
    + + +
    O  +A +C +E +F +G +H +I +K +L +M +Q +R +S +T +U +W + TOP +

    +onClose +()
    + +onGetFeaturesForLanguage +(String, String, String)
    + + +
    Q  +A +C +E +F +G +H +I +K +L +M +O +R +S +T +U +W + TOP +

    +QUALITY_QVGA +
    + +QUALITY_TIME_LAPSE_QVGA +
    + + +
    R  +A +C +E +F +G +H +I +K +L +M +O +Q +S +T +U +W + TOP +

    +READ_SOCIAL_STREAM +
    + +RemoteException +(String) constructor
    + +RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS +
    + + +
    S  +A +C +E +F +G +H +I +K +L +M +O +Q +R +T +U +W + TOP +

    +setContentDescription +(int, CharSequence)
    + +setDefaultBufferSize +(int, int)
    + +setMaxScrollX +(int)
    + +setMaxScrollY +(int)
    + +setOffsetNotificationsEnabled +(boolean)
    + +setOnUtteranceProgressListener +(UtteranceProgressListener)
    + +setSelector +(Intent)
    + +setUserVisibleHint +(boolean)
    + +setVideoStabilization +(boolean)
    + + +
    T  +A +C +E +F +G +H +I +K +L +M +O +Q +R +S +U +W + TOP +

    +TransactionTooLargeException
    + +TYPE_RESOURCE +
    + + +
    U  +A +C +E +F +G +H +I +K +L +M +O +Q +R +S +T +W + TOP +

    +UtteranceProgressListener
    + + +
    W  +A +C +E +F +G +H +I +K +L +M +O +Q +R +S +T +U + TOP +

    +WRITE_SOCIAL_STREAM +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/alldiffs_index_all.html b/docs/html/sdk/api_diff/15/changes/alldiffs_index_all.html new file mode 100644 index 0000000000000..c4a67daf00b2c --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/alldiffs_index_all.html @@ -0,0 +1,828 @@ + + + + + + + + + +All Differences Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Differences +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + + +
    A  +B +C +E +F +G +H +I +K +L +M +O +Q +R +S +T +U +V +W + TOP +

    +ACCESSIBILITY_SPEAK_PASSWORD +
    + +AccessibilityRecord
    + +ACTION_UUID +
    + +ALLOWED_ATTENDEE_TYPES +
    + +ALLOWED_AVAILABILITY +
    + +android
    + +android.app
    + +android.appwidget
    + +android.bluetooth
    + +android.content
    + +android.database
    + +android.graphics
    + +android.hardware
    + +android.media
    + +android.opengl
    + +android.os
    + +android.provider
    + +android.service.textservice
    + +android.service.wallpaper
    + +android.speech.tts
    + +android.text.style
    + +android.view
    + +android.view.accessibility
    + +android.view.textservice
    + +android.webkit
    + +android.widget
    + +AppWidgetHostView
    + +AVAILABILITY_TENTATIVE +
    + + +
    B  +A +C +E +F +G +H +I +K +L +M +O +Q +R +S +T +U +V +W + TOP +

    +BIND_ADJUST_WITH_ACTIVITY +
    + +BluetoothDevice
    + +Build.VERSION_CODES
    + + +
    C  +A +B +E +F +G +H +I +K +L +M +O +Q +R +S +T +U +V +W + TOP +

    +CALENDAR_COLOR_KEY +
    + +CalendarContract.AttendeesColumns
    + +CalendarContract.CalendarColumns
    + +CalendarContract.Colors
    + +CalendarContract.ColorsColumns
    + +CalendarContract.EventsColumns
    + +callOnClick +()
    + +CamcorderProfile
    + +Camera.Parameters
    + +cancel +()
    + +CATEGORY_APP_BROWSER +
    + +CATEGORY_APP_CALCULATOR +
    + +CATEGORY_APP_CALENDAR +
    + +CATEGORY_APP_CONTACTS +
    + +CATEGORY_APP_EMAIL +
    + +CATEGORY_APP_GALLERY +
    + +CATEGORY_APP_MAPS +
    + +CATEGORY_APP_MESSAGING +
    + +CATEGORY_APP_MUSIC +
    + +ContactsContract.Contacts.StreamItems
    + +ContactsContract.RawContacts.StreamItems
    + +ContactsContract.StreamItemPhotos
    + +ContactsContract.StreamItemPhotosColumns
    + +ContactsContract.StreamItems
    + +ContactsContract.StreamItems.StreamItemPhotos
    + +ContactsContract.StreamItemsColumns
    + +Context
    + +CrossProcessCursorWrapper
    + +CursorWindow
    +  android.database
    + +  CursorWindow +(String) constructor
    + +  CursorWindow +(boolean) constructor
    + + +
    E  +A +B +C +F +G +H +I +K +L +M +O +Q +R +S +T +U +V +W + TOP +

    +EVENT_COLOR_KEY +
    + +EXTRA_UUID +
    + + +
    F  +A +B +C +E +G +H +I +K +L +M +O +Q +R +S +T +U +V +W + TOP +

    +fetchUuidsWithSdp +()
    + +FILL_IN_SELECTOR +
    + +FLAG_AUTO_CORRECTION +
    + +Fragment
    + + +
    G  +A +B +C +E +F +H +I +K +L +M +O +Q +R +S +T +U +V +W + TOP +

    +getDefaultPaddingForWidget +(Context, ComponentName, Rect)
    + +getFeatures +(Locale)
    + +getLayoutAlgorithm +()
    + +getMaxScrollX +()
    + +getMaxScrollY +()
    + +getSelector +()
    + +getUserVisibleHint +()
    + +getUuids +()
    + +getVideoStabilization +()
    + +GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES +
    + +GL_SAMPLER_EXTERNAL_OES +
    + +GL_TEXTURE_BINDING_EXTERNAL_OES +
    + +GL_TEXTURE_EXTERNAL_OES +
    + +GLES11Ext
    + + +
    H  +A +B +C +E +F +G +I +K +L +M +O +Q +R +S +T +U +V +W + TOP +

    +hasOnClickListeners +()
    + + +
    I  +A +B +C +E +F +G +H +K +L +M +O +Q +R +S +T +U +V +W + TOP +

    +IBinder
    + +ICE_CREAM_SANDWICH_MR1 +
    + +Intent
    + +INTENT_ACTION_MUSIC_PLAYER +
    + +isVideoStabilizationSupported +()
    + + +
    K  +A +B +C +E +F +G +H +I +L +M +O +Q +R +S +T +U +V +W + TOP +

    +KEY_FEATURE_EMBEDDED_SYNTHESIS +
    + +KEY_FEATURE_NETWORK_SYNTHESIS +
    + +KEYCODE_CALCULATOR +
    + +KEYCODE_CALENDAR +
    + +KEYCODE_CONTACTS +
    + +KEYCODE_MUSIC +
    + +KeyEvent
    + + +
    L  +A +B +C +E +F +G +H +I +K +M +O +Q +R +S +T +U +V +W + TOP +

    +LIKE_TRANSACTION +
    + + +
    M  +A +B +C +E +F +G +H +I +K +L +O +Q +R +S +T +U +V +W + TOP +

    +makeMainSelectorActivity +(String, String)
    + +Manifest.permission
    + +MediaMetadataRetriever
    + +MediaStore
    + +METADATA_KEY_LOCATION +
    + + +
    O  +A +B +C +E +F +G +H +I +K +L +M +Q +R +S +T +U +V +W + TOP +

    +onClose +()
    + +onGetFeaturesForLanguage +(String, String, String)
    + + +
    Q  +A +B +C +E +F +G +H +I +K +L +M +O +R +S +T +U +V +W + TOP +

    +QUALITY_QVGA +
    + +QUALITY_TIME_LAPSE_QVGA +
    + + +
    R  +A +B +C +E +F +G +H +I +K +L +M +O +Q +S +T +U +V +W + TOP +

    +READ_SOCIAL_STREAM +
    + +RemoteException
    +  android.os
    + +  RemoteException +(String) constructor
    + +RemoteViews
    + +RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS +
    + + +
    S  +A +B +C +E +F +G +H +I +K +L +M +O +Q +R +T +U +V +W + TOP +

    +setContentDescription +(int, CharSequence)
    + +setDefaultBufferSize +(int, int)
    + +setLayoutAlgorithm +(LayoutAlgorithm)
    + +setMaxScrollX +(int)
    + +setMaxScrollY +(int)
    + +setOffsetNotificationsEnabled +(boolean)
    + +setOnUtteranceCompletedListener +(OnUtteranceCompletedListener)
    + +setOnUtteranceProgressListener +(UtteranceProgressListener)
    + +setSelector +(Intent)
    + +Settings.Secure
    + +setUserVisibleHint +(boolean)
    + +setVideoStabilization +(boolean)
    + +SpellCheckerService.Session
    + +SpellCheckerSession
    + +SuggestionsInfo
    + +SuggestionSpan
    + +SurfaceTexture
    + + +
    T  +A +B +C +E +F +G +H +I +K +L +M +O +Q +R +S +U +V +W + TOP +

    +TextToSpeech
    + +TextToSpeech.Engine
    + +TextToSpeechService
    + +TransactionTooLargeException
    + +TYPE_RESOURCE +
    + + +
    U  +A +B +C +E +F +G +H +I +K +L +M +O +Q +R +S +T +V +W + TOP +

    +UtteranceProgressListener
    + + +
    V  +A +B +C +E +F +G +H +I +K +L +M +O +Q +R +S +T +U +W + TOP +

    +View
    + + +
    W  +A +B +C +E +F +G +H +I +K +L +M +O +Q +R +S +T +U +V + TOP +

    +WallpaperService.Engine
    + +WebSettings
    + +WebSettings.LayoutAlgorithm
    + +WRITE_SOCIAL_STREAM +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/alldiffs_index_changes.html b/docs/html/sdk/api_diff/15/changes/alldiffs_index_changes.html new file mode 100644 index 0000000000000..5ee38037824e0 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/alldiffs_index_changes.html @@ -0,0 +1,398 @@ + + + + + + + + + +All Changes Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Differences +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + + +
    A  +B +C +F +G +I +K +M +R +S +T +V +W + TOP +

    +AccessibilityRecord
    + +android
    + +android.app
    + +android.appwidget
    + +android.bluetooth
    + +android.content
    + +android.database
    + +android.graphics
    + +android.hardware
    + +android.media
    + +android.opengl
    + +android.os
    + +android.provider
    + +android.service.textservice
    + +android.service.wallpaper
    + +android.speech.tts
    + +android.text.style
    + +android.view
    + +android.view.accessibility
    + +android.view.textservice
    + +android.webkit
    + +android.widget
    + +AppWidgetHostView
    + + +
    B  +A +C +F +G +I +K +M +R +S +T +V +W + TOP +

    +BIND_ADJUST_WITH_ACTIVITY +
    + +BluetoothDevice
    + +Build.VERSION_CODES
    + + +
    C  +A +B +F +G +I +K +M +R +S +T +V +W + TOP +

    +CalendarContract.AttendeesColumns
    + +CalendarContract.CalendarColumns
    + +CalendarContract.EventsColumns
    + +CamcorderProfile
    + +Camera.Parameters
    + +Context
    + +CursorWindow
    +  android.database
    + +  CursorWindow +(boolean) constructor
    + + +
    F  +A +B +C +G +I +K +M +R +S +T +V +W + TOP +

    +Fragment
    + + +
    G  +A +B +C +F +I +K +M +R +S +T +V +W + TOP +

    +getLayoutAlgorithm +()
    + +GLES11Ext
    + + +
    I  +A +B +C +F +G +K +M +R +S +T +V +W + TOP +

    +IBinder
    + +Intent
    + +INTENT_ACTION_MUSIC_PLAYER +
    + + +
    K  +A +B +C +F +G +I +M +R +S +T +V +W + TOP +

    +KeyEvent
    + + +
    M  +A +B +C +F +G +I +K +R +S +T +V +W + TOP +

    +Manifest.permission
    + +MediaMetadataRetriever
    + +MediaStore
    + + +
    R  +A +B +C +F +G +I +K +M +S +T +V +W + TOP +

    +RemoteException
    + +RemoteViews
    + + +
    S  +A +B +C +F +G +I +K +M +R +T +V +W + TOP +

    +setLayoutAlgorithm +(LayoutAlgorithm)
    + +setOnUtteranceCompletedListener +(OnUtteranceCompletedListener)
    + +Settings.Secure
    + +SpellCheckerService.Session
    + +SpellCheckerSession
    + +SuggestionsInfo
    + +SuggestionSpan
    + +SurfaceTexture
    + + +
    T  +A +B +C +F +G +I +K +M +R +S +V +W + TOP +

    +TextToSpeech
    + +TextToSpeech.Engine
    + +TextToSpeechService
    + + +
    V  +A +B +C +F +G +I +K +M +R +S +T +W + TOP +

    +View
    + + +
    W  +A +B +C +F +G +I +K +M +R +S +T +V + TOP +

    +WallpaperService.Engine
    + +WebSettings
    + +WebSettings.LayoutAlgorithm
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/alldiffs_index_removals.html b/docs/html/sdk/api_diff/15/changes/alldiffs_index_removals.html new file mode 100644 index 0000000000000..68d2c20bf961a --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/alldiffs_index_removals.html @@ -0,0 +1,61 @@ + + + + + + + + + +All Removals Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Differences +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.Manifest.permission.html b/docs/html/sdk/api_diff/15/changes/android.Manifest.permission.html new file mode 100644 index 0000000000000..37bbd8cb38ec5 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.Manifest.permission.html @@ -0,0 +1,129 @@ + + + + + + + + + +android.Manifest.permission + + + + + + + + + + +
    +
    +
    +

    +Class android.Manifest.permission +

    + + + +

    + + + + + + + + + + + + +
    Added Fields +
    + + String READ_SOCIAL_STREAM +  
    + + String WRITE_SOCIAL_STREAM +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.app.Fragment.html b/docs/html/sdk/api_diff/15/changes/android.app.Fragment.html new file mode 100644 index 0000000000000..2b1976eff74d3 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.app.Fragment.html @@ -0,0 +1,129 @@ + + + + + + + + + +android.app.Fragment + + + + + + + + + + +
    +
    +
    +

    +Class android.app.Fragment +

    + + +

    + + + + + + + + + + + + +
    Added Methods +
    + + boolean getUserVisibleHint() +  
    + + void setUserVisibleHint(boolean) +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.appwidget.AppWidgetHostView.html b/docs/html/sdk/api_diff/15/changes/android.appwidget.AppWidgetHostView.html new file mode 100644 index 0000000000000..59bdb1f6a04bd --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.appwidget.AppWidgetHostView.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.appwidget.AppWidgetHostView + + + + + + + + + + +
    +
    +
    +

    +Class android.appwidget.AppWidgetHostView +

    + + +

    + + + + + + + + +
    Added Methods +
    + + Rect getDefaultPaddingForWidget(Context, ComponentName, Rect) +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.bluetooth.BluetoothDevice.html b/docs/html/sdk/api_diff/15/changes/android.bluetooth.BluetoothDevice.html new file mode 100644 index 0000000000000..a2c87cda716a5 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.bluetooth.BluetoothDevice.html @@ -0,0 +1,151 @@ + + + + + + + + + +android.bluetooth.BluetoothDevice + + + + + + + + + + +
    +
    +
    +

    +Class android.bluetooth.BluetoothDevice +

    + + +

    + + + + + + + + + + + + +
    Added Methods +
    + + boolean fetchUuidsWithSdp() +  
    + + ParcelUuid[] getUuids() +  
    +  + +

    + + + + + + + + + + + + +
    Added Fields +
    + + String ACTION_UUID +  
    + + String EXTRA_UUID +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.content.Context.html b/docs/html/sdk/api_diff/15/changes/android.content.Context.html new file mode 100644 index 0000000000000..b3b8f1e76a5fa --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.content.Context.html @@ -0,0 +1,124 @@ + + + + + + + + + +android.content.Context + + + + + + + + + + +
    +
    +
    +

    +Class android.content.Context +

    + + + +

    + + + + + + + + + +
    Changed Fields +
    + + int BIND_ADJUST_WITH_ACTIVITY +Changed in value from 64 to 128. +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.content.Intent.html b/docs/html/sdk/api_diff/15/changes/android.content.Intent.html new file mode 100644 index 0000000000000..dd2f466c91ffc --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.content.Intent.html @@ -0,0 +1,214 @@ + + + + + + + + + +android.content.Intent + + + + + + + + + + +
    +
    +
    +

    +Class android.content.Intent +

    + + +

    + + + + + + + + + + + + + + + + +
    Added Methods +
    + + Intent getSelector() +  
    + + Intent makeMainSelectorActivity(String, String) +  
    + + void setSelector(Intent) +  
    +  + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Added Fields +
    + + String CATEGORY_APP_BROWSER +  
    + + String CATEGORY_APP_CALCULATOR +  
    + + String CATEGORY_APP_CALENDAR +  
    + + String CATEGORY_APP_CONTACTS +  
    + + String CATEGORY_APP_EMAIL +  
    + + String CATEGORY_APP_GALLERY +  
    + + String CATEGORY_APP_MAPS +  
    + + String CATEGORY_APP_MESSAGING +  
    + + String CATEGORY_APP_MUSIC +  
    + + int FILL_IN_SELECTOR +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.database.CursorWindow.html b/docs/html/sdk/api_diff/15/changes/android.database.CursorWindow.html new file mode 100644 index 0000000000000..4ba4252fc6608 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.database.CursorWindow.html @@ -0,0 +1,140 @@ + + + + + + + + + +android.database.CursorWindow + + + + + + + + + + +
    +
    +
    +

    +Class android.database.CursorWindow +

    + +

    + + + + + + + + +
    Added Constructors +
    + + CursorWindow(String) +  
    +  +

    + + + + + + + + + +
    Changed Constructors +
    + + CursorWindow(boolean) + +Now deprecated.
    +
     
    +  + + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.graphics.SurfaceTexture.html b/docs/html/sdk/api_diff/15/changes/android.graphics.SurfaceTexture.html new file mode 100644 index 0000000000000..ca44add0feea8 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.graphics.SurfaceTexture.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.graphics.SurfaceTexture + + + + + + + + + + +
    +
    +
    +

    +Class android.graphics.SurfaceTexture +

    + + +

    + + + + + + + + +
    Added Methods +
    + + void setDefaultBufferSize(int, int) +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.hardware.Camera.Parameters.html b/docs/html/sdk/api_diff/15/changes/android.hardware.Camera.Parameters.html new file mode 100644 index 0000000000000..02afe902c388e --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.hardware.Camera.Parameters.html @@ -0,0 +1,136 @@ + + + + + + + + + +android.hardware.Camera.Parameters + + + + + + + + + + +
    +
    +
    +

    +Class android.hardware.Camera.Parameters +

    + + +

    + + + + + + + + + + + + + + + + +
    Added Methods +
    + + boolean getVideoStabilization() +  
    + + boolean isVideoStabilizationSupported() +  
    + + void setVideoStabilization(boolean) +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.media.CamcorderProfile.html b/docs/html/sdk/api_diff/15/changes/android.media.CamcorderProfile.html new file mode 100644 index 0000000000000..6b556bcef1519 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.media.CamcorderProfile.html @@ -0,0 +1,129 @@ + + + + + + + + + +android.media.CamcorderProfile + + + + + + + + + + +
    +
    +
    +

    +Class android.media.CamcorderProfile +

    + + + +

    + + + + + + + + + + + + +
    Added Fields +
    + + int QUALITY_QVGA +  
    + + int QUALITY_TIME_LAPSE_QVGA +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.media.MediaMetadataRetriever.html b/docs/html/sdk/api_diff/15/changes/android.media.MediaMetadataRetriever.html new file mode 100644 index 0000000000000..8247ea94d11a3 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.media.MediaMetadataRetriever.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.media.MediaMetadataRetriever + + + + + + + + + + +
    +
    +
    +

    +Class android.media.MediaMetadataRetriever +

    + + + +

    + + + + + + + + +
    Added Fields +
    + + int METADATA_KEY_LOCATION +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.opengl.GLES11Ext.html b/docs/html/sdk/api_diff/15/changes/android.opengl.GLES11Ext.html new file mode 100644 index 0000000000000..50913ad8a9c81 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.opengl.GLES11Ext.html @@ -0,0 +1,143 @@ + + + + + + + + + +android.opengl.GLES11Ext + + + + + + + + + + +
    +
    +
    +

    +Class android.opengl.GLES11Ext +

    + + + +

    + + + + + + + + + + + + + + + + + + + + +
    Added Fields +
    + + int GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES +  
    + + int GL_SAMPLER_EXTERNAL_OES +  
    + + int GL_TEXTURE_BINDING_EXTERNAL_OES +  
    + + int GL_TEXTURE_EXTERNAL_OES +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.os.Build.VERSION_CODES.html b/docs/html/sdk/api_diff/15/changes/android.os.Build.VERSION_CODES.html new file mode 100644 index 0000000000000..83994577346cf --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.os.Build.VERSION_CODES.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.os.Build.VERSION_CODES + + + + + + + + + + +
    +
    +
    +

    +Class android.os.Build.VERSION_CODES +

    + + + +

    + + + + + + + + +
    Added Fields +
    + + int ICE_CREAM_SANDWICH_MR1 +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.os.IBinder.html b/docs/html/sdk/api_diff/15/changes/android.os.IBinder.html new file mode 100644 index 0000000000000..1d090ed4a3bb3 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.os.IBinder.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.os.IBinder + + + + + + + + + + +
    +
    +
    +

    +Interface android.os.IBinder +

    + + + +

    + + + + + + + + +
    Added Fields +
    + + int LIKE_TRANSACTION +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.os.RemoteException.html b/docs/html/sdk/api_diff/15/changes/android.os.RemoteException.html new file mode 100644 index 0000000000000..55659e3c8307a --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.os.RemoteException.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.os.RemoteException + + + + + + + + + + +
    +
    +
    +

    +Class android.os.RemoteException +

    + +

    + + + + + + + + +
    Added Constructors +
    + + RemoteException(String) +  
    +  + + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.AttendeesColumns.html b/docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.AttendeesColumns.html new file mode 100644 index 0000000000000..d2c1f617091de --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.AttendeesColumns.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.provider.CalendarContract.AttendeesColumns + + + + + + + + + + +
    +
    +
    +

    +Interface android.provider.CalendarContract.AttendeesColumns +

    + + + +

    + + + + + + + + +
    Added Fields +
    + + int TYPE_RESOURCE +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.CalendarColumns.html b/docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.CalendarColumns.html new file mode 100644 index 0000000000000..60e05ef58135b --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.CalendarColumns.html @@ -0,0 +1,136 @@ + + + + + + + + + +android.provider.CalendarContract.CalendarColumns + + + + + + + + + + +
    +
    +
    +

    +Interface android.provider.CalendarContract.CalendarColumns +

    + + + +

    + + + + + + + + + + + + + + + + +
    Added Fields +
    + + String ALLOWED_ATTENDEE_TYPES +  
    + + String ALLOWED_AVAILABILITY +  
    + + String CALENDAR_COLOR_KEY +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.EventsColumns.html b/docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.EventsColumns.html new file mode 100644 index 0000000000000..625136000006a --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.provider.CalendarContract.EventsColumns.html @@ -0,0 +1,129 @@ + + + + + + + + + +android.provider.CalendarContract.EventsColumns + + + + + + + + + + +
    +
    +
    +

    +Interface android.provider.CalendarContract.EventsColumns +

    + + + +

    + + + + + + + + + + + + +
    Added Fields +
    + + int AVAILABILITY_TENTATIVE +  
    + + String EVENT_COLOR_KEY +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.provider.MediaStore.html b/docs/html/sdk/api_diff/15/changes/android.provider.MediaStore.html new file mode 100644 index 0000000000000..34ee9a857d1f5 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.provider.MediaStore.html @@ -0,0 +1,124 @@ + + + + + + + + + +android.provider.MediaStore + + + + + + + + + + +
    +
    +
    +

    +Class android.provider.MediaStore +

    + + + +

    + + + + + + + + + +
    Changed Fields +
    + + String INTENT_ACTION_MUSIC_PLAYER +Now deprecated.
    +
     
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.provider.Settings.Secure.html b/docs/html/sdk/api_diff/15/changes/android.provider.Settings.Secure.html new file mode 100644 index 0000000000000..f1cb57b2c21c7 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.provider.Settings.Secure.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.provider.Settings.Secure + + + + + + + + + + +
    +
    +
    +

    +Class android.provider.Settings.Secure +

    + + + +

    + + + + + + + + +
    Added Fields +
    + + String ACCESSIBILITY_SPEAK_PASSWORD +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.service.textservice.SpellCheckerService.Session.html b/docs/html/sdk/api_diff/15/changes/android.service.textservice.SpellCheckerService.Session.html new file mode 100644 index 0000000000000..019b98a7f6c04 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.service.textservice.SpellCheckerService.Session.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.service.textservice.SpellCheckerService.Session + + + + + + + + + + +
    +
    +
    +

    +Class android.service.textservice.SpellCheckerService.Session +

    + + +

    + + + + + + + + +
    Added Methods +
    + + void onClose() +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.service.wallpaper.WallpaperService.Engine.html b/docs/html/sdk/api_diff/15/changes/android.service.wallpaper.WallpaperService.Engine.html new file mode 100644 index 0000000000000..356cf9de28f3b --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.service.wallpaper.WallpaperService.Engine.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.service.wallpaper.WallpaperService.Engine + + + + + + + + + + +
    +
    +
    +

    +Class android.service.wallpaper.WallpaperService.Engine +

    + + +

    + + + + + + + + +
    Added Methods +
    + + void setOffsetNotificationsEnabled(boolean) +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeech.Engine.html b/docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeech.Engine.html new file mode 100644 index 0000000000000..6f53f8fca31f0 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeech.Engine.html @@ -0,0 +1,129 @@ + + + + + + + + + +android.speech.tts.TextToSpeech.Engine + + + + + + + + + + +
    +
    +
    +

    +Class android.speech.tts.TextToSpeech.Engine +

    + + + +

    + + + + + + + + + + + + +
    Added Fields +
    + + String KEY_FEATURE_EMBEDDED_SYNTHESIS +  
    + + String KEY_FEATURE_NETWORK_SYNTHESIS +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeech.html b/docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeech.html new file mode 100644 index 0000000000000..e6e22a554a80c --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeech.html @@ -0,0 +1,147 @@ + + + + + + + + + +android.speech.tts.TextToSpeech + + + + + + + + + + +
    +
    +
    +

    +Class android.speech.tts.TextToSpeech +

    + + +

    + + + + + + + + + + + + +
    Added Methods +
    + + Set<String> getFeatures(Locale) +  
    + + int setOnUtteranceProgressListener(UtteranceProgressListener) +  
    +  +

    + + + + + + + + + +
    Changed Methods +
    + + int setOnUtteranceCompletedListener(OnUtteranceCompletedListener) + +Now deprecated.
    +
     
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeechService.html b/docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeechService.html new file mode 100644 index 0000000000000..e772e1938ba3d --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.speech.tts.TextToSpeechService.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.speech.tts.TextToSpeechService + + + + + + + + + + +
    +
    +
    +

    +Class android.speech.tts.TextToSpeechService +

    + + +

    + + + + + + + + +
    Added Methods +
    + + Set<String> onGetFeaturesForLanguage(String, String, String) +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.text.style.SuggestionSpan.html b/docs/html/sdk/api_diff/15/changes/android.text.style.SuggestionSpan.html new file mode 100644 index 0000000000000..0add186ec5869 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.text.style.SuggestionSpan.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.text.style.SuggestionSpan + + + + + + + + + + +
    +
    +
    +

    +Class android.text.style.SuggestionSpan +

    + + + +

    + + + + + + + + +
    Added Fields +
    + + int FLAG_AUTO_CORRECTION +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.view.KeyEvent.html b/docs/html/sdk/api_diff/15/changes/android.view.KeyEvent.html new file mode 100644 index 0000000000000..70843f63d6e35 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.view.KeyEvent.html @@ -0,0 +1,143 @@ + + + + + + + + + +android.view.KeyEvent + + + + + + + + + + +
    +
    +
    +

    +Class android.view.KeyEvent +

    + + + +

    + + + + + + + + + + + + + + + + + + + + +
    Added Fields +
    + + int KEYCODE_CALCULATOR +  
    + + int KEYCODE_CALENDAR +  
    + + int KEYCODE_CONTACTS +  
    + + int KEYCODE_MUSIC +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.view.View.html b/docs/html/sdk/api_diff/15/changes/android.view.View.html new file mode 100644 index 0000000000000..fa772f9984352 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.view.View.html @@ -0,0 +1,129 @@ + + + + + + + + + +android.view.View + + + + + + + + + + +
    +
    +
    +

    +Class android.view.View +

    + + +

    + + + + + + + + + + + + +
    Added Methods +
    + + boolean callOnClick() +  
    + + boolean hasOnClickListeners() +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.view.accessibility.AccessibilityRecord.html b/docs/html/sdk/api_diff/15/changes/android.view.accessibility.AccessibilityRecord.html new file mode 100644 index 0000000000000..b88467c7f71ba --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.view.accessibility.AccessibilityRecord.html @@ -0,0 +1,143 @@ + + + + + + + + + +android.view.accessibility.AccessibilityRecord + + + + + + + + + + +
    +
    +
    +

    +Class android.view.accessibility.AccessibilityRecord +

    + + +

    + + + + + + + + + + + + + + + + + + + + +
    Added Methods +
    + + int getMaxScrollX() +  
    + + int getMaxScrollY() +  
    + + void setMaxScrollX(int) +  
    + + void setMaxScrollY(int) +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.view.textservice.SpellCheckerSession.html b/docs/html/sdk/api_diff/15/changes/android.view.textservice.SpellCheckerSession.html new file mode 100644 index 0000000000000..0782c9c8a06f8 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.view.textservice.SpellCheckerSession.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.view.textservice.SpellCheckerSession + + + + + + + + + + +
    +
    +
    +

    +Class android.view.textservice.SpellCheckerSession +

    + + +

    + + + + + + + + +
    Added Methods +
    + + void cancel() +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.view.textservice.SuggestionsInfo.html b/docs/html/sdk/api_diff/15/changes/android.view.textservice.SuggestionsInfo.html new file mode 100644 index 0000000000000..bd1859b32c0c3 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.view.textservice.SuggestionsInfo.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.view.textservice.SuggestionsInfo + + + + + + + + + + +
    +
    +
    +

    +Class android.view.textservice.SuggestionsInfo +

    + + + +

    + + + + + + + + +
    Added Fields +
    + + int RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.webkit.WebSettings.LayoutAlgorithm.html b/docs/html/sdk/api_diff/15/changes/android.webkit.WebSettings.LayoutAlgorithm.html new file mode 100644 index 0000000000000..40424ed4e8807 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.webkit.WebSettings.LayoutAlgorithm.html @@ -0,0 +1,108 @@ + + + + + + + + + +android.webkit.WebSettings.LayoutAlgorithm + + + + + + + + + + +
    +
    +
    +

    +Class android.webkit.WebSettings.LayoutAlgorithm +

    +

    Change from deprecated to undeprecated.
    + + + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.webkit.WebSettings.html b/docs/html/sdk/api_diff/15/changes/android.webkit.WebSettings.html new file mode 100644 index 0000000000000..b7005a053dbf8 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.webkit.WebSettings.html @@ -0,0 +1,135 @@ + + + + + + + + + +android.webkit.WebSettings + + + + + + + + + + +
    +
    +
    +

    +Class android.webkit.WebSettings +

    + + +

    + + + + + + + + + + + + + + +
    Changed Methods +
    + + LayoutAlgorithm getLayoutAlgorithm() + +Change from deprecated to undeprecated.
    +
     
    + + void setLayoutAlgorithm(LayoutAlgorithm) + +Change from deprecated to undeprecated.
    +
     
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/android.widget.RemoteViews.html b/docs/html/sdk/api_diff/15/changes/android.widget.RemoteViews.html new file mode 100644 index 0000000000000..50cacaba1f0b5 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/android.widget.RemoteViews.html @@ -0,0 +1,122 @@ + + + + + + + + + +android.widget.RemoteViews + + + + + + + + + + +
    +
    +
    +

    +Class android.widget.RemoteViews +

    + + +

    + + + + + + + + +
    Added Methods +
    + + void setContentDescription(int, CharSequence) +  
    +  + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/changes-summary.html b/docs/html/sdk/api_diff/15/changes/changes-summary.html new file mode 100644 index 0000000000000..0acb973bcc674 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/changes-summary.html @@ -0,0 +1,275 @@ + + + + + + + + + +Android API Differences Report + + + + + + + + + + +
    +
    +
    +
    +

    Android API Differences Report

    +

    This report details the changes in the core Android framework API between two API Level +specifications. It shows additions, modifications, and removals for packages, classes, methods, and fields. +The report also includes general statistics that characterize the extent and type of the differences.

    +

    This report is based a comparison of the Android API specifications +whose API Level identifiers are given in the upper-right corner of this page. It compares a +newer "to" API to an older "from" API, noting all changes relative to the +older API. So, for example, API elements marked as removed are no longer present in the "to" +API specification.

    +

    To navigate the report, use the "Select a Diffs Index" and "Filter the Index" +controls on the left. The report uses text formatting to indicate interface names, +links to reference documentation, and links to change +description. The statistics are accessible from the "Statistics" link in the upper-right corner.

    +

    For more information about the Android framework API and SDK, +see the Android Developers site.

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Changed Packages +
    + + android +  
    + + android.app +  
    + + android.appwidget +  
    + + android.bluetooth +  
    + + android.content +  
    + + android.database +  
    + + android.graphics +  
    + + android.hardware +  
    + + android.media +  
    + + android.opengl +  
    + + android.os +  
    + + android.provider +  
    + + android.service.textservice +  
    + + android.service.wallpaper +  
    + + android.speech.tts +  
    + + android.text.style +  
    + + android.view +  
    + + android.view.accessibility +  
    + + android.view.textservice +  
    + + android.webkit +  
    + + android.widget +  
    +  + + +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/classes_index_additions.html b/docs/html/sdk/api_diff/15/changes/classes_index_additions.html new file mode 100644 index 0000000000000..16969ea6b225f --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/classes_index_additions.html @@ -0,0 +1,91 @@ + + + + + + + + + +Class Additions Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Classes +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    C  +T +U + TOP +

    +CalendarContract.Colors
    +CalendarContract.ColorsColumns
    +ContactsContract.Contacts.StreamItems
    +ContactsContract.RawContacts.StreamItems
    +ContactsContract.StreamItemPhotos
    +ContactsContract.StreamItemPhotosColumns
    +ContactsContract.StreamItems
    +ContactsContract.StreamItems.StreamItemPhotos
    +ContactsContract.StreamItemsColumns
    +CrossProcessCursorWrapper
    + +
    T  +C +U + TOP +

    +TransactionTooLargeException
    + +
    U  +C +T + TOP +

    +UtteranceProgressListener
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/classes_index_all.html b/docs/html/sdk/api_diff/15/changes/classes_index_all.html new file mode 100644 index 0000000000000..e03eba3cc6303 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/classes_index_all.html @@ -0,0 +1,345 @@ + + + + + + + + + +Class Differences Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +Classes +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    A  +B +C +F +G +I +K +M +R +S +T +U +V +W + TOP +

    +AccessibilityRecord
    +AppWidgetHostView
    + +
    B  +A +C +F +G +I +K +M +R +S +T +U +V +W + TOP +

    +BluetoothDevice
    +Build.VERSION_CODES
    + +
    C  +A +B +F +G +I +K +M +R +S +T +U +V +W + TOP +

    +CalendarContract.AttendeesColumns
    +CalendarContract.CalendarColumns
    +CalendarContract.Colors
    +CalendarContract.ColorsColumns
    +CalendarContract.EventsColumns
    +CamcorderProfile
    +Camera.Parameters
    +ContactsContract.Contacts.StreamItems
    +ContactsContract.RawContacts.StreamItems
    +ContactsContract.StreamItemPhotos
    +ContactsContract.StreamItemPhotosColumns
    +ContactsContract.StreamItems
    +ContactsContract.StreamItems.StreamItemPhotos
    +ContactsContract.StreamItemsColumns
    +Context
    +CrossProcessCursorWrapper
    +CursorWindow
    + +
    F  +A +B +C +G +I +K +M +R +S +T +U +V +W + TOP +

    +Fragment
    + +
    G  +A +B +C +F +I +K +M +R +S +T +U +V +W + TOP +

    +GLES11Ext
    + +
    I  +A +B +C +F +G +K +M +R +S +T +U +V +W + TOP +

    +IBinder
    +Intent
    + +
    K  +A +B +C +F +G +I +M +R +S +T +U +V +W + TOP +

    +KeyEvent
    + +
    M  +A +B +C +F +G +I +K +R +S +T +U +V +W + TOP +

    +Manifest.permission
    +MediaMetadataRetriever
    +MediaStore
    + +
    R  +A +B +C +F +G +I +K +M +S +T +U +V +W + TOP +

    +RemoteException
    +RemoteViews
    + +
    S  +A +B +C +F +G +I +K +M +R +T +U +V +W + TOP +

    +Settings.Secure
    +SpellCheckerService.Session
    +SpellCheckerSession
    +SuggestionsInfo
    +SuggestionSpan
    +SurfaceTexture
    + +
    T  +A +B +C +F +G +I +K +M +R +S +U +V +W + TOP +

    +TextToSpeech
    +TextToSpeech.Engine
    +TextToSpeechService
    +TransactionTooLargeException
    + +
    U  +A +B +C +F +G +I +K +M +R +S +T +V +W + TOP +

    +UtteranceProgressListener
    + +
    V  +A +B +C +F +G +I +K +M +R +S +T +U +W + TOP +

    +View
    + +
    W  +A +B +C +F +G +I +K +M +R +S +T +U +V + TOP +

    +WallpaperService.Engine
    +WebSettings
    +WebSettings.LayoutAlgorithm
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/classes_index_changes.html b/docs/html/sdk/api_diff/15/changes/classes_index_changes.html new file mode 100644 index 0000000000000..3109b6e7bece7 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/classes_index_changes.html @@ -0,0 +1,303 @@ + + + + + + + + + +Class Changes Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Classes +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    A  +B +C +F +G +I +K +M +R +S +T +V +W + TOP +

    +AccessibilityRecord
    +AppWidgetHostView
    + +
    B  +A +C +F +G +I +K +M +R +S +T +V +W + TOP +

    +BluetoothDevice
    +Build.VERSION_CODES
    + +
    C  +A +B +F +G +I +K +M +R +S +T +V +W + TOP +

    +CalendarContract.AttendeesColumns
    +CalendarContract.CalendarColumns
    +CalendarContract.EventsColumns
    +CamcorderProfile
    +Camera.Parameters
    +Context
    +CursorWindow
    + +
    F  +A +B +C +G +I +K +M +R +S +T +V +W + TOP +

    +Fragment
    + +
    G  +A +B +C +F +I +K +M +R +S +T +V +W + TOP +

    +GLES11Ext
    + +
    I  +A +B +C +F +G +K +M +R +S +T +V +W + TOP +

    +IBinder
    +Intent
    + +
    K  +A +B +C +F +G +I +M +R +S +T +V +W + TOP +

    +KeyEvent
    + +
    M  +A +B +C +F +G +I +K +R +S +T +V +W + TOP +

    +Manifest.permission
    +MediaMetadataRetriever
    +MediaStore
    + +
    R  +A +B +C +F +G +I +K +M +S +T +V +W + TOP +

    +RemoteException
    +RemoteViews
    + +
    S  +A +B +C +F +G +I +K +M +R +T +V +W + TOP +

    +Settings.Secure
    +SpellCheckerService.Session
    +SpellCheckerSession
    +SuggestionsInfo
    +SuggestionSpan
    +SurfaceTexture
    + +
    T  +A +B +C +F +G +I +K +M +R +S +V +W + TOP +

    +TextToSpeech
    +TextToSpeech.Engine
    +TextToSpeechService
    + +
    V  +A +B +C +F +G +I +K +M +R +S +T +W + TOP +

    +View
    + +
    W  +A +B +C +F +G +I +K +M +R +S +T +V + TOP +

    +WallpaperService.Engine
    +WebSettings
    +WebSettings.LayoutAlgorithm
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/classes_index_removals.html b/docs/html/sdk/api_diff/15/changes/classes_index_removals.html new file mode 100644 index 0000000000000..e6da73f487d3b --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/classes_index_removals.html @@ -0,0 +1,61 @@ + + + + + + + + + +Class Removals Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Classes +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/constructors_index_additions.html b/docs/html/sdk/api_diff/15/changes/constructors_index_additions.html new file mode 100644 index 0000000000000..c834d4ffd96af --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/constructors_index_additions.html @@ -0,0 +1,75 @@ + + + + + + + + + +Constructor Additions Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Constructors +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    C  +R + TOP +

    +CursorWindow +(String) constructor
    + +
    R  +C + TOP +

    +RemoteException +(String) constructor
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/constructors_index_all.html b/docs/html/sdk/api_diff/15/changes/constructors_index_all.html new file mode 100644 index 0000000000000..4e8e6923f69bf --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/constructors_index_all.html @@ -0,0 +1,78 @@ + + + + + + + + + +Constructor Differences Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +Constructors +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    C  +R + TOP +

    +CursorWindow
    +  CursorWindow +(String) constructor
    +  CursorWindow +(boolean) constructor
    + +
    R  +C + TOP +

    +RemoteException +(String) constructor
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/constructors_index_changes.html b/docs/html/sdk/api_diff/15/changes/constructors_index_changes.html new file mode 100644 index 0000000000000..74dc718904f5b --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/constructors_index_changes.html @@ -0,0 +1,67 @@ + + + + + + + + + +Constructor Changes Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Constructors +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    C  + TOP +

    +CursorWindow +(boolean) constructor
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/constructors_index_removals.html b/docs/html/sdk/api_diff/15/changes/constructors_index_removals.html new file mode 100644 index 0000000000000..f1a99529b22d0 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/constructors_index_removals.html @@ -0,0 +1,61 @@ + + + + + + + + + +Constructor Removals Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Constructors +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/fields_index_additions.html b/docs/html/sdk/api_diff/15/changes/fields_index_additions.html new file mode 100644 index 0000000000000..6012ce8841a47 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/fields_index_additions.html @@ -0,0 +1,345 @@ + + + + + + + + + +Field Additions Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Fields +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    A  +C +E +F +G +I +K +L +M +Q +R +T +W + TOP +

    +ACCESSIBILITY_SPEAK_PASSWORD +
    +ACTION_UUID +
    +ALLOWED_ATTENDEE_TYPES +
    +ALLOWED_AVAILABILITY +
    +AVAILABILITY_TENTATIVE +
    + +
    C  +A +E +F +G +I +K +L +M +Q +R +T +W + TOP +

    +CALENDAR_COLOR_KEY +
    +CATEGORY_APP_BROWSER +
    +CATEGORY_APP_CALCULATOR +
    +CATEGORY_APP_CALENDAR +
    +CATEGORY_APP_CONTACTS +
    +CATEGORY_APP_EMAIL +
    +CATEGORY_APP_GALLERY +
    +CATEGORY_APP_MAPS +
    +CATEGORY_APP_MESSAGING +
    +CATEGORY_APP_MUSIC +
    + +
    E  +A +C +F +G +I +K +L +M +Q +R +T +W + TOP +

    +EVENT_COLOR_KEY +
    +EXTRA_UUID +
    + +
    F  +A +C +E +G +I +K +L +M +Q +R +T +W + TOP +

    +FILL_IN_SELECTOR +
    +FLAG_AUTO_CORRECTION +
    + +
    G  +A +C +E +F +I +K +L +M +Q +R +T +W + TOP +

    +GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES +
    +GL_SAMPLER_EXTERNAL_OES +
    +GL_TEXTURE_BINDING_EXTERNAL_OES +
    +GL_TEXTURE_EXTERNAL_OES +
    + +
    I  +A +C +E +F +G +K +L +M +Q +R +T +W + TOP +

    +ICE_CREAM_SANDWICH_MR1 +
    + +
    K  +A +C +E +F +G +I +L +M +Q +R +T +W + TOP +

    +KEY_FEATURE_EMBEDDED_SYNTHESIS +
    +KEY_FEATURE_NETWORK_SYNTHESIS +
    +KEYCODE_CALCULATOR +
    +KEYCODE_CALENDAR +
    +KEYCODE_CONTACTS +
    +KEYCODE_MUSIC +
    + +
    L  +A +C +E +F +G +I +K +M +Q +R +T +W + TOP +

    +LIKE_TRANSACTION +
    + +
    M  +A +C +E +F +G +I +K +L +Q +R +T +W + TOP +

    +METADATA_KEY_LOCATION +
    + +
    Q  +A +C +E +F +G +I +K +L +M +R +T +W + TOP +

    +QUALITY_QVGA +
    +QUALITY_TIME_LAPSE_QVGA +
    + +
    R  +A +C +E +F +G +I +K +L +M +Q +T +W + TOP +

    +READ_SOCIAL_STREAM +
    +RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS +
    + +
    T  +A +C +E +F +G +I +K +L +M +Q +R +W + TOP +

    +TYPE_RESOURCE +
    + +
    W  +A +C +E +F +G +I +K +L +M +Q +R +T + TOP +

    +WRITE_SOCIAL_STREAM +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/fields_index_all.html b/docs/html/sdk/api_diff/15/changes/fields_index_all.html new file mode 100644 index 0000000000000..66fbf8f9938f3 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/fields_index_all.html @@ -0,0 +1,379 @@ + + + + + + + + + +Field Differences Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +Fields +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    A  +B +C +E +F +G +I +K +L +M +Q +R +T +W + TOP +

    +ACCESSIBILITY_SPEAK_PASSWORD +
    +ACTION_UUID +
    +ALLOWED_ATTENDEE_TYPES +
    +ALLOWED_AVAILABILITY +
    +AVAILABILITY_TENTATIVE +
    + +
    B  +A +C +E +F +G +I +K +L +M +Q +R +T +W + TOP +

    +BIND_ADJUST_WITH_ACTIVITY +
    + +
    C  +A +B +E +F +G +I +K +L +M +Q +R +T +W + TOP +

    +CALENDAR_COLOR_KEY +
    +CATEGORY_APP_BROWSER +
    +CATEGORY_APP_CALCULATOR +
    +CATEGORY_APP_CALENDAR +
    +CATEGORY_APP_CONTACTS +
    +CATEGORY_APP_EMAIL +
    +CATEGORY_APP_GALLERY +
    +CATEGORY_APP_MAPS +
    +CATEGORY_APP_MESSAGING +
    +CATEGORY_APP_MUSIC +
    + +
    E  +A +B +C +F +G +I +K +L +M +Q +R +T +W + TOP +

    +EVENT_COLOR_KEY +
    +EXTRA_UUID +
    + +
    F  +A +B +C +E +G +I +K +L +M +Q +R +T +W + TOP +

    +FILL_IN_SELECTOR +
    +FLAG_AUTO_CORRECTION +
    + +
    G  +A +B +C +E +F +I +K +L +M +Q +R +T +W + TOP +

    +GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES +
    +GL_SAMPLER_EXTERNAL_OES +
    +GL_TEXTURE_BINDING_EXTERNAL_OES +
    +GL_TEXTURE_EXTERNAL_OES +
    + +
    I  +A +B +C +E +F +G +K +L +M +Q +R +T +W + TOP +

    +ICE_CREAM_SANDWICH_MR1 +
    +INTENT_ACTION_MUSIC_PLAYER +
    + +
    K  +A +B +C +E +F +G +I +L +M +Q +R +T +W + TOP +

    +KEY_FEATURE_EMBEDDED_SYNTHESIS +
    +KEY_FEATURE_NETWORK_SYNTHESIS +
    +KEYCODE_CALCULATOR +
    +KEYCODE_CALENDAR +
    +KEYCODE_CONTACTS +
    +KEYCODE_MUSIC +
    + +
    L  +A +B +C +E +F +G +I +K +M +Q +R +T +W + TOP +

    +LIKE_TRANSACTION +
    + +
    M  +A +B +C +E +F +G +I +K +L +Q +R +T +W + TOP +

    +METADATA_KEY_LOCATION +
    + +
    Q  +A +B +C +E +F +G +I +K +L +M +R +T +W + TOP +

    +QUALITY_QVGA +
    +QUALITY_TIME_LAPSE_QVGA +
    + +
    R  +A +B +C +E +F +G +I +K +L +M +Q +T +W + TOP +

    +READ_SOCIAL_STREAM +
    +RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS +
    + +
    T  +A +B +C +E +F +G +I +K +L +M +Q +R +W + TOP +

    +TYPE_RESOURCE +
    + +
    W  +A +B +C +E +F +G +I +K +L +M +Q +R +T + TOP +

    +WRITE_SOCIAL_STREAM +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/fields_index_changes.html b/docs/html/sdk/api_diff/15/changes/fields_index_changes.html new file mode 100644 index 0000000000000..82b093dcb156e --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/fields_index_changes.html @@ -0,0 +1,75 @@ + + + + + + + + + +Field Changes Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Fields +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    B  +I + TOP +

    +BIND_ADJUST_WITH_ACTIVITY +
    + +
    I  +B + TOP +

    +INTENT_ACTION_MUSIC_PLAYER +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/fields_index_removals.html b/docs/html/sdk/api_diff/15/changes/fields_index_removals.html new file mode 100644 index 0000000000000..9f62d88abf0d9 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/fields_index_removals.html @@ -0,0 +1,61 @@ + + + + + + + + + +Field Removals Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Fields +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/jdiff_help.html b/docs/html/sdk/api_diff/15/changes/jdiff_help.html new file mode 100644 index 0000000000000..415299866a344 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/jdiff_help.html @@ -0,0 +1,134 @@ + + + + + + + + + +JDiff Help + + + + + + + + + + + + + + + + + +
    Generated by
    JDiff
    +
    + +
    +

    JDiff Documentation

    +
    +
    +JDiff is a Javadoc doclet which generates a report of the API differences between two versions of a product. It does not report changes in Javadoc comments, or changes in what a class or method does. +This help page describes the different parts of the output from JDiff. +
    +
    + See the reference page in the source for JDiff for information about how to generate a report like this one. +
    +
    +The indexes shown in the top-left frame help show each type of change in more detail. The index "All Differences" contains all the differences between the APIs, in alphabetical order. +These indexes all use the same format: +
      +
    • Removed packages, classes, constructors, methods and fields are struck through.
    • +
    • Added packages, classes, constructors, methods and fields appear in bold.
    • +
    • Changed packages, classes, constructors, methods and fields appear in normal text.
    • +
    +
    +
    +You can always tell when you are reading a JDiff page, rather than a Javadoc page, by the color of the index bar and the color of the background. +Links which take you to a Javadoc page are always in a typewriter font. +Just like Javadoc, all interface names are in italic, and class names are not italicized. Where there are multiple entries in an index with the same name, the heading for them is also in italics, but is not a link. +
    +
    +

    Javadoc

    +This is a link to the top-level Javadoc page for the new version of the product. +
    +
    +

    Overview

    +The overview is the top-level summary of what was removed, added and changed between versions. +
    +
    +

    Package

    +This is a link to the package containing the current changed class or interface. +
    +
    +

    Class

    +This is highlighted when you are looking at the changed class or interface. +
    +
    +

    Text Changes

    +This is a link to the top-level index of all documentation changes for the current package or class. +If it is not present, then there are no documentation changes for the current package or class. +This link can be removed entirely by not using the -docchanges option. +
    +
    +

    Statistics

    +This is a link to a page which shows statistics about the changes between the two APIs. +This link can be removed entirely by not using the -stats option. +
    +
    +

    Help

    +A link to this Help page for JDiff. +
    +
    +

    Prev/Next

    +These links take you to the previous and next changed package or class. +
    +
    +

    Frames/No Frames

    +These links show and hide the HTML frames. All pages are available with or without frames. +
    +
    +

    Complex Changes

    +There are some complex changes which can occur between versions, for example, when two or more methods with the same name change simultaneously, or when a method or field is moved into or from a superclass. +In these cases, the change will be seen as a removal and an addition, rather than as a change. Unexpected removals or additions are often part of one of these type of changes. +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/jdiff_statistics.html b/docs/html/sdk/api_diff/15/changes/jdiff_statistics.html new file mode 100644 index 0000000000000..2c15e7659d0a0 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/jdiff_statistics.html @@ -0,0 +1,447 @@ + + + + + + + + + +API Change Statistics + + + + + + + + + + +
    +
    +
    +

    API Change Statistics

    +

    The overall difference between API Levels 14 and 15 is approximately 0.14%. +

    +
    + +

    Total of Differences, by Number and Type

    +

    +The table below lists the numbers of program elements (packages, classes, constructors, methods, and fields) that were added, changed, or removed. The table includes only the highest-level program elements — that is, if a class with two methods was added, the number of methods added does not include those two methods, but the number of classes added does include that class. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TypeAdditionsChangesRemovalsTotal
    Packages021021
    Classes and Interfaces1234046
    Constructors2103
    Methods253028
    Fields382040
    Total77610138
    +
    + +

    Changed Packages, Sorted by Percentage Difference

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Percentage Difference*Package
    7android.speech.tts
    3android.service.textservice
    2android.provider
    2android.database
    1android.view.textservice
    1android.os
    1android.service.wallpaper
    1android.appwidget
    <1android.view.accessibility
    <1android.webkit
    <1android.bluetooth
    <1android.media
    <1android.graphics
    <1android.text.style
    <1android.hardware
    <1android.opengl
    <1android.content
    <1android
    <1android.app
    <1android.view
    <1android.widget
    +

    * See Calculation of Change Percentages, below.

    +
    + +

    Changed Classes and Interfaces, Sorted by Percentage Difference

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Percentage
    Difference*
    Class or Interface
    33 +android.os.RemoteException
    25 +android.webkit.WebSettings.LayoutAlgorithm
    7 +android.graphics.SurfaceTexture
    7 +android.view.textservice.SpellCheckerSession
    7 +android.bluetooth.BluetoothDevice
    6 +android.provider.CalendarContract.CalendarColumns
    6 +android.service.textservice.SpellCheckerService.Session
    6 +android.speech.tts.TextToSpeechService
    5 +android.appwidget.AppWidgetHostView
    4 +android.view.accessibility.AccessibilityRecord
    4 +android.database.CursorWindow
    4 +android.speech.tts.TextToSpeech
    4 +android.speech.tts.TextToSpeech.Engine
    3 +android.view.textservice.SuggestionsInfo
    3 +android.media.CamcorderProfile
    3 +android.os.Build.VERSION_CODES
    3 +android.os.IBinder
    2 +android.provider.CalendarContract.AttendeesColumns
    2 +android.service.wallpaper.WallpaperService.Engine
    2 +android.text.style.SuggestionSpan
    2 +android.content.Intent
    1 +android.provider.MediaStore
    1 +android.provider.CalendarContract.EventsColumns
    1 +android.app.Fragment
    1 +android.media.MediaMetadataRetriever
    1 +android.widget.RemoteViews
    1 +android.hardware.Camera.Parameters
    1 +android.webkit.WebSettings
    <1 +android.opengl.GLES11Ext
    <1 +android.Manifest.permission
    <1 +android.provider.Settings.Secure
    <1 +android.view.KeyEvent
    <1 +android.content.Context
    <1 +android.view.View
    +

    * See Calculation of Change Percentages, below.

    +
    +

    Calculation of Change Percentages

    +

    +The percent change statistic reported for all elements in the "to" API Level specification is defined recursively as follows:

    +
    +Percentage difference = 100 * (added + removed + 2*changed)
    +                        -----------------------------------
    +                        sum of public elements in BOTH APIs
    +
    +

    where added is the number of packages added, removed is the number of packages removed, and changed is the number of packages changed. +This definition is applied recursively for the classes and their program elements, so the value for a changed package will be less than 1, unless every class in that package has changed. +The definition ensures that if all packages are removed and all new packages are +added, the change will be 100%.

    +
    + +
    +
    + + + diff --git a/docs/html/sdk/api_diff/15/changes/jdiff_topleftframe.html b/docs/html/sdk/api_diff/15/changes/jdiff_topleftframe.html new file mode 100644 index 0000000000000..36f9836e44784 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/jdiff_topleftframe.html @@ -0,0 +1,63 @@ + + + + + + + + + +Android API Version Differences + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Select a Diffs Index:
    All Differences
    By Package
    By Class
    By Constructor
    By Method
    By Field
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/methods_index_additions.html b/docs/html/sdk/api_diff/15/changes/methods_index_additions.html new file mode 100644 index 0000000000000..260ec1e30c30d --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/methods_index_additions.html @@ -0,0 +1,199 @@ + + + + + + + + + +Method Additions Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Methods +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    C  +F +G +H +I +M +O +S + TOP +

    +callOnClick +()
    +cancel +()
    + +
    F  +C +G +H +I +M +O +S + TOP +

    +fetchUuidsWithSdp +()
    + +
    G  +C +F +H +I +M +O +S + TOP +

    +getDefaultPaddingForWidget +(Context, ComponentName, Rect)
    +getFeatures +(Locale)
    +getMaxScrollX +()
    +getMaxScrollY +()
    +getSelector +()
    +getUserVisibleHint +()
    +getUuids +()
    +getVideoStabilization +()
    + +
    H  +C +F +G +I +M +O +S + TOP +

    +hasOnClickListeners +()
    + +
    I  +C +F +G +H +M +O +S + TOP +

    +isVideoStabilizationSupported +()
    + +
    M  +C +F +G +H +I +O +S + TOP +

    +makeMainSelectorActivity +(String, String)
    + +
    O  +C +F +G +H +I +M +S + TOP +

    +onClose +()
    +onGetFeaturesForLanguage +(String, String, String)
    + +
    S  +C +F +G +H +I +M +O + TOP +

    +setContentDescription +(int, CharSequence)
    +setDefaultBufferSize +(int, int)
    +setMaxScrollX +(int)
    +setMaxScrollY +(int)
    +setOffsetNotificationsEnabled +(boolean)
    +setOnUtteranceProgressListener +(UtteranceProgressListener)
    +setSelector +(Intent)
    +setUserVisibleHint +(boolean)
    +setVideoStabilization +(boolean)
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/methods_index_all.html b/docs/html/sdk/api_diff/15/changes/methods_index_all.html new file mode 100644 index 0000000000000..2f0e7348593b7 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/methods_index_all.html @@ -0,0 +1,205 @@ + + + + + + + + + +Method Differences Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +Methods +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    C  +F +G +H +I +M +O +S + TOP +

    +callOnClick +()
    +cancel +()
    + +
    F  +C +G +H +I +M +O +S + TOP +

    +fetchUuidsWithSdp +()
    + +
    G  +C +F +H +I +M +O +S + TOP +

    +getDefaultPaddingForWidget +(Context, ComponentName, Rect)
    +getFeatures +(Locale)
    +getLayoutAlgorithm +()
    +getMaxScrollX +()
    +getMaxScrollY +()
    +getSelector +()
    +getUserVisibleHint +()
    +getUuids +()
    +getVideoStabilization +()
    + +
    H  +C +F +G +I +M +O +S + TOP +

    +hasOnClickListeners +()
    + +
    I  +C +F +G +H +M +O +S + TOP +

    +isVideoStabilizationSupported +()
    + +
    M  +C +F +G +H +I +O +S + TOP +

    +makeMainSelectorActivity +(String, String)
    + +
    O  +C +F +G +H +I +M +S + TOP +

    +onClose +()
    +onGetFeaturesForLanguage +(String, String, String)
    + +
    S  +C +F +G +H +I +M +O + TOP +

    +setContentDescription +(int, CharSequence)
    +setDefaultBufferSize +(int, int)
    +setLayoutAlgorithm +(LayoutAlgorithm)
    +setMaxScrollX +(int)
    +setMaxScrollY +(int)
    +setOffsetNotificationsEnabled +(boolean)
    +setOnUtteranceCompletedListener +(OnUtteranceCompletedListener)
    +setOnUtteranceProgressListener +(UtteranceProgressListener)
    +setSelector +(Intent)
    +setUserVisibleHint +(boolean)
    +setVideoStabilization +(boolean)
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/methods_index_changes.html b/docs/html/sdk/api_diff/15/changes/methods_index_changes.html new file mode 100644 index 0000000000000..d22fde31835eb --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/methods_index_changes.html @@ -0,0 +1,77 @@ + + + + + + + + + +Method Changes Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Methods +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + +
    G  +S + TOP +

    +getLayoutAlgorithm +()
    + +
    S  +G + TOP +

    +setLayoutAlgorithm +(LayoutAlgorithm)
    +setOnUtteranceCompletedListener +(OnUtteranceCompletedListener)
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/methods_index_removals.html b/docs/html/sdk/api_diff/15/changes/methods_index_removals.html new file mode 100644 index 0000000000000..b5aea4f9d673d --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/methods_index_removals.html @@ -0,0 +1,61 @@ + + + + + + + + + +Method Removals Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Methods +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/packages_index_additions.html b/docs/html/sdk/api_diff/15/changes/packages_index_additions.html new file mode 100644 index 0000000000000..1776064fe6a99 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/packages_index_additions.html @@ -0,0 +1,63 @@ + + + + + + + + + +Package Additions Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Packages +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/packages_index_all.html b/docs/html/sdk/api_diff/15/changes/packages_index_all.html new file mode 100644 index 0000000000000..ef665684fc5f7 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/packages_index_all.html @@ -0,0 +1,85 @@ + + + + + + + + + +Package Differences Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +Packages +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    +
    +
    + +android
    +android.app
    +android.appwidget
    +android.bluetooth
    +android.content
    +android.database
    +android.graphics
    +android.hardware
    +android.media
    +android.opengl
    +android.os
    +android.provider
    +android.service.textservice
    +android.service.wallpaper
    +android.speech.tts
    +android.text.style
    +android.view
    +android.view.accessibility
    +android.view.textservice
    +android.webkit
    +android.widget
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/packages_index_changes.html b/docs/html/sdk/api_diff/15/changes/packages_index_changes.html new file mode 100644 index 0000000000000..a2b0a19152256 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/packages_index_changes.html @@ -0,0 +1,85 @@ + + + + + + + + + +Package Changes Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Packages +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    +
    +
    + +android
    +android.app
    +android.appwidget
    +android.bluetooth
    +android.content
    +android.database
    +android.graphics
    +android.hardware
    +android.media
    +android.opengl
    +android.os
    +android.provider
    +android.service.textservice
    +android.service.wallpaper
    +android.speech.tts
    +android.text.style
    +android.view
    +android.view.accessibility
    +android.view.textservice
    +android.webkit
    +android.widget
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/packages_index_removals.html b/docs/html/sdk/api_diff/15/changes/packages_index_removals.html new file mode 100644 index 0000000000000..9fd0f7e9a8e7d --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/packages_index_removals.html @@ -0,0 +1,63 @@ + + + + + + + + + +Package Removals Index + + + + + + + + + + + + + + + +
    + Filter the Index: +
    +All Packages +
    +Removals +
    +Additions +
    +Changes +
    +
    +Listed as: Added, Removed, Changed +
    +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.app.html b/docs/html/sdk/api_diff/15/changes/pkg_android.app.html new file mode 100644 index 0000000000000..1b2e65b1aee94 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.app.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.app + + + + + + + + + + +
    +
    +
    +

    +Package android.app +

    +

    + + + + + + + + +
    Changed Classes +
    + + Fragment +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.appwidget.html b/docs/html/sdk/api_diff/15/changes/pkg_android.appwidget.html new file mode 100644 index 0000000000000..46bc1dc03e091 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.appwidget.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.appwidget + + + + + + + + + + +
    +
    +
    +

    +Package android.appwidget +

    +

    + + + + + + + + +
    Changed Classes +
    + + AppWidgetHostView +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.bluetooth.html b/docs/html/sdk/api_diff/15/changes/pkg_android.bluetooth.html new file mode 100644 index 0000000000000..16e9db7369cd0 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.bluetooth.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.bluetooth + + + + + + + + + + +
    +
    +
    +

    +Package android.bluetooth +

    +

    + + + + + + + + +
    Changed Classes +
    + + BluetoothDevice +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.content.html b/docs/html/sdk/api_diff/15/changes/pkg_android.content.html new file mode 100644 index 0000000000000..036a96e03883c --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.content.html @@ -0,0 +1,126 @@ + + + + + + + + + +android.content + + + + + + + + + + +
    +
    +
    +

    +Package android.content +

    +

    + + + + + + + + + + + + +
    Changed Classes +
    + + Context +  
    + + Intent +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.database.html b/docs/html/sdk/api_diff/15/changes/pkg_android.database.html new file mode 100644 index 0000000000000..a8a2963ce37d5 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.database.html @@ -0,0 +1,134 @@ + + + + + + + + + +android.database + + + + + + + + + + +
    +
    +
    +

    +Package android.database +

    +

    + + + + + + + + +
    Added Classes +
    + + CrossProcessCursorWrapper +  
    +  +

    + + + + + + + + +
    Changed Classes +
    + + CursorWindow +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.graphics.html b/docs/html/sdk/api_diff/15/changes/pkg_android.graphics.html new file mode 100644 index 0000000000000..838846647c20e --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.graphics.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.graphics + + + + + + + + + + +
    +
    +
    +

    +Package android.graphics +

    +

    + + + + + + + + +
    Changed Classes +
    + + SurfaceTexture +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.hardware.html b/docs/html/sdk/api_diff/15/changes/pkg_android.hardware.html new file mode 100644 index 0000000000000..7b0273533f9af --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.hardware.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.hardware + + + + + + + + + + +
    +
    +
    +

    +Package android.hardware +

    +

    + + + + + + + + +
    Changed Classes +
    + + Camera.Parameters +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.html b/docs/html/sdk/api_diff/15/changes/pkg_android.html new file mode 100644 index 0000000000000..3af011e815893 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.html @@ -0,0 +1,119 @@ + + + + + + + + + +android + + + + + + + + + + +
    +
    +
    +

    +Package android +

    +

    + + + + + + + + +
    Changed Classes +
    + + Manifest.permission +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.media.html b/docs/html/sdk/api_diff/15/changes/pkg_android.media.html new file mode 100644 index 0000000000000..e537fc9a326d2 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.media.html @@ -0,0 +1,126 @@ + + + + + + + + + +android.media + + + + + + + + + + +
    +
    +
    +

    +Package android.media +

    +

    + + + + + + + + + + + + +
    Changed Classes +
    + + CamcorderProfile +  
    + + MediaMetadataRetriever +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.opengl.html b/docs/html/sdk/api_diff/15/changes/pkg_android.opengl.html new file mode 100644 index 0000000000000..dff132d2938a5 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.opengl.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.opengl + + + + + + + + + + +
    +
    +
    +

    +Package android.opengl +

    +

    + + + + + + + + +
    Changed Classes +
    + + GLES11Ext +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.os.html b/docs/html/sdk/api_diff/15/changes/pkg_android.os.html new file mode 100644 index 0000000000000..ba005a0f60e6b --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.os.html @@ -0,0 +1,148 @@ + + + + + + + + + +android.os + + + + + + + + + + +
    +
    +
    +

    +Package android.os +

    +

    + + + + + + + + +
    Added Classes +
    + + TransactionTooLargeException +  
    +  +

    + + + + + + + + + + + + + + + + +
    Changed Classes and Interfaces +
    + + Build.VERSION_CODES +  
    + + IBinder +  
    + + RemoteException +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.provider.html b/docs/html/sdk/api_diff/15/changes/pkg_android.provider.html new file mode 100644 index 0000000000000..93209facf4505 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.provider.html @@ -0,0 +1,218 @@ + + + + + + + + + +android.provider + + + + + + + + + + +
    +
    +
    +

    +Package android.provider +

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Added Classes and Interfaces +
    + + CalendarContract.Colors +  
    + + CalendarContract.ColorsColumns +  
    + + ContactsContract.Contacts.
    StreamItems
    +
     
    + + ContactsContract.RawContacts.
    StreamItems
    +
     
    + + ContactsContract.StreamItemPhotos +  
    + + ContactsContract.StreamItemPhotosColumns +  
    + + ContactsContract.StreamItems +  
    + + ContactsContract.StreamItems.
    StreamItemPhotos
    +
     
    + + ContactsContract.StreamItemsColumns +  
    +  +

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Changed Classes and Interfaces +
    + + CalendarContract.AttendeesColumns +  
    + + CalendarContract.CalendarColumns +  
    + + CalendarContract.EventsColumns +  
    + + MediaStore +  
    + + Settings.Secure +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.service.textservice.html b/docs/html/sdk/api_diff/15/changes/pkg_android.service.textservice.html new file mode 100644 index 0000000000000..5a14d82a5fad2 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.service.textservice.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.service.textservice + + + + + + + + + + +
    +
    +
    +

    +Package android.service.textservice +

    +

    + + + + + + + + +
    Changed Classes +
    + + SpellCheckerService.Session +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.service.wallpaper.html b/docs/html/sdk/api_diff/15/changes/pkg_android.service.wallpaper.html new file mode 100644 index 0000000000000..b6f52e4548e75 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.service.wallpaper.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.service.wallpaper + + + + + + + + + + +
    +
    +
    +

    +Package android.service.wallpaper +

    +

    + + + + + + + + +
    Changed Classes +
    + + WallpaperService.Engine +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.speech.tts.html b/docs/html/sdk/api_diff/15/changes/pkg_android.speech.tts.html new file mode 100644 index 0000000000000..1afe9e3a842ab --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.speech.tts.html @@ -0,0 +1,148 @@ + + + + + + + + + +android.speech.tts + + + + + + + + + + +
    +
    +
    +

    +Package android.speech.tts +

    +

    + + + + + + + + +
    Added Classes +
    + + UtteranceProgressListener +  
    +  +

    + + + + + + + + + + + + + + + + +
    Changed Classes +
    + + TextToSpeech +  
    + + TextToSpeech.Engine +  
    + + TextToSpeechService +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.text.style.html b/docs/html/sdk/api_diff/15/changes/pkg_android.text.style.html new file mode 100644 index 0000000000000..5936ed56cae52 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.text.style.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.text.style + + + + + + + + + + +
    +
    +
    +

    +Package android.text.style +

    +

    + + + + + + + + +
    Changed Classes +
    + + SuggestionSpan +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.view.accessibility.html b/docs/html/sdk/api_diff/15/changes/pkg_android.view.accessibility.html new file mode 100644 index 0000000000000..7cca96d5df55a --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.view.accessibility.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.view.accessibility + + + + + + + + + + +
    +
    +
    +

    +Package android.view.accessibility +

    +

    + + + + + + + + +
    Changed Classes +
    + + AccessibilityRecord +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.view.html b/docs/html/sdk/api_diff/15/changes/pkg_android.view.html new file mode 100644 index 0000000000000..a9c91e07cb5e0 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.view.html @@ -0,0 +1,126 @@ + + + + + + + + + +android.view + + + + + + + + + + +
    +
    +
    +

    +Package android.view +

    +

    + + + + + + + + + + + + +
    Changed Classes +
    + + KeyEvent +  
    + + View +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.view.textservice.html b/docs/html/sdk/api_diff/15/changes/pkg_android.view.textservice.html new file mode 100644 index 0000000000000..2d874b2f62261 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.view.textservice.html @@ -0,0 +1,126 @@ + + + + + + + + + +android.view.textservice + + + + + + + + + + +
    +
    +
    +

    +Package android.view.textservice +

    +

    + + + + + + + + + + + + +
    Changed Classes +
    + + SpellCheckerSession +  
    + + SuggestionsInfo +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.webkit.html b/docs/html/sdk/api_diff/15/changes/pkg_android.webkit.html new file mode 100644 index 0000000000000..ad6337812138d --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.webkit.html @@ -0,0 +1,126 @@ + + + + + + + + + +android.webkit + + + + + + + + + + +
    +
    +
    +

    +Package android.webkit +

    +

    + + + + + + + + + + + + +
    Changed Classes +
    + + WebSettings +  
    + + WebSettings.LayoutAlgorithm +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/changes/pkg_android.widget.html b/docs/html/sdk/api_diff/15/changes/pkg_android.widget.html new file mode 100644 index 0000000000000..02e4b8069f0f1 --- /dev/null +++ b/docs/html/sdk/api_diff/15/changes/pkg_android.widget.html @@ -0,0 +1,119 @@ + + + + + + + + + +android.widget + + + + + + + + + + +
    +
    +
    +

    +Package android.widget +

    +

    + + + + + + + + +
    Changed Classes +
    + + RemoteViews +  
    +  +

    + +
    +
    + + + + diff --git a/docs/html/sdk/api_diff/15/stylesheet-jdiff.css b/docs/html/sdk/api_diff/15/stylesheet-jdiff.css new file mode 100644 index 0000000000000..edafaa3da3e52 --- /dev/null +++ b/docs/html/sdk/api_diff/15/stylesheet-jdiff.css @@ -0,0 +1,44 @@ + +/* (http://www.jdiff.org) */ + +div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;} +table.diffspectable {border:1px;padding:0px;margin:0px;} +.diffspechead {background-color:#eee;} +.diffspectable tr {border:0px;padding:0px;} +.diffspectable td {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;} +td.diffvalueold {color:orange;background-color:white;border:0px;font-size:80%;font-style:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;} +td.diffvaluenew {color:green;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;} +td.diffvalue {color:444;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;} +td.diffspec {background-color:white;border:0px;font-size:80%;font-weight:normal;padding:1px;color:444;text-align:right;padding-right:.5em;line-height:.95em;} +tt {font-size:11pt;font-family:monospace;} +.indexHeader { + font-size:96%; + line-height:.8em;} +.jdiffIndex td { + font-size:96%; + xline-height:.8em; + padding:2px; + padding-left:1em;} +.indexText { + font-size:100%; + padding-left:1em;} +#indexTableCaption { + font-size:96%; + margin-top:.25em; + margin-bottom:0; + } +.hiddenlink { + font-size:96%; + line-height:.8em; + text-decoration:none;} +a { + text-decoration:none;} +a:hover { + text-decoration:underline;} +.indexBox { + border: 1px solid red; + margin:1em 0 0 0;} +.letterIndexHead { + font-size: 1.5em;font-weight:9; + margin:0 0 0em 0; + border: 1px solid red;} From 604e4ed4814169f85312a1ca788b81c819b9f049 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Tue, 13 Dec 2011 18:24:34 -0800 Subject: [PATCH 3/8] doc change: Android U lessons for audio and battery Change-Id: I98d83f8458e3ad62be28d09b85fe099916d1b73d --- .../training/managing-audio/audio-focus.jd | 183 ++++++++++++++++++ .../training/managing-audio/audio-output.jd | 88 +++++++++ docs/html/training/managing-audio/index.jd | 62 ++++++ .../managing-audio/volume-playback.jd | 156 +++++++++++++++ .../battery-monitoring.jd | 156 +++++++++++++++ .../connectivity-monitoring.jd | 90 +++++++++ .../docking-monitoring.jd | 90 +++++++++ .../training/monitoring-device-state/index.jd | 63 ++++++ .../manifest-receivers.jd | 64 ++++++ 9 files changed, 952 insertions(+) create mode 100644 docs/html/training/managing-audio/audio-focus.jd create mode 100644 docs/html/training/managing-audio/audio-output.jd create mode 100644 docs/html/training/managing-audio/index.jd create mode 100644 docs/html/training/managing-audio/volume-playback.jd create mode 100644 docs/html/training/monitoring-device-state/battery-monitoring.jd create mode 100644 docs/html/training/monitoring-device-state/connectivity-monitoring.jd create mode 100644 docs/html/training/monitoring-device-state/docking-monitoring.jd create mode 100644 docs/html/training/monitoring-device-state/index.jd create mode 100644 docs/html/training/monitoring-device-state/manifest-receivers.jd diff --git a/docs/html/training/managing-audio/audio-focus.jd b/docs/html/training/managing-audio/audio-focus.jd new file mode 100644 index 0000000000000..07a4465f2bed5 --- /dev/null +++ b/docs/html/training/managing-audio/audio-focus.jd @@ -0,0 +1,183 @@ +page.title=Managing Audio Focus +parent.title=Managing Audio Playback and Focus +parent.link=index.html + +trainingnavtop=true +previous.title=Controlling Your App's Volume and Playback +previous.link=volume-playback.html +next.title=Dealing with Audio Output Hardware +next.link=audio-output.html + +@jd:body + + +
    +
    + +

    This lesson teaches you to

    +
      +
    1. Request the Audio Focus
    2. +
    3. Handle the Loss of Audio Focus
    4. +
    5. Duck!
    6. +
    + + +

    You should also read

    + + +
    +
    + + +

    With multiple apps potentially playing audio it's important to think about how they should +interact. To avoid every music app playing at the same time, Android uses audio focus to moderate +audio playback—only apps that hold the audio focus should play audio.

    + +

    Before your app starts playing audio it should request—and receive—the audio focus. +Likewise, it should know how to listen for a loss of audio focus and respond appropriately when that +happens.

    + + +

    Request the Audio Focus

    + +

    Before your app starts playing any audio, it should hold the audio focus for the stream +it will be using. This is done with a call to {@link android.media.AudioManager#requestAudioFocus +requestAudioFocus()} which returns +{@link android.media.AudioManager#AUDIOFOCUS_REQUEST_GRANTED} if your request is successful.

    + +

    You must specify which stream you're using and whether you expect to require transient or +permanent audio focus. Request transient focus when you expect to play audio for only a short time +(for example when playing navigation instructions). Request permanent audio focus when you +plan to play audio for the foreseeable future (for example, when playing music).

    + +

    The following snippet requests permanent audio focus on the music audio stream. You should +request the audio focus immediately before you begin playback, such as when the user presses +play or the background music for the next game level begins.

    + +
    +AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
    +...
    +
    +// Request audio focus for playback
    +int result = am.requestAudioFocus(afChangeListener,
    +                                 // Use the music stream.
    +                                 AudioManager.STREAM_MUSIC,
    +                                 // Request permanent focus.
    +                                 AudioManager.AUDIOFOCUS_GAIN);
    +   
    +if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
    +    am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
    +    // Start playback.
    +}
    +
    + +

    Once you've finished playback be sure to call {@link +android.media.AudioManager#abandonAudioFocus abandonAudioFocus()}. This notifies +the system that you no longer require focus and unregisters the associated {@link +android.media.AudioManager.OnAudioFocusChangeListener}. In the case of abandoning transient focus, +this allows any interupted app to continue playback.

    + +
    +// Abandon audio focus when playback complete    
    +am.abandonAudioFocus(afChangeListener);
    +
    + +

    When requesting transient audio focus you have an additional option: whether or not you want to +enable "ducking." Normally, when a well-behaved audio app loses audio focus it immediately +silences its playback. By requesting a transient audio focus that allows ducking you tell other +audio apps that it’s acceptable for them to keep playing, provided they lower their volume until the +focus returns to them.

    + +
    +// Request audio focus for playback
    +int result = am.requestAudioFocus(afChangeListener,
    +                             // Use the music stream.
    +                             AudioManager.STREAM_MUSIC,
    +                             // Request permanent focus.
    +                             AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
    +   
    +if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
    +    // Start playback.
    +}
    +
    + +

    Ducking is particularly suitable for apps that use the audio stream intermittently, such as for +audible driving directions.

    + +

    Whenever another app requests audio focus as described above, its choice between permanent and +transient (with or without support for ducking) audio focus is received by the listener you +registered when requesting focus.

    + + +

    Handle the Loss of Audio Focus

    + +

    If your app can request audio focus, it follows that it will in turn lose that focus when another +app requests it. How your app responds to a loss of audio focus depends on the manner of that +loss.

    + +

    The {@link android.media.AudioManager.OnAudioFocusChangeListener#onAudioFocusChange +onAudioFocusChange()} callback method of they audio focus change listener you registered when +requesting audio focus receives a parameter that describes the focus change event. Specifically, +the possible focus loss events mirror the focus request types from the previous +section—permanent loss, transient loss, and transient with ducking permitted.

    + +

    Generally speaking, a transient (temporary) loss of audio focus should result in your app +silencing it’s audio stream, but otherwise maintaining the same state. You should continue to +monitor changes in audio focus and be prepared to resume playback where it was paused once you’ve +regained the focus.

    + +

    If the audio focus loss is permanent, it’s assumed that another application is now being used to +listen to audio and your app should effectively end itself. In practical terms, that means stopping +playback, removing media button listeners—allowing the new audio player to exclusively handle +those events—and abandoning your audio focus. At that point, you would expect a user action +(pressing play in your app) to be required before you resume playing audio.

    + +

    In the following code snippet, we pause the playback or our media player object if the audio +loss is transien and resume it when we have regained the focus. If the loss is permanent, it +unregisters our media button event receiver and stops monitoring audio focus changes.

    + +

    +OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
    +    public void onAudioFocusChange(int focusChange) {
    +        if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT
    +            // Pause playback
    +        } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
    +            // Resume playback 
    +        } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
    +            am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
    +            am.abandonAudioFocus(afChangeListener);
    +            // Stop playback
    +        }
    +    }
    +};
    +
    + +

    In the case of a transient loss of audio focus where ducking is permitted, rather than pausing +playback, you can "duck" instead.

    + + +

    Duck!

    + +

    Ducking is the process of lowering your audio stream output volume to make transient audio from +another app easier to hear without totally disrupting the audio from your own application.

    + +

    In the following code snippet lowers the volume on our media player object when we temporarily +lose focus, then returns it to its previous level when we regain focus.

    + +
    +OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
    +    public void onAudioFocusChange(int focusChange) {
    +        if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
    +            // Lower the volume
    +        } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
    +            // Raise it back to normal
    +        }
    +    }
    +};
    +
    + +

    A loss of audio focus is the most important broadcast to react to, but not the only one. The +system broadcasts a number of intents to alert you to changes in user’s audio experience. +The next lesson demonstrates how to monitor them to improve the user’s overall experience.

    diff --git a/docs/html/training/managing-audio/audio-output.jd b/docs/html/training/managing-audio/audio-output.jd new file mode 100644 index 0000000000000..d5d7e4b97e0c8 --- /dev/null +++ b/docs/html/training/managing-audio/audio-output.jd @@ -0,0 +1,88 @@ +page.title=Dealing with Audio Output Hardware +parent.title=Managing Audio Playback and Focus +parent.link=index.html + +trainingnavtop=true +previous.title=Managing Audio Focus +previous.link=audio-focus.html + +@jd:body + + +
    +
    + +

    This lesson teaches you to

    +
      +
    1. Check What Hardware is Being Used
    2. +
    3. Handle Changes in the Audio Output Hardware
    4. +
    + + +

    You should also read

    + + + +
    +
    + +

    Users have a number of alternatives when it comes to enjoying the audio from their Android +devices. Most devices have a built-in speaker, headphone jacks for wired headsets, and many also +feature Bluetooth connectivity and support for A2DP audio.

    + + +

    Check What Hardware is Being Used

    + +

    How your app behaves might be affected by which hardware its output is being routed to.

    + +

    You can query the {@link android.media.AudioManager} to determine if the audio is currently +being routed to the device speaker, wired headset, or attached Bluetooth device as shown in the +following snippet:

    + +
    +if (isBluetoothA2dpOn()) {
    +    // Adjust output for Bluetooth.
    +} else if (isSpeakerphoneOn()) {
    +    // Adjust output for Speakerphone.
    +} else if (isWiredHeadsetOn()) {
    +    // Adjust output for headsets
    +} else { 
    +    // If audio plays and noone can hear it, is it still playing?
    +}
    +
    + + +

    Handle Changes in the Audio Output Hardware

    + +

    When a headset is unplugged, or a Bluetooth device disconnected, the audio stream +automatically reroutes to the built in speaker. If you listen to your music at as high a volume as I +do, that can be a noisy surprise.

    + +

    Luckily the system broadcasts an {@link android.media.AudioManager#ACTION_AUDIO_BECOMING_NOISY} +intent when this happens. It’s good practice to register a {@link android.content.BroadcastReceiver} +that listens for this intent whenever you’re playing audio. In the case of music players, users +typically expect the playback to be paused—while for games you may choose to significantly +lower the volume.

    + +
    +private class NoisyAudioStreamReceiver extends BroadcastReceiver {
    +    @Override
    +    public void onReceive(Context context, Intent intent) {
    +        if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
    +            // Pause the playback
    +        }
    +    }
    +}
    +
    +private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
    +
    +private void startPlayback() {
    +    registerReceiver(myNoisyAudioStreamReceiver(), intentFilter);
    +}
    +
    +private void stopPlayback() {
    +    unregisterReceiver(myNoisyAudioStreamReceiver);
    +}
    +
    diff --git a/docs/html/training/managing-audio/index.jd b/docs/html/training/managing-audio/index.jd new file mode 100644 index 0000000000000..c7df39be73543 --- /dev/null +++ b/docs/html/training/managing-audio/index.jd @@ -0,0 +1,62 @@ +page.title=Managing Audio Playback and Focus + +trainingnavtop=true +startpage=true +next.title=Controlling Your App's Volume and Playback +next.link=volume-playback.html + +@jd:body + +
    +
    + +

    Dependencies and prerequisites

    + + +

    You should also read

    + + +
    +
    + + +

    If your app plays audio, it’s important that your users can control the audio in a predictable +manner. To ensure a great user experience, it’s also important that your app manages the audio focus +to ensure multiple apps aren’t playing audio at the same time.

    + +

    After this class, you will be able to build apps that respond to hardware audio key presses, +which request audio focus when playing audio, and which respond appropriately to changes in audio +focus caused by the system or other applications.

    + + + + +

    Lessons

    + + + +
    +
    Controlling Your App’s Volume and +Playback
    +
    Learn how to ensure your users can control the volume of your app using the hardware or +software volume controls and where available the play, stop, pause, skip, and previous media +playback keys.
    + +
    Managing Audio Focus
    +
    With multiple apps potentially playing audio it's important to think about how they should +interact. To avoid every music app playing at the same time, Android uses audio focus to moderate +audio playback. Learn how to request the audio focus, listen for a loss of audio focus, and how to +respond when that happens.
    + +
    Dealing with Audio Output Hardware
    +
    Audio can be played from a number of sources. Learn how to find out where the audio is being +played and how to handle a headset being disconnected during playback.
    +
    \ No newline at end of file diff --git a/docs/html/training/managing-audio/volume-playback.jd b/docs/html/training/managing-audio/volume-playback.jd new file mode 100644 index 0000000000000..7038ddfbd7824 --- /dev/null +++ b/docs/html/training/managing-audio/volume-playback.jd @@ -0,0 +1,156 @@ +page.title=Controlling Your App’s Volume and Playback +parent.title=Managing Audio Playback and Focus +parent.link=index.html + +trainingnavtop=true +next.title=Managing Audio Focus +next.link=audio-focus.html + +@jd:body + + + + + + +

    A good user experience is a predictable one. If your app plays media it’s important that your +users can control the volume of your app using the hardware or software volume controls of their +device, bluetooth headset, or headphones.

    + +

    Similarly, where appropriate and available, the play, stop, pause, skip, and previous media +playback keys should perform their respective actions on the audio stream used by your app.

    + + +

    Identify Which Audio Stream to Use

    + +

    The first step to creating a predictable audio experience is understanding which audio stream +your app will use.

    + +

    Android maintains a separate audio stream for playing music, alarms, notifications, the incoming +call ringer, system sounds, in-call volume, and DTMF tones. This is done primarily to allow users to +control the volume of each stream independently.

    + +

    Most of these streams are restricted to system events, so unless your app is a replacement alarm +clock, you’ll almost certainly be playing your audio using the {@link +android.media.AudioManager#STREAM_MUSIC} stream.

    + + +

    Use Hardware Volume Keys to Control Your App’s Audio Volume

    + +

    By default, pressing the volume controls modify the volume of the active audio stream. If your +app isn't currently playing anything, hitting the volume keys adjusts the ringer volume.

    + +

    If you've got a game or music app, then chances are good that when the user hits the volume keys +they want to control the volume of the game or music, even if they’re currently between songs or +there’s no music in the current game location.

    + +

    You may be tempted to try and listen for volume key presses and modify the volume of your +audio stream that way. Resist the urge. Android provides the handy {@link +android.app.Activity#setVolumeControlStream setVolumeControlStream()} method to direct volume key +presses to the audio stream you specify.

    + +

    Having identified the audio stream your application +will be using, you should set it as the volume stream target. You should make this call early in +your app’s lifecycle—because you only need to call it once during the activity lifecycle, you +should typically call it within the {@code onCreate()} method (of the {@link +android.app.Activity} or {@link android.app.Fragment} that controls +your media). This ensures that whenever your app is visible, the +volume controls function as the user expects.

    + +

    +setVolumeControlStream(AudioManager.STREAM_MUSIC);
    +
    + + +

    From this point onwards, pressing the volume keys on the device affect the audio stream you +specify (in this case “music”) whenever the target activity or fragment is visible.

    + + +

    Use Hardware Playback Control Keys to Control Your App’s Audio +Playback

    + +

    Media playback buttons such as play, pause, stop, skip, and previous are available on some +handsets and many connected or wireless headsets. Whenever a user presses one of these hardware +keys, the system broadcasts an intent with the {@link android.content.Intent#ACTION_MEDIA_BUTTON} +action.

    + +

    To respond to media button clicks, you need to register a {@link +android.content.BroadcastReceiver} in your manifest that listens for this action broadcast as shown +below.

    + +
    +<receiver android:name=".RemoteControlReceiver">
    +    <intent-filter>
    +        <action android:name="android.intent.action.MEDIA_BUTTON" />
    +    </intent-filter>
    +</receiver>
    +
    + +

    The receiver implementation itself needs to extract which key was pressed to cause the broadcast. +The {@link android.content.Intent} includes this under the {@link +android.content.Intent#EXTRA_KEY_EVENT} key, while the {@link android.view.KeyEvent} class includes +a list {@code KEYCODE_MEDIA_*} static constants that represents each of the possible media +buttons, such as {@link android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE} and {@link +android.view.KeyEvent#KEYCODE_MEDIA_NEXT}.

    + +

    The following snippet shows how to extract the media button pressed and affects the media playback accordingly.

    + +
    +public class RemoteControlReceiver extends BroadcastReceiver {
    +    @Override
    +    public void onReceive(Context context, Intent intent) {
    +        if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
    +            KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
    +            if (KeyEvent.KEYCODE_MEDIA_PLAY == event.getKeyCode()) {
    +                // Handle key press.
    +            }
    +        }
    +    }
    +}
    +
    + +

    Because multiple applications might want to listen for media button presses, you must +also programmatically control when your app should receive media button press events.

    + +

    The following code can be used within your app to register and de-register your media button +event receiver using the {@link android.media.AudioManager}. When registered, your broadcast +receiver is the exclusive receiver of all media button broadcasts.

    + +

    +AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
    +...
    +
    +// Start listening for button presses
    +am.registerMediaButtonEventReceiver(RemoteControlReceiver);
    +...
    +
    +// Stop listening for button presses
    +am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
    +
    + +

    Typically, apps should unregister most of their receivers whenever they become inactive or +invisible (such as during the {@link android.app.Activity#onStop onStop()} callback). However, it’s +not that simple for media playback apps—in fact, responding to media playback buttons is most +important when your application isn’t visible and therefore can’t be controlled by the on-screen +UI.

    + +

    A better approach is to register and unregister the media button event receiver when your +application gains and losses the audio focus. This is covered in detail in the next lesson.

    diff --git a/docs/html/training/monitoring-device-state/battery-monitoring.jd b/docs/html/training/monitoring-device-state/battery-monitoring.jd new file mode 100644 index 0000000000000..a442140aaad87 --- /dev/null +++ b/docs/html/training/monitoring-device-state/battery-monitoring.jd @@ -0,0 +1,156 @@ +page.title=Monitoring the Battery Level and Charging State +parent.title=Monitoring Device State to Optimize Battery Life +parent.link=index.html + +trainingnavtop=true +next.title=Determining and Monitoring the Docking State and Type +next.link=docking-monitoring.html + +@jd:body + + + +

    When you're altering the frequency of your background updates to reduce the effect of those +updates on battery life, checking the current battery level and charging state is a good place to +start.

    + +

    The battery-life impact of performing application updates depends on the battery level and +charging state of the device. The impact of performing updates while the device is charging over AC +is negligible, so in most cases you can maximize your refresh rate whenever the device is connected +to a wall charger. Conversely, if the device is discharging, reducing your update rate helps +prolong the battery life.

    + +

    Similarly, you can check the battery charge level, potentially reducing the frequency of—or +even stopping—your updates when the battery charge is nearly exhausted.

    + + +

    Determine the Current Charging State

    + +

    Start by determining the current charge status. The {@link android.os.BatteryManager} +broadcasts all battery and charging details in a sticky {@link android.content.Intent} that includes +the charging status.

    + +

    Because it's a sticky intent, you don't need to register a {@link +android.content.BroadcastReceiver}—by simply calling {@code registerReceiver} passing in +{@code null} as the receiver as shown in the next snippet, the current battery status intent is +returned. You could pass in an actual {@link android.content.BroadcastReceiver} object here, but +we'll be handling updates in a later section so it's not necessary.

    + +
    IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    +Intent batteryStatus = context.registerReceiver(null, ifilter);
    + +

    You can extract both the current charging status and, if the device is being charged, whether +it's charging via USB or AC charger:

    + +

    // Are we charging / charged?
    +int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
    +boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
    +                     status == BatteryManager.BATTERY_STATUS_FULL;
    +
    +// How are we charging?
    +int chargePlug = battery.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
    +boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
    +boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;
    + +

    Typically you should maximize the rate of your background updates in the case where the device is +connected to an AC charger, reduce the rate if the charge is over USB, and lower it +further if the battery is discharging.

    + + +

    Monitor Changes in Charging State

    + +

    The charging status can change as easily as a device can be plugged in, so it's important to +monitor the charging state for changes and alter your refresh rate accordingly.

    + +

    The {@link android.os.BatteryManager} broadcasts an action whenever the device is connected or +disconnected from power. It's important to to receive these events even while your app isn't +running—particularly as these events should impact how often you start your app in order to +initiate a background update—so you should register a {@link +android.content.BroadcastReceiver} in your manifest to listen for both events by defining the +{@link android.content.Intent#ACTION_POWER_CONNECTED} and {@link +android.content.Intent#ACTION_POWER_DISCONNECTED} within an intent filter.

    + +
    <receiver android:name=".PowerConnectionReceiver">
    +  <intent-filter>
    +    <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
    +    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
    +  </intent-filter>
    +</receiver>
    + +

    Within the associated {@link android.content.BroadcastReceiver} implementation, you can extract +the current charging state and method as described in the previous step.

    + +
    public class PowerConnectionReceiver extends BroadcastReceiver {
    +    @Override
    +    public void onReceive(Context context, Intent intent) { 
    +        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
    +        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
    +                            status == BatteryManager.BATTERY_STATUS_FULL;
    +    
    +        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
    +        boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
    +        boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;
    +    }
    +}
    + + +

    Determine the Current Battery Level

    + +

    In some cases it's also useful to determine the current battery level. You may choose to reduce +the rate of your background updates if the battery charge is below a certain level.

    + +

    You can find the current battery charge by extracting the current battery level and scale from +the battery status intent as shown here:

    + +
    int level = battery.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
    +int scale = battery.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    +
    +float batteryPct = level / (float)scale;
    + + +

    Monitor Significant Changes in Battery Level

    + +

    You can't easily continually monitor the battery state, but you don't need to.

    + +

    Generally speaking, the impact of constantly monitoring the battery level has a greater +impact on the battery than your app's normal behavior, so it's good practice to only monitor +significant changes in battery level—specifically when the device enters or exits a low +battery state.

    + +

    The manifest snippet below is extracted from the intent filter element within a broadcast +receiver. The receiver is triggered whenever the device battery becomes low or exits the low +condition by listening for {@link android.content.Intent#ACTION_BATTERY_LOW} and {@link +android.content.Intent#ACTION_BATTERY_OKAY}.

    + +
    <receiver android:name=".BatteryLevelReceiver">
    +<intent-filter>
    +  <action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
    +  <action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
    +  </intent-filter>
    +</receiver>
    + +

    It is generally good practice to disable all your background updates when the battery is +critically low. It doesn't matter how fresh your data is if the phone turns itself off before you +can make use of it.

    + +

    In many cases, the act of charging a device is coincident with putting it into a dock. The next +lesson shows you how to determine the current dock state and monitor for changes in device +docking.

    + diff --git a/docs/html/training/monitoring-device-state/connectivity-monitoring.jd b/docs/html/training/monitoring-device-state/connectivity-monitoring.jd new file mode 100644 index 0000000000000..4c71279059399 --- /dev/null +++ b/docs/html/training/monitoring-device-state/connectivity-monitoring.jd @@ -0,0 +1,90 @@ +page.title=Determining and Monitoring the Connectivity Status +parent.title=Monitoring Device State to Optimize Battery Life +parent.link=index.html + +trainingnavtop=true + +previous.title=Determining and Monitoring the Docking State and Type +previous.link=docking-monitoring.html +next.title=Manipulating Broadcast Receivers On Demand +next.link=manifest-receivers.html + +@jd:body + + + +

    Some of the most common uses for repeating alarms and background services is to schedule regular +updates of application data from Internet resources, cache data, or execute long running downloads. +But if you aren't connected to the Internet, or the connection is too slow to complete your +download, why both waking the device to schedule the update at all?

    + +

    You can use the {@link android.net.ConnectivityManager} to check that you're actually +connected to the Internet, and if so, what type of connection is in place.

    + + +

    Determine if You Have an Internet Connection

    + +

    There's no need to schedule an update based on an Internet resource if you aren't connected to +the Internet. The following snippet shows how to use the {@link android.net.ConnectivityManager} +to query the active network and determine if it has Internet connectivity.

    + +
    ConnectivityManager cm =
    +        (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    + 
    +NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    +boolean isConnected = activeNetwork.isConnectedOrConnecting();
    + + +

    Determine the Type of your Internet Connection

    + +

    It's also possible to determine the type of Internet connection currently available.

    + +

    Device connectivity can be provided by mobile data, WiMAX, Wi-Fi, and ethernet connections. By +querying the type of the active network, as shown below, you can alter your refresh rate based on +the bandwidth available.

    + +
    boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    + +

    Mobile data costs tend to be significantly higher than Wi-Fi, so in most cases, your app's update +rate should be lower when on mobile connections. Similarly, downloads of significant size should be +suspended until you have a Wi-Fi connection.

    + +

    Having disabled your updates, it's important that you listen for changes in connectivity in order +to resume them once an Internet connection has been established.

    + + +

    Monitor for Changes in Connectivity

    + +

    The {@link android.net.ConnectivityManager} broadcasts the {@link +android.net.ConnectivityManager#CONNECTIVITY_ACTION} ({@code +"android.net.conn.CONNECTIVITY_CHANGE"}) action whenever the connectivity details have changed. You +can register a broadcast receiver in your manifest to listen for these changes and resume (or +suspend) your background updates accordingly.

    + +
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
    + +

    Changes to a device's connectivity can be very frequent—this broadcast is triggered +every time you move between mobile data and Wi-Fi. As a result, it's good practice to monitor +this broadcast only when you've previously suspended updates or downloads in order to resume them. +It's generally sufficient to simply check for Internet connectivity before beginning an update and, +should there be none, suspend further updates until connectivity is restored.

    + +

    This technique requires toggling broadcast receivers you've declard in the manifest, which is +described in the next lesson.

    diff --git a/docs/html/training/monitoring-device-state/docking-monitoring.jd b/docs/html/training/monitoring-device-state/docking-monitoring.jd new file mode 100644 index 0000000000000..6a4a9a8e1a91a --- /dev/null +++ b/docs/html/training/monitoring-device-state/docking-monitoring.jd @@ -0,0 +1,90 @@ +page.title=Determining and Monitoring the Docking State and Type +parent.title=Monitoring Device State to Optimize Battery Life +parent.link=index.html + +trainingnavtop=true +previous.title= Monitoring the Battery Level and Charging State +previous.link=battery-monitoring.html +next.title= Determining and Monitoring the Connectivity Status +next.link=connectivity-monitoring.html + +@jd:body + +
    + +
    + +

    Android devices can be docked into several different kinds of docks. These include car or home +docks and digital versus analog docks. The dock-state is typically closely linked to the charging +state as many docks provide power to docked devices.

    + +

    How the dock-state of the phone affects your update rate depends on your app. You may choose +to increase the update frequency of a sports center app when it's in the desktop dock, or disable +your updates completely if the device is car docked. Conversely, you may choose to maximize your +updates while car docked if your background service is updating traffic conditions.

    + +

    The dock state is also broadcast as a sticky {@link android.content.Intent}, allowing you to +query if the device is docked or not, and if so, in which kind of dock.

    + + +

    Determine the Current Docking State

    + +

    The dock-state details are included as an extra in a sticky broadcast of the {@link +android.content.Intent#ACTION_DOCK_EVENT} action. Because it's sticky, you don't need to register a +{@link android.content.BroadcastReceiver}. You can simply call {@link +android.content.Context#registerReceiver registerReceiver()} passing in {@code null} as the +broadcast receiver as shown in the next snippet.

    + +
    IntentFilter ifilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
    +Intent dockStatus = context.registerReceiver(null, ifilter);
    + +

    You can extract the current docking status from the {@code EXTRA_DOCK_STATE} extra:

    + +

    int dockState = battery.getIntExtra(EXTRA_DOCK_STATE, -1);
    +boolean isDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
    + + +

    Determine the Current Dock Type

    + +

    If a device is docked, it can be docked in any one of four different type of dock: +

    • Car
    • +
    • Desk
    • +
    • Low-End (Analog) Desk
    • +
    • High-End (Digital) Desk

    + +

    Note that the latter two options were only introduced to Android in API level 11, so it's good +practice to check for all three where you are only interested in the type of dock rather than it +being digital or analog specifically:

    + +
    boolean isCar = dockState == EXTRA_DOCK_STATE_CAR;
    +boolean isDesk = dockState == EXTRA_DOCK_STATE_DESK || 
    +                 dockState == EXTRA_DOCK_STATE_LE_DESK ||
    +                 dockState == EXTRA_DOCK_STATE_HE_DESK;
    + + +

    Monitor for Changes in the Dock State or Type

    + +

    Whenever the the device is docked or undocked, the {@link +android.content.Intent#ACTION_DOCK_EVENT} action is broadcast. To monitor changes in the +device's dock-state, simply register a broadcast receiver in your application manifest as shown in +the snippet below:

    + +
    <action android:name="android.intent.action.ACTION_DOCK_EVENT"/>
    + +

    You can extract the dock type and state within the receiver implementation using the same +techniques described in the previous step.

    diff --git a/docs/html/training/monitoring-device-state/index.jd b/docs/html/training/monitoring-device-state/index.jd new file mode 100644 index 0000000000000..e92e1e8a30275 --- /dev/null +++ b/docs/html/training/monitoring-device-state/index.jd @@ -0,0 +1,63 @@ +page.title=Monitoring Device State to Optimize Battery Life + +trainingnavtop=true +startpage=true +next.title=Monitoring the Battery Level and Charging State +next.link=battery-monitoring.html + +@jd:body + +
    +
    + +

    Dependencies and prerequisites

    + + +

    You should also read

    + + +
    +
    + +

    For your app to be a good citizen, it should seek to limit its impact on the battery life of its +host device. After this class you will be able to build apps that monitor modify their functionality +and behavior based on the state of the host device.

    + +

    By taking steps such as disabling background service updates when you lose connectivity, or +reducing the rate of such updates when the battery level is low, you can ensure that the impact of +your app on battery life is minimized, without compromising the user experience.

    + +

    Lessons

    + + + +
    +
    Monitoring the Battery Level and Charging State
    +
    Learn how to alter your app's update rate by determining, and monitoring, the current battery +level and changes in charging state.
    + +
    Determining and Monitoring the Docking State and +Type
    +
    Optimal refresh rates can vary based on how the host device is being used. Learn how to +determine, and monitor, the docking state and type of dock being used to affect your app's +behavior.
    + +
    Determining and Monitoring the Connectivity +Status
    +
    Without Internet connectivity you can't update your app from an online source. Learn how to +check the connectivity status to alter your background update rate. You'll also learn to check for +Wi-Fi or mobile connectivity before beginning high-bandwidth operations.
    + +
    Manipulating Broadcast Receivers On Demand
    +
    Broadcast receivers that you've declared in the manifest can be toggled at runtime to disable +those that aren't necessary due to the current device state. Learn to improve +efficiency by toggling and cascading state change receivers and delay actions until the device is in +a specific state.
    +
    \ No newline at end of file diff --git a/docs/html/training/monitoring-device-state/manifest-receivers.jd b/docs/html/training/monitoring-device-state/manifest-receivers.jd new file mode 100644 index 0000000000000..bf5462a1e7c3a --- /dev/null +++ b/docs/html/training/monitoring-device-state/manifest-receivers.jd @@ -0,0 +1,64 @@ +page.title=Manipulating Broadcast Receivers On Demand +parent.title=Monitoring Device State to Optimize Battery Life +parent.link=index.html + +trainingnavtop=true + +previous.title=Determining and Monitoring the Connectivity Status +previous.link=connectivity-monitoring.html + +@jd:body + +
    +
    + +

    This lesson teaches you to

    +
      +
    1. Toggle and Cascade State Change Receivers to Improve +Efficiency
    2. +
    + + +

    You should also read

    + + +
    +
    + +

    The simplest way to monitor device state changes is to create a {@link +android.content.BroadcastReceiver} for each state you're monitoring and register each of them in +your application manifest. Then within each of these receivers you simply reschedule your recurring +alarms based on the current device state.

    + +

    A side-effect of this approach is that your app will wake the device each time any of these +receivers is triggered—potentially much more frequently than required.

    + +

    A better approach is to disable or enable the broadcast receivers at runtime. That way you can +use the receivers you declared in the manifest as passive alarms that are triggered by system events +only when necessary.

    + + +

    Toggle and Cascade State Change Receivers to Improve Efficiency

    + +

    Use can use the {@link android.content.pm.PackageManager} to toggle the enabled state on any +component defined in the manifest, including whichever broadcast receivers you wish to enable or +disable as shown in the snippet below:

    + +
    ComponentName receiver = new ComponentName(context, myReceiver.class);
    +
    +PackageManager pm = context.getPackageManager();
    +
    +pm.setComponentEnabledSetting(receiver,
    +        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
    +        PackageManager.DONT_KILL_APP)
    + +

    Using this technique, if you determine that connectivity has been lost, you can disable all of +your receivers except the connectivity-change receiver. Conversely, once you are connected you can +stop listening for connectivity changes and simply check to see if you're online immediately before +performing an update and rescheduling a recurring update alarm.

    + +

    You can use the same technique to delay a download that requires higher bandwidth to complete. +Simply enable a broadcast receiver that listens for connectivity changes and initiates the +download only after you are connected to Wi-Fi.

    From d70c64db9f67dbe8f888de6b1bdcc835226ec526 Mon Sep 17 00:00:00 2001 From: James Dong Date: Wed, 14 Dec 2011 10:57:05 -0800 Subject: [PATCH 4/8] Revert the following patches because they may lead to power regression because SHA/MD5 module is stuck 1. Revert "Fix drm flag setting missed in false drm recognition fix." This reverts commit 9f704f6c46a171357e49c411c83458b9d4565f3b. 2. Revert "Fixed the false drm recognition." This reverts commit aadbd80b307c817698ce5110ff8e002804d1b230. 3. Revert "Fix drm enumeration order, resolves failure to play forward lock ringtones" This reverts commit a5cbf023e349f2394ba6fc58d73b4375cfec4369. 4. Revert "Fix ANRs due to Widevine DRM plugin sniff taking too long." This reverts commit d0d19db1ca1c289b069db33f4665bcb9386064e9. As a result of the reverting, many ANRs from WV sniffing are back. related-to-bug: 5739618 --- drm/drmserver/DrmManager.cpp | 5 +- media/libstagefright/AwesomePlayer.cpp | 29 ++++------- media/libstagefright/DRMExtractor.cpp | 8 +-- media/libstagefright/DataSource.cpp | 2 - media/libstagefright/MediaExtractor.cpp | 3 -- media/libstagefright/WVMExtractor.cpp | 56 ++++----------------- media/libstagefright/include/WVMExtractor.h | 8 --- 7 files changed, 27 insertions(+), 84 deletions(-) diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp index eaf884d5cf083..b2fa05378258c 100644 --- a/drm/drmserver/DrmManager.cpp +++ b/drm/drmserver/DrmManager.cpp @@ -99,12 +99,11 @@ void DrmManager::removeUniqueId(int uniqueId) { status_t DrmManager::loadPlugIns() { - String8 pluginDirPath("/system/lib/drm"); - loadPlugIns(pluginDirPath); - String8 vendorPluginDirPath("/vendor/lib/drm"); loadPlugIns(vendorPluginDirPath); + String8 pluginDirPath("/system/lib/drm"); + loadPlugIns(pluginDirPath); return DRM_NO_ERROR; } diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index ba6ff10bde0c6..50c264e78ecc1 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -335,13 +335,11 @@ status_t AwesomePlayer::setDataSource_l( return UNKNOWN_ERROR; } - if (extractor->getDrmFlag()) { - dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient); - if (mDecryptHandle != NULL) { - CHECK(mDrmManagerClient); - if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) { - notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE); - } + dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient); + if (mDecryptHandle != NULL) { + CHECK(mDrmManagerClient); + if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) { + notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE); } } @@ -2093,7 +2091,7 @@ status_t AwesomePlayer::finishSetDataSource_l() { String8 mimeType; float confidence; sp dummy; - bool success = SniffWVM(dataSource, &mimeType, &confidence, &dummy); + bool success = SniffDRM(dataSource, &mimeType, &confidence, &dummy); if (!success || strcasecmp( @@ -2101,11 +2099,8 @@ status_t AwesomePlayer::finishSetDataSource_l() { return ERROR_UNSUPPORTED; } - dataSource->DrmInitialization(); - mWVMExtractor = new WVMExtractor(dataSource); mWVMExtractor->setAdaptiveStreamingMode(true); - mWVMExtractor->setDrmFlag(true); extractor = mWVMExtractor; } else { extractor = MediaExtractor::Create( @@ -2116,14 +2111,12 @@ status_t AwesomePlayer::finishSetDataSource_l() { } } - if (extractor->getDrmFlag()) { - dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient); + dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient); - if (mDecryptHandle != NULL) { - CHECK(mDrmManagerClient); - if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) { - notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE); - } + if (mDecryptHandle != NULL) { + CHECK(mDrmManagerClient); + if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) { + notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE); } } diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp index afc4a803518d5..1f3d58181471c 100644 --- a/media/libstagefright/DRMExtractor.cpp +++ b/media/libstagefright/DRMExtractor.cpp @@ -282,13 +282,13 @@ bool SniffDRM( if (decryptHandle != NULL) { if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) { *mimeType = String8("drm+container_based+") + decryptHandle->mimeType; - *confidence = 10.0f; } else if (decryptHandle->decryptApiType == DecryptApiType::ELEMENTARY_STREAM_BASED) { *mimeType = String8("drm+es_based+") + decryptHandle->mimeType; - *confidence = 10.0f; - } else { - return false; + } else if (decryptHandle->decryptApiType == DecryptApiType::WV_BASED) { + *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM; + LOGW("SniffWVM: found match\n"); } + *confidence = 10.0f; return true; } diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index 6134344d8b65d..43539bb8d2acf 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -26,7 +26,6 @@ #include "include/DRMExtractor.h" #include "include/FLACExtractor.h" #include "include/AACExtractor.h" -#include "include/WVMExtractor.h" #include "matroska/MatroskaExtractor.h" @@ -114,7 +113,6 @@ void DataSource::RegisterDefaultSniffers() { RegisterSniffer(SniffMP3); RegisterSniffer(SniffAAC); RegisterSniffer(SniffMPEG2PS); - RegisterSniffer(SniffWVM); char value[PROPERTY_VALUE_MAX]; if (property_get("drm.service.enabled", value, NULL) diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp index 9eee6aac83474..374ecf703613a 100644 --- a/media/libstagefright/MediaExtractor.cpp +++ b/media/libstagefright/MediaExtractor.cpp @@ -111,9 +111,6 @@ sp MediaExtractor::Create( ret = new MPEG2TSExtractor(source); } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) { ret = new WVMExtractor(source); - if (ret != NULL) { - isDrm = true; - } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) { ret = new AACExtractor(source); } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) { diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp index 79dedcab16948..26eda0c4cfb17 100644 --- a/media/libstagefright/WVMExtractor.cpp +++ b/media/libstagefright/WVMExtractor.cpp @@ -45,12 +45,17 @@ namespace android { static Mutex gWVMutex; WVMExtractor::WVMExtractor(const sp &source) - : mDataSource(source) -{ - Mutex::Autolock autoLock(gWVMutex); + : mDataSource(source) { + { + Mutex::Autolock autoLock(gWVMutex); + if (gVendorLibHandle == NULL) { + gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW); + } - if (!getVendorLibHandle()) { - return; + if (gVendorLibHandle == NULL) { + LOGE("Failed to open libwvm.so"); + return; + } } typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp); @@ -66,19 +71,6 @@ WVMExtractor::WVMExtractor(const sp &source) } } -bool WVMExtractor::getVendorLibHandle() -{ - if (gVendorLibHandle == NULL) { - gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW); - } - - if (gVendorLibHandle == NULL) { - LOGE("Failed to open libwvm.so"); - } - - return gVendorLibHandle != NULL; -} - WVMExtractor::~WVMExtractor() { } @@ -121,33 +113,5 @@ void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) { } } -bool SniffWVM( - const sp &source, String8 *mimeType, float *confidence, - sp *) { - - Mutex::Autolock autoLock(gWVMutex); - - if (!WVMExtractor::getVendorLibHandle()) { - return false; - } - - typedef WVMLoadableExtractor *(*SnifferFunc)(sp); - SnifferFunc snifferFunc = - (SnifferFunc) dlsym(gVendorLibHandle, - "_ZN7android15IsWidevineMediaENS_2spINS_10DataSourceEEE"); - - if (snifferFunc) { - if ((*snifferFunc)(source)) { - *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM; - *confidence = 10.0f; - return true; - } - } else { - LOGE("IsWidevineMedia not found in libwvm.so"); - } - - return false; -} - } //namespace android diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h index 9f763f9debef5..deecd2543a922 100644 --- a/media/libstagefright/include/WVMExtractor.h +++ b/media/libstagefright/include/WVMExtractor.h @@ -23,8 +23,6 @@ namespace android { -struct AMessage; -class String8; class DataSource; class WVMLoadableExtractor : public MediaExtractor { @@ -60,8 +58,6 @@ public: // is used. void setAdaptiveStreamingMode(bool adaptive); - static bool getVendorLibHandle(); - protected: virtual ~WVMExtractor(); @@ -73,10 +69,6 @@ private: WVMExtractor &operator=(const WVMExtractor &); }; -bool SniffWVM( - const sp &source, String8 *mimeType, float *confidence, - sp *); - } // namespace android #endif // DRM_EXTRACTOR_H_ From 70645e363e8601550468b726251f4f52f383b9fc Mon Sep 17 00:00:00 2001 From: Scott Main Date: Tue, 13 Dec 2011 16:06:16 -0800 Subject: [PATCH 5/8] Docs: Add class for Sharing Content Change-Id: I078a02d952e652c16f84e1b3f7613f3dc9364c97 --- .../sharing/share-text-screenshot.png | Bin 0 -> 33210 bytes docs/html/training/sharing/index.jd | 46 +++++ docs/html/training/sharing/receive.jd | 149 ++++++++++++++ docs/html/training/sharing/send.jd | 194 ++++++++++++++++++ docs/html/training/sharing/shareaction.jd | 115 +++++++++++ 5 files changed, 504 insertions(+) create mode 100644 docs/html/images/training/sharing/share-text-screenshot.png create mode 100644 docs/html/training/sharing/index.jd create mode 100644 docs/html/training/sharing/receive.jd create mode 100644 docs/html/training/sharing/send.jd create mode 100644 docs/html/training/sharing/shareaction.jd diff --git a/docs/html/images/training/sharing/share-text-screenshot.png b/docs/html/images/training/sharing/share-text-screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..089221ccace64e97ca5d78e6145e4bd132f54143 GIT binary patch literal 33210 zcmXt<1yCGavxXNZxVyW%yF+jdZo%E%39iB2-Q6vO;O_1Y!Gimp?^gX&Ma}FoJ3Hre zpWg0%pNUjfltzTZg9Cv;h+kzSRDt~n2n1#V3l1DTrp_w^J1`ejX)#dk6u~L*0{Xk0 zv;?pRwrBCK0ATmUQAXPZ1cFEZ?+*-=nT-Ry3FG=zK@w&i0TCM-a{RR91q31ieU%VZ z_gwqi|)}wKtn+ue^f)9-*bj2 zzXj!QUp;#Eh{3KqRnjsRz-p-3tut+%z(XEQWS!qXv#m0G)t(8eeHeeI7e!P?(%|(x z{FL~%qPAc-G0N{Nv|Szdurvf+XB6y0(nvsUH+rq^`rUVfV>0nQjY&Uq(j1wXFMC^5VS&KfZnkOFy{|05)Rr#6nRKxGW2aL={$6IjzI5oW=+%^Omk39zN!02zLg;4O zXdSd;=vG_iHKXDe!-uud zEzD>a9mBvviny6UP$WMWC7E2>x>9!q6<8YU&|so=nwICGqzjDt@u#=>S=zRZK>%$< z@6*F@JNHWcUiLwfaIEkv3$Htv2K*5-$=6aVxRSkdDR4+|k!&!25a_y=XB~%^j{Pf0 zM(7h?gz62^Gy@cf@C6pMP`ed|sHq_6+J;F4HY6eoGP+-OQH{Ury{OP^^*UydS{&~I ztFiI79Zp*Pc)w(`d-%HwkHtVjGS7jEI))uBA%P|XE|b`3dSB*#51pEuAlPiPrcZ^T zim@dS?FCWTu^AVpo$s`SNId@6hqdMX3n=idv$3{8@defAa#@jY)_ZaCn*iHG5wpd^ z6$mu6^7ed-Jz@BZhn;bL{~i=HypO7f;Z>BrhBKGBo?Zx^fMtD5^ohWoT3CSM{v8hF zsb(|qBFDz;pkV9QeEPc$a>>9_QmRSX(B9`9=1p$N4Egel{_}E$U3?a~v>tj5QuXqH z%%wk<=TN9SUFuffz~hRv1_n5L*S)!T2#+$ql%Nkcg?aF9-(pOA(nEaPV9pZZx;s7`| z4Q1JgLDo~*SF(v1-84DF#g?j^G9mmWX}^WxueI6@Of_)idbh9Ub}+GDf;PEAzvhFj#r@ zdoAa4%MA;gqUxDP&P4^<+TFE5Uxr%=CzLWJ=G=xz3zfA5zF%!)c{I2Mo9YrzCoK=> zxhh}$M0(WOlA=DzF~hcURS=@2%$XY6xrCgIINz{JsXt{vu{r>fX4@k7&$t!q{u@3 z=%1RJN=Qghr{lCcNa-Pe6wb*Zytp7_?zvOFX&I~2Ep+2K?l)q|kmrk2Q~Nv=n$8p6 zW{HufVz-#e77s@%ozJkg$Ym9UZ7>~8RHs|q-j4T->B{Ulq)3X&?4uhJ0o##40_WQy zam*)>M}?F|7I!oE#<8)ova+{Fg8mV=Z`!o#$iv3Rr(+^TQka`d1j56^V~SAZzi3`s z`Zk;(D7eY*{#V2_8jCS*@OyZh%Mbvft#>q@_Z0B25+{L4j*w&}~hQ zP_0N_K8J?{@9F6Q=5N+=!YO;T={UVqh=pZ`N0BZCJg~#%m`S^Fg=IpXYJY2MEQMY} zBX;n6O-&6xm#wA46)@WP!S7+lTB(?@kl$+fYAPyt36LO+XfUiTEwvg=BT;_$=z_vd zdQoY7q$51{WKk2ay=r7Pa}^X6fG>?W$>fKPVTS^_(GR6pIuZvZMNr2-5WCUG{%f%` zU3XVfimyHY@#BZ;m{Gm)WagskSZXR(-ZXyn;1usM!Q-HZySr4;EZ_`N&)3&Rd^zru z535ZU@T5}G!_d&sWC;<==Q+Xwz56_smB1*TPG&!b!ot|61=#UoA08gSML6&_o2}Gz zbsJc4(;Lqz{wsljne{buH&@rY$H(d1O%ohw z)Exhp)7@(cY3bocvvGpq(~AoQsw9It3&2!i#=u%6{mzwjahhR=GxYTI1h`6%fr9{% z@ax|u4Gl!d;K@ma3U%j;wU#FHNj3zN-QS_DcG5+&WF?Z4=#$MZi8~?5Xomt2`Wek>0grbqc^eBMhmmVbkfjZ>5?U! z{QaBFZozc?H^U;AxBfG*lBTi}gUDs~w`5Y1nshvom5t4MFeVi^f#K~RHDkfEZcroJ^#4UNdK z$Aq2K|0 zGsW-qfl$!f6);NX@Boj4jm>_xhnt&OleYeJm>3XoCxQ6_e#G!%U*3f@GgAC%sVM9;=BW4co-&hjGQ)5Mk>gWg%DQRkIvf#|z zR|D0}voC1p_F2zp_71<|I!@8CBK^Sy^^la)WK@bGC|$hNelSQGT>&A~>^v+hHW7*f-OV-+wvwm@#VP<5Jy{mJN9|@i;ARQU*G*d6Dj2=Mhgl^2Uxww1y}8ih7z`VHEj@V>WccEmJg&Bmj*j4&yHQYHUS59h z*4LibR%A|^wih1sP6Wd@z7cj{-9^&oB%E+FPCaXSdz(9~I0_w4G!jfD%e9^cFf5G0C?Kp1eW;T`gnmgYCXL6SxoFpBB8GP1Ru==mlm zSCy>TFu1n1cJ}y64%|r2Q8s<0bw;TxLHw`@5E9ny?CfG1EIH1+)i5O+?ABZDBvp8h zOReal$V!?SyzhwR#8zwD{}YjTUxswx9?9_D{eEH$(b;6 zFf!uEmosJF1SBE3+;zZs1y^mCdJ2d46I46TzvwSVmUmRpq990-CD?Mog9?;K_HQJ} zP>0fM&m*c^S~Ql~!;Cv&vGiQsJWj)eScP`+5P*o4dWdJ-SxZh&ze49Njrjva9jBf= z{Zmr$OX6j`?pQLfREP|NSqSgE-k@|yTr-7s=pof1nv=+~n@2~sAtVnuIeBR4kL1Rk zjqfpEX{o8npIMN=NKhq#`jukua-SzIX|j{w)NOMU2Pr%{Z_3Tqd5UqokpUj0cMN4x zeO=JhM2=x?WeJOfhzKl%4v%!Fw8B~{>PEYD4u$bXv`EhzL{qkmn;R!h8?wUOzF1qX z^N-@f1}zRO`s$dCTkM(?Qyu}8=FrtRK^7L}mBdNmd>`|+T4)QV&T>`ou}E6X!3V!l z{}@(PV~pG^{6uoeNt(pCCp;?VFj?cqir`?mS z(UFmn1$B-9XPUl_3?=oKZZj2fZdq1BXBvYr&AS9u%5ap)H%GCrWo5tjmiIqaXJ%M@ z9&9B@zLzG+;}yZ($~xQ5;W{siTAy-on)7iP`@88~vM~wW8h+D3V_^yi9b~1XspO{_ zI{$JnL0ydjukwy&gxNc}KdNe6?JTAFobl;AH-?Ld*)$V}YsJf&djgrF+CNlD;5Myr ztDcE`b2hK8m`=dR^C9qO8M^C*2dRDmD2}B4vK{fpyRMsG+LVa{?nu**Y69TzZ-$q( z+~})>J~(~_t3KKTr)fy{J2_z6uUa#WLRnN}mhmGWh{fLDyX&JGvvO6E!hrtVoY0by zBof6BPgcLkeOMY$wp(0&R%ZP9IO(J0_D`ACDeBwMywM3WP7j6E0>iZ>wF#f@Ar~``{DIYdq z%)OwypBCj6>ox&T0&)b>xz-B|&9`?+4yWffmp2jS^`^4|%7%-|`QLfAr!Iw)G4 zR@Op)a*<;-#jrY{s^(9}*~u3uPyfa3ls`4mW5)8-R zdrs-0b`Ag8IG<}DD?`AfwPqsBCbYlp71GB)jp&v{T7-`Dc;(&BT_E z==A(5@amy?WAQDH$L*w^w) z2VYD&Z$5K>fnn8xtp@q1j;-^6ONU}u5(dw5qjb^(9yPz|$A?sf@FSuWWOCU5wXh_Uzua)?Wa64lEyPig= zSXu$8ro65Xl}XD6=I|~m6i7tM8!v=vNx#zI#-QPb&(gBsn#9szdeZQq%%NBwT!yTX z>VRk7z28-m zp{h*q+cNVY$$$w@r#bjJ=c;N(-IW@1PD5CK^JRf=W$4 zki}%dD5^3C3u08LnJdBE%?9Dpuv1WsHAy)85ZudeP9t;wkqS{#32||V<8Ji;Hm0(n zWcWHYE`zFoeXR52?Zkobk|n(Z1Y!}5!|17e^_Un0HpNler52HFe=x{Q zV`~IkbUg8sFGe=V=lWk8SO&>$cdZ-Fd_nmqJkCfFMtCO<>RV5WW&?}PcPx@pBuS

    J>fd2*LgCN@REm< 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

    ZiibG2k;Qt2~x=5hL83ZVCj74hdXkLJz0 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 SLwE@Ir6i{=TOn;8{C@!dV(Z!f literal 0 HcmV?d00001 diff --git a/docs/html/training/sharing/index.jd b/docs/html/training/sharing/index.jd new file mode 100644 index 0000000000000..cb133c393c419 --- /dev/null +++ b/docs/html/training/sharing/index.jd @@ -0,0 +1,46 @@ +page.title=Sharing Content + +trainingnavtop=true +startpage=true +next.title=Sending Content to Other Apps +next.link=send.html + +@jd:body + +

    +
    + + +

    Dependencies and prerequisites

    + + +
    +
    + + +

    One of the great things about Android applications is their ability to communicate and +integrate with each other. Why reinvent functionality that isn't core to your application when it +already exists in another application?

    + +

    This class shows some common ways you can send and receive content between +applications using {@link android.content.Intent} APIs and the {@link +android.view.ActionProvider}.

    + + +

    Lessons

    + +
    +
    Sending Content to Other Apps
    +
    Learn how to set up your application to be able to send text and binary data to other +applications with intents.
    + +
    Receiving Content from Other Apps
    +
    Learn how to set up your application to receive text and binary data from intents.
    + +
    Adding an Easy Share Action
    +
    Learn how to add a "share" action item to your action bar.
    +
    diff --git a/docs/html/training/sharing/receive.jd b/docs/html/training/sharing/receive.jd new file mode 100644 index 0000000000000..b2cac304325d0 --- /dev/null +++ b/docs/html/training/sharing/receive.jd @@ -0,0 +1,149 @@ +page.title=Receiving Content from Other Apps +parent.title=Sharing Content +parent.link=index.html + +trainingnavtop=true +previous.title=Sending Content to Other Apps +previous.link=send.html +next.title=Adding an Easy Share Action +next.link=shareaction.html + +@jd:body + +
    +
    + + +

    This lesson teaches you to

    +
      +
    1. Update Your Manifest
    2. +
    3. Handle the Incoming Content
    4. +
    + + +

    You should also read

    + + +
    +
    + +

    Just as your application can send data to other applications, so too can it easily receive data +from applications. Think about how users interact with your application, and what data types you +want to receive from other applications. For example, a social networking application would likely +be interested in receiving text content, like an interesting web URL, from another app. The +Google+ Android +application +accepts both text and single or multiple images. With this app, a user can easily start a +new Google+ post with photos from the Android Gallery app.

    + + +

    Update Your Manifest

    + +

    Intent filters inform the system what intents an application component is willing to accept. +Just as you constructed an intent with action {@link android.content.Intent#ACTION_SEND} in the +Send Content to Other Apps Using Intents +lesson, you create intent filters in order to be able to receive intents with this action. You +define an intent filter in your manifest, using the +<intent-filter> +element. For example, if your application handles receiving text content, a single image of any +type, or multiple images of any type, your manifest would look like:

    + +
    +<activity android:name=".ui.MyActivity" >
    +    <intent-filter>
    +        <action android:name="android.intent.action.SEND" />
    +        <category android:name="android.intent.category.DEFAULT" />
    +        <data android:mimeType="image/*" />
    +    </intent-filter>
    +    <intent-filter>
    +        <action android:name="android.intent.action.SEND" />
    +        <category android:name="android.intent.category.DEFAULT" />
    +        <data android:mimeType="text/plain" />
    +    </intent-filter>
    +    <intent-filter>
    +        <action android:name="android.intent.action.SEND_MULTIPLE" />
    +        <category android:name="android.intent.category.DEFAULT" />
    +        <data android:mimeType="image/*" />
    +    </intent-filter>
    +</activity>
    +
    + +

    Note: For more information on intent filters and intent resolution +please read Intents and Intent +Filters

    + +

    When another application tries to share any of these things by constructing an intent and passing +it to {@link android.content.Context#startActivity(android.content.Intent) startActivity()}, your +application will be listed as an option in the intent chooser (see figure 1). If the user selects +your application, the corresponding activity (.ui.MyActivity in the example above) will +be started. It is then up to you to handle the content appropriately within your code and UI.

    + + +

    Handle the Incoming Content

    + +

    To handle the content delivered by an {@link android.content.Intent}, start by calling {@link +android.content.Intent#getIntent(String) getIntent()} +to get {@link android.content.Intent} object. Once you have the object, you can examine its +contents to determine what to do next. Keep in mind that if this activity can be started from other +parts of the system, such as the launcher, then you will need to take this into consideration when +examining the intent.

    + +
    +void onCreate (Bundle savedInstanceState) {
    +    ...
    +    // Get intent, action and MIME type
    +    Intent intent = getIntent();
    +    String action = intent.getAction();
    +    String type = intent.getType();
    +
    +    if (Intent.ACTION_SEND.equals(action) && type != null) {
    +        if ("text/plain".equals(type)) {
    +            handleSendText(intent); // Handle text being sent
    +        } else if (type.startsWith("image/")) {
    +            handleSendImage(intent); // Handle single image being sent
    +        }
    +    } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
    +        if (type.startsWith("image/")) {
    +            handleSendMultipleImages(intent); // Handle multiple images being sent
    +        }
    +    } else {
    +        // Handle other intents, such as being started from the home screen
    +    }
    +    ...
    +}
    +
    +void handleSendText(Intent intent) {
    +    String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
    +    if (sharedText != null) {
    +        // Update UI to reflect text being shared
    +    }
    +}
    +
    +void handleSendImage(Intent intent) {
    +    Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
    +    if (imageUri != null) {
    +        // Update UI to reflect image being shared
    +    }
    +}
    +
    +void handleSendMultipleImages(Intent intent) {
    +    ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
    +    if (imageUris != null) {
    +        // Update UI to reflect multiple images being shared
    +    }
    +}
    +
    + +

    Caution: Take extra care to check the incoming data, you never +know what some other application may send you. For example, the wrong MIME type might be set, or the +image being sent might be extremely large. Also, remember to process binary data in a separate +thread rather than the main ("UI") thread.

    + +

    Updating the UI can be as simple as populating an {@link android.widget.EditText}, or it can +be more complicated like applying an interesting photo filter to an image. It's really specific +to your application what happens next.

    + diff --git a/docs/html/training/sharing/send.jd b/docs/html/training/sharing/send.jd new file mode 100644 index 0000000000000..d151ed03c7dbe --- /dev/null +++ b/docs/html/training/sharing/send.jd @@ -0,0 +1,194 @@ +page.title=Sending Content to Other Apps +parent.title=Sharing Content +parent.link=index.html + +trainingnavtop=true +next.title=Receiving Content from Other Apps +next.link=receive.html + +@jd:body + +
    +
    + + +

    This lesson teaches you to

    +
      +
    1. Send Text Content
    2. +
    3. Send Binary Content
    4. +
    5. Send Multiple Pieces of Content
    6. +
    + + +

    You should also read

    + + +
    +
    + +

    When you construct an intent, you must specify the action you want the intent to "trigger." +Android defines several actions, including {@link android.content.Intent#ACTION_SEND} which, as +you can probably guess, indicates that the intent is sending data from one activity to another, +even across process boundaries. To send data to another activity, all you need to do is speicify +the data and its type, the system will identify compatible receiving activities and display them +to the user (if there are multiple options) or immediately start the activity (if there is only +one option). Similarly, you can advertise the data types that your activities support receiving +from other applications by specifying them in your manifest.

    + +

    Sending and receiving data between applications with intents is most commonly used for social +sharing of content. Intents allow users to share information quickly and easily, using their +favorite social applications.

    + +

    Note: The best way to add a share action item to an +{@link android.app.ActionBar} is to use {@link android.widget.ShareActionProvider}, which became +available in API level 14. {@link android.widget.ShareActionProvider} is discussed in the lesson +about Adding an Easy Share Action.

    + + +

    Send Text Content

    + +
    + +

    + Figure 1. Screenshot of {@link android.content.Intent#ACTION_SEND} intent chooser +on a handset. +

    +
    + +

    The most straightforward and common use of the {@link android.content.Intent#ACTION_SEND} +action is sending text content from one activity to another. For example, the built-in Browser +app can share the URL of the currently-displayed page as text with any application. This is useful +for sharing an article or website with friends via email or social networking. Here is the code to +implement this type of sharing:

    + +
    +Intent sendIntent = new Intent();
    +sendIntent.setAction(Intent.ACTION_SEND);
    +sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
    +sendIntent.setType("text/plain");
    +startActivity(sendIntent);
    +
    + +

    If there's an installed application with a filter that matches +{@link android.content.Intent#ACTION_SEND} and MIME type text/plain, the Android system will run +it; if more than one application matches, the system displays a disambiguation dialog (a "chooser") +that allows the user to choose an app. If you call +{@link android.content.Intent#createChooser(android.content.Intent, CharSequence) +Intent.createChooser()} +for the intent, Android will always display the chooser. This has some +advantages:

    + +
      +
    • Even if the user has previously selected a default action for this intent, the chooser will +still be displayed.
    • +
    • If no applications match, Android displays a system message.
    • +
    • You can specify a title for the chooser dialog.
    • +
    + +

    Here's the updated code:

    + +
    +Intent sendIntent = new Intent();
    +sendIntent.setAction(Intent.ACTION_SEND);
    +sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
    +sendIntent.setType("text/plain");
    +startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to));
    +
    + +

    The resulting dialog is shown in figure 1.

    + +

    Optionally, you can set some standard extras for the intent: +{@link android.content.Intent#EXTRA_EMAIL}, {@link android.content.Intent#EXTRA_CC}, +{@link android.content.Intent#EXTRA_BCC}, {@link android.content.Intent#EXTRA_SUBJECT}. However, +if the receiving application is not designed to use them, nothing will happen. You can use +custom extras as well, but there's no effect unless the receiving application understands them. +Typically, you'd use custom extras defined by the receiving application itself.

    + +

    Note: Some e-mail applications, such as Gmail, expect a +{@link java.lang.String String[]} for extras like {@link android.content.Intent#EXTRA_EMAIL} and +{@link android.content.Intent#EXTRA_CC}, use +{@link android.content.Intent#putExtra(String,String[]) putExtra(String, String[])} to add these +to your intent.

    + + +

    Send Binary Content

    + +

    Binary data is shared using the {@link android.content.Intent#ACTION_SEND} action combined with +setting the appropriate MIME type and placing the URI to the data in an extra named {@link +android.content.Intent#EXTRA_STREAM}. This is commonly used to share an image but can be used to +share any type of binary content:

    + +
    +Intent shareIntent = new Intent();
    +shareIntent.setAction(Intent.ACTION_SEND);
    +shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
    +shareIntent.setType("image/jpeg");
    +startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
    +
    + +

    Note the following:

    +
      +
    • You can use a MIME type of {@code "*/*"}, but this will only match activities that are able to +handle generic data streams.
    • +
    • The receiving application needs permission to access the data the {@link android.net.Uri} +points to. There are a number of ways to handle this: +
        +
      • Write the data to a file on external/shared storage (such as the SD card), which all apps +can read. Use {@link android.net.Uri#fromFile(java.io.File) Uri.fromFile()} to create the +{@link android.net.Uri} that can be passed to the share intent. However, keep in mind that not +all applications process a {@code file://} style {@link android.net.Uri}.
      • +
      • Write the data to a file in your own application directory using {@link +android.content.Context#openFileOutput(java.lang.String, int) openFileOutput()} with mode {@link +android.content.Context#MODE_WORLD_READABLE} after which {@link +android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()} can be used to +return a {@link java.io.File}. As with the previous option, {@link +android.net.Uri#fromFile(java.io.File) Uri.fromFile()} will create a {@code file://} style {@link +android.net.Uri} for your share intent.
      • +
      • Media files like images, videos and audio can be scanned and added to the system {@link +android.provider.MediaStore} using {@link +android.media.MediaScannerConnection#scanFile(android.content.Context, java.lang.String[], +java.lang.String[], android.media.MediaScannerConnection.OnScanCompletedListener) scanFile()}. The +{@link +android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted(java.lang.String, +android.net.Uri) onScanCompleted()} callback returns a {@code content://} style {@link +android.net.Uri} suitable for including in your share intent.
      • +
      • Images can be inserted into the system {@link android.provider.MediaStore} using {@link +android.provider.MediaStore.Images.Media#insertImage(android.content.ContentResolver, +android.graphics.Bitmap, java.lang.String, java.lang.String) insertImage()} which will return a +{@code content://} style {@link android.net.Uri} suitable for including in a share intent.
      • +
      • Store the data in your own {@link android.content.ContentProvider}, make sure that other +apps have the correct permission to access your provider (or use per-URI permissions).
      • +
      +
    • +
    + + +

    Send Multiple Pieces of Content

    + +

    To share multiple pieces of content, use the {@link android.content.Intent#ACTION_SEND_MULTIPLE} +action together with a list of URIs pointing to the content. The MIME type varies according to the +mix of content you're sharing. For example, if you share 3 JPEG images, the type is still {@code +"image/jpeg"}. For a mixture of image types, it should be {@code "image/*"} to match an activity +that handles any type of image. You should only use {@code "*/*"} if you're sharing out a wide +variety of types. As previously stated, it's up to the receiving application to parse and process +your data. Here's an example:

    + +
    +ArrayList<Uri> imageUris = new ArrayList<Uri>();
    +imageUris.add(imageUri1); // Add your image URIs here
    +imageUris.add(imageUri2);
    +
    +Intent shareIntent = new Intent();
    +shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
    +shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
    +shareIntent.setType("image/*");
    +startActivity(Intent.createChooser(shareIntent, "Share images to.."));
    +
    + +

    As before, make sure the provided {@link android.net.Uri URIs} point to data that a receiving +application can access.

    + diff --git a/docs/html/training/sharing/shareaction.jd b/docs/html/training/sharing/shareaction.jd new file mode 100644 index 0000000000000..f6be745b93b84 --- /dev/null +++ b/docs/html/training/sharing/shareaction.jd @@ -0,0 +1,115 @@ +page.title=Adding an Easy Share Action +parent.title=Sharing Content +parent.link=index.html + +trainingnavtop=true +previous.title=Receiving Content from Other Apps +previous.link=receive.html + +@jd:body + +
    +
    + + +

    This lesson teaches you to

    +
      +
    1. Update Menu Declarations
    2. +
    3. Set the Share Intent
    4. +
    + + +

    You should also read

    + + +
    +
    + + +

    Implementing an effective and user friendly share action in your {@link android.app.ActionBar} +is made even easier with the introduction of {@link android.view.ActionProvider} in Android 4.0 +(API Level 14). An {@link android.view.ActionProvider}, once attached to a menu item in the action +bar, handles both the appearance and behavior of that item. In the case of {@link +android.widget.ShareActionProvider}, you provide a share intent and it does the rest.

    + +

    Note:  {@link android.widget.ShareActionProvider} is available +starting with API Level 14 and higher.

    + + +
    + +

    + Figure 1. The {@link android.widget.ShareActionProvider} in the Gallery app. +

    +
    + +

    Update Menu Declarations

    + +

    To get started with {@link android.widget.ShareActionProvider ShareActionProviders}, define the android:actionProviderClass attribute for the corresponding <item> in your menu resource file:

    + +
    +<menu xmlns:android="http://schemas.android.com/apk/res/android">
    +    <item android:id="@+id/menu_item_share"
    +        android:showAsAction="ifRoom"
    +        android:title="Share"
    +        android:actionProviderClass="android.widget.ShareActionProvider" />
    +    ...
    +</menu>
    +
    + +

    This delegates responsibility for the item's appearance and function to +{@link android.widget.ShareActionProvider}. However, you will need to tell the provider what you +would like to share.

    + + +

    Set the Share Intent

    + +

    In order for {@link android.widget.ShareActionProvider} to function, you must provide it a share +intent. This share intent should be the same as described in the Sending Content to Other Apps +lesson, with action {@link android.content.Intent#ACTION_SEND} and additional data set via extras +like {@link android.content.Intent#EXTRA_TEXT} and {@link android.content.Intent#EXTRA_STREAM}. To +assign a share intent, first find the corresponding {@link android.view.MenuItem} while inflating +your menu resource in your {@link android.app.Activity} or {@link android.app.Fragment}. Next, call +{@link android.view.MenuItem#getActionProvider() MenuItem.getActionProvider()} to retreive an +instance of {@link android.widget.ShareActionProvider}. Use {@link +android.widget.ShareActionProvider#setShareIntent(android.content.Intent) setShareIntent()} to +update the share intent associated with that action item. Here's an example:

    + +
    +private ShareActionProvider mShareActionProvider;
    +...
    +
    +@Override
    +public boolean onCreateOptionsMenu(Menu menu) {
    +    // Inflate menu resource file.
    +    getMenuInflater().inflate(R.menu.share_menu, menu);
    +
    +    // Locate MenuItem with ShareActionProvider
    +    MenuItem item = menu.findItem(R.id.menu_item_share);
    +
    +    // Fetch and store ShareActionProvider
    +    mShareActionProvider = (ShareActionProvider) item.getActionProvider();
    +
    +    // Return true to display menu
    +    return true;
    +}
    +
    +// Call to update the share intent
    +private void setShareIntent(Intent shareIntent) {
    +    if (mShareActionProvider != null) {
    +        mShareActionProvider.setShareIntent(shareIntent);
    +    }
    +}
    +
    + +

    You may only need to set the share intent once during the creation of your menus, or you may +want to set it and then update it as the UI changes. For example, when you view photos full screen +in the Gallery app, the sharing intent changes as you flip between photos.

    + +

    For further discussion about the {@link android.widget.ShareActionProvider}, see the Action Bar guide.

    + + From 9a6b4245c98b0327f6aaeaafc72de86cdc8e3e62 Mon Sep 17 00:00:00 2001 From: Dirk Dougherty Date: Mon, 12 Dec 2011 13:49:31 -0800 Subject: [PATCH 6/8] Doc change: add MR1 API summary and updated highlights. Change-Id: I9a9b13b9c7b8ae3011772a62735c788762b45f7f --- Android.mk | 1 + docs/html/guide/appendix/api-levels.jd | 10 +- docs/html/sdk/android-4.0-highlights.jd | 14 +- docs/html/sdk/android-4.0.3.jd | 513 ++++++++++++++++++++++++ docs/html/sdk/sdk_toc.cs | 8 +- 5 files changed, 533 insertions(+), 13 deletions(-) create mode 100644 docs/html/sdk/android-4.0.3.jd diff --git a/Android.mk b/Android.mk index 371c370614311..77d9cb2c980ea 100644 --- a/Android.mk +++ b/Android.mk @@ -398,6 +398,7 @@ framework_docs_LOCAL_DROIDDOC_OPTIONS := \ -since ./frameworks/base/api/12.xml 12 \ -since ./frameworks/base/api/13.xml 13 \ -since ./frameworks/base/api/14.txt 14 \ + -since ./frameworks/base/api/15.txt 15 \ -werror -hide 113 \ -overview $(LOCAL_PATH)/core/java/overview.html diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd index 95542bc37418a..6ace709f3c5f4 100644 --- a/docs/html/guide/appendix/api-levels.jd +++ b/docs/html/guide/appendix/api-levels.jd @@ -83,8 +83,14 @@ Android platform.

    - - + + + + + + +
    Platform VersionAPI LevelVERSION_CODENotes
    Android 4.0
    Android 4.0.315{@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1}Platform +Highlights
    Android 4.0, 4.0.1, 4.0.2 14 {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} Platform diff --git a/docs/html/sdk/android-4.0-highlights.jd b/docs/html/sdk/android-4.0-highlights.jd index c1162d4c7de43..922bb0874f38c 100644 --- a/docs/html/sdk/android-4.0-highlights.jd +++ b/docs/html/sdk/android-4.0-highlights.jd @@ -298,7 +298,7 @@ profiles

    linked together and integrated for easy accessibility. At the center is a new People app that offers richer profile information, including a large profile picture, phone numbers, addresses and accounts, status updates, -events, and a new button for connecting on integrated social networks.

    +events, stream items, and a new button for connecting on integrated social networks.

    The user's own contact information is stored in a new "Me" profile, allowing easier sharing with apps and people. All of the @@ -562,7 +562,7 @@ can connect to compatible devices to take advantage of new features such as instant sharing of files, photos, or other media; streaming video or audio from another device; or connecting to compatible printers or other devices.

    -

    Android 4.0 also introduces built-in support for connecting to Bluetooth Health Device Profile (HDP) devices. With support from third-party apps, users can connect to wireless medical devices and sensors in hospitals, fitness centers, homes, and elsewhere. In addition, for connecting to higher quality Bluetooth audio devices, Android 4.0 adds support for Bluetooth Hands Free Profile (HFP) 1.6.

    +

    Android 4.0 also introduces built-in support for connecting to Bluetooth Health Device Profile (HDP) devices. With support from third-party apps, users can connect to wireless medical devices and sensors in hospitals, fitness centers, homes, and elsewhere.

    New Developer Features

    @@ -633,21 +633,21 @@ development across the range of Android-powered devices.

    Communication and sharing

    Android 4.0 extends social and sharing features to any application on the -device. Applications can integrate contacts, profile data, and calendar events -from any of the user’s activities or social networks.

    +device. Applications can integrate contacts, profile data, stream items, +and calendar events from any of the user’s activities or social networks.

    Social API

    A shared social provider and API provide a new unified store for contacts, -profile data, status updates, and photos. Any app or social network with user +profile data, stream items, and photos. Any app or social network with user permission can contribute raw contacts and make them accessible to other apps and networks. Applications with user permission can also read profile data from the provider and display it in their applications.

    The social API lets applications store standard contact data as well as new -types of content for any given contact, including large profile photos and -recent activity feedback. Recent activity feedback is a standard way for +types of content for any given contact, including large profile photos, stream +items, and recent activity feedback. Recent activity feedback is a standard way for applications to “tag” a contact with common activity, such as when the user calls the contact or sends an email or SMS message. The social provider uses the recent activity feedback as a new signal in ranking, such as for name diff --git a/docs/html/sdk/android-4.0.3.jd b/docs/html/sdk/android-4.0.3.jd new file mode 100644 index 0000000000000..68257cd89cbc5 --- /dev/null +++ b/docs/html/sdk/android-4.0.3.jd @@ -0,0 +1,513 @@ +page.title=Android 4.0.3 Platform +sdk.platform.version=4.0.3 +sdk.platform.apiLevel=15 +@jd:body + +

    + +

    API Level: {@sdkPlatformApiLevel}

    + +

    Android {@sdkPlatformVersion} is an incremental release of the Android 4.x +(Ice Cream Sandwich) platform family. This release includes new features for +users and developers, API changes, and various bug fixes.

    + +

    For developers, the Android {@sdkPlatformVersion} platform is available as a +downloadable component for the Android SDK. The development platform includes a +fully compliant Android library and system image as well as a set of emulator +skins, sample applications, and more. The downloadable platform includes no +external libraries.

    + +

    To start developing or testing against Android {@sdkPlatformVersion}, +use the Android SDK Manager to download the platform into your SDK. For more +information, see Adding SDK +Components. If you are new to Android, download the SDK Starter Package first.

    + +

    For a high-level overview of the new user and developer features, see the +Platform +Highlights.

    + + +

    Development Platform Revisions

    + +

    The sections below provide notes about successive revisions of the Android +{@sdkPlatformVersion} development platform for the Android SDK, as denoted by +revision number. To determine what revisions you have installed in your SDK +environment, refer to the "Installed Packages" listing in the Android SDK +Manager.

    + + +
    + +

    + + Android {@sdkPlatformVersion}, Revision 1 (December 2011) +

    + +
    + +
    +
    Initial release. SDK Tools r14 or higher is required. +

    Important: To download the new Android + 4.x system components from the Android SDK Manager, you must first update the + SDK tools to revision 14 or later and restart the Android SDK Manager. If you do not, + the Android 4.0 system components will not be available for download.

    +
    +
    + +
    +
    + + +

    API Overview

    + +

    The sections below provide a technical overview of new APIs in Android 4.0.3.

    + + + + + + + +

    Social stream API in Contacts provider

    + +

    Applications that use social stream data such as status updates and check-ins +can now sync that data with each of the user’s contacts, providing items in a +stream along with photos for each.

    + +

    The database table that contains an individual contact’s social stream is +defined by {@link android.provider.ContactsContract.StreamItems}, the Uri for +which is nested within the {@link android.provider.ContactsContract.RawContacts} +directory to which the stream items belong. Each social stream table includes +several columns for metadata about each stream item, such as an icon +representing the source (an avatar), a label for the item, the primary text +content, comments about the item (such as responses from other people), and +more. Photos associated with a stream are stored in another table, defined by +{@link android.provider.ContactsContract.StreamItemPhotos}, which is available +as a sub-directory of the {@link android.provider.ContactsContract.StreamItems} +Uri.

    + +

    See {@link android.provider.ContactsContract.StreamItems} and +{@link android.provider.ContactsContract.StreamItemPhotos} for more information.

    + +

    To read or write social stream items for a contact, an application must +request permission from the user by declaring <uses-permission +android:name="android.permission.READ_SOCIAL_STREAM"> and/or <uses-permission +android:name="android.permission.WRITE_SOCIAL_STREAM"> in their manifest files.

    + +

    Calendar provider

    +
      +
    • Adds the class {@link android.provider.CalendarContract.Colors} to represent +a color table in the Calendar provider. The class provivdes fields for accessing +colors available for a given account. Colors are referenced by +{@link android.provider.CalendarContract.ColorsColumns#COLOR_KEY COLOR_KEY} +which must be unique for a given account name/type. These values can only be +updated by the sync adapter.
    • +
    • Adds {@link android.provider.CalendarContract.CalendarColumns#ALLOWED_AVAILABILITY ALLOWED_AVAILABILITY} +and +{@link android.provider.CalendarContract.CalendarColumns#ALLOWED_ATTENDEE_TYPES ALLOWED_ATTENDEE_TYPES} +for exchange/sync support.
    • +
    • Adds {@link android.provider.CalendarContract.AttendeesColumns#TYPE_RESOURCE} +(such as conference rooms) for attendees and +{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY_TENTATIVE}, +as well as {@link android.provider.CalendarContract.EventsColumns#EVENT_COLOR_KEY} +for events.
    • +
    + +

    Home screen widgets

    + +

    Starting from Android 4.0, home screen widgets should no longer include their +own padding. Instead, the system now automatically adds padding for each widget, +based the characteristics of the current screen. This leads to a more uniform, +consistent presentation of widgets in a grid. To assist applications that host +home screen widgets, the platform provides a new method +{@link android.appwidget.AppWidgetHostView#getDefaultPaddingForWidget(android.content.Context, android.content.ComponentName, android.graphics.Rect) +getDefaultPaddingForWidget()}. Applications can call this method to get the +system-defined padding and account for it when computing the number of cells to +allocate to the widget.

    + +

    Spell-checking

    + +
      +
    • For apps that accessing spell-checker services, a new {@link +android.view.textservice.SpellCheckerSession#cancel() cancel()} method cancels +any pending and running spell-checker tasks in a session.
    • + +
    • For spell-checker services, a new suggestions flag, +{@link android.view.textservice.SuggestionsInfo#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS}, +lets the services distinguish higher-confidence suggestions from +lower-confidence ones. For example, a spell-checker could set the flag if an +input word is not in the user dictionary but has likely suggestions, or not set +the flag if an input word is not in the dictionary and has suggestions that are +likely to be less useful. + +

      Apps connected to the spell-checker can use the {@link +android.view.textservice.SuggestionsInfo#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS} +flag in combination with other suggestion attributes, as well as the {@link +android.view.textservice.SuggestionsInfo#getSuggestionsAttributes()} and {@link +android.view.textservice.SuggestionsInfo#getSuggestionsCount()} methods, to +determine whether to mark input words as typos and offer suggestions.

    • + +
    • A new {@link android.text.style.SuggestionSpan#FLAG_AUTO_CORRECTION} style +for text spans indicates that auto correction is about to be applied to a +word/text that the user is typing/composing. This type of suggestion is rendered +differently, to indicate the auto correction is happening.
    • +
    + +

    Bluetooth

    +

    New public methods {@link +android.bluetooth.BluetoothDevice#fetchUuidsWithSdp()} and {@link +android.bluetooth.BluetoothDevice#getUuids()} let apps determine the features +(UUIDs) supported by a remote device. In the case of {@link +android.bluetooth.BluetoothDevice#fetchUuidsWithSdp()}, the system performs a +service discovery on the remote device to get the UUIDs supported, then +broadcasts the result in an {@link +android.bluetooth.BluetoothDevice#ACTION_UUID} intent.

    + +

    UI toolkit

    + +

    New methods {@link android.app.Fragment#setUserVisibleHint(boolean) setUserVisibleHint()} and +{@link android.app.Fragment#getUserVisibleHint() getUserVisibleHint()} allow a +fragment to set a hint of whether or not it is currently user-visible. The +system defers the start of fragments that are not user-visible until the loaders +for visible fragments have run. The visibility hint is "true" by default. +

    + +

    Graphics

    + +
      +
    • New method {@link android.graphics.SurfaceTexture#setDefaultBufferSize(int +width, int height)} in SurfaceTexture sets the default size of the image +buffers. This method may be used to set the image size when producing images +with {@link android.graphics.Canvas} (via {@link +android.view.Surface#lockCanvas}), or OpenGL ES (via an EGLSurface).
    • +
    • Adds definitions for the enums of the GL_OES_EGL_image_external OpenGL ES extension — +{@link android.opengl.GLES11Ext#GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES}, +{@link android.opengl.GLES11Ext#GL_SAMPLER_EXTERNAL_OES}, +{@link android.opengl.GLES11Ext#GL_TEXTURE_BINDING_EXTERNAL_OES}, and +{@link android.opengl.GLES11Ext#GL_TEXTURE_EXTERNAL_OES}.
    • +
    + +

    Accessibility

    + +
      +
    • Clients of {@link android.widget.RemoteViews} can now use the method {@link +android.widget.RemoteViews#setContentDescription(int, java.lang.CharSequence) +setContentDescription()} to set and get the content description of any View in +the inflated layout.
    • + +
    • The methods {@link android.view.accessibility.AccessibilityRecord#getMaxScrollX()}, +{@link android.view.accessibility.AccessibilityRecord#getMaxScrollY()}, +{@link android.view.accessibility.AccessibilityRecord#setMaxScrollX(int) setMaxScrollX()}, and +{@link android.view.accessibility.AccessibilityRecord#setMaxScrollY(int) setMaxScrollY()} +allow apps to get and set the maximum scroll offset for an +{@link android.view.accessibility.AccessibilityRecord} object.
    • + +
    • When touch-exploration mode is enabled, a new secure setting +{@link android.provider.Settings.Secure#ACCESSIBILITY_SPEAK_PASSWORD} +indicates whether the user requests the IME to speak text entered in password fields, even when +a headset is not in use. By default, no password text is spoken unless a headset +is in use.
    • +
    + +

    Text-to-speech

    + +
      +
    • Adds the new method {@link +android.speech.tts.TextToSpeech.Engine#getFeatures(java.util.Locale) +getFeatures()}for querying and enabling network TTS support. +
    • Adds a new listener class, {@link +android.speech.tts.UtteranceProgressListener}, that engines can register to +receive notification of speech-sythesis errors.
    • +
    + +

    Database

    + +
      +
    • A new {@link android.database.CrossProcessCursorWrapper} class lets content +providers return results for a cross-process query more effieciently. The new +class is a useful building block for wrapping cursors that will be sent to +processes remotely. It can also transform normal {@link android.database.Cursor} +objects into {@link android.database.CrossProcessCursor} objects +transparently. + +

      The {@link android.database.CrossProcessCursorWrapper} class fixes common +performance issues and bugs that applications have encountered when +implementing content providers.

    • + +
    • The {@link android.database.CursorWindow#CursorWindow(java.lang.String)} +constructor now takes a name string as input. The system no longer distinguishes +between local and remote cursor windows, so {@link +android.database.CursorWindow#CursorWindow(boolean)} is now deprecated.
    • +
    + +

    Intents

    + +

    Adds for categories for targeting common types of applications on the +device, such as {@link android.content.Intent#CATEGORY_APP_BROWSER}, {@link +android.content.Intent#CATEGORY_APP_CALENDAR}, {@link +android.content.Intent#CATEGORY_APP_MAPS}, and more. + +

    Camera

    + +
      +
    • {@link android.media.MediaMetadataRetriever} adds the new constant +{@link android.media.MediaMetadataRetriever#METADATA_KEY_LOCATION} to let apps +access retrieve location information for an image or video.
    • + +
    • {@link android.media.CamcorderProfile} adds the QVGA (320x240) resolution +profiles. Quality level is represented by the +{@link android.media.CamcorderProfile#QUALITY_QVGA}.and +{@link android.media.CamcorderProfile#QUALITY_TIME_LAPSE_QVGA} constants.
    • + +
    • New methods {@link android.hardware.Camera.Parameters#setVideoStabilization(boolean) setVideoStabilization()}, +{@link android.hardware.Camera.Parameters#getVideoStabilization() setVideoStabilization()}, and {android.hardware.Camera.Parameters#isVideoStabilizationSupported() isVideoStabilizationSupported()} +let you check and manage video stabilization for a {@link android.hardware.Camera}.
    • +
    + +

    Permissions

    + +

    The following are new permissions:

    +
      +
    • {@link android.Manifest.permission#READ_SOCIAL_STREAM} and +{@link android.Manifest.permission#WRITE_SOCIAL_STREAM}: Allow a sync +adapter to read and write social stream data to a contact in the shared +contacts provider.
    • +
    + + +
    +

    For a detailed view of all API changes in Android {@sdkPlatformVersion} (API Level +{@sdkPlatformApiLevel}), see the API Differences Report.

    +
    + + +

    API Level

    + +

    The Android {@sdkPlatformVersion} API is assigned an integer +identifier—{@sdkPlatformApiLevel}—that is stored in the system itself. +This identifier, called the "API level", allows the system to correctly determine whether an +application is compatible with the system, prior to installing the application.

    + +

    To use APIs introduced in Android {@sdkPlatformVersion} in your application, you need compile the +application against an Android platform that supports API level {@sdkPlatformApiLevel} or +higher. Depending on your needs, you might also need to add an +android:minSdkVersion="{@sdkPlatformApiLevel}" attribute to the +{@code <uses-sdk>} +element.

    + +

    For more information, see the API Levels +document.

    + + +

    Built-in Applications

    + +

    The system image included in the downloadable platform provides these +built-in applications:

    + + + + + + +
    +
      +
    • API Demos
    • +
    • Browser
    • +
    • Calculator
    • +
    • Calendar
    • +
    • Camera
    • +
    • Clock
    • +
    • Custom Locale
    • +
    • Dev Tools
    • +
    • Downloads
    • +
    • Email
    • +
    • Gallery
    • +
    +
    +
      +
    • Gestures Builder
    • +
    • Messaging
    • +
    • Music
    • +
    • People
    • +
    • Phone
    • +
    • Search
    • +
    • Settings
    • +
    • Speech Recorder
    • +
    • Widget Preview
    • +
    +
    + + +

    Locales

    + +

    The system image included in the downloadable SDK platform provides a variety of built-in +locales. In some cases, region-specific strings are available for the locales. In other cases, a +default version of the language is used. The languages that are available in the Android 3.0 system +image are listed below (with language_country/region locale descriptor).

    + + + + + + +
    +
      +
    • Arabic, Egypt (ar_EG)
    • +
    • Arabic, Israel (ar_IL)
    • +
    • Bulgarian, Bulgaria (bg_BG)
    • +
    • Catalan, Spain (ca_ES)
    • +
    • Czech, Czech Republic (cs_CZ)
    • +
    • Danish, Denmark(da_DK)
    • +
    • German, Austria (de_AT)
    • +
    • German, Switzerland (de_CH)
    • +
    • German, Germany (de_DE)
    • +
    • German, Liechtenstein (de_LI)
    • +
    • Greek, Greece (el_GR)
    • +
    • English, Australia (en_AU)
    • +
    • English, Canada (en_CA)
    • +
    • English, Britain (en_GB)
    • +
    • English, Ireland (en_IE)
    • +
    • English, India (en_IN)
    • +
    • English, New Zealand (en_NZ)
    • +
    • English, Singapore(en_SG)
    • +
    • English, US (en_US)
    • +
    • English, Zimbabwe (en_ZA)
    • +
    • Spanish (es_ES)
    • +
    • Spanish, US (es_US)
    • +
    • Finnish, Finland (fi_FI)
    • +
    • French, Belgium (fr_BE)
    • +
    • French, Canada (fr_CA)
    • +
    • French, Switzerland (fr_CH)
    • +
    • French, France (fr_FR)
    • +
    • Hebrew, Israel (he_IL)
    • +
    • Hindi, India (hi_IN)
    • +
    +
    +
  • Croatian, Croatia (hr_HR)
  • +
  • Hungarian, Hungary (hu_HU)
  • +
  • Indonesian, Indonesia (id_ID)
  • +
  • Italian, Switzerland (it_CH)
  • +
  • Italian, Italy (it_IT)
  • +
  • Japanese (ja_JP)
  • +
  • Korean (ko_KR)
  • +
  • Lithuanian, Lithuania (lt_LT)
  • +
  • Latvian, Latvia (lv_LV)
  • +
  • Norwegian bokmål, Norway (nb_NO)
  • +
  • Dutch, Belgium (nl_BE)
  • +
  • Dutch, Netherlands (nl_NL)
  • +
  • Polish (pl_PL)
  • +
  • Portuguese, Brazil (pt_BR)
  • +
  • Portuguese, Portugal (pt_PT)
  • +
  • Romanian, Romania (ro_RO)
  • +
  • Russian (ru_RU)
  • +
  • Slovak, Slovakia (sk_SK)
  • +
  • Slovenian, Slovenia (sl_SI)
  • +
  • Serbian (sr_RS)
  • +
  • Swedish, Sweden (sv_SE)
  • +
  • Thai, Thailand (th_TH)
  • +
  • Tagalog, Philippines (tl_PH)
  • +
  • Turkish, Turkey (tr_TR)
  • +
  • Ukrainian, Ukraine (uk_UA)
  • +
  • Vietnamese, Vietnam (vi_VN)
  • +
  • Chinese, PRC (zh_CN)
  • +
  • Chinese, Taiwan (zh_TW)
  • +
    + +

    Note: The Android platform may support more +locales than are included in the SDK system image. All of the supported locales +are available in the Android Open Source +Project.

    + +

    Emulator Skins

    + +

    The downloadable platform includes the following emulator skins:

    + +
      +
    • + QVGA (240x320, low density, small screen) +
    • +
    • + WQVGA400 (240x400, low density, normal screen) +
    • +
    • + WQVGA432 (240x432, low density, normal screen) +
    • +
    • + HVGA (320x480, medium density, normal screen) +
    • +
    • + WVGA800 (480x800, high density, normal screen) +
    • +
    • + WVGA854 (480x854 high density, normal screen) +
    • +
    • + WXGA720 (1280x720, extra-high density, normal screen) +
    • +
    • + WSVGA (1024x600, medium density, large screen) +
    • +
    • + WXGA (1280x800, medium density, xlarge screen) +
    • +
    + +

    To test your application on an emulator that represents the latest Android device, you can create +an AVD with the new WXGA720 skin (it's an xhdpi, normal screen device). Note that the emulator +currently doesn't support the new on-screen navigation bar for devices without hardware navigation +buttons, so when using this skin, you must use keyboard keys Home for the Home button, +ESC for the Back button, and F2 or Page-up for the Menu button.

    + +

    However, due to performance issues in the emulator when running high-resolution screens such as +the one for the WXGA720 skin, we recommend that you primarily use the traditional WVGA800 skin +(hdpi, normal screen) to test your application.

    + diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs index 791e7aa201f73..f0651ea2c047c 100644 --- a/docs/html/sdk/sdk_toc.cs +++ b/docs/html/sdk/sdk_toc.cs @@ -76,11 +76,11 @@ class="new">new!
    • - +
    • From 251fe263756988a6d6207fe73bb0f64bf2abacda Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 14 Dec 2011 17:20:54 -0800 Subject: [PATCH 7/8] Fix some java docs. Change-Id: I0eeba6f9108db74418063fba522ed3ef1c27ae95 --- core/java/android/content/Intent.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 4e5598b3a0a1d..e3b1f541d2113 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2318,7 +2318,7 @@ public class Intent implements Parcelable, Cloneable { *

      NOTE: This should not be used as the primary key of an Intent, * since it will not result in the app launching with the correct * action and category. Instead, use this with - * {@link #makeMainSelectorActivity(String, String) to generate a main + * {@link #makeMainSelectorActivity(String, String)} to generate a main * Intent with this category in the selector.

      */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) @@ -2330,7 +2330,7 @@ public class Intent implements Parcelable, Cloneable { *

      NOTE: This should not be used as the primary key of an Intent, * since it will not result in the app launching with the correct * action and category. Instead, use this with - * {@link #makeMainSelectorActivity(String, String) to generate a main + * {@link #makeMainSelectorActivity(String, String)} to generate a main * Intent with this category in the selector.

      */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) @@ -2342,7 +2342,7 @@ public class Intent implements Parcelable, Cloneable { *

      NOTE: This should not be used as the primary key of an Intent, * since it will not result in the app launching with the correct * action and category. Instead, use this with - * {@link #makeMainSelectorActivity(String, String) to generate a main + * {@link #makeMainSelectorActivity(String, String)} to generate a main * Intent with this category in the selector.

      */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) @@ -2354,7 +2354,7 @@ public class Intent implements Parcelable, Cloneable { *

      NOTE: This should not be used as the primary key of an Intent, * since it will not result in the app launching with the correct * action and category. Instead, use this with - * {@link #makeMainSelectorActivity(String, String) to generate a main + * {@link #makeMainSelectorActivity(String, String)} to generate a main * Intent with this category in the selector.

      */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) @@ -2366,7 +2366,7 @@ public class Intent implements Parcelable, Cloneable { *

      NOTE: This should not be used as the primary key of an Intent, * since it will not result in the app launching with the correct * action and category. Instead, use this with - * {@link #makeMainSelectorActivity(String, String) to generate a main + * {@link #makeMainSelectorActivity(String, String)} to generate a main * Intent with this category in the selector.

      */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) @@ -2379,7 +2379,7 @@ public class Intent implements Parcelable, Cloneable { *

      NOTE: This should not be used as the primary key of an Intent, * since it will not result in the app launching with the correct * action and category. Instead, use this with - * {@link #makeMainSelectorActivity(String, String) to generate a main + * {@link #makeMainSelectorActivity(String, String)} to generate a main * Intent with this category in the selector.

      */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) @@ -2391,7 +2391,7 @@ public class Intent implements Parcelable, Cloneable { *

      NOTE: This should not be used as the primary key of an Intent, * since it will not result in the app launching with the correct * action and category. Instead, use this with - * {@link #makeMainSelectorActivity(String, String) to generate a main + * {@link #makeMainSelectorActivity(String, String)} to generate a main * Intent with this category in the selector.

      */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) @@ -2403,7 +2403,7 @@ public class Intent implements Parcelable, Cloneable { *

      NOTE: This should not be used as the primary key of an Intent, * since it will not result in the app launching with the correct * action and category. Instead, use this with - * {@link #makeMainSelectorActivity(String, String) to generate a main + * {@link #makeMainSelectorActivity(String, String)} to generate a main * Intent with this category in the selector.

      */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) @@ -2416,7 +2416,7 @@ public class Intent implements Parcelable, Cloneable { *

      NOTE: This should not be used as the primary key of an Intent, * since it will not result in the app launching with the correct * action and category. Instead, use this with - * {@link #makeMainSelectorActivity(String, String) to generate a main + * {@link #makeMainSelectorActivity(String, String)} to generate a main * Intent with this category in the selector.

      */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) From 3e0f448fbe4b7e4835f090168e52469997617eca Mon Sep 17 00:00:00 2001 From: Jamie Gennis Date: Thu, 15 Dec 2011 18:14:05 -0800 Subject: [PATCH 8/8] SurfaceMediaSource: use the HW_TEXTURE usage bit This change makes SurfaceMediaSource request Gralloc buffers with the HW_TEXTURE usage bit rather than the VIDEO_ENCODER bit. It is a temporary workaround for what is likely a Gralloc bug. Bug: 5771063 Change-Id: I9cce615e80fc14a1644fae27ba06970c262dd179 --- media/libstagefright/SurfaceMediaSource.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp index 86b33d1c4fd1e..38daf72f9104e 100644 --- a/media/libstagefright/SurfaceMediaSource.cpp +++ b/media/libstagefright/SurfaceMediaSource.cpp @@ -336,7 +336,9 @@ status_t SurfaceMediaSource::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, (uint32_t(buffer->height) != h) || (uint32_t(buffer->format) != format) || ((uint32_t(buffer->usage) & usage) != usage)) { - usage |= GraphicBuffer::USAGE_HW_VIDEO_ENCODER; + // XXX: This will be changed to USAGE_HW_VIDEO_ENCODER once driver + // issues with that flag get fixed. + usage |= GraphicBuffer::USAGE_HW_TEXTURE; status_t error; sp graphicBuffer( mGraphicBufferAlloc->createGraphicBuffer(