<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2portuguesefull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0" xml:base="http://www.broculos.net">
<channel>
 <title>Broculos.net</title>
 <link>http://www.broculos.net</link>
 <description>Programming tutorials, always fresh and nutritive.</description>
 <language>pt-pt</language>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/broculospt" /><feedburner:info uri="broculospt" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbroculospt" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbroculospt" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/broculospt" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbroculospt" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fbroculospt" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbroculospt" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fbroculospt" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><item>
 <title>SharePoint 2010 Branding: Master page invalida em sites non-publishing</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/WZKYuoWGmbU/sharepoint-2010-branding-master-page-invalida-em-sites-non-publishing</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Ao criar-se um novo site non-publishing vai aparecer um erro da master page ("The site master page setting currently applied to this site is invalid. Please select a new master page and apply it") e a master page usada passa a ser a v4.master. Isto apenas acontece se o site raiz for um site publishing. Tambem é graças ao site raiz ser um publishing site que podemos navegar até à pagina de configuração da master page através do url /_layouts/changesitemasterpage.aspx e ver o referido erro.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-invalidmaster-1.PNG" style="width: 600px; height: 316px; " /&gt;&lt;/p&gt;
&lt;p&gt;Esta poderá ser a razão pela qual, por omissão, não é possível criar sites non-publishing dentro de um site publishing... No entanto, as pessoas precisam e querem usar estes site templates, por isso é necessário encontrar uma solução para este problema.&lt;/p&gt;
&lt;p&gt;Se estiver a usar as master page standard não vai notar nenhum problema, visto que apesar do erro o site usará a master page v4. O problema surge quando se pretende usar uma master page personalizada, por causa dos problemas de herança o CSS vai&lt;span style="white-space: nowrap;"&gt; ser usado&lt;/span&gt;, as master pages não.&lt;/p&gt;
&lt;p&gt;Quando a herança é manualmente activada na pagina de configuração da master page o erro desaparece e os estilos do site funcionam correctamente, mas não posso pedir a todos os clientes que reproduzam estes passos manualmente sempre que quiserem usar um site template non-publishing. Por isso criei uma feature que activa as opções e outra que faz o stapling da feature de herança aos site templates que necessito. Esta funcionalidade pode ser reutilizada em todos os meus projectos.&lt;/p&gt;
&lt;h2&gt;Feature para a herança&lt;/h2&gt;
&lt;p&gt;Esta feature é activada ao nível (scope) Web. O mais importante da feature está no seu event receiver. O código é claro, as três propriedades de herança que se encontram na página de configuração da master page são activadas.&lt;/p&gt;
&lt;pre class="brush:csharp;"&gt;
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
	SPWeb web = (SPWeb)properties.Feature.Parent;
	
	if (!web.IsRootWeb) 
	{
		Hashtable hash = web.AllProperties;
		web.MasterUrl = web.ParentWeb.MasterUrl;
		hash["__InheritsMasterUrl"] = "True";

		web.CustomMasterUrl = web.ParentWeb.CustomMasterUrl;
		hash["__InheritsCustomMasterUrl"] = "True";

		web.AlternateCssUrl = web.ParentWeb.AlternateCssUrl;
		hash["__InheritsAlternateCssUrl"] = "True";

		web.Update();
	}
}&lt;/pre&gt;&lt;h2&gt;Feature de stapling&lt;/h2&gt;
&lt;p&gt;Nesta feature associa-se a feature de herança aos site templates desejados. Em baixo encontra-se um exemplo de como activar a feature para o site template Team Site.&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;Elements xmlns="http://schemas.microsoft.com/sharepoint/"&amp;gt;  
	&amp;lt;FeatureSiteTemplateAssociation Id="00000000-0000-0000-0000-000000000000" TemplateName="STS#0" /&amp;gt;
&amp;lt;/Elements&amp;gt;&lt;/pre&gt;&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Hg2R28trVelp1ko8XQiEluCkT8w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Hg2R28trVelp1ko8XQiEluCkT8w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Hg2R28trVelp1ko8XQiEluCkT8w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Hg2R28trVelp1ko8XQiEluCkT8w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WZKYuoWGmbU:EIXrSveFHC8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WZKYuoWGmbU:EIXrSveFHC8:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=WZKYuoWGmbU:EIXrSveFHC8:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WZKYuoWGmbU:EIXrSveFHC8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WZKYuoWGmbU:EIXrSveFHC8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=WZKYuoWGmbU:EIXrSveFHC8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WZKYuoWGmbU:EIXrSveFHC8:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=WZKYuoWGmbU:EIXrSveFHC8:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WZKYuoWGmbU:EIXrSveFHC8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=WZKYuoWGmbU:EIXrSveFHC8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WZKYuoWGmbU:EIXrSveFHC8:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/WZKYuoWGmbU" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 12 Mar 2012 10:30:06 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">144 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-2010-branding-master-page-invalida-em-sites-non-publishing</feedburner:origLink></item>
<item>
 <title>Redireccionamento de websites no IIS 6</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/mniyamBLsik/redireccionamento-de-websites-no-iis-6</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Por vezes quando trabalhamos num website com vários domínios (org, com, net, etc.), queremos que os domínios secundários redireccionem para o domínio principal. É fácil de fazer isto no IIS (IIS 6, sem módulos necessários). O IIS tem um &lt;a href="http://www.webmasterworld.com/forum23/3432.htm"&gt;módulo rewrite embutido&lt;/a&gt; que permite &lt;a href="http://www.windowshostingasp.net/windows_hosting_forums/showthread.php?t=35"&gt;redireccionar para um URL específico&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Também é possível ter vários URLs mapeados para o mesmo website no IIS, mas não é isto que queremos, porque precisamos que os URLs secundários redireccionem de facto para o URL principal (por exemplo transformando automaticamente &lt;strong&gt;domain.org/something&lt;/strong&gt; em &lt;strong&gt;&lt;a href="http://www.domain.com/something"&gt;www.domain.com/something&lt;/a&gt;&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;É necessário criar um website no IIS para os redirects (todos os URLs secundários podem ser mapeados para este mesmo website no IIS, para assim podermos aplicar a regra de redirect a todos eles ao mesmo tempo). Podem usar a mesma configuração do site principal. A directoria que escolhem no sistema de ficheiros não interessa, pois será alterada mais tarde.&lt;/p&gt;
&lt;p&gt;Como configurar o redireccionamento no IIS:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Abrir as propriedades do website onde se vai configurar a redirecção.&lt;/li&gt;
&lt;li&gt;Abrir a tab &lt;strong&gt;Home Directory&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Escolher &lt;strong&gt;A redirection to a URL&lt;/strong&gt;.
&lt;ul&gt;&lt;li&gt;Escrever o URL para onde redireccionar (por exemplo &lt;strong&gt;&lt;a href="http://www.example-new.com"&gt;http://www.example-new.com&lt;/a&gt;$S$Q&lt;/strong&gt; - reparem nos parâmetros e na falta de barras).&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Activem &lt;strong&gt;The exact URL entered above&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Activem &lt;strong&gt;A permanent redirection for this resource&lt;/strong&gt; se quiserem um redirect permanente (301) ou deixem desactivado para um redirect temporário (302).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Os parâmetros depois do URL principal dizem ao IIS para redireccionar para o mesmo caminho e com a mesma query string que foram pedidos. Podem ver em mais detalhes sobre o que cada parâmetro faz na &lt;a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/41c238b2-1188-488f-bf2d-464383b1bb08.mspx?mfr=true"&gt;referência de Redirect do IIS 6&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/p24MINNIkE9-1Zmju5POqNdUzJg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p24MINNIkE9-1Zmju5POqNdUzJg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/p24MINNIkE9-1Zmju5POqNdUzJg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p24MINNIkE9-1Zmju5POqNdUzJg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=mniyamBLsik:GI2GpdDgsTw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=mniyamBLsik:GI2GpdDgsTw:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=mniyamBLsik:GI2GpdDgsTw:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=mniyamBLsik:GI2GpdDgsTw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=mniyamBLsik:GI2GpdDgsTw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=mniyamBLsik:GI2GpdDgsTw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=mniyamBLsik:GI2GpdDgsTw:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=mniyamBLsik:GI2GpdDgsTw:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=mniyamBLsik:GI2GpdDgsTw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=mniyamBLsik:GI2GpdDgsTw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=mniyamBLsik:GI2GpdDgsTw:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/mniyamBLsik" height="1" width="1"/&gt;</description>
 <pubDate>Sun, 15 Jan 2012 18:02:48 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">142 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/redireccionamento-de-websites-no-iis-6</feedburner:origLink></item>
<item>
 <title>Google Currents: Edição do Broculos.net</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/cvSgejy4pqw/google-currents-edi%C3%A7%C3%A3o-do-broculosnet</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Acabamos de criar a nossa &lt;a href="http://www.google.com/producer/editions/CAowwZlD/broculosnet_programming_tutorials"&gt;edição do Google Currents&lt;/a&gt; com o conteúdo deste blog e com a nossa actividade no Google+.&lt;/p&gt;
&lt;p&gt;O &lt;a href="http://www.google.com/producer/currents"&gt;Google Currents&lt;/a&gt; é um leitor de notícias para dispositivos Android e iOS. Tem um layout simples onde o conteúdo se adapta ao dispositivo. Cada publicação pode ser uma combinação de feeds, media e canais sociais. Uma das funcionalidades mais úteis do Google Currents é a sua capacidade para guardar os artigos para leitura offline, podendo assim serem lidos em qualquer lado.&lt;/p&gt;
&lt;p&gt;Para subscrever à nossa edição do Google Currents primeiro instale a aplicação do Google Currents e depois siga &lt;a href="http://www.google.com/producer/editions/CAowwZlD/broculosnet_programming_tutorials"&gt;este link&lt;/a&gt; no seu dispositivo.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NdpxwP9axeWVGztzjWoiWLOQOqg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NdpxwP9axeWVGztzjWoiWLOQOqg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NdpxwP9axeWVGztzjWoiWLOQOqg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NdpxwP9axeWVGztzjWoiWLOQOqg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=cvSgejy4pqw:ElNZYUrY3B0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=cvSgejy4pqw:ElNZYUrY3B0:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=cvSgejy4pqw:ElNZYUrY3B0:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=cvSgejy4pqw:ElNZYUrY3B0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=cvSgejy4pqw:ElNZYUrY3B0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=cvSgejy4pqw:ElNZYUrY3B0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=cvSgejy4pqw:ElNZYUrY3B0:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=cvSgejy4pqw:ElNZYUrY3B0:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=cvSgejy4pqw:ElNZYUrY3B0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=cvSgejy4pqw:ElNZYUrY3B0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=cvSgejy4pqw:ElNZYUrY3B0:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/cvSgejy4pqw" height="1" width="1"/&gt;</description>
 <pubDate>Sun, 18 Dec 2011 21:57:51 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">140 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/noticia/google-currents-edi%C3%A7%C3%A3o-do-broculosnet</feedburner:origLink></item>
<item>
 <title>Android 101: Publicar no mercado Android</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/fk8dKizhpo4/android-101-publicar-no-mercado-android</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-como-criar-um-widget-stackview"&gt;Como criar um widget StackView&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Embora tenhamos optado por não publicar a aplicação Honeybuzz no mercado (por &lt;a href="http://googleblog.blogspot.com/2011/10/fall-sweep.html"&gt;razões óbvias&lt;/a&gt;), ainda aprendemos algumas coisas que poderão ser úteis a qualquer programador Android.&lt;/p&gt;
&lt;h2&gt;A sua aplicação no Android Market&lt;/h2&gt;
&lt;p&gt;Agora que terminou a primeira versão da sua aplicação e está pronto a publicá-la no mercado, não pode ignorar os dados que coloca na página da sua aplicação no Android Market. Deverá colocar tanto esforço nesta informação como o esforço que dedicou à criação da aplicação. O utilizador pode decidir não descarregar a aplicação se:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;A descrição da aplicação for pobre, tiver erros ortográficos e/ou não descrever claramente o que a aplicação faz.&lt;/li&gt;
&lt;li&gt;Tiver poucos screenshots, as imagens tiverem má qualidade ou se não tiver screenshots das funcionalidades principais da aplicação.&lt;/li&gt;
&lt;li&gt;O logótipo, nome da aplicação ou nome do criador parecer fictício, pouco profissional ou foleiro.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Esta informação pode fazer toda a diferença no sucesso da sua aplicação. Se o utilizador encontrar uma página confusa ou pouco profissional, ele irá simplesmente procurar outra aplicação que lhe pareça mais confiável e que faça o mesmo que a sua. Não deite a perder todo o tempo que gastou a desenvolver uma aplicação só porque não quer gastar mais algum tempo a construir uma boa descrição ou a tirar screenshots de qualidade. Estes pormenores fazem mesmo a diferença.&lt;/p&gt;
&lt;h2&gt;O logótipo: Amor à primeira vista?&lt;/h2&gt;
&lt;p&gt;Se um utilizador procurar por “note taking app” vão surgir centenas de resultados. Qual será a aplicação que o utilizador escolherá? Qual seria a que você escolheria?&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/content/android101-13-1.png" style="width: 628px; height: 394px; " width="628" height="394" /&gt;&lt;/p&gt;
&lt;p&gt;Possivelmente escolheria a aplicação com o logótipo com melhor aspecto e com o nome que lhe soasse melhor. Entre tantas opções o utilizador tem de fazer generalizações e suposições baseando-se nos 10 segundos que passa a olhar para os resultados da pesquisa.&lt;/p&gt;
&lt;p&gt;Veja estes recursos com mais informações sobre como criar um óptimo logótipo para a sua aplicação:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://developer.android.com/guide/practices/ui_guidelines/icon_design_launcher.html"&gt;Launcher Icons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.google.com/support/androidmarket/developer/bin/answer.py?&amp;amp;&amp;amp;answer=1078870"&gt;Graphic Assets for your Application&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Aplique-se na criação da descrição da aplicação&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Estude o mercado. Leia as paginas das aplicações que concorrem com a sua. Não basta fazer o que eles fazem, dê um passo adiante. Se os seus concorrentes têm apenas screenshots da aplicação, adicione uma demonstração em vídeo da sua.&lt;/li&gt;
&lt;li&gt;Descrição acima da dobra. Se tiver uma descrição grande da sua aplicação esta será colapsada na página do mercado. O utilizador pode ou não expandi-la para ler todo o conteúdo. Certifique-se de transmitir o objectivo principal da aplicação acima da dobra. Diga ao utilizador porque deve descarregar a sua aplicação.&lt;/li&gt;
&lt;li&gt;Descreva todas as funcionalidades principais da sua aplicação.&lt;/li&gt;
&lt;li&gt;Não tenha medo de se gabar. Se a sua aplicação ganhou um prémio ou foi referida positivamente numa publicação de renome, diga-o. Este tipo de informação dá ao utilizador confiança na qualidade da sua aplicação.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Mais recursos&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://developer.android.com/guide/publishing/publishing.html"&gt;Publishing on Android Market&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.google.com/events/io/2011/sessions/android-market-for-developers.html"&gt;Android Market for Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.android.com/guide/practices/screens_support.html"&gt;Supporting Multiple Screens&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/khM838rB0iKUuEvAoEllX4ov1XY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/khM838rB0iKUuEvAoEllX4ov1XY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/khM838rB0iKUuEvAoEllX4ov1XY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/khM838rB0iKUuEvAoEllX4ov1XY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=fk8dKizhpo4:0tPFPPvE3sY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=fk8dKizhpo4:0tPFPPvE3sY:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=fk8dKizhpo4:0tPFPPvE3sY:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=fk8dKizhpo4:0tPFPPvE3sY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=fk8dKizhpo4:0tPFPPvE3sY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=fk8dKizhpo4:0tPFPPvE3sY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=fk8dKizhpo4:0tPFPPvE3sY:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=fk8dKizhpo4:0tPFPPvE3sY:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=fk8dKizhpo4:0tPFPPvE3sY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=fk8dKizhpo4:0tPFPPvE3sY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=fk8dKizhpo4:0tPFPPvE3sY:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/fk8dKizhpo4" height="1" width="1"/&gt;</description>
 <pubDate>Wed, 14 Dec 2011 10:00:48 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">136 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-publicar-no-mercado-android</feedburner:origLink></item>
<item>
 <title>Android 101: Como criar um widget StackView</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/HGE0GaeiRMQ/android-101-como-criar-um-widget-stackview</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-como-monetizar-uma-aplica%C3%A7%C3%A3o-android"&gt;Como monetizar uma aplicação Android&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Widgets são uma boa ferramenta para os utilizadores personalizarem o ecrã principal do seu dispositivo. É uma boa forma de aumentar o interesse numa aplicação. Um widget pode fornecer bastante informação de forma sucinta e mostrar atalhos para acções comuns.&lt;/p&gt;
&lt;p&gt;O Honeycomb introduziu widgets para colecções. Como o nome implica, são capazes de mostrar vários itens. Existem vários tipos de widgets para colecções:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;ListView&lt;/strong&gt;: uma lista vertical de itens (e.g. o widget do Gmail).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GridView&lt;/strong&gt;: uma lista vertical com duas colunas (e.g. o widget dos bookmarks).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;StackView&lt;/strong&gt;: uma vista de cartas empilhadas, onde o item da frente pode ser passado à frente para dar lugar ao item a seguir (e.g. o widget do Market).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AdapterViewFlipper&lt;/strong&gt;: anima entre vistas, apenas mostrando uma de cada vez.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Vou explicar como fizemos o widget para a aplicação Honeybuzz. É um widget &lt;strong&gt;StackView &lt;/strong&gt;e mostra os Buzzes com uma foto do autor e uma porção do texto.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_widget.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_widget-200x125.png" style="width: 200px; height: 125px; " width="200" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Adicionar o widget ao manifesto&lt;/h2&gt;
&lt;p&gt;É necessário que o widget esteja declarado no manifesto da aplicação. Como estamos a usar um widget &lt;strong&gt;StackView&lt;/strong&gt;, temos que especificar tanto um widget provider como um widget service.&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;application&amp;gt;

	&amp;lt;!-- StackWidget Provider --&amp;gt;
	&amp;lt;receiver android:name="StackWidgetProvider"&amp;gt;
		&amp;lt;intent-filter&amp;gt;
			&amp;lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&amp;gt;
		&amp;lt;/intent-filter&amp;gt;
		&amp;lt;meta-data
			android:name="android.appwidget.provider"
			android:resource="@xml/stackwidgetinfo" /&amp;gt;
	&amp;lt;/receiver&amp;gt;
	
	&amp;lt;!-- StackWidget Service --&amp;gt;
	&amp;lt;service android:name="StackWidgetService"
		android:permission="android.permission.BIND_REMOTEVIEWS"
		android:exported="false" /&amp;gt;

&amp;lt;/application&amp;gt;&lt;/pre&gt;&lt;h2&gt;Como criar um widget provider&lt;/h2&gt;
&lt;p&gt;Para o widget provider, temos de especificar a informação necessária e criar a implementação da classe.&lt;/p&gt;
&lt;p&gt;A informação do provider é apenas um ficheiro XML que se cria na pasta &lt;strong&gt;res\xml&lt;/strong&gt;. Este é o ficheiro da aplicação Honeybuzz:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;appwidget-provider
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:minWidth="220dp"
  android:minHeight="220dp"
  android:updatePeriodMillis="1800000"
  android:initialLayout="@layout/stackwidget"
  android:autoAdvanceViewId="@id/stackWidgetView"
  android:previewImage="@drawable/stackwidget_preview"&amp;gt;
&amp;lt;/appwidget-provider&amp;gt;&lt;/pre&gt;&lt;p&gt;A maioria dos atributos são auto-explicativos. O atributo &lt;strong&gt;updatePeriodMillis&lt;/strong&gt; define o intervalo de actualização do provider. O mínimo possível são 15 minutos, mas deve-se actualizar o menos frequentemente possível, de forma a conservar bateria.&lt;/p&gt;
&lt;p&gt;Para determinar o tamanho do widget podem usar a seguinte fórmula (encontrada no site Android Developers):&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;(número de células * 74) - 2&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Portanto, se quiserem um widget 3 por 3 como na aplicação Honeybuzz:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;(3 * 74) - 2 = 220&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;O layout de um widget é parecido com um layout de uma Activity, mas é muito mais restritivo. Baseiam-se em &lt;strong&gt;RemoteViews&lt;/strong&gt; e as classes de layout e das vistas que se podem usar são limitadas (principalmente antes do Honeycomb, onde vistas com scrolling não eram possíveis para widgets).&lt;/p&gt;
&lt;p&gt;O layout para um widget &lt;strong&gt;StackView &lt;/strong&gt;pode ser tão simples quanto o seguinte:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"&amp;gt;
    &amp;lt;StackView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/stackWidgetView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:loopViews="true" /&amp;gt;
    &amp;lt;TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/stackWidgetEmptyView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/no_activities"
        android:background="@drawable/stackwidget_background"
        android:gravity="center"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:textSize="16sp" /&amp;gt;
&amp;lt;/FrameLayout&amp;gt;&lt;/pre&gt;&lt;p&gt;E a implementação da classe do widget provider:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
public class StackWidgetProvider extends AppWidgetProvider {
    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        super.onDeleted(context, appWidgetIds);
    }

    @Override
    public void onDisabled(Context context) {
        super.onDisabled(context);
    }

    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        for (int i = 0; i &amp;lt; appWidgetIds.length; ++i) {
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.stackwidget);

            // set intent for widget service that will create the views
            Intent serviceIntent = new Intent(context, StackWidgetService.class);
            serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
            serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); // embed extras so they don't get ignored
            remoteViews.setRemoteAdapter(appWidgetIds[i], R.id.stackWidgetView, serviceIntent);
            remoteViews.setEmptyView(R.id.stackWidgetView, R.id.stackWidgetEmptyView);
            
            // set intent for item click (opens main activity)
            Intent viewIntent = new Intent(context, HoneybuzzListActivity.class);
            viewIntent.setAction(HoneybuzzListActivity.ACTION_VIEW);
            viewIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
            viewIntent.setData(Uri.parse(viewIntent.toUri(Intent.URI_INTENT_SCHEME)));
            
            PendingIntent viewPendingIntent = PendingIntent.getActivity(context, 0, viewIntent, 0);
            remoteViews.setPendingIntentTemplate(R.id.stackWidgetView, viewPendingIntent);
            
            // update widget
            appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
        }
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }
}&lt;/pre&gt;&lt;p&gt;No método &lt;strong&gt;onUpdate &lt;/strong&gt;iteramos por todas as instâncias de widgets e adicionamos os Intents para o serviço que vai criar cada vista e também para cada click num item.&lt;/p&gt;
&lt;h2&gt;Criar o widget service e a vista para cada item&lt;/h2&gt;
&lt;p&gt;Num widget &lt;strong&gt;StackView&lt;/strong&gt; preciamos de um layout separado para cada item da colecção. Já devem saber como criar um, mas aqui está o que foi utilizado no widget do Honeybuzz:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/stackWidgetItem"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:background="@drawable/stackwidget_border"
    android:padding="4dp"&amp;gt;
    &amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:background="@drawable/stackwidget_background"&amp;gt;
          &amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/stackWidgetItemUser"
            android:orientation="vertical"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:padding="10dp"&amp;gt;
             &amp;lt;ImageView android:id="@+id/stackWidgetItemPicture"
                 android:layout_height="100dip"
                 android:layout_width="100dip"&amp;gt;
            &amp;lt;/ImageView&amp;gt;
            &amp;lt;TextView android:id="@+id/stackWidgetItemUsername"
                android:textSize="10sp"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                 android:paddingTop="6dp"&amp;gt;
            &amp;lt;/TextView&amp;gt;
           &amp;lt;/LinearLayout&amp;gt;
         &amp;lt;TextView android:id="@+id/stackWidgetItemContent"
             android:layout_height="fill_parent"
             android:layout_width="fill_parent"
             android:maxLines="7"
            android:paddingTop="6dp"
            android:paddingBottom="6dp"
            android:paddingRight="6dp"
            android:paddingLeft="0dp"&amp;gt;
        &amp;lt;/TextView&amp;gt;
    &amp;lt;/LinearLayout&amp;gt;
&amp;lt;/LinearLayout&amp;gt;&lt;/pre&gt;&lt;p&gt;O widget service tem de especificar a fábrica das views, que é responsável por criar a vista para cada item da colecção.&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
public class StackWidgetService extends RemoteViewsService {
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
    }
}

class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
    private final ImageDownloader imageDownloader = new ImageDownloader();
    private List&amp;lt;Buzz&amp;gt; mBuzzes = new ArrayList&amp;lt;Buzz&amp;gt;();
    private Context mContext;
    private int mAppWidgetId;

    public StackRemoteViewsFactory(Context context, Intent intent) {
        mContext = context;
        mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
    }

    public void onCreate() {
    }

    public void onDestroy() {
        mBuzzes.clear();
    }

    public int getCount() {
        return mBuzzes.size();
    }

    public RemoteViews getViewAt(int position) {
        RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.stackwidget_item);
        
        if (position &amp;lt;= getCount()) {
            Buzz buzz = mBuzzes.get(position);
            
            if (buzz.picture != null) {
                try {
                    Bitmap picture = imageDownloader.downloadBitmap(buzz.picture, 100, 100, 70);
                    rv.setImageViewBitmap(R.id.stackWidgetItemPicture, picture);
                }
                catch(Exception e) {
                    Logging.e("Error reading picture file", e);
                }
            }
            
            if (!buzz.username.isEmpty()) {
                rv.setTextViewText(R.id.stackWidgetItemUsername, buzz.username);
            }
            rv.setTextViewText(R.id.stackWidgetItemContent, Html.fromHtml(buzz.content));
            
            // store the buzz ID in the extras so the main activity can use it
            Bundle extras = new Bundle();
            extras.putString(HoneybuzzListActivity.EXTRA_ID, buzz.id);
            Intent fillInIntent = new Intent();
            fillInIntent.putExtras(extras);
            rv.setOnClickFillInIntent(R.id.stackWidgetItem, fillInIntent);
        }
        
        return rv;
    }

    public RemoteViews getLoadingView() {
        return null;
    }

    public int getViewTypeCount() {
        return 1;
    }

    public long getItemId(int position) {
        return position;
    }

    public boolean hasStableIds() {
        return true;
    }

    public void onDataSetChanged() {
        mBuzzes = Buzz.getBuzzes(HoneybuzzApplication.buzz, mContext);
    }
}&lt;/pre&gt;&lt;p&gt;As partes mais importantes:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;StackWidgetService&lt;/strong&gt;: escrever o método &lt;strong&gt;onGetViewFactory &lt;/strong&gt;para devolver a fábrica das views.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;StackRemoteViewsFactory&lt;/strong&gt;: gere as views para cada item da colecção.
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;onDataSetChanged&lt;/strong&gt;: carrega a informação necessária para mostrar no widget.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;onDestroy&lt;/strong&gt;: destruir todos os objectos que já não são necessários.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;getViewAt&lt;/strong&gt;: tem de devolver uma vista para o item na posição específica. Criamos uma nova vista com o ficheiro de layout especificado anteriormente, depois vamos buscar o objecto Buzz apropriado que usamos para preencher a vista com informação. No final adicionamos o Intent para o click, de forma a que quando o item seja seleccionado, a aplicação Honeybuzz seja aberta com o mesmo.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Como criar uma imagem de amostra para o widget&lt;/h2&gt;
&lt;p&gt;Uma imagem de amostra é apresentada quando o utilizador está a navegar na galeria dos widgets e ajuda o mesmo a perceber como o widget funciona. Se não for fornecida uma imagem de amostra, será usado o ícone da aplicação no seu lugar.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_widget_preview.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_widget_preview-200x125.png" style="width: 200px; height: 125px; " width="200" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Felizmente, o emulador e o SDK do Android vêm com uma aplicação para gerar imagens de amostra a partir de widgets. A aplicação chama-se "Widget Preview" e pode ser usada a partir do emulador ou ser copiada para um dispositivo e ser corrida a partir daí. O código da aplicação está na pasta do SDK no caminho &lt;strong&gt;android-sdk\samples\android-11\WidgetPreview&lt;/strong&gt;. É possível abrir o projecto, fazer o build e copiá-lo para um dispositivo. A aplicação é simples de usar e muito útil. Depois de gerar uma imagem, é necessário adicioná-la aos drawables do projecto e especificá-la na informação do widget provider (ver mais a cima para um exemplo).&lt;/p&gt;
&lt;h2&gt;Mais recursos&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://developer.android.com/guide/topics/appwidgets/index.html"&gt;App Widgets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html"&gt;Widget Design Guidelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.android.com/resources/samples/StackWidget/index.html"&gt;StackWidget&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-publicar-no-mercado-android"&gt;Publicar no mercado Android&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9sIuMnqY5LLrw11xhYtQukzWmLY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9sIuMnqY5LLrw11xhYtQukzWmLY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9sIuMnqY5LLrw11xhYtQukzWmLY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9sIuMnqY5LLrw11xhYtQukzWmLY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=HGE0GaeiRMQ:knv1RtvS0Zk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=HGE0GaeiRMQ:knv1RtvS0Zk:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=HGE0GaeiRMQ:knv1RtvS0Zk:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=HGE0GaeiRMQ:knv1RtvS0Zk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=HGE0GaeiRMQ:knv1RtvS0Zk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=HGE0GaeiRMQ:knv1RtvS0Zk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=HGE0GaeiRMQ:knv1RtvS0Zk:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=HGE0GaeiRMQ:knv1RtvS0Zk:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=HGE0GaeiRMQ:knv1RtvS0Zk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=HGE0GaeiRMQ:knv1RtvS0Zk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=HGE0GaeiRMQ:knv1RtvS0Zk:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/HGE0GaeiRMQ" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 12 Dec 2011 10:16:10 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">130 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-como-criar-um-widget-stackview</feedburner:origLink></item>
<item>
 <title>Android 101: Como monetizar uma aplicação Android</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/QMB1irqlWSw/android-101-como-monetizar-uma-aplica%C3%A7%C3%A3o-android</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-services-asynctasks-e-notifications"&gt; Services, AsyncTasks e Notifications&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Há diversas maneiras de ganhar dinheiro através de aplicações. Mais abaixo alguns detalhes sobre cada uma destas estratégias:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Aplicações pagas&lt;/li&gt;
&lt;li&gt;Compras dentro da aplicação&lt;/li&gt;
&lt;li&gt;Anúncios&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;A forma que escolhemos para monetizar a nossa aplicação foi através de anúncios e por isso pode encontrar no fim deste artigo instruções de como criar anúncios usando o Google AdMob.&lt;/p&gt;
&lt;h2&gt;Aplicações pagas&lt;/h2&gt;
&lt;p&gt;Aplicações pagas são descarregadas menos vezes do que aplicações grátis. No entanto, o lucro que trará é certo para cada download.&lt;/p&gt;
&lt;h4&gt;Apenas uma versão paga&lt;/h4&gt;
&lt;p&gt;Poderá ter apenas uma versão paga da sua aplicação. Considere bem todas as implicações de ir por este caminho. O utilizador precisa confiar que a promessa que lhe faz quando descreve a sua aplicação se vai tornar realidade quando a descarregar e utilizar. O utilizador está a dar-lhe dinheiro por algo que possivelmente nunca usou antes. Por isso precisa ganhar a sua confiança. Prepare uma boa campanha de marketing. Tome atenção ao que outros utilizadores dizem nas reviews da aplicação. Faça videos demonstrativos das funcionalidades da aplicação. Um portfólio de aplicações com boas avaliações é uma garantia de boa qualidade das aplicações novas que criar.&lt;/p&gt;
&lt;h4&gt;Versão Lite&lt;/h4&gt;
&lt;p&gt;Pode ter uma versão lite gratuita da sua aplicação e uma versão paga com funcionalidades extra. Esta é uma óptima forma de mostrar aos utilizadores o valor da aplicação sem eles terem que gastar dinheiro à partida. O utilizador pode testar a aplicação, as funcionalidades principais, a sensação de usar a aplicação e decidir se quer ou não o pacote completo. Certifique-se que inclui na versão lite as funcionalidades suficientes para que o utilizador possa testar correctamente a aplicação, mas deixe de fora os pormenores que serão indispensáveis ao utilizador se quiser ter um uso perfeito da aplicação.&lt;/p&gt;
&lt;h4&gt;Sem anúncios&lt;/h4&gt;
&lt;p&gt;Pode ter uma versão gratuita da aplicação suportada por anúncios e uma outra versão que poderá promover na grátis, sem anúncios.&lt;/p&gt;
&lt;h4&gt;Tome uma decisão&lt;/h4&gt;
&lt;p&gt;Estude a hipótese de vender a sua aplicação. As pessoas só gastarão dinheiro por algo que não conseguem encontrar de borla e que lhes traz valor acrescentado. Estude o mercado, que tipo de aplicações existem que fazem algo semelhante a sua? Como são essas aplicações monetizadas?&lt;/p&gt;
&lt;h2&gt;Compras dentro da aplicação&lt;/h2&gt;
&lt;p&gt;Com vendas dentro da aplicação poderá rentabilizá-la através da venda de conteúdos ou funcionalidades extra. Por exemplo, dentro de um jogo poderá ter níveis extra disponíveis mediante pagamento.&lt;/p&gt;
&lt;h4&gt;Freemium&lt;/h4&gt;
&lt;p&gt;Uma aplicacao freemium é uma aplicação grátis para descarregar, mas depois para poder usar as suas funcionalidades terá que comprar funcionalidades extra dentro da app. Por exemplo, uma aplicação para ler e vender livros onde o lucro viria da venda dos livros.&lt;/p&gt;
&lt;h2&gt;Os anúncios&lt;/h2&gt;
&lt;p&gt;Os anúncios são uma importante forma de obter receitas na sua aplicação. Ter anuncios dá-lhe a vantagem de ter uma aplicação gratuita (e logo mais facilmente descarregada do que uma paga) e ainda ser capaz de a rentabilizar. Os anúncios são uma velha forma de monetizar qualquer producto. TV, revistas e websites já o fazem.&lt;/p&gt;
&lt;p&gt;Dentro da sua aplicação pode facilmente controlar onde os anúncios são mostrados.&lt;/p&gt;
&lt;h4&gt;Aprenda o básico&lt;/h4&gt;
&lt;p&gt;É essencial saber &lt;a href="http://www.google.com/events/io/2011/sessions/dont-just-build-a-mobile-app-build-a-business.html"&gt;como os anúncios funcionam&lt;/a&gt; para que possa optimizar o seu rendimento. Conceitos como custo por click, request vs. impressions, são algo que deve entender para saber como os anúncios geram dinheiro.&lt;/p&gt;
&lt;h4&gt;Registar os resultados&lt;/h4&gt;
&lt;p&gt;Você também pode acompanhar o uso da aplicação para optimizar os anúncios que nela coloca. Isso é fácil de se fazer com o Google&lt;/p&gt;
&lt;h4&gt;Promoção Cruzada&lt;/h4&gt;
&lt;p&gt;Faça promoção cruzada da sua aplicação. Mostre anúncios dentro de uma das suas aplicações para outra aplicação que tenha criado. Também poderá ter, por exemplo, uma pequena aplicação grátis onde promove outras aplicações pagas criadas por si.&lt;/p&gt;
&lt;h4&gt;Patrocínio&lt;/h4&gt;
&lt;p&gt;Também poderá tentar encontrar um patrocinador para a sua aplicação. Por exemplo, se tiver uma aplicação relacionada com fitness, poderá encontrar uma empresa de venda de bebidas energéticas que poderá estar interessada em negociar um patrocínio. Obviamente este não será o meio de rentabilização mais fácil de se atingir, mas pode ser algo que encaixe no perfil da sua aplicação e portanto interessante de se ter em conta.&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; line-height: normal; background-color: rgba(255, 255, 255, 0.917969); "&gt;&lt;br /&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Instalação de anúncios com AdMob&lt;/h2&gt;
&lt;p&gt;É muito fácil instalar anúncios numa aplicação usando o &lt;a href="http://www.admob.com/"&gt;AdMob&lt;/a&gt; da Google. A Google fornece um conjunto claro e sucinto de instruções sobre &lt;a href="http://code.google.com/mobile/ads/docs/android/fundamentals.html"&gt;como configurar o AdMob&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;1. Criar uma conta AdMob ou usar a sua conta Google.&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/android101-11-1.png"&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/resize/content/android101-11-1-600x308.png" style="width: 600px; height: 308px; " width="600" height="308" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;2. Adicionar uma nova aplicação na sua conta AdMob.&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/android101-11-2.png"&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/resize/content/android101-11-2-600x325.png" style="width: 600px; height: 325px; " width="600" height="325" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ela vai aparecer em Sites &amp;amp; Apps.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/content/android101-11-3.png" style="width: 375px; height: 70px; " width="375" height="70" /&gt;&lt;/p&gt;
&lt;h4&gt;3. Ir a Manage Settings.&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/android101-11-4.png"&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/resize/content/android101-11-4-600x200.png" style="width: 600px; height: 200px; " width="600" height="200" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Aqui encontrará o Publisher ID que terá de usar mais tarde. Clique em "Get Publisher Code". Aqui é possível obter as bibliotecas de código necessárias para adicionar ao seu projecto.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/android101-11-5.png"&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/resize/content/android101-11-5-600x303.png" style="width: 600px; height: 303px; " width="600" height="303" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;4. Configurar o código.&lt;/h4&gt;
&lt;p&gt;Use as &lt;a href="http://code.google.com/mobile/ads/docs/android/fundamentals.html"&gt;instruções da Google&lt;/a&gt; para adicionar o código que descarregou ao seu projecto.&lt;/p&gt;
&lt;p&gt;Você também vai precisar do Publisher ID que mencionei no passo anterior.&lt;/p&gt;
&lt;h4&gt;5. Concluído.&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/android101-11-6.png"&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/resize/content/android101-11-6-600x355.png" style="width: 600px; height: 355px; " width="600" height="355" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Mais recursos&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.guidetotheappgalaxy.com/"&gt;The Guide to The App Galaxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.google.com/events/io/2011/sessions/dont-just-build-a-mobile-app-build-a-business.html"&gt;Don’t just build a mobile app. Build a business.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.androidguys.com/2009/09/14/40bizmodels/"&gt;40 Android Business Models, Part One&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-como-criar-um-widget-stackview"&gt;Como criar um widget StackView&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Y25DafZ1UuAL7-Gy_w9OEQyCvrk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y25DafZ1UuAL7-Gy_w9OEQyCvrk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Y25DafZ1UuAL7-Gy_w9OEQyCvrk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y25DafZ1UuAL7-Gy_w9OEQyCvrk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=QMB1irqlWSw:w2MmltyKJGQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=QMB1irqlWSw:w2MmltyKJGQ:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=QMB1irqlWSw:w2MmltyKJGQ:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=QMB1irqlWSw:w2MmltyKJGQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=QMB1irqlWSw:w2MmltyKJGQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=QMB1irqlWSw:w2MmltyKJGQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=QMB1irqlWSw:w2MmltyKJGQ:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=QMB1irqlWSw:w2MmltyKJGQ:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=QMB1irqlWSw:w2MmltyKJGQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=QMB1irqlWSw:w2MmltyKJGQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=QMB1irqlWSw:w2MmltyKJGQ:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/QMB1irqlWSw" height="1" width="1"/&gt;</description>
 <pubDate>Fri, 09 Dec 2011 09:35:50 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">132 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-como-monetizar-uma-aplica%C3%A7%C3%A3o-android</feedburner:origLink></item>
<item>
 <title>Android 101: Services, AsyncTasks e Notifications</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/zLc0U0PJzi0/android-101-services-asynctasks-e-notifications</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-usar-fragmentos-para-lidar-com-diferentes-orientações-de-ecrã"&gt;Usar fragmentos para lidar com diferentes orientações de ecrã&lt;/a&gt;&lt;/h3&gt;
&lt;h2&gt;AsyncTasks&lt;/h2&gt;
&lt;p&gt;As &lt;a href="http://developer.android.com/reference/android/os/AsyncTask.html"&gt;AsyncTask&lt;/a&gt; são semelhantes a threads, no entanto são mais simples de usar, porque não é necessário manipular threads ou handlers. A AsyncTask permite a execução de operações em segundo plano, sem bloquear a thread UI principal, no entanto pode manipular elementos do interface a partir da AsyncTask.&lt;/p&gt;
&lt;p&gt;Para implementar uma AsyncTask precisa criar uma subclasse desta e fazer override dos seus métodos, sendo o método de maior relevo o doInBackground(Params. ..). Como o nome deste método indica, ele irá executar um trecho de código em segundo plano.&lt;/p&gt;
&lt;p&gt;Na nossa aplicação necessitamos carregar o stream de Buzzes através da rede. A melhor maneira de o fazer é através de uma AsyncTask. Isto libertará a thread principal da aplicação, o que evita o bloqueio da interface do utilizador ou, num caso pior, o sistema lançar um aviso ao utilizador para matar a aplicação porque esta não se encontra a responder. Veja mais detalhes de &lt;a href="http://developer.android.com/guide/practices/design/responsiveness.html"&gt;como desenhar a sua aplicação para dar uma resposta mais imediata&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Um exemplo de como usar a AsyncTask retirado da nossa aplicação:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
class LoadBuzzes extends AsyncTask&amp;lt;Void, Void, ArrayList&amp;lt; Buzz&amp;gt;&amp;gt; {
	@Override
	protected void onPreExecute() {
		getHoneybuzzActivity().showProgress(); // show loading screen
	}

	@Override
	protected ArrayList&amp;lt;Buzz&amp;gt; doInBackground(Void... params) {
		try {
			// we’re caching the data so we’ll check if we need to update it from the server or just load from cache
			boolean refresh = Buzz.getUpdateChachedBuzzes(getActivity());
			Buzz.setUpdateChachedBuzzes(getActivity(), false);
			return Buzz.getBuzzes(getBuzz(), getActivity(), refresh);
		}
		catch (Exception e) {
			handleException(e);
			return null;
		}
	}

	@Override
	protected void onPostExecute(ArrayList&amp;lt; Buzz&amp;gt; feed) {
		getHoneybuzzActivity().hideProgress(); // hide loading screen
		if (feed != null) {
			try {
				// load buzzes list onto the UI
			}
			catch(Exception e) {
				Logging.e("Error loading buzzes", e);
			}
		}
	}
}&lt;/pre&gt;&lt;p&gt;Esta tarefa é lançada da seguinte forma:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
new LoadBuzzes().execute();&lt;/pre&gt;&lt;h2&gt;Services&lt;/h2&gt;
&lt;p&gt;Na &lt;a href="http://developer.android.com/reference/android/app/Service.html"&gt;documentação Android:&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Um Service é um componente que representa tanto a intenção de uma aplicação executar uma operação de longa duração enquanto não interage com o utilizador ou fornecer funcionalidades para outras aplicações usarem.&lt;/p&gt;
&lt;p&gt;Para verificar se existem actualizações no stream do Buzz usamos um Service que corre em segundo plano. Quando actualizações são encontradas, o Service mostra uma notificação. Estes são os trechos de código mais importantes na nossa classe de sincronização:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
private Timer mTimer = new Timer();
private NotificationManager mNM;

@Override
public void onCreate() {
	mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

	// the time interval between checks is saved in the app’s preferences
	SharedPreferences prefs = HoneybuzzApplication.getSharedPreferences();
	int intervalMinutes = Integer.parseInt(prefs.getString(HoneybuzzApplication.PREFERENCE_INTERVAL, String.valueOf(30)));
	int intervalMiliseconds = intervalMinutes * 60 * 1000;
	mTimer.schedule(mUpdateTask, intervalMiliseconds, intervalMiliseconds);
}

private TimerTask mUpdateTask = new TimerTask() {
	@Override
	public void run() {
		try {
			String lastUpdated = com.quasibit.honeybuzz.Buzz.getLastUpdated(getApplicationContext());
			String serverUpdate = com.quasibit.honeybuzz.Buzz.getServerUpdated(HoneybuzzApplication.buzz, getApplicationContext());

			// check if the last update to the server is the same as the last update available in cache
			if (!lastUpdated.equals(serverUpdate)) {
				Buzz.getBuzzes(HoneybuzzApplication.buzz, getApplicationContext(), true);

				// after the updates are loaded the user gets a notification
				showNotification();
			}
		}
		catch(Exception e) {
			Logging.e(e);
		}
	}
};&lt;/pre&gt;&lt;p&gt;Aqui encontram um bom artigo com a &lt;a href="http://techtej.blogspot.com/2011/03/android-thread-constructspart-4.html"&gt;comparação entre AsyncTask, Service, Thread, e IntentService&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Notificações&lt;/h2&gt;
&lt;p&gt;Uma &lt;a href="http://developer.android.com/guide/topics/ui/notifiers/notifications.html"&gt;notificação&lt;/a&gt; é uma mensagem que aparecerá na barra de status do sistema alertando o utilizador sobre algo que ele deve saber. A sua implementação é muito simples.&lt;/p&gt;
&lt;p&gt;No caso da nossa aplicação, notificamos o utilizador sempre que encontrarmos actualizações no seu stream do Buzz. Veja como lançamos a nossa notificação:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
private NotificationManager mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

private void showNotification() {
	String msg = getApplicationContext().getString(R.string.notif_buzzupdates);
	Notification notification = new Notification(R.drawable.ic_launcher_honeybuzz, msg, System.currentTimeMillis());
	PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, HoneybuzzListActivity.class), 0);
	notification.setLatestEventInfo(this, getApplicationContext().getString(R.string.app_name), msg, contentIntent);
	mNM.notify(NOTIFICATION, notification);
}&lt;/pre&gt;&lt;p&gt;Opcionalmente pode adicionar à sua notificação uma mensagem, um som de alerta, vibração e/ou piscar de LED.&lt;/p&gt;
&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-como-monetizar-uma-aplicação-android"&gt;Como monetizar uma aplicação Android&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Sh_bnzm5FADnbgqKklfEgQk3M_c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Sh_bnzm5FADnbgqKklfEgQk3M_c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Sh_bnzm5FADnbgqKklfEgQk3M_c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Sh_bnzm5FADnbgqKklfEgQk3M_c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=zLc0U0PJzi0:Epqpn377tvI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=zLc0U0PJzi0:Epqpn377tvI:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=zLc0U0PJzi0:Epqpn377tvI:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=zLc0U0PJzi0:Epqpn377tvI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=zLc0U0PJzi0:Epqpn377tvI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=zLc0U0PJzi0:Epqpn377tvI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=zLc0U0PJzi0:Epqpn377tvI:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=zLc0U0PJzi0:Epqpn377tvI:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=zLc0U0PJzi0:Epqpn377tvI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=zLc0U0PJzi0:Epqpn377tvI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=zLc0U0PJzi0:Epqpn377tvI:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/zLc0U0PJzi0" height="1" width="1"/&gt;</description>
 <pubDate>Wed, 07 Dec 2011 11:00:41 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">138 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-services-asynctasks-e-notifications</feedburner:origLink></item>
<item>
 <title>Android 101: Usar fragmentos para lidar com diferentes orientações de ecrã</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/4FzC1RpLjR0/android-101-usar-fragmentos-para-lidar-com-diferentes-orienta%C3%A7%C3%B5es-de-ecr%C3%A3</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-temas"&gt;Estilos e themes&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;O Honeycomb introduziu o conceito de fragmentos. Os fragmentos são a resposta para lidar com ecrãs de diferentes tamanho, desde telemóveis até tablets, televisões e outros gadgets. Um fragmento representa uma porção de um interface de utilizador. Uma Acitvity pode ter diversos fragmentos e o mesmo fragmento pode ser usado em mais que uma Activity.&lt;/p&gt;
&lt;p&gt;Vamos considerar o exemplo comum que demonstra a sua utilidade. Temos um painel esquerdo com uma listagem de itens e um painel direito que mostra os detalhes do item seleccionado. Este layout é usado na aplicação Honeybuzz. Um layout destes podem ser feito com dois fragmentos: um para a listagem dos itens e outro para os detalhes de um item. Dependendo da orientação do dispositivo, ou mostramos os fragmentos lado a lado ou, se o dispositivo estiver em modo portrait, mostramos apenas um dos fragmentos.&lt;/p&gt;
&lt;h2&gt;Um layout para uma listagem e detalhes, usando fragmentos&lt;/h2&gt;
&lt;p&gt;São necessárias diversas partes para construir um layout como o usado na aplicação Honeybuzz:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;ListActivity&lt;/strong&gt;: tem um layout diferente conforme a orientação do ecrã:
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;layout&lt;/strong&gt;: layout no modo paisagem. Contém &lt;strong&gt;ListFragment &lt;/strong&gt;e &lt;strong&gt;DetailsFragment&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;layout-port&lt;/strong&gt;: layout no modo portrait. Apenas contém &lt;strong&gt;ListFragment&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DetailsActivity&lt;/strong&gt;: apenas usada no modo portrait. Contém &lt;strong&gt;DetailsFragment&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ListFragment&lt;/strong&gt;: quando um item é seleccionado, dependendo da orientação do ecrã, vai actualizar o &lt;strong&gt;DetailsFragment &lt;/strong&gt;ou então lançar a &lt;strong&gt;DetailsActivity&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_landscape.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_landscape-200x125.png" style="width: 200px; height: 125px; " width="200" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_portrait_listing.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_portrait_listing-78x125.png" style="width: 78px; height: 125px; " width="78" height="125" /&gt;&lt;/a&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_portrait_details.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_portrait_details-78x125.png" style="width: 78px; height: 125px; " width="78" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;No fundo temos duas estratégias diferentes e vamos usá-las conforme a orientação do ecrã.&lt;/p&gt;
&lt;h2&gt;Criar a ListActivity e o ListFragment&lt;/h2&gt;
&lt;p&gt;A &lt;strong&gt;ListActivity&lt;/strong&gt; é bastante simples. É uma Activity normal, mas com um layout diferente dependendo da orientação do ecrã. Como expliquei anteriormente, o layout no modo paisagem contém tanto o &lt;strong&gt;ListFragment &lt;/strong&gt;como o &lt;strong&gt;DetailsFragment&lt;/strong&gt; e o layout no modo portrait contém apenas o &lt;strong&gt;ListFragment&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;O Android é bastante esperto no que toca a escolher o ficheiro de recurso apropriado para um layout. Se o dispositivo estiver no modo paisagem, o Android vai primeiro procurar na pasta &lt;strong&gt;layout-land&lt;/strong&gt; pelo ficheiro de recurso. Se não estiver disponível, só então irá tentar encontrá-lo na pasta &lt;strong&gt;layout&lt;/strong&gt;. De igual forma para o modo portrait, mas procurando antes na pasta &lt;strong&gt;layout-port&lt;/strong&gt;. Basicamente criam-se dois ficheiros de layout separados com o mesmo nome, colocando-os nas pastas apropriadas e o Android vai carregá-los apropriadamente de acordo com a orientação do ecrã.&lt;/p&gt;
&lt;p&gt;O ficheiro de layout no modo paisagem é o seguinte:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"&amp;gt;
    &amp;lt;fragment class="com.quasibit.honeybuzz.HoneybuzzListFragment"
            android:id="@+id/listFragment"
            android:layout_weight="1"
            android:layout_width="@dimen/list_item_size"
            android:layout_height="fill_parent" /&amp;gt;
    &amp;lt;fragment class="com.quasibit.honeybuzz.HoneybuzzDetailsFragment"
            android:id="@+id/details"
            android:layout_weight="2"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:background="?android:attr/detailsElementBackground" /&amp;gt;
&amp;lt;/LinearLayout&amp;gt;&lt;/pre&gt;&lt;p&gt;E no modo portrait:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"&amp;gt;
    &amp;lt;fragment class="com.quasibit.honeybuzz.HoneybuzzListFragment"
            android:id="@+id/listFragment"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent" /&amp;gt;
&amp;lt;/LinearLayout&amp;gt;&lt;/pre&gt;&lt;p&gt;Quanto ao &lt;strong&gt;ListFragment&lt;/strong&gt;, este será o fragmento que irá mostrar a listagem dos itens. Pode-se usar um ficheiro de layout normal. O nosso layout só tem um &lt;strong&gt;LinearLayout&lt;/strong&gt;, uma &lt;strong&gt;ListView&lt;/strong&gt; e um &lt;strong&gt;TextView&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listLayout"
      android:orientation="vertical" 
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"&amp;gt;
    &amp;lt;ListView
        android:id="@+id/listBuzzes" 
        android:drawSelectorOnTop="false" 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" /&amp;gt;
    &amp;lt;TextView android:id="@android:id/empty"
               android:layout_height="fill_parent"
               android:text="@string/no_activities"
               android:layout_width="wrap_content"
               android:layout_gravity="left"
               android:layout_marginLeft="10dp"
               android:layout_marginTop="10dp" /&amp;gt;
&amp;lt;/LinearLayout&amp;gt;&lt;/pre&gt;&lt;p&gt;A parte importante é a classe do fragmento. Fica aqui um excerto com as partes mais importantes:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
public class HoneybuzzListFragment extends HoneybuzzFragment implements OnItemClickListener {
    protected String mCurrentId;
    protected ListView mListView;
    protected ArrayList&amp;lt;com.quasibit.honeybuzz.Buzz&amp;gt; mBuzzes;
    protected Boolean mDualPane;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.list_fragment, container, false);
        
        return view;
    }
        
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        
        // set list view properties
        this.mListView = (ListView) getActivity().findViewById(R.id.listBuzzes);
        
        if (this.mListView != null) {
            this.mListView.setOnItemClickListener(this);
            this.mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        }

        // check if we are in dual pane mode
        HoneybuzzDetailsFragment details = (HoneybuzzDetailsFragment) getFragmentManager().findFragmentById(R.id.details);
        mDualPane = !(details == null || !details.isInLayout());
        
        // get current id from saved state or extras
        if (savedInstanceState != null) {
            // Restore last state for checked position.
            mCurrentId = savedInstanceState.getString(HoneybuzzListActivity.EXTRA_ID);
        }
        
        if (this.getActivity().getIntent() != null) {
            String id = this.getActivity().getIntent().getStringExtra(HoneybuzzListActivity.EXTRA_ID);
            
            if (id != null &amp;amp;&amp;amp; !id.isEmpty()) {
                mCurrentId = id;
            }
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(HoneybuzzListActivity.EXTRA_ID, mCurrentId);
    }

    @Override
    public void onItemClick(AdapterView&amp;lt;?&amp;gt; l, View v, int position, long id) {
        if (position &amp;lt; mBuzzes.size()) {
            // get matching buzz id from position
            String buzzId = mBuzzes.get(position).id;
            showDetails(buzzId);
        }
    }

    public void showDetails(String id) {
        if (id != null &amp;amp;&amp;amp; !id.isEmpty() &amp;amp;&amp;amp; mBuzzes != null &amp;amp;&amp;amp; !mBuzzes.isEmpty()) {
 // find buzz object
            com.quasibit.honeybuzz.Buzz buzz = getBuzz(id);
            
            if (buzz != null) {
                mCurrentId = id;
                
                // highlight selected item
                int index = mBuzzes.indexOf(buzz);
                
                if (index &amp;gt;= 0) {
                    mListView.setItemChecked(index, true);
                }
        
                // load item
                if (mDualPane) {
                    HoneybuzzDetailsFragment details = (HoneybuzzDetailsFragment) getFragmentManager().findFragmentById(R.id.details);
                    details.load(buzz);
                } else {
                    // launch new activity because we're in single mode pane
                    Intent showContent = new Intent(getActivity(), HoneybuzzDetailsActivity.class);
                    showContent.putExtra(HoneybuzzDetailsActivity.EXTRA_BUZZ, buzz);
                    startActivity(showContent);
                }
            }
        }
    }
}&lt;/pre&gt;&lt;p&gt;Algumas notas:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;A classe descende de &lt;strong&gt;HoneybuzzFragment&lt;/strong&gt;, que é um fragmento com código Google Analytics e com outros métodos úteis.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;onCreateView&lt;/strong&gt;: usado para especificar o ficheiro de layout.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;onActivityCreated&lt;/strong&gt;: determina se o ecrã está em modo duplo e regista isso na variável &lt;strong&gt;mDualPane&lt;/strong&gt;. Tentamos ler o ID actual tanto da instância gravada (quando a Activity está a ser recuperada) como da informação dos extras (quando outra parte da aplicação pede para ver os detalhes de um ID particular).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;onSaveInstanceState&lt;/strong&gt;: o ID actual é gravado antes da Activity ir para estado de background. Este ID é recuperado quando a Activity é recriada.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;showDetails&lt;/strong&gt;: carrega o objecto Buzz com a ID dada. O importante é o modo como os detalhes são mostrados. Se estivermos em modo duplo, vamos buscar o &lt;strong&gt;HoneybuzzDetailsFragment&lt;/strong&gt; e passamos o objecto Buzz. De outra forma, lançamos a &lt;strong&gt;HoneybuzzDetailsActivity&lt;/strong&gt; e passamos o objecto Buzz.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Construir o DetailsFragment e a DetailsActivity&lt;/h2&gt;
&lt;p&gt;A &lt;strong&gt;DetailsActivity &lt;/strong&gt;só é usada em modo portrait. Neste modo precisamos de uma &lt;strong&gt;ListActivity&lt;/strong&gt; e de uma &lt;strong&gt;DetailsActivity&lt;/strong&gt;, porque temos dois ecrãs diferentes e só um é mostrado de cada vez.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;DetailsActivity&lt;/strong&gt; é bastante simples, apenas reusamos o &lt;strong&gt;DetailsFragment &lt;/strong&gt;(que também é usado na &lt;strong&gt;ListActivity&lt;/strong&gt;):&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
public class HoneybuzzDetailsActivity extends HoneybuzzActivity {
    public static final String EXTRA_BUZZ = "com.quasibit.honeybuzz.HoneybuzzListActivity.EXTRA_BUZZ";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // If the screen is now in landscape mode, we can show the
            // dialog in-line with the list so we don't need this activity.
            finish();
            return;
        }

        if (savedInstanceState == null) {
            // During initial setup, plug in the details fragment.
            HoneybuzzDetailsFragment details = new HoneybuzzDetailsFragment();
            details.setArguments(getIntent().getExtras());
            getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
        }
    }
}&lt;/pre&gt;&lt;p&gt;O &lt;strong&gt;DetailsFragment &lt;/strong&gt;tem um método &lt;strong&gt;load &lt;/strong&gt;que preenche o layout com a informação do objecto Buzz.&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
public class HoneybuzzDetailsFragment extends HoneybuzzFragment implements OnClickListener {
    protected com.quasibit.honeybuzz.Buzz mBuzz;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.details, container, false);
        
        return view;
    }
        
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        
        if (savedInstanceState != null) {
            // Restore last state for checked position.
            mBuzz = (Buzz) savedInstanceState.getSerializable(HoneybuzzDetailsActivity.EXTRA_BUZZ);
        }
        
        if (this.getActivity().getIntent() != null) {
            com.quasibit.honeybuzz.Buzz buzz = (Buzz) this.getActivity().getIntent().getSerializableExtra(HoneybuzzDetailsActivity.EXTRA_BUZZ);
            
            if (buzz != null) {
                mBuzz = buzz;
            }
        }
        
        if (mBuzz != null) {
            load(mBuzz);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putSerializable(HoneybuzzDetailsActivity.EXTRA_BUZZ, mBuzz);
    }
    
    public void load(com.quasibit.honeybuzz.Buzz buzz) {
        mBuzz = buzz;
        
        if (buzz != null) {
            // load views with Buzz object data
        }
    }
}&lt;/pre&gt;&lt;p&gt;Em &lt;strong&gt;onActivityCreated &lt;/strong&gt;tentamos encontrar o objecto Buzz a mostrar, tanto um gravado antes da Activity ir para o background, como um passado nos extras (chamado a partir de outra parte da aplicação).&lt;/p&gt;
&lt;h2&gt;More resources&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://developer.android.com/guide/topics/fundamentals/fragments.html"&gt;Fragments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://android-developers.blogspot.com/2011/02/android-30-fragments-api.html"&gt;The Android 3.0 Fragments API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-services-asynctasks-e-notifications"&gt;Services, AsyncTasks e Notifications&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/t6EO-bhsTl6MaVk_RYLGe6lphGA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t6EO-bhsTl6MaVk_RYLGe6lphGA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/t6EO-bhsTl6MaVk_RYLGe6lphGA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t6EO-bhsTl6MaVk_RYLGe6lphGA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=4FzC1RpLjR0:Lx7I8WSeuyQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=4FzC1RpLjR0:Lx7I8WSeuyQ:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=4FzC1RpLjR0:Lx7I8WSeuyQ:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=4FzC1RpLjR0:Lx7I8WSeuyQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=4FzC1RpLjR0:Lx7I8WSeuyQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=4FzC1RpLjR0:Lx7I8WSeuyQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=4FzC1RpLjR0:Lx7I8WSeuyQ:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=4FzC1RpLjR0:Lx7I8WSeuyQ:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=4FzC1RpLjR0:Lx7I8WSeuyQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=4FzC1RpLjR0:Lx7I8WSeuyQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=4FzC1RpLjR0:Lx7I8WSeuyQ:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/4FzC1RpLjR0" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 05 Dec 2011 08:50:37 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">128 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-usar-fragmentos-para-lidar-com-diferentes-orienta%C3%A7%C3%B5es-de-ecr%C3%A3</feedburner:origLink></item>
<item>
 <title>Android 101: Estilos e Temas</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/Xx1OlHknO8c/android-101-estilos-e-temas</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-como-criar-um-menu-de-opções-e-adicioná-lo-à-action-bar"&gt;Como criar um menu de opções e adicioná-lo à Action Bar&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;O que são estilos e themes em Android? Na documentação para programadores ficamos a saber que:&lt;/p&gt;
&lt;p&gt;"Um estilo é um conjunto de propriedades que especificam a aparência e formato de uma View ou janela. Um estilo pode especificar propriedades, tais como altura, cor da fonte, preenchimento, tamanho da fonte, cor de fundo e muito mais. Um estilo é definido num recurso XML que é independente do XML que especifica o layout.”&lt;/p&gt;
&lt;p&gt;"Um theme é um estilo aplicado a uma Activity ou aplicação inteira, ao invés de uma View individual. Quando um estilo é aplicado como um theme, todas as Views na Activity ou aplicação irão usar todas as propriedades de estilo por ele definidas.”&lt;/p&gt;
&lt;p&gt;Resumindo, um estilo é um conjunto de propriedades que definem a aparência de uma View ou janela. Um theme é um tipo específico de estilo que tem alcance sobre a Activity ou toda a aplicação.&lt;/p&gt;
&lt;h2&gt;Declarar e aplicar um estilo&lt;/h2&gt;
&lt;p&gt;Vamos ver como declarar um estilo. Adicionar ao ficheiro res/values/styles.xml (se ainda não existir, crie-o).&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;resources&amp;gt;
	&amp;lt;style name="AppTheme.Button" parent="@android:style/Widget.Button"&amp;gt;
		&amp;lt;item name="android:textSize"&amp;gt;12sp&amp;lt;/item&amp;gt;
		&amp;lt;item name="android:paddingLeft"&amp;gt;10dp&amp;lt;/item&amp;gt;
		&amp;lt;item name="android:paddingRight"&amp;gt;10dp&amp;lt;/item&amp;gt;
	&amp;lt;/style&amp;gt;
&amp;lt;/resources&amp;gt;&lt;/pre&gt;&lt;p&gt;Este estilo tem como atributo pai o widget Button, o que significa que este estilo herdará todas as definições de estilo que um botão padrão tem. Ou seja, se não declaramos nenhuma regra no nosso estilo, os botões que usarem este estilo serão exactamente iguais aos botões padrão, mas neste caso substituímos as propriedades de tamanho do texto e do padding.&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;Button
	style="@style/AppTheme.Button"
	android:text="@string/buttontext" /&amp;gt;&lt;/pre&gt;&lt;p&gt;O que fizemos aqui for criar um botão especifico na nossa aplicação com um estilo personalizado. Algo mais interessante do que isto seria alterar todos os botões na nossa aplicação da mesma forma. Para isso não é necessário alterar todas as definições de todos os botões, basta usar um theme.&lt;/p&gt;
&lt;h2&gt;Declarar e aplicar um theme&lt;/h2&gt;
&lt;p&gt;Eis como declarar um theme:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;style name="AppTheme.Light" parent="@android:style/Theme.Holo.Light"&amp;gt;
	&amp;lt;item name="android:textSize"&amp;gt;14sp&amp;lt;/item&amp;gt;
	&amp;lt;item name="android:buttonStyle"&amp;gt;@style/AppTheme.Button&amp;lt;/item&amp;gt;
	&amp;lt;item name="android:editTextStyle"&amp;gt;@style/AppTheme.EditText&amp;lt;/item&amp;gt;
	&amp;lt;item name="listItemStyle"&amp;gt;@style/AppTheme.ListItemStyle&amp;lt;/item&amp;gt;
&amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;p&gt;Praticamente o mesmo que a declaração de um estilo, mas note a diferença no atributo parent do estilo. O parent é um theme out-of-the-box do Android. Algo que pode notar na segunda propriedade do theme é que estamos a associar a todos os botões da aplicação um estilo (android:buttonStyle). Como pode ver, fazemos referência ao estilo criado anteriormente.&lt;/p&gt;
&lt;p&gt;Agora este theme pode ser aplicado a uma Activity ou a toda a aplicação. Necessita editar o ficheiro AndroidManifest.xml.&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;application android:theme="@style/AppTheme.Light"&amp;gt;
&amp;lt;activity android:theme="@style/AppTheme.Light "&amp;gt;&lt;/pre&gt;&lt;p&gt;Use um ou outro, dependendo do alcance necessário.&lt;/p&gt;
&lt;h2&gt;Herança em estilos&lt;/h2&gt;
&lt;p&gt;Na nossa aplicação criamos dois temas, um com tons claros (Light) e um mais escuro (Dark).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/android101-8-light.png"&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/resize/content/android101-8-light-600x375.png" style="width: 600px; height: 375px; " width="600" height="375" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(Light)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/android101-8-dark.png"&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/resize/content/android101-8-dark-600x375.png" style="border-style: initial; border-color: initial; width: 600px; height: 375px; " width="600" height="375" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(Dark)&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; line-height: normal; background-color: rgba(255, 255, 255, 0.917969); "&gt;&lt;br /&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Portanto tivemos que criar duas definições de themes.&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;style name="AppTheme.Light" parent="@android:style/Theme.Holo.Light"&amp;gt;
	&amp;lt;item name="android:textSize"&amp;gt;14sp&amp;lt;/item&amp;gt;
	&amp;lt;item name="android:buttonStyle"&amp;gt;@style/AppTheme.Button&amp;lt;/item&amp;gt;
	&amp;lt;item name="android:editTextStyle"&amp;gt;@style/AppTheme.EditText&amp;lt;/item&amp;gt;
	&amp;lt;item name="listItemStyle"&amp;gt;@style/AppTheme.ListItemStyle&amp;lt;/item&amp;gt;
&amp;lt;/style&amp;gt;

&amp;lt;style name="AppTheme.Dark" parent="@android:style/Theme.Holo"&amp;gt;
	&amp;lt;item name="android:textSize"&amp;gt;14sp&amp;lt;/item&amp;gt;
	&amp;lt;item name="android:buttonStyle"&amp;gt;@style/AppTheme.Button&amp;lt;/item&amp;gt;
	&amp;lt;item name="android:editTextStyle"&amp;gt;@style/AppTheme.EditText&amp;lt;/item&amp;gt;
	&amp;lt;item name="listItemStyle"&amp;gt;@style/AppTheme.ListItemStyle.Dark&amp;lt;/item&amp;gt;
&amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;p&gt;Além do atributo parent há outra forma de declarar herança através da nomenclatura dos estilos. Por exemplo, para a declaração dos widgets no tema Dark, podemos herdar todas as definições a partir da definição do tema Light e só substituir o que precisamos:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;style name="AppTheme.ListItemStyle.Dark"&amp;gt;
	&amp;lt;item name="android:background"&amp;gt;@color/list_item_dark&amp;lt;/item&amp;gt;
&amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;p&gt;AppTheme.ListItemStyle.Dark é interpretado como uma herança do estilo já definido AppTheme.ListItemStyle. Esta é uma forma mais estruturada e legível de declarar relações de parentesco, especialmente se tivermos vários temas ou estilos para widgets.&lt;/p&gt;
&lt;p&gt;Veja todos os &lt;a href="http://developer.android.com/reference/android/R.style.html"&gt;widgets disponíveis para substituição aqui.&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Criar um estilo personalizado para uma vista&lt;/h2&gt;
&lt;p&gt;Uma das propriedades na definição do theme que mostrei é listItemStyle.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class="brush:xml;" style="border-style: initial; border-color: initial; "&gt;
&amp;lt;style name="AppTheme.Light" parent="@android:style/Theme.Holo.Light"&amp;gt;
	&amp;lt;item name="android:textSize"&amp;gt;14sp&amp;lt;/item&amp;gt;
	&amp;lt;item name="listItemStyle"&amp;gt;@style/AppTheme.ListItemStyle&amp;lt;/item&amp;gt;
&amp;lt;/style&amp;gt;

&amp;lt;style name="AppTheme.ListItemStyle"&amp;gt;
	&amp;lt;item name="android:background"&amp;gt;@color/list_item&amp;lt;/item&amp;gt;
&amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;p&gt;Tive a necessidade de criar este valor personalizado porque queria criar um estilo para um LinearLayout, que seria diferente dependendo do theme activo. Essa opção não existe no namespace android (como o android:textSize, por exemplo).&lt;/p&gt;
&lt;p&gt;Esta é a minha definição da vista:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/feedListItem"
	android:layout_height="wrap_content"
	android:layout_width="fill_parent"
	style="?listItemStyle"&amp;gt;
	&amp;lt;ImageView android:id="@+id/picture"
		android:layout_height="100dip"
		android:layout_width="100dip"/&amp;gt;
	&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		android:id="@+id/user"
		android:orientation="vertical"
		android:layout_height="wrap_content"
		android:layout_width="fill_parent"
		android:padding="10dp"&amp;gt;
		&amp;lt;TextView android:id="@+id/textUsername"
			android:textAppearance="?android:attr/textAppearanceSmall"
			android:layout_height="wrap_content"
			android:layout_width="fill_parent"
			android:layout_gravity="center_horizontal"
			android:textStyle="bold"/&amp;gt;
		&amp;lt;TextView android:id="@+id/textContent"
			android:layout_height="fill_parent"
			android:layout_width="fill_parent"
			android:paddingTop="6dp"
			android:maxLines="3"/&amp;gt;
	&amp;lt;/LinearLayout&amp;gt;
&amp;lt;/LinearLayout&amp;gt;&lt;/pre&gt;&lt;p&gt;Repare no atributo style no LinearLayout raiz.&lt;/p&gt;
&lt;p&gt;A última coisa que precisamos fazer para que isso funcione é declarar o novo atributo. Caso contrário, terá um erro que diz que o atributo não existe:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/content/android101-8-error.png" style="width: 470px; height: 25px; " width="470" height="25" /&gt;&lt;/p&gt;
&lt;p&gt;No ficheiro res/values/attrs.xml crie uma nova declaração:&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;

&lt;/pre&gt;&lt;p&gt;&amp;lt;resources&amp;gt; &amp;lt;attr name="listItemStyle" format="reference" /&amp;gt; &amp;lt;/resources&amp;gt;&lt;/p&gt;
&lt;h2&gt;Mudar o estilo ou theme em tempo de execução&lt;/h2&gt;
&lt;p&gt;Como tínhamos dois themes diferentes queríamos permitir que o utilizador alterasse o theme activo através das preferências.&lt;/p&gt;
&lt;p&gt;Guardamos a preferência selecionada nas &lt;a href="http://developer.android.com/guide/topics/data/data-storage.html#pref"&gt;SharedPreferences&lt;/a&gt; da aplicação e carregamo-la no método onCreate da Activity.&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	SharedPreferences prefs = HoneybuzzApplication.getSharedPreferences();
	String themeName = prefs.getString(HoneybuzzApplication.PREFERENCE_THEME, "AppTheme.Light");
	int themeId = getResources().getIdentifier(themeName, "style", getPackageName());
	setTheme(themeId);
}&lt;/pre&gt;&lt;p&gt;Terá que fazer isto para todas as Activities na sua aplicação ou, como nos fizemos, criar uma classe Activity que trata de todas as personalizações e da qual todas as Activities vão herdar.&lt;/p&gt;
&lt;p&gt;Também é necessário recarregar o theme de cada vez que o utilizador alterar as preferências da aplicação. Fazêmo-lo na nossa Activity da qual as outras vão herdar.&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
// handle updates to preferences
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
	if (key.equals(HoneybuzzApplication.PREFERENCE_THEME)) {
		// recreate activity so theme gets updated
		this.recreate();
	}
}&lt;/pre&gt;&lt;h2&gt;Mais recursos&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://developer.android.com/guide/topics/ui/themes.html"&gt;Styles and Themes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://brainflush.wordpress.com/2009/03/15/understanding-android-themes-and-styles/"&gt;Understanding Android Themes And Styles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-usar-fragmentos-para-lidar-com-diferentes-orienta%C3%A7%C3%B5es-de-ecr%C3%A3"&gt;Usar fragmentos para lidar com diferentes orientações de ecrã&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tWaQ-qrD8-AgFIFX3oZBuwaFNRM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tWaQ-qrD8-AgFIFX3oZBuwaFNRM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tWaQ-qrD8-AgFIFX3oZBuwaFNRM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tWaQ-qrD8-AgFIFX3oZBuwaFNRM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=Xx1OlHknO8c:37jrKjlRaSk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=Xx1OlHknO8c:37jrKjlRaSk:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=Xx1OlHknO8c:37jrKjlRaSk:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=Xx1OlHknO8c:37jrKjlRaSk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=Xx1OlHknO8c:37jrKjlRaSk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=Xx1OlHknO8c:37jrKjlRaSk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=Xx1OlHknO8c:37jrKjlRaSk:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=Xx1OlHknO8c:37jrKjlRaSk:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=Xx1OlHknO8c:37jrKjlRaSk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=Xx1OlHknO8c:37jrKjlRaSk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=Xx1OlHknO8c:37jrKjlRaSk:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/Xx1OlHknO8c" height="1" width="1"/&gt;</description>
 <pubDate>Wed, 30 Nov 2011 09:15:55 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">119 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-estilos-e-temas</feedburner:origLink></item>
<item>
 <title>Android 101: Como criar um menu de opções e adicioná-lo à Action Bar</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/B9gjn_cS7Mo/android-101-como-criar-um-menu-de-op%C3%A7%C3%B5es-e-adicion%C3%A1-lo-%C3%A0-action-bar</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-guardar-e-ler-prefer%C3%AAncias-do-utilizador"&gt;Guardar e ler as preferências do utilizador&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Um menu é útil para disponibilizar acesso a diferentes partes de uma aplicação. É fácil adicionar um menu a uma aplicação Android.&lt;/p&gt;
&lt;h2&gt;Criar um ficheiro de recurso para o menu&lt;/h2&gt;
&lt;p&gt;O primeiro passo é criar uma pasta &lt;strong&gt;menu&lt;/strong&gt; na pasta &lt;strong&gt;res&lt;/strong&gt; da aplicação.&lt;/p&gt;
&lt;p&gt;Depois é necessário adicionar um ficheiro XML.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/new_menu.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/new_menu-200x217.png" style="width: 200px; height: 217px; " width="200" height="217" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Definem-se as opções individuais usando o elemento &lt;strong&gt;item&lt;/strong&gt;. Especificam-se os atributos &lt;strong&gt;id&lt;/strong&gt;, &lt;strong&gt;icon&lt;/strong&gt; e &lt;strong&gt;title&lt;/strong&gt; para cada opção. Eis o ficheiro do menu da aplicação Honeybuzz:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;menu
  xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;
    &amp;lt;item android:id="@+id/menuRefresh"
          android:icon="@android:drawable/ic_popup_sync"
          android:title="@string/menu_refresh"
          android:alphabeticShortcut="r"
          android:showAsAction="always" /&amp;gt;
    &amp;lt;item android:id="@+id/menuProgress"
          android:actionLayout="@layout/progress"
          android:showAsAction="always" /&amp;gt;
    &amp;lt;item android:id="@+id/menuNewBuzz"
          android:icon="@android:drawable/ic_input_add"
          android:title="@string/menu_new_buzz"
          android:alphabeticShortcut="n"
          android:showAsAction="ifRoom|withText" /&amp;gt;
    &amp;lt;item android:id="@+id/menuAccounts"
          android:icon="@android:drawable/ic_lock_lock"
          android:title="@string/menu_accounts"
          android:alphabeticShortcut="a"
          android:showAsAction="withText" /&amp;gt;
    &amp;lt;item android:id="@+id/menuPreferences"
          android:icon="@android:drawable/ic_menu_preferences"
          android:title="@string/menu_preferences"
          android:alphabeticShortcut="s"
          android:showAsAction="withText" /&amp;gt;
    &amp;lt;item android:id="@+id/menuAbout"
          android:icon="@android:drawable/ic_menu_info_details"
          android:title="@string/menu_about"
          android:alphabeticShortcut="b"
          android:showAsAction="withText" /&amp;gt;
&amp;lt;/menu&amp;gt;&lt;/pre&gt;&lt;p&gt;O atributo &lt;strong&gt;showAsAction&lt;/strong&gt; permite especificar quando e como é que cada opção aparece-se na &lt;strong&gt;ActionBar&lt;/strong&gt; (a &lt;strong&gt;ActionBar&lt;/strong&gt; é a barra com o título que aparece no topo de uma aplicação Android a partir da versão Honeycomb). Os valores disponíveis são: &lt;strong&gt;ifRoom&lt;/strong&gt;, &lt;strong&gt;withText&lt;/strong&gt;, &lt;strong&gt;never&lt;/strong&gt; e &lt;strong&gt;always&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_options_menu.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_options_menu-200x125.png" style="width: 200px; height: 125px; " width="200" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Construir o menu e gerir as opções&lt;/h2&gt;
&lt;p&gt;Depois é preciso actualizar a &lt;strong&gt;Activity&lt;/strong&gt; onde o menu vai aparecer. É preciso criar o método &lt;strong&gt;onCreateOptionsMenu &lt;/strong&gt;para construir o menu e também o método &lt;strong&gt;onOptionsItemSelected &lt;/strong&gt;para gerir as opções. Foi assim que o menu da aplicação Honeybuzz foi construído:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
	this.menuHandler = menu;

	MenuInflater inflater = getMenuInflater();
	inflater.inflate(R.menu.menu, menu);
	hideProgress();

	return super.onCreateOptionsMenu(menu);
}

public void showProgress() {
	this.menuHandler.findItem(R.id.menuRefresh).setVisible(false);
	this.menuHandler.findItem(R.id.menuProgress).setVisible(true);
}

public void hideProgress() {
	this.menuHandler.findItem(R.id.menuProgress).setVisible(false);
	this.menuHandler.findItem(R.id.menuRefresh).setVisible(true);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
	switch (item.getItemId()) {
		case android.R.id.home:
			// go home
			Intent intent = new Intent(this, HoneybuzzListActivity.class);
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
			return true;
		case R.id.menuNewBuzz:
			startActivity(new Intent(this, HoneybuzzAddActivity.class));
			return true;
		case R.id.menuAccounts:
			showDialog(DIALOG_ACCOUNTS);
			return true;
		case R.id.menuPreferences:
			startActivity(new Intent(this, HoneybuzzPreferences.class));
			return true;
		case R.id.menuRefresh:
			// refresh buzzes (handled on child Activity)
			return true;
			case R.id.menuAbout:
			loadAboutDialog(getString(R.string.about_title));
			return true;
	}

	return super.onOptionsItemSelected(item);
}&lt;/pre&gt;&lt;p&gt;A Action Bar aparece por padrão no Honeycomb. Fica no topo do ecrã e inclui o ícone da aplicação. O menu vai ser adicionado à Action Bar e, dependendo dos atributos de cada opção, algumas opções irão aparecer como botões só com um ícone, enquanto as restantes estarão disponíveis como texto numa dropdown.&lt;/p&gt;
&lt;p&gt;Normalmente quando se selecciona uma opção inicia-se uma &lt;strong&gt;Activity&lt;/strong&gt;. Como a maioria das &lt;strong&gt;Activities&lt;/strong&gt; é descendente da &lt;strong&gt;Activity &lt;/strong&gt;principal, estas vão partilhar o mesmo menu. Os métodos &lt;strong&gt;showProgress&lt;/strong&gt;/&lt;strong&gt;hideProgress&lt;/strong&gt; são usados quando a aplicação está ocupada a processar informação. Existe um botão de refresh que pode ser activado para carregar os dados de novo e, quando a aplicação está a processar os dados, o botão vai ser substituído por um indicador de progresso.&lt;/p&gt;
&lt;p&gt;Para gerir o botão home (o botão com o ícone da aplicação que fica no canto superior esquerdo) basta comparar o ID com &lt;strong&gt;android.R.id.home&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;h2&gt;Como gerar ícones para as opções da Action Bar&lt;/h2&gt;
&lt;p&gt;Em geral cada opção é acompanhada de um ícone. É necessário fazerem-se diferentes imagens para tamanhos diferentes de ecrãs. O &lt;a href="http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html"&gt;Android Asset Studio&lt;/a&gt; é uma ferramenta útil que gera as diferentes imagens. Basta fornecer uma imagem ou escolher uma da galeria e permite também adicionar um texto personalizado. Existem outras opções de configuração (padding, trim, theme) e no final faz-se o download de um arquivo zip com todas as imagens.&lt;/p&gt;
&lt;p&gt;O &lt;a href="http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html"&gt;Android Asset Studio&lt;/a&gt; também é útil para gerar ícones para outras partes da aplicação (launcher, Action Bar, etc.) e faz parte do &lt;a href="http://code.google.com/p/android-ui-utils/"&gt;android-ui-utils&lt;/a&gt;, que também fornece templates Photoshop para os ícones respeitando as directrizes do Android.&lt;/p&gt;
&lt;p&gt;Além de poder criar os seus próprios ícones, também pode usar os ícones que vêm com o Android. O Android vem com um conjunto de drawables que podem ser usados em várias situações diferentes. Por exemplo, para o Froyo (Android 2.2) podem ver no &lt;a href="http://androiddrawableexplorer.appspot.com/"&gt;Android Drawables explorer&lt;/a&gt; o que está disponível. Acedem-se a estes recursos desta forma: &lt;strong&gt;android.R.drawable.ic_menu_save&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Para ver que drawables estão disponíveis no Honeycomb (ou noutra versão qualquer), recomendo que adicionem uma &lt;strong&gt;ImageView&lt;/strong&gt; a um ficheiro de layout, usando a vista "Graphical Layout". Depois se escolherem "System Resources" vão ver todas as opções disponíveis assim como uma imagem de amostra.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/system_drawables.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/system_drawables-200x182.png" style="width: 200px; height: 182px; " width="200" height="182" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Mais recursos&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://developer.android.com/guide/topics/ui/menus.html"&gt;Creating Menus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.android.com/guide/topics/ui/actionbar.html"&gt;Using the Action Bar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-estilos-e-temas"&gt;Estilos e themes&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EUtqfbNG6SyffhcbrI_Ajfbz8R8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EUtqfbNG6SyffhcbrI_Ajfbz8R8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EUtqfbNG6SyffhcbrI_Ajfbz8R8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EUtqfbNG6SyffhcbrI_Ajfbz8R8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=B9gjn_cS7Mo:K900jtZhxP8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=B9gjn_cS7Mo:K900jtZhxP8:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=B9gjn_cS7Mo:K900jtZhxP8:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=B9gjn_cS7Mo:K900jtZhxP8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=B9gjn_cS7Mo:K900jtZhxP8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=B9gjn_cS7Mo:K900jtZhxP8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=B9gjn_cS7Mo:K900jtZhxP8:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=B9gjn_cS7Mo:K900jtZhxP8:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=B9gjn_cS7Mo:K900jtZhxP8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=B9gjn_cS7Mo:K900jtZhxP8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=B9gjn_cS7Mo:K900jtZhxP8:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/B9gjn_cS7Mo" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 28 Nov 2011 07:55:43 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">126 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-como-criar-um-menu-de-op%C3%A7%C3%B5es-e-adicion%C3%A1-lo-%C3%A0-action-bar</feedburner:origLink></item>
<item>
 <title>Android 101: Guardar e ler as preferências do utilizador</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/tsZpv4lsDyg/android-101-guardar-e-ler-prefer%C3%AAncias-do-utilizador</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-usar-google-analytics-numa-aplica%C3%A7%C3%A3o-android"&gt;Usar Google Analytics numa aplicação Android&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Permitir aos utilizadores configurar a aplicação ao seu gosto é uma das funcionalidades básicas de uma aplicação. Neste artigo vou descrever como construir um ecrã de preferências para uma aplicação Android e como guardar e ler as preferências do utilizador.&lt;/p&gt;
&lt;h2&gt;Como criar um ecrã de preferências no Android&lt;/h2&gt;
&lt;p&gt;Um ecrã de preferências cria-se da seguinte forma:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Criar uma pasta &lt;strong&gt;xml&lt;/strong&gt; na pasta &lt;strong&gt;res&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Criar um ficheiro &lt;strong&gt;preferences.xml&lt;/strong&gt; (especificar que é um recurso do tipo &lt;strong&gt;Preference&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_preferences_xml_create.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_preferences_xml_create-200x216.png" style="width: 200px; height: 216px; " width="200" height="216" /&gt;&lt;/a&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_preferences_xml_create2.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_preferences_xml_create2-200x195.png" style="width: 200px; height: 195px; " width="200" height="195" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;O elemento raiz das preferências deve ser um &lt;strong&gt;PreferenceScreen&lt;/strong&gt;. Agora é necessário adicionar as diferentes opções.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Usa-se uma &lt;strong&gt;PreferenceCategory&lt;/strong&gt; para separar as opções em determinados grupos.&lt;/li&gt;
&lt;li&gt;Existem diferentes widgets de preferências como &lt;strong&gt;CheckBoxPreference&lt;/strong&gt;, &lt;strong&gt;ListPreference&lt;/strong&gt; e &lt;strong&gt;EditTextPreference&lt;/strong&gt;, entre outros.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Para cada preferência é necessário especificar uma chave, um título e uma descrição. Também é possível especificar valores padrão, opções de persistência e outras propriedades específicas a cada widget.&lt;/p&gt;
&lt;p&gt;Eis um exemplo de um ficheiro de preferências da aplicação Honeybuzz:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;
    &amp;lt;PreferenceCategory android:title="@string/pref_category_design"&amp;gt;
        &amp;lt;ListPreference
            android:title="@string/pref_theme_title"
            android:summary="@string/pref_theme_summary"
            android:key="honeybuzz.theme"
            android:persistent="true"
            android:defaultValue="AppTheme.Light"
            android:entries="@array/themeNames"
            android:entryValues="@array/themeValues" /&amp;gt;
    &amp;lt;/PreferenceCategory&amp;gt;
    &amp;lt;PreferenceCategory android:title="@string/pref_category_service"&amp;gt;
        &amp;lt;ListPreference
            android:title="@string/pref_interval_title"
            android:summary="@string/pref_interval_summary"
            android:key="honeybuzz.interval"
            android:persistent="true"
            android:defaultValue="30"
            android:entries="@array/intervalNames"
            android:entryValues="@array/intervalValues" /&amp;gt;
    &amp;lt;/PreferenceCategory&amp;gt;
    &amp;lt;PreferenceCategory android:title="@string/pref_category_error"&amp;gt;
        &amp;lt;CheckBoxPreference android:key="acra.enable"
            android:persistent="true"
            android:title="@string/pref_disable_acra"
            android:summaryOn="@string/pref_acra_enabled"
            android:summaryOff="@string/pref_acra_disabled"
            android:defaultValue="true"/&amp;gt;
        &amp;lt;CheckBoxPreference android:key="acra.syslog.enable"
            android:persistent="true"
            android:title="@string/pref_acra_syslog"
            android:summaryOn="@string/pref_acra_syslog_enabled"
            android:summaryOff="@string/pref_acra_syslog_disabled"
            android:defaultValue="true"/&amp;gt;
        &amp;lt;CheckBoxPreference android:key="acra.alwaysaccept"
            android:persistent="true"
            android:title="@string/pref_acra_alwaysaccept"
            android:summaryOn="@string/pref_acra_alwaysaccept_enabled"
            android:summaryOff="@string/pref_acra_alwaysaccept_disabled"
            android:defaultValue="false"/&amp;gt;
    &amp;lt;/PreferenceCategory&amp;gt;
&amp;lt;/PreferenceScreen&amp;gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: A &lt;strong&gt;ListPreferences&lt;/strong&gt; só funciona com vectores de strings. Não é possível usar vectores de inteiros (ou de outro tipo qualquer) com a &lt;strong&gt;ListPreferences&lt;/strong&gt;, caso contrário será gerado um erro.&lt;/p&gt;
&lt;h2&gt;Criar uma Activity para as preferências&lt;/h2&gt;
&lt;p&gt;Agora que as preferências foram definidas, é necessário criar uma &lt;strong&gt;Activy&lt;/strong&gt; para as mostrar, devendo ser uma sub-classe da &lt;strong&gt;PreferenceActivity&lt;/strong&gt; e adicionar as preferências partir de um ficheiro de recurso.&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
package com.quasibit.honeybuzz;

import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;

public class HoneybuzzPreferences extends PreferenceActivity {
      @Override 
      public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 

        PreferenceManager prefMgr = getPreferenceManager();
        prefMgr.setSharedPreferencesName(HoneybuzzApplication.PREFERENCES_NAME);
        prefMgr.setSharedPreferencesMode(HoneybuzzApplication.PREFERENCES_MODE);
        
        addPreferencesFromResource(R.xml.preferences); 
      }
}&lt;/pre&gt;&lt;p&gt;Especificamos também o nome e o modo das preferências.&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;Na classe principal da aplicação definimos as constantes das preferências e estabelecemos os valores padrão do &lt;strong&gt;PreferenceManager&lt;/strong&gt;.&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
public class HoneybuzzApplication extends Application {
    public static final String PREFERENCES_NAME = "HoneybuzzPrefs";
    public static final int PREFERENCES_MODE = MODE_PRIVATE;

    public static final String PREFERENCE_THEME = "honeybuzz.theme";
    public static final String PREFERENCE_ISFIRSTUSE = "honeybuzz.firstuse";
    public static final String PREFERENCE_INTERVAL = "honeybuzz.interval";
    
    @Override
    public void onCreate() {
        ...

        PreferenceManager.setDefaultValues(this, PREFERENCES_NAME, PREFERENCES_MODE, R.xml.preferences, false); // set default preferences
        super.onCreate();
    }

    public static SharedPreferences getSharedPreferences() {
        return getInstance().getSharedPreferences(PREFERENCES_NAME, PREFERENCES_MODE);
    }
}&lt;/pre&gt;&lt;p&gt;Para iniciar a &lt;strong&gt;Activity &lt;/strong&gt;das preferências adicionamos uma opção ao menu da aplicação e chamamos o ecrã desta forma:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
startActivity(new Intent(this, HoneybuzzPreferences.class));&lt;/pre&gt;&lt;p&gt;O resultado final é o seguinte:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_prefences.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_prefences-200x125.png" style="width: 200px; height: 125px; " width="200" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Como ler as preferências do utilizador&lt;/h2&gt;
&lt;p&gt;Como adicionamos um método auxiliar à classe principal da aplicação, vamos usá-lo para ir buscar as preferências do utilizador.&lt;/p&gt;
&lt;p&gt;Neste exemplo lemos o theme seleccionado pelo utilizador:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
SharedPreferences prefs = HoneybuzzApplication.getSharedPreferences();
String themeName = prefs.getString(HoneybuzzApplication.PREFERENCE_THEME, "AppTheme.Light");&lt;/pre&gt;&lt;p&gt;Desta forma torna-se fácil ler as preferências do utilizador.&lt;/p&gt;
&lt;h2&gt;SeekBarPreference&lt;/h2&gt;
&lt;p&gt;Cedo descobre-se que não há um widget &lt;strong&gt;SeekBarPreference&lt;/strong&gt;&lt;sup&gt;&lt;a href="#cmnt1" name="cmnt_ref1" id="cmnt_ref1"&gt;[a]&lt;/a&gt;&lt;/sup&gt;. Este é um tipo comum que é útil em muitas situações diferentes. Uma &lt;strong&gt;SeekBarPreference&lt;/strong&gt; é no fundo um slider, útil para preferências numéricas ou de outros tipos.&lt;/p&gt;
&lt;p&gt;Felizmente já várias pessoas passaram por isto e decidiram partilhar os seus widgets.&lt;/p&gt;
&lt;p&gt;Encontrei vários exemplos e cada um deles diferente, por isso verifiquem-nos e escolham o mais apropriado:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://android.hlidskialf.com/blog/code/android-seekbar-preference"&gt;SeekBarPreference from Hlidskialf Android Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/android/seekbar_preference.aspx"&gt;SeekBar Preference by Mike in CodeProject&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://android-journey.blogspot.com/2010/01/for-almost-any-application-we-need-to.html"&gt;Android Preferences from Android &amp;amp; Amir&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cmwmobile.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=15&amp;amp;Itemid=16"&gt;How to create a SeekBarDialogPreference at CMW Mobile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Mais recursos&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/acra/wiki/AdvancedUsage#Letting_your_users_control_ACRA"&gt;Letting your users control ACRA&lt;/a&gt; (como permitir ao utilizador configurar o ACRA)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.kaloer.com/android-preferences"&gt;Android Preferences&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mobdev.olin.edu/mobdevwiki/FrontPage/Tutorials/Preferences"&gt;Steps to Adding Preferences to Your Application&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-como-criar-um-menu-de-op%C3%A7%C3%B5es-e-adicion%C3%A1-lo-%C3%A0-action-bar"&gt;Como criar um menu de opções e adicioná-lo à Action Bar&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GIfM5Qm4yEfrBRWnj_qi9EOZdnA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GIfM5Qm4yEfrBRWnj_qi9EOZdnA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GIfM5Qm4yEfrBRWnj_qi9EOZdnA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GIfM5Qm4yEfrBRWnj_qi9EOZdnA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=tsZpv4lsDyg:vBUOoIWARfg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=tsZpv4lsDyg:vBUOoIWARfg:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=tsZpv4lsDyg:vBUOoIWARfg:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=tsZpv4lsDyg:vBUOoIWARfg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=tsZpv4lsDyg:vBUOoIWARfg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=tsZpv4lsDyg:vBUOoIWARfg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=tsZpv4lsDyg:vBUOoIWARfg:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=tsZpv4lsDyg:vBUOoIWARfg:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=tsZpv4lsDyg:vBUOoIWARfg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=tsZpv4lsDyg:vBUOoIWARfg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=tsZpv4lsDyg:vBUOoIWARfg:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/tsZpv4lsDyg" height="1" width="1"/&gt;</description>
 <pubDate>Fri, 25 Nov 2011 07:40:17 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">124 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-guardar-e-ler-prefer%C3%AAncias-do-utilizador</feedburner:origLink></item>
<item>
 <title>Android 101: Usar Google Analytics numa aplicação Android</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/MKHusznMsoI/android-101-usar-google-analytics-numa-aplica%C3%A7%C3%A3o-android</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-como-lidar-com-erros"&gt;Como lidar com erros&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Análise e estatísticas ajudam a perceber que partes de uma aplicação são as mais populares ou quais são as mais problemáticas para os utilizadores. O Google Analytics não é só para websites, também pode ser usado em aplicações Android.&lt;/p&gt;
&lt;h2&gt;Instalar o Google Analytics num projecto Android&lt;/h2&gt;
&lt;p&gt;Para adicionar o Google Analytics a uma aplicação Android é necessário:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Fazer o &lt;a href="http://code.google.com/mobile/analytics/download.html#Google_Analytics_SDK_for_Android"&gt;download do SDK do Google Analytics&lt;/a&gt; para Android.&lt;/li&gt;
&lt;li&gt;Adicionar a biblioteca &lt;strong&gt;libGoogleAnalytics.jar&lt;/strong&gt; ao projecto. Para saber como fazer isto vejam o artigo &lt;a href="http://www.broculos.net/pt/artigo/android-101-ambiente-de-desenvolvimento-e-cria%C3%A7%C3%A3o-do-projecto#libraries"&gt;Ambiente de desenvolvimento e criação do projecto&lt;/a&gt; (a parte sobre como adicionar bibliotecas externas).&lt;/li&gt;
&lt;li&gt;Adicionar as permissões necessárias ao manifesto Android.&lt;/li&gt;
&lt;/ul&gt;&lt;pre class="brush:xml;"&gt;
&amp;lt;uses-permission android:name="android.permission.INTERNET" /&amp;gt;
&amp;lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&amp;gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Ir à conta do &lt;a href="http://www.google.com/analytics/"&gt;Google Analytics&lt;/a&gt; e criar um perfil como se fosse para um website. Escolham um URL descritivo (embora não tenha de ser verdadeiro).
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/honeybuzz_ga_id.png"&gt;&lt;img src="http://www.broculos.net/sites/default/files/resize/content/honeybuzz_ga_id-200x124.png" style="width: 200px; height: 124px; " width="200" height="124" /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;É necessário informar os utilizadores, algures na aplicação ou nos termos de serviço, que estes estão a ser monitorizados anonimamente.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Monitorizar as fontes de instalação da aplicação&lt;/h3&gt;
&lt;p&gt;Uma parte importante da análise de uma aplicação é saber a fonte da instalação da mesma (caso estejam a usar publicidade, por exemplo, ou se têm links de instalação em vários sites).&lt;/p&gt;
&lt;p&gt;Para poder saber isso é necessário usar um link no seguinte formato:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://market.android.com/search?q=pname:&amp;lt;package&amp;gt;&amp;amp;referrer=&amp;lt;referral&amp;gt;"&gt;http://market.android.com/search?q=pname:&amp;lt;package&amp;gt;&amp;amp;referrer=&amp;lt;referral&amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;lt;package&amp;gt;&lt;/strong&gt; é o nome do package da aplicação.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;lt;referral&amp;gt;&lt;/strong&gt; é informação específica de uma campanha.&lt;/li&gt;
&lt;li&gt;Podem gerar URLs usando a ferramenta &lt;a href="http://code.google.com/mobile/analytics/docs/android/#android-market-tracking"&gt;Android Market Campaign Tracking&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;pre class="brush:xml;"&gt;
&amp;lt;application&amp;gt;

    &amp;lt;!-- Used for install referrer tracking (analytics) --&amp;gt;
    &amp;lt;receiver android:name="com.google.android.apps.analytics.AnalyticsReceiver"
              android:exported="true"&amp;gt;
      &amp;lt;intent-filter&amp;gt;
        &amp;lt;action android:name="com.android.vending.INSTALL_REFERRER" /&amp;gt;
      &amp;lt;/intent-filter&amp;gt;
    &amp;lt;/receiver&amp;gt;

&amp;lt;/application&amp;gt;&lt;/pre&gt;&lt;h2&gt;Fazer monitorização nas Activities&lt;/h2&gt;
&lt;p&gt;Pode-se usar o &lt;strong&gt;GoogleAnalyticsTracker&lt;/strong&gt; para monitorizar page views ou eventos numa aplicação. Por exemplo:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
GoogleAnalyticsTracker tracker = GoogleAnalyticsTracker.getInstance();
tracker.start(“your analytics tracking ID”, 20, this);
tracker.trackPageView("/welcome");
this.tracker.trackEvent("Category", "Action", "Label", "Value");
tracker.setCustomVar(1, "Name", "Value"); // first parameter is the slot (1 to 5)&lt;/pre&gt;&lt;p&gt;Para poupar bateria, esta informação só é enviada passado um intervalo de tempo (20 segundos no exemplo acima), mas também é possível enviar a informação manualmente usando o método &lt;strong&gt;tracker.dispatch()&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;Para tornar esta tarefa mais simples, em vez de adicionar este código manualmente a todas as Activites, criei uma classe a partir da qual todas as Activities são feitas, que não só monitoriza cada Activity, como também tem métodos úteis para fazer a monitorização de eventos e de variáveis personalizadas.&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
package com.quasibit.honeybuzz;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;

import com.google.android.apps.analytics.GoogleAnalyticsTracker;

public class TrackedActivity extends Activity {
    private static final String TRACKER_ID = "your analytics tracking ID ";
    private static final boolean DISPATCH_MANUAL = false;
    private static final int DISPATCH_INTERVAL = 20;
    private static final boolean DEBUG = false; // If true stores analytics requests in the log cat
    private static final boolean DRY_RUN = false; // If true only stores data locally (doesn't send data to analytics)

    @SuppressWarnings("unused")
    private static final int SCOPE_VISITOR = 1; // Call the first time your application is run on a device. Useful for anything that won't change during the lifetime of the installation of the application (app version, lite vs full, type of phone).
    
    @SuppressWarnings("unused")
    private static final int SCOPE_SESSION = 2; // Call at the beginning of an Activity. Applies to all pageviews and events for the lifecycle of the activity.
    
    @SuppressWarnings("unused")
    private static final int SCOPE_PAGE = 3; // Call before trackEvent or trackPageView that the custom variable should apply to.
    
    @SuppressWarnings("unused")
    private static final int SLOT_1 = 1;
    
    @SuppressWarnings("unused")
    private static final int SLOT_2 = 2;
    
    @SuppressWarnings("unused")
    private static final int SLOT_3 = 3;
    
    @SuppressWarnings("unused")
    private static final int SLOT_4 = 4;
    
    @SuppressWarnings("unused")
    private static final int SLOT_5 = 5;
    
    private GoogleAnalyticsTracker tracker;
    private String pageId;

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.pageId = getClass().getSimpleName();
        this.tracker = GoogleAnalyticsTracker.getInstance();
        
        if (DISPATCH_MANUAL) {
            this.tracker.start(TRACKER_ID, this);
        } else {
            this.tracker.start(TRACKER_ID, DISPATCH_INTERVAL, getApplicationContext());
        }
        this.tracker.setDebug(DEBUG);
        this.tracker.setDryRun(DRY_RUN);
    }

    @Override
    protected void onResume() {
        super.onResume();

        this.tracker.trackPageView("/" + this.pageId);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.tracker.dispatch();
        this.tracker.stop();
    }

    public void dispatch() {
        if (this.tracker != null) {
            this.tracker.dispatch();
        }
    }

    public static void dispatch(final Context baseContext) {
        final GoogleAnalyticsTracker tracker = GoogleAnalyticsTracker.getInstance();
        tracker.start(TRACKER_ID, baseContext);
        tracker.dispatch();
        tracker.stop();
    }

    protected void trackPage(final String page) {
        this.tracker.trackPageView(page);
    }

    protected void trackEvent(final String category, final String action, final String label, final int value) {
        this.tracker.trackEvent(category, action, label, value);
    }

    protected void trackEvent(final String category, final String action, final String label) {
        trackEvent(category, action, label, 0);
    }

    protected void trackEvent(final String action, final String label, final int value) {
        this.tracker.trackEvent(this.pageId, action, label, value);
    }

    protected void trackEvent(final String action, final String label) {
        trackEvent(this.pageId, action, label, 0);
    }

    protected void setCustomVar(final int slot, final String name, final String value, final int scope) {
        this.tracker.setCustomVar(slot, name, value, scope);
    }

    protected void setCustomVar(final int slot, final String name, final String value) {
        this.tracker.setCustomVar(slot, name, value);
    }
}&lt;/pre&gt;&lt;p&gt;Como vamos usar fragmentos, a classe TrackedFragment também foi construída.&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
package com.quasibit.honeybuzz;

import com.google.android.apps.analytics.GoogleAnalyticsTracker;

import android.app.Fragment;
import android.os.Bundle;

public class TrackedFragment extends Fragment {
    private GoogleAnalyticsTracker tracker;
    private String activityId;
    private String fragmentId;

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.tracker = GoogleAnalyticsTracker.getInstance();
        this.fragmentId = getClass().getSimpleName();
        this.activityId = getActivity().getClass().getSimpleName();
    }
    
    @Override
    public void onResume() {
        super.onResume();
        this.tracker.trackPageView("/" + this.activityId + "/" + this.fragmentId);
    }
}&lt;/pre&gt;&lt;p&gt;Para mais informação sobre como usar o Google Analytics no Android vejam a sessão da Google I/O &lt;a href="http://www.google.com/events/io/2011/sessions/optimizing-android-apps-with-google-analytics.html"&gt;Optimizing Android Apps with Google Analytics&lt;/a&gt;. Outro bom recurso é o artigo &lt;a href="http://android-developers.blogspot.com/2010/12/analytics-for-android-apps.html"&gt;Analytics for Android Apps&lt;/a&gt; que foi publicado no blog Android Developer.&lt;/p&gt;
&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-guardar-e-ler-prefer%C3%AAncias-do-utilizador"&gt;Guardar e ler as preferências do utilizador&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zc4K86kkxJSMSMkFD0l_28HPLZ0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zc4K86kkxJSMSMkFD0l_28HPLZ0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zc4K86kkxJSMSMkFD0l_28HPLZ0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zc4K86kkxJSMSMkFD0l_28HPLZ0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MKHusznMsoI:rPs9vdIDDFI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MKHusznMsoI:rPs9vdIDDFI:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=MKHusznMsoI:rPs9vdIDDFI:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MKHusznMsoI:rPs9vdIDDFI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MKHusznMsoI:rPs9vdIDDFI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=MKHusznMsoI:rPs9vdIDDFI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MKHusznMsoI:rPs9vdIDDFI:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=MKHusznMsoI:rPs9vdIDDFI:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MKHusznMsoI:rPs9vdIDDFI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=MKHusznMsoI:rPs9vdIDDFI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MKHusznMsoI:rPs9vdIDDFI:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/MKHusznMsoI" height="1" width="1"/&gt;</description>
 <pubDate>Wed, 23 Nov 2011 10:23:44 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">122 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-usar-google-analytics-numa-aplica%C3%A7%C3%A3o-android</feedburner:origLink></item>
<item>
 <title>Android 101: Como lidar com erros</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/G09uWCwgDa8/android-101-como-lidar-com-erros</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://broculos.net/pt/artigo/android-101-trabalhar-com-api-google-buzz"&gt;Trabalhar com a API Google Buzz&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;O registo de erros e a forma como se lidam com estes é um aspecto importante duma aplicação, não só porque permite descobrir as áreas mais problemáticas de uma aplicação, mas também para fornecer uma boa experiência ao utilizador quando um erro ocorre.&lt;/p&gt;
&lt;p&gt;Uma biblioteca popular para lidar com erros em Android é o &lt;a href="http://code.google.com/p/acra/"&gt;ACRA&lt;/a&gt;. O ACRA fornece relatórios detalhados com informação de cada erro e guarda a informação num formulário Google Doc (ou envia a informação para um script custom ou até para um email - mas um Google Doc é prático e fácil de configurar).&lt;/p&gt;
&lt;p&gt;Além disso, o ACRA é personalizável na forma como os erros são apresentados ao utilizador: tanto pode enviar erros silenciosamente sem chamar a atenção, como também é possível mostrar uma caixa de diálogo ao utilizador em que este tem de aceitar voluntariamente o envio do erro e pode ainda deixar uma descrição.&lt;/p&gt;
&lt;p&gt;A partir do Froyo, os relatórios de crash são enviados para o programador através do Android Market (se o utilizador aceitar enviá-los), mas o ACRA é mais personalizável e fornece relatórios detalhados.&lt;/p&gt;
&lt;h2&gt;Configurar uma Google Spreadsheet para relatórios do ACRA&lt;/h2&gt;
&lt;p&gt;Podem ler um &lt;a href="http://code.google.com/p/acra/wiki/BasicSetup"&gt;guia de instalação do ACRA&lt;/a&gt; no site do projecto. Vou descrever brevemente o procedimento.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Fazer download da última versão a partir do site do &lt;a href="http://code.google.com/p/acra/"&gt;ACRA&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Vão ao &lt;a href="https://docs.google.com"&gt;Google Docs&lt;/a&gt; e importem o template &lt;strong&gt;CrashReports-template.csv&lt;/strong&gt;. Certifiquem-se que a conversão está activa.
&lt;ul&gt;&lt;li&gt;&lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_import.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_import.png" style="width: 200px; height: 160px; " /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Abram o novo documento e vão a &lt;strong&gt;Tools&lt;/strong&gt; &amp;gt; &lt;strong&gt;Form&lt;/strong&gt; &amp;gt; &lt;strong&gt;Create a form&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Copiem o valor &lt;strong&gt;formKey&lt;/strong&gt; que está visível na parte de baixo da janela.
&lt;ul&gt;&lt;li&gt;&lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_formkey.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_formkey.png" style="width: 200px; height: 166px; " /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Escrevam algo na descrição para poderem gravar o formulário.&lt;/li&gt;
&lt;li&gt;Se quiserem receber notificações de cada vez que um relatório é gerado (ou diariamente por exemplo), podem editar as regras de notificação.
&lt;ul&gt;&lt;li&gt;No interface antigo do Google Docs expandam o &lt;strong&gt;Share&lt;/strong&gt; e a opção aparece.&lt;/li&gt;
&lt;li&gt;No novo interface do Google Docs têm de ir a &lt;strong&gt;Tools&lt;/strong&gt; &amp;gt; &lt;strong&gt;Notification rules...&lt;/strong&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_notifications.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_notifications.png" style="width: 200px; height: 155px; " /&gt;&lt;/a&gt;&lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_notifications_rules.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_notifications_rules.png" style="width: 200px; height: 157px; " /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Para lerem as mensagens de erro com mais facilidade devem redimensionar as colunas e mudar o alinhamento desta forma:
&lt;ul&gt;&lt;li&gt;&lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_align.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_acra_gdocs_align.png" style="width: 200px; height: 99px; " /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Adicionar o ACRA ao vosso projecto&lt;/h2&gt;
&lt;p&gt;Adicionem a biblioteca ACRA ao vosso projecto. Sigam as instruções fornecidas no artigo &lt;a href="http://broculos.net/pt/artigo/android-101-ambiente-de-desenvolvimento-e-criação-do-projecto#libraries"&gt;Android 101: Ambiente de desenvolvimento e criação do projecto&lt;/a&gt; (ver a parte de como adicionar bibliotecas externas ao projecto).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_acra_eclipse.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_acra_eclipse.png" style="width: 200px; height: 183px; " /&gt;&lt;/a&gt;&lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_acra_eclipse_jar.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_acra_eclipse_jar.png" style="width: 260px; height: 183px; " /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Na configuração mais básica, só é necessário adicionar um atributo à classe Application com a chave do formulário da vossa Google Spreadsheet. Para esta aplicação, fomos um pouco mais longe e adicionamos as seguintes opções:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
@ReportsCrashes(formKey="your form key",
                mode = ReportingInteractionMode.NOTIFICATION,
                resToastText = R.string.crash_toast_text, // optional, displayed as soon as the crash occurs, before collecting data which can take a few seconds
                resNotifTickerText = R.string.crash_notif_ticker_text,
                resNotifTitle = R.string.crash_notif_title,
                resNotifText = R.string.crash_notif_text,
                resNotifIcon = android.R.drawable.stat_notify_error, // optional. default is a warning sign
                resDialogText = R.string.crash_dialog_text,
                resDialogIcon = android.R.drawable.ic_dialog_info, //optional. default is a warning sign
                resDialogTitle = R.string.crash_dialog_title, // optional. default is your application name
                resDialogCommentPrompt = R.string.crash_dialog_comment_prompt, // optional. when defined, adds a user text field input with this text resource as a label
                resDialogOkToast = R.string.crash_dialog_ok_toast, // optional. displays a Toast message when the user accepts to send a report.
                sharedPreferencesName = HoneybuzzApplication.PREFERENCES_NAME, // Name of the SharedPreferences that will host the acra.enable or acra.disable preference.
                sharedPreferencesMode = HoneybuzzApplication.PREFERENCES_MODE // The mode that you need for the SharedPreference file creation: Context.MODE_PRIVATE, Context.MODE_WORLD_READABLE or Context.MODE_WORLD_WRITEABLE.
                )
public class HoneybuzzApplication extends Application {
    public static final String PREFERENCES_NAME = "HoneybuzzPrefs";
    public static final int PREFERENCES_MODE = MODE_PRIVATE;

    @Override
    public void onCreate() {
        ACRA.init(this); // error reporting
        Logging.setLoggingLevel(); // logging level
        PreferenceManager.setDefaultValues(this, PREFERENCES_NAME, PREFERENCES_MODE, R.xml.preferences, false); // set default preferences
        super.onCreate();
    }
}&lt;/pre&gt;&lt;p&gt;Especificamos o modo de interacção dos erros, umas mensagens e ícones personalizados e o nome das preferências para que estas possam ser gravas pelos utilizadores.&lt;/p&gt;
&lt;p&gt;Existem três tipos de interação:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;SILENT: os erros são enviados sem notificar os utilizadores e é mostrado o ecrã padrão do Android (a partir do Froyo).&lt;/li&gt;
&lt;li&gt;TOAST: é mostrada ao utilizador uma simples mensagem durante alguns segundos, avisando que foi enviado um relatório de erros, sem que esta tenha que dar qualquer tipo de confirmação.&lt;/li&gt;
&lt;li&gt;NOTIFICATION: uma notificação é mostrada ao utilizador que este tem que aceitar para que o relatório de erros seja enviado, com a possibilidade de deixar informação adicional.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;Outra funcionalidade interessante é que os utilizadores podem &lt;a href="http://code.google.com/p/acra/wiki/AdvancedUsage#Letting_your_users_control_ACRA"&gt;especificar nas preferências da aplicação como querem que seja feita a interacção dos erros&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Classe de Logging&lt;/h2&gt;
&lt;p&gt;Acabamos por criar uma classe à medida, semelhante à classe &lt;strong&gt;android.utils.Log&lt;/strong&gt;, para agregar toda a funcionalidade de logging: não apenas para escrever relatórios ACRA, mas também para escrever para os logs do Android (que podem ser lidos atráves do LogCat). Esta classe é usada ao longo da aplicação para gravar mensagens, assim como excepções e erros.&lt;/p&gt;
&lt;p&gt;Dependendo do nível de logging configurado, os relatórios seriam enviados para o ACRA.&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
package com.quasibit.honeybuzz;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.acra.ErrorReporter;

import android.util.Log;

public class Logging {
    private static Level LOGGING_LEVEL = Level.ALL;
    private static final String TAG = "Honeybuzz";
    
    public static void setLoggingLevel() {
        Logger.getLogger("com.google.api.client").setLevel(LOGGING_LEVEL);
    }
    
    public static int e(String tag, String msg, Throwable tr) {
        acraReport(Level.SEVERE, tag, msg, tr);
        
        return Log.e(tag, msg, tr);
    }
    
    public static int e(String msg, Throwable tr) {
        return e(TAG, msg, tr);
    }
    
    public static int e(Throwable tr) {
        return e(TAG, tr.getMessage(), tr);
    }
    
    public static int w(String tag, String msg, Throwable tr) {
        acraReport(Level.WARNING, tag, msg, tr);
        
        return Log.w(tag, msg, tr);
    }
    
    public static int w(String msg, Throwable tr) {
        return w(TAG, msg, tr);
    }
    
    public static int w(String tag, String msg) {
        acraReport(Level.WARNING, tag, msg);
        
        return Log.w(tag, msg);
    }
    
    public static int w(String msg) {
        return w(TAG, msg);
    }
    
    public static int i(String tag, String msg, Throwable tr) {
        acraReport(Level.INFO, tag, msg, tr);
        
        return Log.i(tag, msg, tr);
    }
    
    public static int i(String msg, Throwable tr) {
        return i(TAG, msg, tr);
    }
    
    public static int i(String tag, String msg) {
        acraReport(Level.INFO, tag, msg);
        
        return Log.i(tag, msg);
    }
    
    public static int i(String msg) {
        return i(TAG, msg);
    }
    
    public static int d(String tag, String msg) {
        acraReport(Level.FINEST, tag, msg);
        
        return Log.d(tag, msg);
    }
    
    public static int d(String msg) {
        return d(TAG, msg);
    }

    public static int v(String tag, String msg, Throwable tr) {
        acraReport(Level.FINE, tag, msg, tr);
        
        return Log.v(tag, msg, tr);
    }
    
    public static int v(String msg, Throwable tr) {
        return v(TAG, msg, tr);
    }
    
    public static int v(String tag, String msg) {
        acraReport(Level.FINE, tag, msg);
        
        return Log.v(tag, msg);
    }
    
    public static int v(String msg) {
        return v(TAG, msg);
    }

    private static void acraReport(Level level, String tag, String msg, Throwable tr) {
        if (level.intValue() &amp;gt;= LOGGING_LEVEL.intValue()) {
            acraReport(level, tag, msg);
            // report exception to acra silently
            ErrorReporter.getInstance().handleSilentException(tr);
        }
    }
    
    private static void acraReport(Level level, String tag, String msg) {
        if (level.intValue() &amp;gt;= LOGGING_LEVEL.intValue()) {
            ErrorReporter.getInstance().putCustomData(level.getName() + ": " + tag, msg);
        }
    }
}&lt;/pre&gt;&lt;h2&gt;Análise de relatórios ACRA&lt;/h2&gt;
&lt;p&gt;O Google Spreadsheets não fornece propriamente uma experiência agradável para a leitura de relatórios de erros. Existem aplicações que foram feitas para lidar com os relatórios criados pelo ACRA. Podem ver alguns exemplos &lt;a href="http://code.google.com/p/acra/wiki/Contribs"&gt;na página de contribuições no site do ACRA&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;O &lt;a href="http://www.bugsense.com/"&gt;BugSense&lt;/a&gt;, por exemplo, funciona bem com o ACRA. Ainda não o testei, mas parece ter um bom conjunto de funcionalidades e apenas requer uma configuração mínima.&lt;/p&gt;
&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-usar-google-analytics-numa-aplica%C3%A7%C3%A3o-android"&gt;Usar Google Analytics numa aplicação Android&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xCpl7OeGOKYVHrzjh5l1M_F_PJE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xCpl7OeGOKYVHrzjh5l1M_F_PJE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xCpl7OeGOKYVHrzjh5l1M_F_PJE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xCpl7OeGOKYVHrzjh5l1M_F_PJE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=G09uWCwgDa8:xKZFP0Bn6tI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=G09uWCwgDa8:xKZFP0Bn6tI:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=G09uWCwgDa8:xKZFP0Bn6tI:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=G09uWCwgDa8:xKZFP0Bn6tI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=G09uWCwgDa8:xKZFP0Bn6tI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=G09uWCwgDa8:xKZFP0Bn6tI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=G09uWCwgDa8:xKZFP0Bn6tI:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=G09uWCwgDa8:xKZFP0Bn6tI:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=G09uWCwgDa8:xKZFP0Bn6tI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=G09uWCwgDa8:xKZFP0Bn6tI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=G09uWCwgDa8:xKZFP0Bn6tI:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/G09uWCwgDa8" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 21 Nov 2011 08:15:54 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">120 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-como-lidar-com-erros</feedburner:origLink></item>
<item>
 <title>Android 101: Trabalhar com a API Google Buzz </title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/IEOfFAIMteA/android-101-trabalhar-com-api-google-buzz</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Anterior: &lt;a href="http://www.broculos.net/pt/artigo/android-101-ambiente-de-desenvolvimento-e-cria%C3%A7%C3%A3o-do-projecto"&gt;Ambiente de desenvolvimento e criação do projecto&lt;/a&gt;&lt;/h3&gt;
&lt;h2&gt;APIs Google&lt;/h2&gt;
&lt;p&gt;A Google Buzz API faz parte da mais recente família das Google APIs. Esta família é baseada numa nova infra-estrutura de API (mais sobre isso na apresentação do Google IO: &lt;a href="http://www.google.com/events/io/2010/sessions/how-google-builds-apis.html"&gt;How Google builds APIs&lt;/a&gt; . Por cima desta nova infra-estrutura a Google criou uma série de &lt;a href="http://googlecode.blogspot.com/2011/05/google-apis-discovery-service-one-api.html"&gt;ferramentas&lt;/a&gt; que ajudam os programadores a criar aplicações.&lt;/p&gt;
&lt;p&gt;Em Outubro de 2011, a Google&lt;a href="http://googleblog.blogspot.com/2011/10/fall-sweep.html"&gt; &lt;/a&gt; &lt;a href="http://googleblog.blogspot.com/2011/10/fall-sweep.html"&gt;anunciou&lt;/a&gt; que iria descontinuar o Google Buzz e a sua API.&lt;/p&gt;
&lt;h3&gt;HTTP Transport&lt;/h3&gt;
&lt;p&gt;Em Android existem algumas opções para fazer o transporte HTTP de mensagens de e para os serviços da Google (neste caso estamos a usar o serviço do Buzz).&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;UrlFetchTransport -&lt;/strong&gt; Apenas em Google App Engine.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NetHttpTransport&lt;/strong&gt;&lt;strong&gt; - &lt;/strong&gt; Incluído no Java e no Android SDK. Escolha preferencial em Android a partir da versão Gingerbread.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ApacheTransport&lt;/strong&gt;&lt;strong&gt; - &lt;/strong&gt; Incluído no Android SDK. Escolha preferencial para versões antigas do Android SDK (até à versão Froyo).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AndroidHttp.newCompatibleTransport() &lt;/strong&gt; - Escolhe entre NetHttpTransport ou ApacheTransport dependendo da versão do SDK disponível.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;As conexões HTTP não devem ser efectuadas no thread principal do UI, pois não é aconcelhável bloquear o interface por um intervalo indeterminado de tempo enquanto a aplicação comunica com um serviço online. (link para artigo AsyncTask).&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;h3&gt;JSON&lt;/h3&gt;
&lt;p&gt;O JSON é um grande foco nas novas APIs da Google. Deve usá-lo como parser/serializer para evitar erros de falta de memória, que acontecem quando tentamos carregar uma resposta JSON como um objecto. Existem algumas opções para o JSON parser/serializer que pode usar.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;JacksonFactory - &lt;/strong&gt; O mais rápido. Baseado na biblioteca &lt;a href="http://jackson.codehaus.org/"&gt;Jackson&lt;/a&gt; .&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GsonFactory - &lt;/strong&gt; Rápido. Baseado na biblioteca &lt;a href="http://code.google.com/p/google-gson/"&gt;Google GSON&lt;/a&gt; .&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AndroidJsonFactory &lt;/strong&gt; - O&lt;strong&gt; &lt;/strong&gt; mesmo que GSON e disponível na &lt;a href="http://developer.android.com/reference/android/util/JsonReader.html"&gt;versão 3.0 do&lt;/a&gt; &lt;a href="http://developer.android.com/reference/android/util/JsonReader.html"&gt; SDK&lt;/a&gt; .&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Autenticação&lt;/h2&gt;
&lt;p&gt;O gerenciamento de autenticação no Android deve ser feito preferencialmente através do uso da classe &lt;a href="http://developer.android.com/reference/android/accounts/AccountManager.html"&gt;AccountManager&lt;/a&gt; . O AccountManager fornece um registo centralizado de contas de utilizador online. As APIs da Google fornecem uma forma mais específica para lidar com contas Google através da classe &lt;a href="http://javadoc.google-api-java-client.googlecode.com/hg/1.4.1-beta/com/google/api/client/googleapis/extensions/android2/auth/GoogleAccountManager.html"&gt;GoogleAccountManager&lt;/a&gt; .&lt;/p&gt;
&lt;h2&gt;OAuth&lt;/h2&gt;
&lt;p&gt;Embora ainda não se encontre na sua versão final, o uso de OAuth 2.0 é recomendado por causa dos benefícios que traz em comparação com a sua versão anterior.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Suportados por (quase) todas as APIs da Google.&lt;/li&gt;
&lt;li&gt;Controlo mais refinado dos níveis de acesso.&lt;/li&gt;
&lt;li&gt;Exemplo com o Google Buzz
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.googleapis.com/auth/buzz"&gt;https://www.googleapis.com/auth/buzz&lt;/a&gt;&lt;/strong&gt; para acesso de leitura/escrita de dados no Buzz.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.googleapis.com/auth/buzz.readonly"&gt;https://www.googleapis.com/auth/buzz.readonly&lt;/a&gt;&lt;/strong&gt; para acesso de leitura de dados do Buzz.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.googleapis.com/auth/photos"&gt;https://www.googleapis.com/auth/photos&lt;/a&gt;&lt;/strong&gt; para acesso de leitura a fotos do Buzz.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Os token OAuth são temporários e expiram no espaço de 1 hora. Neste sentido é necessário verificar se a resposta é um erro de autenticação (401) e proceder à autenticação do utilizador.&lt;/p&gt;
&lt;p&gt;Aqui está um exemplo retirado de uma &lt;a href="http://www.google.com/events/io/2011/sessions/best-practices-for-accessing-google-apis-on-android.html"&gt;apresentação da Google IO 2011&lt;/a&gt; (ficheiro PowerPoint disponível &lt;a href="http://www.google.com/events/io/2011/static/presofiles/best_practices_for_accessing_google_apis_on_android.ppt"&gt;aqui&lt;/a&gt; , slide #50).&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
@Override
    protected ActivityFeed doInBackground(Void... params) {
     try {
        // execute HTTP requests
     } catch (HttpResponseException e) {
        if (e.response.statusCode == 401) {
          accountManager.invalidateAuthToken(accessProtectedResource.getAccessToken());
          accessProtectedResource.setAccessToken(null);
          SharedPreferences.Editor editor2 = settings.edit();
          editor2.remove(PREF_AUTH_TOKEN);
          editor2.commit();
          getAuthToken(account);
        }
     }
&lt;/pre&gt;&lt;h2&gt;API Access Key&lt;/h2&gt;
&lt;p&gt;Para além de lidar com as contas de utilizador necessitara de uma chave de acesso fornecida pela Google, que permite aceder ao conteúdo dos utilizadores através da API. Eis um exemplo com uma chave falsa:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
buzz = new Buzz(new NetHttpTransport(), accessProtectedResource, new AndroidJsonFactory());
buzz.accessKey = "ABCdef123_9q";
&lt;/pre&gt;&lt;p&gt;Pode registar-se para ter uma chave através da &lt;a href="https://code.google.com/apis/console"&gt;Google API Console&lt;/a&gt; . Mais instrucções sobre &lt;a href="http://code.google.com/apis/console-help/#generatingdevkeys"&gt;como gerar uma chave&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;Leia &lt;a href="http://code.google.com/apis/console-help/#WhatIsKey"&gt;mais sobre chaves de acesso aqui&lt;/a&gt; .&lt;/p&gt;
&lt;h2&gt;Google Buzz API&lt;/h2&gt;
&lt;p&gt;O &lt;a href="https://code.google.com/apis/explorer/#_s=buzz&amp;amp;_v=v1"&gt;Google APIs Explorer&lt;/a&gt; é uma ferramenta muito útil para testar o formato do JSON retornado para cada pedido. Embora não necessite usar directamente o JSON, o explorador é útil para descobrir o nome dos campos e que campo retorna que informação.&lt;/p&gt;
&lt;p&gt;Há uma apresentação da Google IO, &lt;a href="http://www.google.com/events/io/2011/sessions/best-practices-for-accessing-google-apis-on-android.html"&gt;Best Practices for Accessing Google APIs on Android&lt;/a&gt; , que dá algumas dicas sobre o uso de APIs da Google. O orador, Yaniv Inbar, fornece alguns exemplos baseados na API do Google Buzz. Pode encontrar a &lt;a href="http://code.google.com/p/google-api-java-client/source/browse/?repo=samples#hg%2Fbuzz-v1-json-oauth2-android-sample"&gt;versão completa e funcional do código aqu&lt;/a&gt; i. Este código foi o ponto de partida para a nossa aplicação.&lt;/p&gt;
&lt;h3&gt;Limitações&lt;/h3&gt;
&lt;p&gt;A Google Buzz API Java Client 1.0.0 beta que usamos na nossa aplicação não está 100% implementada para alguns dos atributos JSON. Nestes casos terá que usar o JSON de forma um pouco incómoda. Eis o que eu tive que fazer neste caso:&lt;/p&gt;
&lt;pre class="brush:java;"&gt;
ArrayList&amp;lt; ArrayMap&amp;lt;String, Object&amp;gt; &amp;gt; o = (ArrayList&amp;lt;ArrayMap&amp;lt;String, Object&amp;gt;&amp;gt;) a.links.unknownFields.get(linkType);
String s = (String) o.get(0).get("href");&lt;/pre&gt;&lt;p&gt;Para além disto, algumas das mensagens na sua lista podem não ser publicas, neste caso a API retorna a mensagem:&lt;/p&gt;
&lt;p&gt;"Private post only viewable at &lt;a href="https://plus.google.com/xxx/posts/xxx&amp;quot;"&gt;https://plus.google.com/xxx/posts/xxx"&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-como-lidar-com-erros"&gt;Como lidar com erros&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/m8Ve5ujBtQtEDGaWMXa1ekoHghw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m8Ve5ujBtQtEDGaWMXa1ekoHghw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/m8Ve5ujBtQtEDGaWMXa1ekoHghw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m8Ve5ujBtQtEDGaWMXa1ekoHghw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=IEOfFAIMteA:06LeiyAVSEY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=IEOfFAIMteA:06LeiyAVSEY:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=IEOfFAIMteA:06LeiyAVSEY:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=IEOfFAIMteA:06LeiyAVSEY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=IEOfFAIMteA:06LeiyAVSEY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=IEOfFAIMteA:06LeiyAVSEY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=IEOfFAIMteA:06LeiyAVSEY:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=IEOfFAIMteA:06LeiyAVSEY:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=IEOfFAIMteA:06LeiyAVSEY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=IEOfFAIMteA:06LeiyAVSEY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=IEOfFAIMteA:06LeiyAVSEY:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/IEOfFAIMteA" height="1" width="1"/&gt;</description>
 <pubDate>Wed, 16 Nov 2011 09:15:35 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">114 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-trabalhar-com-api-google-buzz</feedburner:origLink></item>
<item>
 <title>Android 101: Ambiente de desenvolvimento e criação do projecto</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/PuI2hp3KNPA/android-101-ambiente-de-desenvolvimento-e-cria%C3%A7%C3%A3o-do-projecto</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;blockquote&gt;&lt;p&gt;Este artigo faz parte de um &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;Guia de Desenvolvimento para Android&lt;/a&gt;. O guia fala de vários temas necessários para construir uma aplicação simples na sua totalidade, abordando várias funcionalidades introduzidas no Honeycomb e que ainda são válidas para o Ice Cream Sandwich. Usamos um cliente do Google Buzz chamado Honeybuzz como exemplo para cada tópico. Na &lt;a href="http://broculos.net/pt/artigo/guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android"&gt;introdução&lt;/a&gt; encontra-se uma listagem completa de todos os artigos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;O primeiro passo é instalar o ambiente de desenvolvimento. Vamos usar o Eclipse, o IDE recomendado.&lt;/p&gt;
&lt;h2&gt;Instalar e configurar o SDK do Android e o ambiente de desenvolvimento&lt;/h2&gt;
&lt;p&gt;Para começar vai precisar de:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.eclipse.org/downloads/"&gt;Instalar o Eclipse&lt;/a&gt; (3.5 ou superior): Usei a edição "Eclipse IDE for Java Developers". Estou a usar a release Helios (3.6).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html"&gt;Instalar o JDK&lt;/a&gt; (5 ou superior): não basta instalar o JRE. É preciso instalar o JDK (estou a usar a versão 6).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.android.com/sdk/index.html"&gt;Instalar o SDK do Android&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.android.com/sdk/eclipse-adt.html#installing"&gt;Instalar o plugin das Android Development Tools&lt;/a&gt; (ADT) para o Eclipse: siga as instruções no link.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.android.com/sdk/installing.html#AddingComponents"&gt;Adicionar plataformas e componentes&lt;/a&gt; usando o AVD manager: certifique-se que adiciona a plataforma Android 3+, as ferramentas do SDK e as APIs da Google.&lt;/li&gt;
&lt;li&gt;Para fazer o debug num dispositivo físico (telefone, tablet, etc.) vai precisar de instalar um &lt;a href="http://developer.android.com/sdk/oem-usb.html"&gt;driver USB&lt;/a&gt;. Os drivers vêm por vezes com o software de instalação para o seu dispositivo, mas em muitos casos é necessário fazer o download do site do fabricante.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Também recomendo que usem um sistema de controlo de versão e os respectivos plugins para o Eclipse, embora isso seja fora do âmbito deste artigo. Podem pesquisar no Eclipse Marketplace a partir do próprio Eclipse (através do menu de ajuda), onde encontrarão muitos plugins differentes.&lt;/p&gt;
&lt;h2&gt;Criar o primeiro projecto Android&lt;/h2&gt;
&lt;p&gt;Criar o primeiro projecto Android é fácil.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Vão a &lt;strong&gt;File&lt;/strong&gt; &amp;gt; &lt;strong&gt;New&lt;/strong&gt; &amp;gt; &lt;strong&gt;Project...&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Escolham &lt;strong&gt;Android Project&lt;/strong&gt; em &lt;strong&gt;Android&lt;/strong&gt;.
&lt;ul&gt;&lt;li&gt;&lt;img src="http://broculos.net/sites/default/files/content/create_android_project.png" style="width: 200px; height: 233px; " /&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Especifiquem os detalhes do projecto:
&lt;ul&gt;&lt;li&gt;&lt;em&gt;Project name:&lt;/em&gt; Honeybuzz neste caso.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Build target&lt;/em&gt;: vamos escolher a versão Android 3.0 para esta aplicação.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Application name&lt;/em&gt;: o nome da aplicação (normalmente é parecido ou o mesmo nome do projecto, mas não necessariamente).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Package name&lt;/em&gt;: um nome único que identifica a vossa aplicação. Escolham este nome com cuidado para evitar conflictos com outras aplicações. É comum escolher-se este nome no formato &lt;strong&gt;com.domain.application&lt;/strong&gt;. Neste caso escolhemos &lt;strong&gt;com.quasibit.Honeybuzz&lt;/strong&gt; (porque temos o domínio quasibit.com).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Create activity&lt;/em&gt;: deve estar seleccionado para a maior parte das aplicações (uma &lt;strong&gt;Activity&lt;/strong&gt; é basicamente um ecrã de uma aplicação Android) e devem escolher um nome descritivo. Por exemplo, a &lt;strong&gt;Activity&lt;/strong&gt; principal desta aplicação é chamada &lt;strong&gt;HoneybuzzListActivity&lt;/strong&gt; (porque mostra uma listagem dos últimos buzzes).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Min SDK version&lt;/em&gt;: a versão mínima compatível com a vossa aplicação. Para o Honeycomb é a versão 11.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a name="libraries" id="libraries"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Adicionar bibliotecas externas&lt;/h3&gt;
&lt;p&gt;Depois de criar o projecto vamos adicionar as bibliotecas que precisamos. Existem diversas formas de definir as dependências. Uma forma popular é usando o Maven, que tem algumas vantagens como fazer o download automático de bibliotecas Java, mas também tem algumas desvantagens: é mais complexo de configurar inicialmente e no caso do Android não é possível iniciar uma sessão de debug num dispositivo a partir do Eclipse, porque as bibliotecas não vão ser incluídas no APK (Android Application Package) desta forma.&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;Vamos adicionar as bibliotecas manualmente:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Façam download das bibliotecas necessárias.
&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/google-api-java-client/"&gt;Google APIs Client Library for Java&lt;/a&gt;: Usei a versão 1.4.1-beta. Façam download da última versão &lt;a href="http://code.google.com/p/google-api-java-client/wiki/Setup#Download_the_Zipped_Jars"&gt;aqui&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/google-api-java-client/wiki/APIs#Buzz_API"&gt;Buzz API&lt;/a&gt;: usamos a versão 1-1.0.0-beta para este projecto. Façam também o download do código fonte e do JavaDoc.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Criem uma nova pasta &lt;strong&gt;libraries&lt;/strong&gt; no vosso projecto.&lt;/li&gt;
&lt;li&gt;Adicionem as bibliotecas, código fonte e JavaDoc a esta pasta. Certifiquem-se que os ficheiros são copiados (e não são meros links). Faço desta forma para poder guardar tudo no controlo de versões. Adicionei estas bibliotecas:
&lt;ul&gt;&lt;li&gt;google-api-client-1.4.1-beta&lt;/li&gt;
&lt;li&gt;google-api-client-extensions-android2-1.4.1-beta&lt;/li&gt;
&lt;li&gt;google-api-client-extensions-android3-1.4.1-beta&lt;/li&gt;
&lt;li&gt;google-api-client-googleapis-1.4.1-beta&lt;/li&gt;
&lt;li&gt;google-api-client-googleapis-extensions-android2-1.4.1-beta&lt;/li&gt;
&lt;li&gt;google-api-services-buzz-v1-1.0.0-beta&lt;/li&gt;
&lt;li&gt;E estas dependências:
&lt;ul&gt;&lt;li&gt;gson-1.6&lt;/li&gt;
&lt;li&gt;guava-r09&lt;/li&gt;
&lt;li&gt;jackson-core-asl-1.6.7&lt;/li&gt;
&lt;li&gt;jsr305-1.3.9&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Mais à frente no guia vamos também adicionar bibliotecas para estatísticas, publicidade e registo de erros.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Especifiquem as bibliotecas nas propriedades do projecto.
&lt;ul&gt;&lt;li&gt;Façam right-click no projecto e abram as propriedades.&lt;/li&gt;
&lt;li&gt;Vão a &lt;strong&gt;Java Build Path&lt;/strong&gt; e abram a tab &lt;strong&gt;Libraries&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Adicionem todas as bibliotecas usando a opção &lt;strong&gt;Add JARs...&lt;/strong&gt;:
&lt;ul&gt;&lt;li&gt;Expandam o vosso projecto e a pasta &lt;strong&gt;libraries&lt;/strong&gt; e escolham o JAR.&lt;/li&gt;
&lt;li&gt;Expandam os detalhes do JAR e especifiquem a localização do código fonte e do JavaDoc quando disponível.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Devem ficar com algo semelhante a isto:
&lt;ul&gt;&lt;li&gt;&lt;a href="http://broculos.net/sites/default/files/content/project_libraries.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/project_libraries.png" style="width: 200px; height: 120px; " /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;O &lt;a href="http://code.google.com/eclipse/"&gt;Google Plugin for Eclipse&lt;/a&gt; também ajuda a adicionar as APIs da Google ao projecto, mas neste caso não fizemos uso dele.&lt;/p&gt;
&lt;h3&gt;Configurar o ProGuard&lt;/h3&gt;
&lt;p&gt;Vamos fazer uma configuração extra para reduzir o tamanho da aplicação. O &lt;a href="http://proguard.sourceforge.net/"&gt;ProGuard&lt;/a&gt; comprime e optimiza ficheiros Java, retirando código que não é usado e fazendo várias optimizações no código restante.&lt;/p&gt;
&lt;p&gt;Como configurar o ProGuard para a vossa aplicação Android:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Editar o ficheiro &lt;strong&gt;default.properties&lt;/strong&gt; e adicionar a linha:&lt;/li&gt;
&lt;/ul&gt;&lt;pre class="brush:plain;"&gt;
proguard.config=proguard.cfg&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Editar o ficheiro &lt;strong&gt;proguard.cfg&lt;/strong&gt; e adicionar as linhas seguintes:&lt;/li&gt;
&lt;/ul&gt;&lt;pre class="brush:plain;"&gt;
# Needed by google-api-client to keep generic types and @Key annotations accessed via reflection

-keepclassmembers class * {
  @com.google.api.client.util.Key &amp;lt;fields&amp;gt;;
}

-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault

# Needed by Guava

-dontwarn sun.misc.Unsafe&lt;/pre&gt;&lt;p&gt;Esta é a base inicial do projecto. Em seguida, damos uma breve introdução ao desenvolvimento em Android.&lt;/p&gt;
&lt;h2&gt;Introdução ao desenvolvimento em Android&lt;/h2&gt;
&lt;p&gt;O melhor recurso sobre desenvolvimento em Android é o site &lt;a href="http://developer.android.com/index.html"&gt;Android Developers&lt;/a&gt;: tem guias de desenvolvimento, referências e recursos.&lt;/p&gt;
&lt;p&gt;Neste guia vamos falar de diferentes tópicos, mas não nos vamos focar em demasia nos fundamentais do Android, porque o site Android Developers já faz um bom trabalho nesse aspecto. Para começar recomendo que leiam &lt;a href="http://developer.android.com/guide/basics/what-is-android.html"&gt;What is Android?&lt;/a&gt; e &lt;a href="http://developer.android.com/guide/topics/fundamentals.html"&gt;Application Fundamentals&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Uma visão geral de uma aplicação Android:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;A maior parte das aplicações usa &lt;strong&gt;Activities&lt;/strong&gt;. Uma &lt;strong&gt;Activity&lt;/strong&gt; é basicamente um ecrã da aplicação.&lt;/li&gt;
&lt;li&gt;Algumas aplicações usam &lt;strong&gt;Services&lt;/strong&gt; quem correm no background. Um &lt;strong&gt;Service&lt;/strong&gt; não tem uma interface e é usado em geral para correr processos de longa duração, como actualizar os dados de uma aplicação.&lt;/li&gt;
&lt;li&gt;Para lançar uma &lt;strong&gt;Activity&lt;/strong&gt; ou um &lt;strong&gt;Service&lt;/strong&gt; é necessário declarar um &lt;strong&gt;Intent&lt;/strong&gt;. Um &lt;strong&gt;Intent&lt;/strong&gt; não tem de pertencer à vossa aplicação. Um exemplo de um &lt;strong&gt;Intent&lt;/strong&gt; é abrir uma página web no browser do utilizador.&lt;/li&gt;
&lt;li&gt;Cada aplicação tem um manifesto. No manifesto especificam-se todas as &lt;strong&gt;Activities&lt;/strong&gt;, os &lt;strong&gt;Services&lt;/strong&gt;, os widgets, as permissões necessárias e ainda mais. Está na raiz do projecto e é chamado &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;O interface das &lt;strong&gt;Activities&lt;/strong&gt; define-se usando ficheiros de layout. Cada layout contém uma ou mais &lt;strong&gt;Views&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Os recursos são guardados na pasta &lt;strong&gt;res&lt;/strong&gt;. Todas as imagens do projecto, os layouts, as strings, as preferências, as configurações e ainda mais, são guardados nessa pasta.&lt;/li&gt;
&lt;li&gt;Uma aplicação Android é instalada usando um APK (Android Application Package): é um arquivo compilado com todos os recursos da aplicação. É este arquivo que é instalado nos dispositivos Android.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Antes de continuar recomendo que leiam pelo menos os 4 primeiros &lt;a href="http://developer.android.com/resources/browser.html?tag=tutorial"&gt;tutoriais encontrados no site Android Developers&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-trabalhar-com-api-google-buzz"&gt;Trabalhar com a API do Google Buzz&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AFLmDFuufK8L1qYZFlvV6u2_Nhk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AFLmDFuufK8L1qYZFlvV6u2_Nhk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AFLmDFuufK8L1qYZFlvV6u2_Nhk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AFLmDFuufK8L1qYZFlvV6u2_Nhk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=PuI2hp3KNPA:4QvfOmabbXk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=PuI2hp3KNPA:4QvfOmabbXk:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=PuI2hp3KNPA:4QvfOmabbXk:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=PuI2hp3KNPA:4QvfOmabbXk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=PuI2hp3KNPA:4QvfOmabbXk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=PuI2hp3KNPA:4QvfOmabbXk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=PuI2hp3KNPA:4QvfOmabbXk:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=PuI2hp3KNPA:4QvfOmabbXk:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=PuI2hp3KNPA:4QvfOmabbXk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=PuI2hp3KNPA:4QvfOmabbXk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=PuI2hp3KNPA:4QvfOmabbXk:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/PuI2hp3KNPA" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 14 Nov 2011 17:08:30 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">116 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-ambiente-de-desenvolvimento-e-cria%C3%A7%C3%A3o-do-projecto</feedburner:origLink></item>
<item>
 <title>Android 101: Guia de introdução ao desenvolvimento em Android</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/-2UtPSeC1mM/android-101-guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Este é o primeiro numa série de artigos sobre desenvolvimento em Android. Tem como objectivo ser uma introdução ao Android, mas o leitor já deverá saber as bases da programação.&lt;/p&gt;
&lt;p&gt;Vamos cobrir os básicos e falar de funcionalidades introduzidas no Honeycomb. Iremos passo a passo até termos uma aplicação Android completa. Apesar de nos focarmos no Honeycomb, o mesmo ainda é válido para o Ice Cream Sandwich.&lt;/p&gt;
&lt;p&gt;Tivemos a ideia para este guia quando estávamos a desenvolver um cliente para Google Buzz chamado Honeybuzz. Quando o Google+ foi anunciado, decidimos abandonar a aplicação, mas pelo menos queríamos fazer uso do conhecimento adquirido para ajudar outras pessoas. Íamos publicar a aplicação (como demonstração), mas depois do &lt;a href="http://googleblog.blogspot.com/2011/10/fall-sweep.html"&gt;fim do Google Buzz ser anunciado&lt;/a&gt; , apercebemos que seria inútil passado pouco tempo.&lt;/p&gt;
&lt;p&gt;Vamos usar a aplicação como referência, servindo de exemplo para cada tópico de como o mesmo pode ser aplicado numa aplicação real. De seguida alguns screenshots do Honeybuzz.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_dark.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_dark.png" style="width: 200px; height: 125px; " /&gt;&lt;/a&gt; &lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_light.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_light.png" style="width: 200px; height: 125px; " /&gt;&lt;/a&gt; &lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_portrait_details.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_portrait_details.png" style="width: 78px; height: 125px; " /&gt;&lt;/a&gt; &lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_portrait_listing.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_portrait_listing.png" style="width: 78px; height: 125px; " /&gt;&lt;/a&gt; &lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_widget.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_widget.png" style="width: 200px; height: 125px; " /&gt;&lt;/a&gt; &lt;a href="http://broculos.net/sites/default/files/content/honeybuzz_prefences.png"&gt;&lt;img src="http://broculos.net/sites/default/files/content/honeybuzz_prefences.png" style="width: 200px; height: 125px; " /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A lista de todos os capítulos do guia:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-ambiente-de-desenvolvimento-e-criação-do-projecto"&gt;Ambiente de desenvolvimento e criação do projecto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-trabalhar-com-api-google-buzz"&gt;Trabalhar com a API do Google Buzz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-como-lidar-com-erros"&gt;Como lidar com erros&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-usar-google-analytics-numa-aplica%C3%A7%C3%A3o-android"&gt;Usar Google Analytics numa aplicação Android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-guardar-e-ler-prefer%C3%AAncias-do-utilizador"&gt;Guardar e ler as preferências do utilizador&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-como-criar-um-menu-de-op%C3%A7%C3%B5es-e-adicion%C3%A1-lo-%C3%A0-action-bar"&gt;Como criar um menu de opções e adicioná-lo à Action Bar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-estilos-e-temas"&gt;Estilos e themes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-usar-fragmentos-para-lidar-com-diferentes-orienta%C3%A7%C3%B5es-de-ecr%C3%A3"&gt;Usar fragmentos para lidar com diferentes orientações de ecrã&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-services-asynctasks-e-notifications"&gt;Services, AsyncTasks e Notifications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-como-monetizar-uma-aplicação-android"&gt;Como monetizar uma aplicação Android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-como-criar-um-widget-stackview"&gt;Como criar um widget StackView&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.broculos.net/pt/artigo/android-101-publicar-no-mercado-android"&gt;Publicar no mercado Android&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Adicionaremos links à medida que os capítulos forem publicados.&lt;/p&gt;
&lt;p&gt;Esperemos que gostem desta série de tutoriais e aguardaremos pelos vossos comentários e sugestões.&lt;/p&gt;
&lt;h3&gt;Próximo: &lt;a href="http://www.broculos.net/pt/artigo/android-101-ambiente-de-desenvolvimento-e-criação-do-projecto"&gt;Ambiente de desenvolvimento e criação do projecto&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Bg6saXfOmM6pyVfVRBui3l-IR-o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bg6saXfOmM6pyVfVRBui3l-IR-o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Bg6saXfOmM6pyVfVRBui3l-IR-o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bg6saXfOmM6pyVfVRBui3l-IR-o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-2UtPSeC1mM:ciQGd-bzZXI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-2UtPSeC1mM:ciQGd-bzZXI:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=-2UtPSeC1mM:ciQGd-bzZXI:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-2UtPSeC1mM:ciQGd-bzZXI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-2UtPSeC1mM:ciQGd-bzZXI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=-2UtPSeC1mM:ciQGd-bzZXI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-2UtPSeC1mM:ciQGd-bzZXI:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=-2UtPSeC1mM:ciQGd-bzZXI:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-2UtPSeC1mM:ciQGd-bzZXI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=-2UtPSeC1mM:ciQGd-bzZXI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-2UtPSeC1mM:ciQGd-bzZXI:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/-2UtPSeC1mM" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 14 Nov 2011 17:08:00 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">112 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/android-101-guia-de-introdu%C3%A7%C3%A3o-ao-desenvolvimento-em-android</feedburner:origLink></item>
<item>
 <title>Broculos.net tem uma Página Google+</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/VbZ4UshdhAM/broculosnet-tem-uma-p%C3%A1gina-google</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Agora também nos pode &lt;a href="https://plus.google.com/104045844362815664699/?prsrc=3"&gt;seguir no Google+&lt;/a&gt;! A Google &lt;a href="http://googleblog.blogspot.com/2011/11/google-pages-connect-with-all-things.html"&gt;anunciou recentemente as Páginas Google+&lt;/a&gt;, uma forma de marcas, empresas e organizações comunicarem com os seus clientes e fãs.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://plus.google.com/104045844362815664699/?prsrc=3"&gt;Adicione-nos a um dos seus círculos do Google+&lt;/a&gt; e mantenha-se actualizado com os nossos artigos e notícias.&lt;/p&gt;
&lt;h2&gt;Como criar uma Página Google+&lt;/h2&gt;
&lt;p&gt;É bastante simples criar uma Página Google+. Visite &lt;a href="https://plus.google.com/pages/create"&gt;Create a Google+ Page&lt;/a&gt;, escolha o tipo de página que deseja e preencha todos os dados.&lt;/p&gt;
&lt;p&gt;Para candidatar a sua página ao Direct connect, que é uma forma dos utilizadores encontrarem uma página no motor de pesquisa da Google através da simples escrita de + seguido do nome da página, necessita de adicionar o seguinte código HTML ao elemento &lt;strong&gt;&amp;lt;head&amp;gt;&lt;/strong&gt; do seu site:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;link href="https://plus.google.com/PAGE_ID/" rel="publisher" /&amp;gt;&lt;/pre&gt;&lt;p&gt;Não se esqueça de preencher toda a informação na sua Página Google+, incluindo o URL para o seu site e toda a informação de contacto.&lt;/p&gt;
&lt;p&gt;Um &lt;a href="https://developers.google.com/+/plugins/badge/"&gt;Google+ Badge&lt;/a&gt;, que se encontra actualmente em preview, permite a um utilizador adicionar a sua página aos seus círculos directamente a partir do seu site. Pode usar a &lt;a href="https://developers.google.com/+/plugins/badge/config"&gt;ferramenta de configuração de Google+ Badges&lt;/a&gt; para gerar o código necessário. Use um badge estático entretanto, enquanto o badge padrão se encontra em preview, para se certificar que todos os seus visitantes vêem um link para a sua Página Google+. Pode ver o nosso badge na coluna do lado direito.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/18KjTHlrW0TJ0ncpAkIOQArEc3U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/18KjTHlrW0TJ0ncpAkIOQArEc3U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/18KjTHlrW0TJ0ncpAkIOQArEc3U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/18KjTHlrW0TJ0ncpAkIOQArEc3U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=VbZ4UshdhAM:T38DvCV5ktI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=VbZ4UshdhAM:T38DvCV5ktI:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=VbZ4UshdhAM:T38DvCV5ktI:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=VbZ4UshdhAM:T38DvCV5ktI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=VbZ4UshdhAM:T38DvCV5ktI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=VbZ4UshdhAM:T38DvCV5ktI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=VbZ4UshdhAM:T38DvCV5ktI:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=VbZ4UshdhAM:T38DvCV5ktI:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=VbZ4UshdhAM:T38DvCV5ktI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=VbZ4UshdhAM:T38DvCV5ktI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=VbZ4UshdhAM:T38DvCV5ktI:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/VbZ4UshdhAM" height="1" width="1"/&gt;</description>
 <pubDate>Sat, 12 Nov 2011 18:37:35 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">135 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/noticia/broculosnet-tem-uma-p%C3%A1gina-google</feedburner:origLink></item>
<item>
 <title>SharePoint 2010 Branding: Navegação de topo 100% horizontal</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/WAAfuCniHi8/sharepoint-2010-branding-navega%C3%A7%C3%A3o-de-topo-100-horizontal</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Em SharePoint 2007 a navegação de topo era um emaranhado de tabelas interminável. Não era possível tentar mudar o design visual da navegação por defeito muito para alem das cores e do espaçamento. Agora, em Sharepoint 2010, a navegação é constituída por listas. Isto possibilita aos front-end developers criar uma grade variedade de designs diferentes. Neste artigo dar-vos-ei alguns exemplos de como se pode fazer a navegação aparecer horizontalmente. O código que vos vou fornecer é o mínimo necessário para cumprir o que se pretende para que possa ser facilmente reutilizado.&lt;/p&gt;
&lt;p&gt;O nosso ponto inicial:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-htopnav-1.png" style="width: 407px; height: 115px; " /&gt;&lt;/p&gt;
&lt;p&gt;Uso uma navegação com apenas dois níveis, se precisar de acomodar mais níveis terá que adaptar este código para acomodar os níveis extra.&lt;/p&gt;
&lt;h3&gt;Mostrar o segundo nível apenas durante o hover&lt;/h3&gt;
&lt;p&gt;Aqui quis manter o comportamento normal da navegação à excepção do segundo nível, que vai aparecer na horizontal. A sublinhar, a criação de algum espaço livre abaixo do primeiro nível para acomodar o espaço necessário ao segundo nível, assim a navegação não vai aparecer por cima do conteúdo.&lt;/p&gt;
&lt;p&gt;Estado normal:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-htopnav-3.png" style="width: 295px; height: 59px; " /&gt;&lt;/p&gt;
&lt;p&gt;Hover sobre a tab 'Work':&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-htopnav-2.png" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; vertical-align: baseline; cursor: default; width: 441px; height: 71px; " /&gt;&lt;/p&gt;
&lt;p&gt;O código explica-se a si próprio. Em caso de dúvida adicionei alguns comentários nas declarações mais importantes.&lt;/p&gt;
&lt;pre class="brush:css;"&gt;
.s4-toplinks {
	padding-bottom: 23px; /* criar espaço para caber a navegação de segundo nível */
	position: relative;
}

.s4-toplinks .s4-tn li {
	position: static !important; /* a navegação de segundo nível fica posicionada relativamente em relação ao contentor .s4-toplinks */
}

/* hover 2nd level */
.s4-tn li.hover-off ul.dynamic,
.s4-tn li.hover ul.dynamic {
	left: 0 !important;
	bottom: 0 !important;
	top: auto !important; /* reset */
}

.s4-toplinks li  &amp;gt; ul.dynamic li.dynamic {
    float: left;
}&lt;/pre&gt;&lt;h3&gt;Mostrar o segundo nível para a tab seleccionada (sempre visível)&lt;/h3&gt;
&lt;p&gt;Esta solução é bastante útil visto que é possível visualizar o segundo nível de navegação do site em que nos encontramos. Todos os outros menus do segundo nível (tabs não seleccionadas) permanecem verticais. Veja o exemplo seguinte de como fazer isto.&lt;/p&gt;
&lt;p&gt;Estado normal (quando dentro do site "Work"):&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-htopnav-4.png" style="width: 523px; height: 76px; " /&gt;&lt;/p&gt;
&lt;p&gt;Hover sobre outra tab:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-htopnav-5.png" style="width: 539px; height: 109px; " /&gt;&lt;/p&gt;
&lt;pre class="brush:css;"&gt;
.s4-toplinks {
	padding-bottom: 23px; /* criar espaço para caber a navegação de segundo nível */
	position: relative;
}

.s4-toplinks .s4-tn li.selected {
	position: static !important; /* a navegação de segundo nível fica posicionada relativamente em relação ao contentor .s4-toplinks */
}

/* hover 2nd level */
.s4-tn li.selected ul.dynamic,
.s4-tn li.selected.hover-off ul.dynamic,
.s4-tn li.selected.hover ul.dynamic {
	left: 0 !important;
	bottom: 0 !important;
	top: auto !important; /* reset */
}

.s4-toplinks li.selected  &amp;gt; ul.dynamic li.dynamic {
    float: left;
}&lt;/pre&gt;&lt;p&gt;&lt;span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; line-height: normal; background-color: rgba(255, 255, 255, 0.917969); "&gt;&lt;br /&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Mostrar o segundo nível para a tab seleccionada (sempre visível) e durante o hover&lt;/h3&gt;
&lt;p&gt;Quero que o segundo nível da navegação esteja sempre visível para a tab seleccionada. Quando faço hover em outras tabs a navegação actual vai ser escondida e aparecerá a lista da navegação da tab seleccionada. Vamos usar JavaScript neste exemplo.&lt;/p&gt;
&lt;p&gt;Estado normal (quando dentro do site "Work"):&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-htopnav-4.png" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; vertical-align: baseline; cursor: default; width: 523px; height: 76px; " /&gt;&lt;/p&gt;
&lt;p&gt;Hover sobre a tab "News":&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-htopnav-6.png" style="width: 534px; height: 68px; " /&gt;&lt;/p&gt;
&lt;p&gt;Isto é uma implementação com os mínimos essenciais. Talvez queira dar algumas pistas visuais através do estilo para identificar a tab seleccionada.&lt;/p&gt;
&lt;p&gt;O CSS:&lt;/p&gt;
&lt;pre class="brush:css;"&gt;
.s4-toplinks {
	padding-bottom: 23px; /* criar espaço para caber a navegação de segundo nível */
	position: relative;
}

.s4-toplinks .s4-tn li {
	position: static !important; /* a navegação de segundo nível fica posicionada relativamente em relação ao contentor .s4-toplinks  */
}

/* hover 2nd level */
.s4-tn li.selected ul.dynamic,
.s4-tn li.hover-off ul.dynamic,
.s4-tn li.hover ul.dynamic {
	left: 0 !important;
	bottom: 0 !important;
	top: auto !important; /* reset */
}

.s4-toplinks li &amp;gt; ul.dynamic li.dynamic {
    float: left;
}&lt;/pre&gt;&lt;p&gt;O JavaScript:&lt;/p&gt;
&lt;pre class="brush:jscript;"&gt;
jQuery(document).ready(function () {
	handleHorizontalNav();
});

function handleHorizontalNav() {
	jQuery(".s4-toplinks li.dynamic-children:not(.selected) &amp;gt; a, .s4-toplinks li.dynamic-children:not(.selected) &amp;gt; ul.dynamic").hover(
	function(){		
		jQuery(".s4-tn li.selected &amp;gt; ul.dynamic").css("display", "none");
	},		
	function(){
		jQuery(".s4-tn li.selected ul.dynamic").css("display", "block");
	});
	
	jQuery(".s4-toplinks li.selected a").unbind('hover');
}&lt;/pre&gt;&lt;h3&gt;Marcar o elemento seleccionado no segundo nível&lt;/h3&gt;
&lt;p&gt;Um problema que se cria quando o segundo nível de navegação esta sempre visível é que não existe um selector (id ou class) para o elemento seleccionado no segundo nível. Podemos resolver este problema usando JavaScript.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-htopnav-7.png" style="width: 517px; height: 64px; " /&gt;&lt;/p&gt;
&lt;pre class="brush:jscript;"&gt;
String.prototype.startsWith = function(str){
    return (this.indexOf(str) === 0);
}

function setActiveItemInTopNavSecondLevel() {
    var cururl = window.location.pathname;
    var menu = jQuery(".s4-toplinks li.selected ul.dynamic");

    menu.children("li").each(function (i, e) {
        var item = jQuery(this).find("a.menu-item");
        var url = item.attr("href");
		
        if (cururl.startsWith(url)) {
            item.addClass("selected");
        }
    });
}&lt;/pre&gt;&lt;h3&gt;Centrar a navegação de segundo nível relativamente à sua raiz&lt;/h3&gt;
&lt;p&gt;Outra pista visual que podemos dar é centrar o segundo nivel horizontalmente relativamente à sua tab raiz, em vez de estar tudo alinhado à esquerda. Vejamos como fazer isto com a ajuda de JavaScript.&lt;/p&gt;
&lt;p&gt;Mudei um pouco o tamanho dos elementos neste exemplo para que o efeito seja mais visível&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-htopnav-8.png" style="width: 561px; height: 69px; " /&gt;&lt;/p&gt;
&lt;pre class="brush:jscript;"&gt;
function centerTopNavSecondLevel() {
    jQuery(".s4-toplinks li.dynamic-children").each(function (i, e) {
		var menu = jQuery(this).children("ul.dynamic");
		
		if (jQuery(this).offset() != null) {
            left = (jQuery(this).offset().left - (menu.width() / 2)) + (jQuery(this).width() / 2);
        }
		
		// check if the menu doesnt overflow to the left
        if (left &amp;lt; 0) {
            left = 0; 
        }
		
        menu.children("li").first().css("margin-left", left + "px");
    });
}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LbnGMvj3JUpBZiVKoACc2Ppan24/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LbnGMvj3JUpBZiVKoACc2Ppan24/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LbnGMvj3JUpBZiVKoACc2Ppan24/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LbnGMvj3JUpBZiVKoACc2Ppan24/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WAAfuCniHi8:N1LwF7mXpPw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WAAfuCniHi8:N1LwF7mXpPw:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=WAAfuCniHi8:N1LwF7mXpPw:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WAAfuCniHi8:N1LwF7mXpPw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WAAfuCniHi8:N1LwF7mXpPw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=WAAfuCniHi8:N1LwF7mXpPw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WAAfuCniHi8:N1LwF7mXpPw:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=WAAfuCniHi8:N1LwF7mXpPw:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WAAfuCniHi8:N1LwF7mXpPw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=WAAfuCniHi8:N1LwF7mXpPw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=WAAfuCniHi8:N1LwF7mXpPw:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/WAAfuCniHi8" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 07 Nov 2011 12:00:19 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">97 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-2010-branding-navega%C3%A7%C3%A3o-de-topo-100-horizontal</feedburner:origLink></item>
<item>
 <title>SharePoint 2010 Branding: A master page application.master</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/6HOyRSvRLVs/sharepoint-2010-branding-master-page-applicationmaster</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Em SharePoint 2010 um pequeno número de páginas ainda usa a masterpage application.master (por exemplo: /_layouts/listkeywords.aspx). Todas as páginas que estão no sistema de ficheiros usam esta master page. Isto é um problema se que quisermos mudar os estilos destas páginas.&lt;/p&gt;
&lt;p&gt;Após alguma pesquisa descobri este &lt;a href="http://support.microsoft.com/kb/944105"&gt;artigo da Microsoft&lt;/a&gt;  que fala em um alguns métodos para modificar um ficheiro no sistema de ficheiros, e chega a recomendar um deles. Alterar ficheiros no sistema de ficheiros é um cenário não suportado pelo SharePoint. Mas se a Microsoft explica como o fazer e ainda recomenda um dos métodos, não vou perder mais tempo com o assunto.&lt;/p&gt;
&lt;p&gt;Vou tornar este processo automático fazendo a instalação da minha master page através de uma solução. Crio também uma versão de backup do ficheiro original. Em caso de desastre o ficheiro fica salvaguardado no servidor. Eis a minha solução:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-appmaster.PNG" style="width: 225px; height: 196px; " /&gt;&lt;/p&gt;
&lt;p&gt;Se o portal suportar a versão 3 do SharePoint UI, talvez precise instalar uma versão do application.master. E, como sempre, respeite o ficheiro. Não copie indiscriminadamente código de outra masterpage. Use os controlos que já lá estão. Mude o layout da mesma forma que mudaria outra masterpage qualquer.&lt;/p&gt;
&lt;p&gt;Pode também usar uma application.master alterada de forma mais apropriada e completamente suportada usando um HTTP module. Se pesquisar online certamente encontrara informação sobre como o fazer.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/oE8cIPEzQj5_5BiqeidjhmX8d-Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oE8cIPEzQj5_5BiqeidjhmX8d-Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/oE8cIPEzQj5_5BiqeidjhmX8d-Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oE8cIPEzQj5_5BiqeidjhmX8d-Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=6HOyRSvRLVs:_sKnO_tUDhA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=6HOyRSvRLVs:_sKnO_tUDhA:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=6HOyRSvRLVs:_sKnO_tUDhA:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=6HOyRSvRLVs:_sKnO_tUDhA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=6HOyRSvRLVs:_sKnO_tUDhA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=6HOyRSvRLVs:_sKnO_tUDhA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=6HOyRSvRLVs:_sKnO_tUDhA:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=6HOyRSvRLVs:_sKnO_tUDhA:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=6HOyRSvRLVs:_sKnO_tUDhA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=6HOyRSvRLVs:_sKnO_tUDhA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=6HOyRSvRLVs:_sKnO_tUDhA:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/6HOyRSvRLVs" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 31 Oct 2011 10:55:57 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">109 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-2010-branding-master-page-applicationmaster</feedburner:origLink></item>
<item>
 <title>SharePoint 2010 Branding: HTML5 masterpage para SharePoint 2010</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/XzLiD1VZOY0/sharepoint-2010-branding-html5-masterpage-para-sharepoint-2010</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;O &lt;a href="http://kyleschaeffer.com"&gt;Kyle Schaeffer&lt;/a&gt; criou uma &lt;a href="http://kyleschaeffer.com/sharepoint/v5-responsive-html5-master-page/"&gt;master page HTML5 para Sharepoint 2010&lt;/a&gt;. Estava a testar a master page e como as instruções de instalação são todas manuais (uploads de ficheiros para bibliotecas SharePoint) decidi automatizar o processo. Criei uma solução Visual Studio com todos os ficheiros e uma feature que permite activar toda a funcionalidade.&lt;/p&gt;
&lt;p&gt;A solução incluí todos os ficheiros criados pelo &lt;a href="http://kyleschaeffer.com" style="border-style: initial; border-color: initial; "&gt;Kyle Schaeffer&lt;/a&gt;, sob a licença  &lt;a href="http://creativecommons.org/licenses/by/3.0/"&gt;Creative Commons Attribution&lt;/a&gt; 3.0. A única coisa fornecida por mim é a solução, todas as instruções de instalação e a feature que activa tudo através do seu Event Receiver.&lt;/p&gt;
&lt;p&gt;Não deixe de ler o artigo completo &lt;a href="http://kyleschaeffer.com/sharepoint/v5-responsive-html5-master-page/" style="border-style: initial; border-color: initial; "&gt;V5, The Responsive HTML5 master page for SharePoint 2010&lt;/a&gt;. Há limitações importantes nesta solução.&lt;/p&gt;
&lt;p&gt;A solução ficou assim:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2020-v5-solutionfiles.PNG" style="width: 279px; height: 342px; " /&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;De relevo  é o metodo do Event Receiver que altera a masterpage activa (site e system masterpage).&lt;/p&gt;
&lt;pre class="brush:csharp;"&gt;
private void UpdateMasterPage(SPWeb web, String newMasterFileName) {
            try {                
                bool webAllowUnsafeUpdates = web.AllowUnsafeUpdates;

                web.AllowUnsafeUpdates = true;

                web.CustomMasterUrl = web.CustomMasterUrl.Replace(Path.GetFileName(web.CustomMasterUrl), newMasterFileName); // Site Masterpage
                web.MasterUrl = web.MasterUrl.Replace(Path.GetFileName(web.MasterUrl), newMasterFileName); // System Masterpage
                web.Update();

                web.AllowUnsafeUpdates = webAllowUnsafeUpdates;               
            }
            catch (Exception e) {
            }
}&lt;/pre&gt;&lt;p&gt;A feature é activada ao nível da site collection.&lt;/p&gt;
&lt;p&gt;Pode descarregar a solução Visual Studio e o ficheiro wsp pronto a instalar. Ambos estão disponíveis sob a mesma licença (&lt;a href="http://creativecommons.org/licenses/by/3.0/" style="border-style: initial; border-color: initial; border-style: initial; border-color: initial; "&gt;Creative Commons Attribution&lt;/a&gt; license 3.0) que os ficheiros originais. Veja os ficheiros anexos no fim do artigo.&lt;/p&gt;
&lt;p&gt;Bom proveito!&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/p05YxqPyQytcNL91A95ytNsJ1hA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p05YxqPyQytcNL91A95ytNsJ1hA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/p05YxqPyQytcNL91A95ytNsJ1hA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p05YxqPyQytcNL91A95ytNsJ1hA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=XzLiD1VZOY0:VI99W-RSRtc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=XzLiD1VZOY0:VI99W-RSRtc:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=XzLiD1VZOY0:VI99W-RSRtc:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=XzLiD1VZOY0:VI99W-RSRtc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=XzLiD1VZOY0:VI99W-RSRtc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=XzLiD1VZOY0:VI99W-RSRtc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=XzLiD1VZOY0:VI99W-RSRtc:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=XzLiD1VZOY0:VI99W-RSRtc:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=XzLiD1VZOY0:VI99W-RSRtc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=XzLiD1VZOY0:VI99W-RSRtc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=XzLiD1VZOY0:VI99W-RSRtc:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/XzLiD1VZOY0" height="1" width="1"/&gt;</description>
 <pubDate>Wed, 26 Oct 2011 07:00:06 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">108 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-2010-branding-html5-masterpage-para-sharepoint-2010</feedburner:origLink></item>
<item>
 <title>SharePoint 2010 Branding: Mudar as setas no menu de Site Actions e Welcome</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/O6DzR5DPhC4/sharepoint-2010-branding-mudar-setas-no-menu-de-site-actions-e-welcome</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Já se perguntou como mudar a seta nos menus de Site Actions e Welcome?&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-sa-welc-arrow-1.PNG" style="width: 380px; height: 47px; " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-sa-welc-arrow-2.PNG" style="width: 148px; height: 24px; " /&gt;&lt;/p&gt;
&lt;p&gt;Veja em baixo como pode fazê-lo. Escondendo a imagem original e dando uma imagem de background ao elemento que continha a imagem:&lt;/p&gt;
&lt;pre class="brush:css;"&gt;
.ms-viewselector-arrow {
    background: transparent url('/_layouts/images/custom/new-arrow.png') no-repeat scroll 0 0;
    height: 4px; /* height of the image */
    width: 5px; /* width of the image */
}

.ms-viewselector-arrow img {
    display: none;
}&lt;/pre&gt;&lt;p&gt;Não é uma grande alteração mas ajuda a manter a consistência do branding.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HhNoeyBk8iuo9k2_c_ov1MQ38fk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HhNoeyBk8iuo9k2_c_ov1MQ38fk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HhNoeyBk8iuo9k2_c_ov1MQ38fk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HhNoeyBk8iuo9k2_c_ov1MQ38fk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=O6DzR5DPhC4:HaO5Ki1NjzU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=O6DzR5DPhC4:HaO5Ki1NjzU:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=O6DzR5DPhC4:HaO5Ki1NjzU:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=O6DzR5DPhC4:HaO5Ki1NjzU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=O6DzR5DPhC4:HaO5Ki1NjzU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=O6DzR5DPhC4:HaO5Ki1NjzU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=O6DzR5DPhC4:HaO5Ki1NjzU:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=O6DzR5DPhC4:HaO5Ki1NjzU:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=O6DzR5DPhC4:HaO5Ki1NjzU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=O6DzR5DPhC4:HaO5Ki1NjzU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=O6DzR5DPhC4:HaO5Ki1NjzU:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/O6DzR5DPhC4" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 24 Oct 2011 14:00:00 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">102 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-2010-branding-mudar-setas-no-menu-de-site-actions-e-welcome</feedburner:origLink></item>
<item>
 <title>Oferta: IDE de PHP CodeLobster edição Profissional</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/ecEz2UF56nk/oferta-ide-de-php-codelobster-edi%C3%A7%C3%A3o-profissional</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;h3&gt;Actualização&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;O concurso terminou e já encontramos os nossos vencedores. Obrigado a todos por participarem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Temos uma oferta especial para todos os programadores de PHP. Vamos oferecer 3 licenças profissionais do IDE de PHP &lt;a href="http://www.codelobster.com/"&gt;CodeLobster&lt;/a&gt;. O CodeLobster é um editor gratuito de PHP, mas também tem uma versão Profissional com vários plugins pagos para CMSs e frameworks comuns.&lt;/p&gt;
&lt;h4&gt;Como participar&lt;/h4&gt;
&lt;p&gt;O concurso é simples: basta deixar um comentário neste artigo e daqui a duas semanas os vencedores serão escolhidos à sorte. Certifiquem-se que preencheram correctamente o vosso email quando colocarem o vosso comentário, para podermos contactá-lo se for um dos vencedores.&lt;/p&gt;
&lt;p&gt;Se for novo ao nosso site pode subscrever ao nosso &lt;a href="http://www.broculos.net/en/rss.xml"&gt;RSS feed&lt;/a&gt; e ficar a par de artigos e ofertas futuras.&lt;/p&gt;
&lt;p&gt;A acompanhar a oferta temos também uma análise ao editor CodeLobster. A CodeLobster Software foi generosa o suficiente para nos oferecer as licenças do concurso e para teste, mas a análise é da minha única responsabilidade e reflecte apenas a minha visão independente.&lt;/p&gt;
&lt;h2&gt;Análise ao editor de PHP CodeLobster&lt;/h2&gt;
&lt;h4&gt;Prós&lt;/h4&gt;
&lt;ul&gt;&lt;li&gt;Editor rápido e simples.&lt;/li&gt;
&lt;li&gt;Bons plugins para Drupal e outros CMSs e frameworks (apenas na versão Professional).&lt;/li&gt;
&lt;li&gt;Versão portável.&lt;/li&gt;
&lt;li&gt;Funcionalidades de FTP e controlo de versões.&lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt;Contras&lt;/h4&gt;
&lt;ul&gt;&lt;li&gt;Ausência de perfis (i.e. perfis diferentes por projecto - desenvolvimento, teste, produção, etc.).&lt;/li&gt;
&lt;li&gt;Suporte SVN limitado (para já).&lt;/li&gt;
&lt;li&gt;Não tem gestor de code snippets.&lt;/li&gt;
&lt;li&gt;Apenas disponível para Windows.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Editor de PHP CodeLobster&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.codelobster.com/"&gt;CodeLobster&lt;/a&gt; é um IDE de PHP para Windows. Há uma versão gratuita (para a qual precisa de se &lt;a href="http://www.codelobster.com/scripts/regform.php"&gt;registar&lt;/a&gt; ) com o suporte habitual para escrever código PHP/JS/HTML/CSS e há também uma &lt;a href="http://www.codelobster.com/order.html"&gt;versão Professional&lt;/a&gt; com plugins para CMSs e frameworks comuns.&lt;/p&gt;
&lt;p&gt;A instalação é simples. O CodeLobster pode associar-se ao sistema de ficheiros para todo o tipo de ficheiros que suporta, mas o que me chamou à atenção durante a instalação foi a possibilidade de instalar uma versão portável. É um bom pormenor que permite mover a pasta do CodeLobster para outra máquina. Se não escolher durante a instalação, pode fazê-lo mais tarde nas preferências.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_config_portable.png"&gt;&lt;img alt="CodeLobster portable preferences" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_config_portable-200x148.png" style="width: 200px; " width="200" height="148" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Depois da instalação vai reparar num ecrã de trial. Se for usar a versão gratuita tem de &lt;a href="http://www.codelobster.com/scripts/regform.php"&gt;requisitar um código&lt;/a&gt; que lhe será enviado para o email.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_splashscreen.png"&gt;&lt;img alt="CodeLobster trial screen" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_splashscreen-200x113.png" style="width: 200px; " width="200" height="113" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A primeira coisa que chama à atenção quando o editor abre é a quantidade de barras de ferramentas e janelas que estão abertas. Apesar de ser bom haver tantas, acho desnecessário estarem todas abertas.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_editor.png"&gt;&lt;img alt="CodeLobster PHP editor" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_editor-200x160.png" style="width: 200px; " width="200" height="160" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Felizmente é fácil de adaptar a interface, podendo fechar ou mover as janelas e barras de ferramentas que pretender.&lt;/p&gt;
&lt;p&gt;A ausência de um ecrã de boas-vindas é também do meu gosto. Muitos IDEs começam com uma janela de boas-vindas ou com as últimas notícias. Acho isto desnecessário, apenas quero ir directamente para o último projecto e ficheiros em que estava a trabalhar, que é o que o CodeLobster faz. No entanto, se preferir ter umas notícias quando abre o editor, tal é possível, pelo menos desde que tenha alguns plugins (estando tal no entanto desactivado por omissão).&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;O CodeLobster é em geral mais simples do que outros IDEs mais avançados como o NetBeans ou o Eclipse, que têm de suportar uma quantidade maior de linguagens e funcionalidades. Como o CodeLobster se foca em PHP e HTML/JS/CSS, torna-se mais simples e fácil de usar e também não tem de suportar funções desnecessárias.&lt;/p&gt;
&lt;p&gt;Vamos agora falar de algumas das suas funcionalidades.&lt;/p&gt;
&lt;h4&gt;Code highlighting e suporte de themes&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_config_theme.png"&gt;&lt;img alt="CodeLobster code highlighting and theme support" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_config_theme-200x148.png" style="width: 200px; " width="200" height="148" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;O CodeLobster suporta vários themes, se não gostar do que vem por omissão. Se já tiver um ficheiro aberto por detrás da janela de preferências, pode ver como um theme vai ficar, bastando para isso seleccioná-lo. Existem themes escuros e também pode desenhar o seu próprio theme.&lt;/p&gt;
&lt;p&gt;Eu usei o theme Zend for Eclipse, que tem umas cores suaves.&lt;/p&gt;
&lt;h4&gt;Autocomplete&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_autocomplete.png"&gt;&lt;img alt="CodeLobster autocomplete" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_autocomplete-200x127.png" style="width: 200px; " width="200" height="127" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A funcionalidade de autocomplete surpreendeu-me, porque detecta as chaves nos vectores!&lt;/p&gt;
&lt;h4&gt;Debugging de PHP&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_debug.png"&gt;&lt;img alt="CodeLobster PHP debugging" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_debug-200x163.png" style="width: 200px; " width="200" height="163" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Uma funcionalidade de debugging é fundamental num IDE. Neste respeito, o CodeLobster não desiludiu e foi muito fácil configurar o debugger e funcionou à primeira tentativa.&lt;/p&gt;
&lt;p&gt;Já tinha o meu servidor Apache ligado, então fui às preferências do debugger e usei a função autodetect, que funcionou muito bem.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_config_debugging.png"&gt;&lt;img alt="CodeLobster PHP debugger settings" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_config_debugging-200x148.png" style="width: 200px; " width="200" height="148" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;FTP&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_ftp.png"&gt;&lt;img alt="CodeLobster FTP" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_ftp-200x102.png" style="width: 200px; " width="200" height="102" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A maioria dos IDEs vem com suporte para FTP. O CodeLobster tem funcionalidades de download e upload por FTP.&lt;/p&gt;
&lt;p&gt;Uma das coisas que me enlouqueceu foi não ser óbvio como criar uma ligação FTP. Aparentemente, não sou o único a pensar assim e, depois de procurar nos &lt;a href="http://codelobster.com/forum/index.php"&gt;fóruns do CodeLobster&lt;/a&gt; , descobri que se configuram as ligações de FTP na janela Explorer. Não é muito intuitivo, mas pelo que sei é algo que irá mudar no futuro.&lt;/p&gt;
&lt;p&gt;Depois de criar a ligação, abra as propriedades do projecto e escolha a sua ligação. Em seguida pode usar as funcionalidades de upload e download.&lt;/p&gt;
&lt;h4&gt;Suporte de controlo de versões&lt;/h4&gt;
&lt;p&gt;O CodeLobster vem com suporte para controladores de versões. Tem suporte limitado para GIT e SVN. Eu uso o TortoiseSVN e, para já, este ainda não é suportado pelo IDE. No entanto, é algo que será adicionado em versões futuras.&lt;/p&gt;
&lt;p&gt;Se usar SVN, o IDE suporta o &lt;a href="http://sourceforge.net/projects/win32svn/"&gt;Subversion para Windows&lt;/a&gt; .&lt;/p&gt;
&lt;h4&gt;Plugins pagos&lt;/h4&gt;
&lt;p&gt;Pode adquirir plugins que adicionam suporte para vários CMSs e frameworks. Vou concentrar-me no plugin para o Drupal, mas os outros são parecidos. Vejam no &lt;a href="http://www.codelobster.com/"&gt;site oficial do CodeLobster&lt;/a&gt; mais informação sobre cada plugin.&lt;/p&gt;
&lt;p&gt;Plugins existentes:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;CakePHP plug-in&lt;/li&gt;
&lt;li&gt;CodeIgniter plug-in&lt;/li&gt;
&lt;li&gt;Drupal plug-in&lt;/li&gt;
&lt;li&gt;Facebook plug-in&lt;/li&gt;
&lt;li&gt;JQuery plug-in&lt;/li&gt;
&lt;li&gt;Joomla plug-in&lt;/li&gt;
&lt;li&gt;Smarty plug-in&lt;/li&gt;
&lt;li&gt;Symfony plug-in&lt;/li&gt;
&lt;li&gt;WordPress plug-in&lt;/li&gt;
&lt;li&gt;Yii plug-in&lt;/li&gt;
&lt;li&gt;SQL manager&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Plugin para Drupal do CodeLobster&lt;/h2&gt;
&lt;p&gt;Eu uso o Drupal, por isso foi com agrado que descobri que o CodeLobster tinha um plugin para Drupal. O plugin ajuda na criação de projectos e módulos e também traz algumas funcionalidades adicionais.&lt;/p&gt;
&lt;p&gt;Para criar um projecto Drupal existem duas opções: criar um site Drupal vazio (pode escolher a versão do Drupal e outros detalhes adicionais) ou começar com site “típico” de Drupal.&lt;/p&gt;
&lt;h4&gt;Wizard de projecto: Typical Drupal Site&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_create_project.png"&gt;&lt;img alt="CodeLobster create typical Drupal site project wizard" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_create_project-200x158.png" style="width: 200px; " width="200" height="158" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;O template Typical Drupal Site só suporta o Drupal 6 e usa actualmente a versão 6.19 do Drupal, que não é a última. Depois de criar o projecto, o site deve ser actualizado para a última versão do Drupal, que inclui várias correcções de segurança.&lt;/p&gt;
&lt;p&gt;O wizard oferece diversas opções de configuração. Algumas notas:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Tem de criar uma base de dados antes de avançar com o wizard.&lt;/li&gt;
&lt;li&gt;Certifique-se que o URL para o projecto está correcto na tab Admin ou o wizard irá falhar.&lt;/li&gt;
&lt;li&gt;Pode escolher o tipo de conteúdo que quer na tab Content.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_create_project_database.png"&gt;&lt;img alt="CodeLobster create typical Drupal site project wizard: basic" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_create_project_database-100x77.png" style="width: 100px; " width="100" height="77" /&gt;&lt;/a&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_create_project_admin.png"&gt;&lt;img alt="CodeLobster create typical Drupal site project wizard: admin" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_create_project_admin-100x77.png" style="width: 100px; " width="100" height="77" /&gt;&lt;/a&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_create_project_content.png"&gt;&lt;img alt="CodeLobster create typical Drupal site project wizard: content" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_create_project_content-100x77.png" style="width: 100px; " width="100" height="77" /&gt;&lt;/a&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_create_project_theme.png"&gt;&lt;img alt="CodeLobster create typical Drupal site project wizard: theme" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_create_project_theme-100x77.png" style="width: 100px; " width="100" height="77" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Não usaria este wizard para os meus projectos, não só porque usa o Drupal 6, mas também porque prefiro sempre fazer desenvolvimento à medida. Apesar de apreciar o facto de vir com vários módulos custom que podem ser ajustados depois de se criar o projecto.&lt;/p&gt;
&lt;h4&gt;Wizard de projecto: Empty Drupal Site&lt;/h4&gt;
&lt;p&gt;O wizard Empy Drupal Site é mais do meu agrado. Permite a escolha da versão do Drupal a instalar e, tanto quanto me apercebi, faz download da última versão a partir do site (pelo menos desde que se escolha Drupal 7), o que é bastante prático.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_create_project_empty_drupal.png"&gt;&lt;img alt="CodeLobster create empty Drupal site wizard" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_create_project_empty_drupal-200x154.png" style="width: 200px; " width="200" height="154" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;O wizard vai criar uma base de dados e um site Drupal vazio, mas pode escolher os módulos que quer activos.&lt;/p&gt;
&lt;h4&gt;Wizard para módulos Drupal&lt;/h4&gt;
&lt;h4&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_plugin_wizards.png"&gt;&lt;img alt="CodeLobster create Drupal module option" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_plugin_wizards-200x125.png" style="width: 200px; " width="200" height="125" /&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Estava à espera de encontrar o wizard quando fizesse right-click no projecto ou na pasta dos módulos, por isso demorei algum tempo até encontrar a opção no menu Plugins que se encontra no topo.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_wizard_drupal_module.png"&gt;&lt;img alt="CodeLobster create Drupal module wizard" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_wizard_drupal_module-200x154.png" style="width: 200px; " width="200" height="154" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;O wizard é uma forma rápida de criar a pasta com os ficheiros essenciais do módulo. Poupa-nos pouco tempo, mas ajuda a suavizar o processo de desenvolvimento.&lt;/p&gt;
&lt;h4&gt;Hooks para módulos Drupal e autocomplete&lt;/h4&gt;
&lt;p&gt;O plugin torna fácil a criação de hooks para os módulos.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_drupal_hooks.png"&gt;&lt;img alt="CodeLobster Drupal module hooks" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_drupal_hooks-200x110.png" style="width: 200px; " width="200" height="110" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Não apenas isso, mas também tem autocomplete para as funções de theme e dos formulários Drupal.&lt;/p&gt;
&lt;h4&gt;Ajuda de contexto&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_context_help.png"&gt;&lt;img alt="CodeLobster Drupal context help" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_context_help-200x235.png" style="width: 200px; " width="200" height="235" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A ajuda contextual vai abrir um browser com a página da API do Drupal para um método ou constante particular. Já não é preciso pesquisar no Google cada vez que quer encontrar a documentação de um método.&lt;/p&gt;
&lt;h4&gt;Encontrar uma função de menu&lt;/h4&gt;
&lt;p&gt;Outra funcionalidade que o plugin Drupal suporta é a possibilidade de encontrar uma função de menu pelo caminho ou vice-versa.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/codelobster_drupal_menu_path.png"&gt;&lt;img alt="CodeLobster Drupal find menu function" src="http://www.broculos.net/sites/default/files/resize/content/codelobster_drupal_menu_path-200x126.png" style="width: 200px; " width="200" height="126" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Conclusão&lt;/h2&gt;
&lt;p&gt;O CodeLobster é um bom e simples editor que todos os programadores de PHP devem considerar. Gosto da sua simplicidade e velocidade. Para mim, o principal problema é a falta de suporte para o TortoiseSVN, mas isso será adicionado no futuro.&lt;/p&gt;
&lt;p&gt;A minha segunda queixa é a falta de perfis para os projectos. Por exemplo, tendo um perfil de desenvolvimento onde poderia configurar a pasta local (ou ligação FTP) para copiar os ficheiros e um URL local para fazer debug ao site. Depois teria perfis para outros ambientes (teste, aceitação e produção). É sempre possível alterar as propriedades do projecto de cada vez, mas é pouco prático. Não é uma função essencial, mas seria algo que eu usaria com alguma frequência.&lt;/p&gt;
&lt;p&gt;Fora isso, vejo-me a usar o IDE mais vezes. A falta de disponibilidade para outros sistemas operativos pode afastar alguns utilizadores. A adição de um gestor de code snippets com suporte de autocomplete seria também algo bom de ter numa versão futura.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HUrXVcEX5lMGeM9cMizCYUnsgBk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HUrXVcEX5lMGeM9cMizCYUnsgBk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HUrXVcEX5lMGeM9cMizCYUnsgBk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HUrXVcEX5lMGeM9cMizCYUnsgBk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=ecEz2UF56nk:F9AurqMVZGk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=ecEz2UF56nk:F9AurqMVZGk:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=ecEz2UF56nk:F9AurqMVZGk:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=ecEz2UF56nk:F9AurqMVZGk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=ecEz2UF56nk:F9AurqMVZGk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=ecEz2UF56nk:F9AurqMVZGk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=ecEz2UF56nk:F9AurqMVZGk:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=ecEz2UF56nk:F9AurqMVZGk:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=ecEz2UF56nk:F9AurqMVZGk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=ecEz2UF56nk:F9AurqMVZGk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=ecEz2UF56nk:F9AurqMVZGk:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/ecEz2UF56nk" height="1" width="1"/&gt;</description>
 <pubDate>Sat, 22 Oct 2011 19:38:04 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">106 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/noticia/oferta-ide-de-php-codelobster-edi%C3%A7%C3%A3o-profissional</feedburner:origLink></item>
<item>
 <title>SharePoint 2010: People picker não mostra sugestões</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/xLi5TUw_VWs/sharepoint-2010-people-picker-n%C3%A3o-mostra-sugest%C3%B5es</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;O campo de people picker em SharePoint 2010 não mostra sugestões, mesmo quando aparentemente foram encontradas sugestões. Não testei isto em todos os campos possíveis, mas isto acontece sempre no Summary Links webpart quando tentamos inserir um novo link.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-peoplepicker-1.PNG" style="width: 526px; height: 450px; " /&gt;&lt;/p&gt;
&lt;p&gt;Tentei clicar como indica a mensagem de erro. Mesmo na tooltip dizia que  existiam resultados.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-peoplepicker-2.PNG" style="width: 391px; height: 91px; " /&gt;&lt;/p&gt;
&lt;p&gt;Cliquei e nada aconteceu. Desesperei, cliquei a torto e a direito até que uma combinação mágica de cliques e teclas tornou a altura do campo maior e consegui perceber o que se passava:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-peoplepicker-3.PNG" style="width: 449px; height: 184px; " /&gt;&lt;/p&gt;
&lt;p&gt;Sim... O menu estava a abrir dentro do campo, ficando obviamente invisível se o campo só tiver uma linha. Depois de inspeccionar o HTML e CSS descobri o problema, eis como o resolver:&lt;/p&gt;
&lt;pre class="brush:css;"&gt;
body div.ms-inputuserfield {
    overflow-x: visible !important;
}
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rxbW05Z88eh-wZM2N9Q9XO7o2lQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rxbW05Z88eh-wZM2N9Q9XO7o2lQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rxbW05Z88eh-wZM2N9Q9XO7o2lQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rxbW05Z88eh-wZM2N9Q9XO7o2lQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=xLi5TUw_VWs:EpIM8zULI6E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=xLi5TUw_VWs:EpIM8zULI6E:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=xLi5TUw_VWs:EpIM8zULI6E:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=xLi5TUw_VWs:EpIM8zULI6E:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=xLi5TUw_VWs:EpIM8zULI6E:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=xLi5TUw_VWs:EpIM8zULI6E:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=xLi5TUw_VWs:EpIM8zULI6E:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=xLi5TUw_VWs:EpIM8zULI6E:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=xLi5TUw_VWs:EpIM8zULI6E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=xLi5TUw_VWs:EpIM8zULI6E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=xLi5TUw_VWs:EpIM8zULI6E:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/xLi5TUw_VWs" height="1" width="1"/&gt;</description>
 <pubDate>Thu, 20 Oct 2011 14:25:02 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">104 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-2010-people-picker-n%C3%A3o-mostra-sugest%C3%B5es</feedburner:origLink></item>
<item>
 <title>Android SDK 4.0 disponível para programadores</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/F9xbS84O444/android-sdk-40-dispon%C3%ADvel-para-programadores</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;A versão unificada do Android, tanto para tablets como telemóveis, foi oficialmente anunciada hoje e o seu SDK já está disponível para programadores.&lt;/p&gt;
&lt;p&gt;A sublinhar nesta versão é a unificacão das versões 2.x e 3.x, o que vem simplificar o processo de desenvolvimento e design de aplicações. &lt;/p&gt;
&lt;p&gt;Algumas funcionalidades a salientar no SDK do Android 4.0:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Social API&lt;/strong&gt;. Foi demonstrada na apresentação através da aplicação People. O Android agora fornece a integração dos contatos com as suas actividades sociais online.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Android Beam. &lt;/strong&gt;Baseado em NFC, permite partilhar informação ou estabelecer uma ligação entre dois telemóveis, bastando aproximá-los fisicamente.&lt;/li&gt;
&lt;li&gt;Encontras mais informação no site dos &lt;a href="http://developer.android.com/sdk/android-4.0-highlights.html#DeveloperApis"&gt;Android developers&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Não percas também a apresentação do Samsung Galaxy Nexus e do Android 4.0 que lhe dá vida, &lt;a href="http://www.youtube.com/watch?v=Ts5WBm0tXzI"&gt;aqui&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4c5ml4SXa9R6TneHQyLZuHfaWkU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4c5ml4SXa9R6TneHQyLZuHfaWkU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4c5ml4SXa9R6TneHQyLZuHfaWkU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4c5ml4SXa9R6TneHQyLZuHfaWkU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=F9xbS84O444:UFGrmaO0wCk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=F9xbS84O444:UFGrmaO0wCk:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=F9xbS84O444:UFGrmaO0wCk:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=F9xbS84O444:UFGrmaO0wCk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=F9xbS84O444:UFGrmaO0wCk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=F9xbS84O444:UFGrmaO0wCk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=F9xbS84O444:UFGrmaO0wCk:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=F9xbS84O444:UFGrmaO0wCk:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=F9xbS84O444:UFGrmaO0wCk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=F9xbS84O444:UFGrmaO0wCk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=F9xbS84O444:UFGrmaO0wCk:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/F9xbS84O444" height="1" width="1"/&gt;</description>
 <pubDate>Wed, 19 Oct 2011 20:56:57 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">101 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/noticia/android-sdk-40-dispon%C3%ADvel-para-programadores</feedburner:origLink></item>
<item>
 <title>SharePoint: Como usar URLs relativos na masterpage da maneira correcta</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/pMQUG_22mjg/sharepoint-como-usar-urls-relativos-na-masterpage-da-maneira-correcta</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Descobri que tenho vindo a usar caminhos relativos de forma incorrecta nas masterpages do SharePoint. Vejamos um exemplo de como eu usava os URLs, com um link para a homepage e uma imagem para o logótipo.&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;a href="http://www.broculos.net/pt" class="logo"&amp;gt;
	&amp;lt;img src="/Style Library/CustomStyle/Images/logo.png" alt="" /&amp;gt;
&amp;lt;/a&amp;gt;&lt;/pre&gt;&lt;p&gt;Este código funciona às mil maravilhas se a raiz site collection se encontrar na raiz do URL, por exemplo: &lt;em&gt;&lt;a href="http://www.example.sp2010.dev/"&gt;http://www.example.sp2010.dev/&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Se este não for o caso, como em site collections com URLs deste tipo: &lt;em&gt;&lt;a href="http://www.example.sp2010.dev/sites/anothersitecolection/"&gt;http://www.example.sp2010.dev/sites/anothersitecolection/&lt;/a&gt;&lt;/em&gt; , o meu link vai ligar a &lt;em&gt;&lt;a href="http://www.example.sp2010.dev/"&gt;http://www.example.sp2010.dev/&lt;/a&gt;&lt;/em&gt; e a source da imagem vai estar a apontar para uma biblioteca errada. Eis como URLs relativos devem ser declarados nas masterpages:&lt;/p&gt;
&lt;pre class="brush:xml;"&gt;
&amp;lt;a href='&amp;lt;SharePoint:EncodedLiteral runat="server" text="&amp;lt;%$SPUrl:~SiteCollection/%&amp;gt;" EncodeMethod="HtmlEncode"/&amp;gt;' class="logo"&amp;gt;
	&amp;lt;img src='&amp;lt;SharePoint:EncodedLiteral runat="server" text="&amp;lt;%$SPUrl:~SiteCollection/Style Library/CustomStyle/Images/logo.png%&amp;gt;" EncodeMethod="HtmlEncode"/&amp;gt;' alt="" /&amp;gt;
&amp;lt;/a&amp;gt;&lt;/pre&gt;&lt;p&gt; &lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aTMQ4QcsPIzt0twI7uRkx1p-q7o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aTMQ4QcsPIzt0twI7uRkx1p-q7o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aTMQ4QcsPIzt0twI7uRkx1p-q7o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aTMQ4QcsPIzt0twI7uRkx1p-q7o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=pMQUG_22mjg:NZPRYlB2Eko:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=pMQUG_22mjg:NZPRYlB2Eko:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=pMQUG_22mjg:NZPRYlB2Eko:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=pMQUG_22mjg:NZPRYlB2Eko:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=pMQUG_22mjg:NZPRYlB2Eko:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=pMQUG_22mjg:NZPRYlB2Eko:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=pMQUG_22mjg:NZPRYlB2Eko:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=pMQUG_22mjg:NZPRYlB2Eko:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=pMQUG_22mjg:NZPRYlB2Eko:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=pMQUG_22mjg:NZPRYlB2Eko:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=pMQUG_22mjg:NZPRYlB2Eko:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/pMQUG_22mjg" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 17 Oct 2011 15:01:51 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">99 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-como-usar-urls-relativos-na-masterpage-da-maneira-correcta</feedburner:origLink></item>
<item>
 <title>SharePoint 2010 Branding: Caixas de pesquisa originais apenas com CSS</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/5ih7UsaOuQY/sharepoint-2010-branding-caixas-de-pesquisa-originais-apenas-com-css</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Quer fazer algo mais complexo com os estilos da caixa de texto do SharePoint usando CSS? Aqui tem um exemplo de como o fazer.&lt;/p&gt;
&lt;p&gt;A nossa caixa original:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-fancysearch-2.PNG" style="width: 241px; height: 40px; " /&gt;&lt;/p&gt;
&lt;p&gt;O resultado final:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-fancysearch-1.PNG" style="width: 358px; height: 34px; " /&gt;&lt;/p&gt;
&lt;p&gt;A ideia principal nesta implementação é colocar uma imagem com todos os elementos da pesquisa (input e botão) como fundo da área de pesquisa. Depois, ajustam-se as alturas e larguras dos elementos (input e botão) ao que temos no background. Para terminar, é apenas necessário camuflar os elementos, todas as borders e backgrounds têm de desaparecer.&lt;/p&gt;
&lt;p&gt;Para perceber melhor como isto funciona, em baixo tem o exemplo da caixa inacabada com os controlos ainda visíveis. O botão parece pequeno demais porque a imagem que contem é do tamanho que se vê, no entanto a largura do botão deve ser a mesma do background.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-fancysearch-3.PNG" style="width: 361px; height: 39px; " /&gt;&lt;/p&gt;
&lt;p&gt;Aqui esta o código que usei:&lt;/p&gt;
&lt;pre class="brush:css;"&gt;
#s4-searcharea {
    background: transparent url('/_layouts/images/custom/search-box.png') no-repeat scroll 0 0;    
    height: 30px; /* height of image */
    width: 354px; /* width of image */
}

.s4-search input.ms-sbplain {
    background: transparent;
    border-color: transparent !important;
    color: #9ca052;
    height: 23px;
    padding-left: 30px; /* to acomodate the magnifier icon */
    padding-top: 0 !important;   
    width: 247px !important;
}


#banner .ms-sbgo a {
    border-color: transparent !important;
    display: block;
    height: 30px;
    width: 70px !important;
}

#banner .ms-sbgo &amp;gt; a &amp;gt; img {
    display: none;
}&lt;/pre&gt;&lt;p&gt;Aqui ficam outros exemplos onde usei esta técnica: &lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-fancysearch-4.PNG" style="width: 299px; height: 41px; " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-fancysearch-5.PNG" style="width: 299px; height: 44px; " /&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sfE9NdB6KLAjW7PL6b7OtOgGcrw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sfE9NdB6KLAjW7PL6b7OtOgGcrw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sfE9NdB6KLAjW7PL6b7OtOgGcrw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sfE9NdB6KLAjW7PL6b7OtOgGcrw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=5ih7UsaOuQY:bsG_bsY71xo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=5ih7UsaOuQY:bsG_bsY71xo:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=5ih7UsaOuQY:bsG_bsY71xo:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=5ih7UsaOuQY:bsG_bsY71xo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=5ih7UsaOuQY:bsG_bsY71xo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=5ih7UsaOuQY:bsG_bsY71xo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=5ih7UsaOuQY:bsG_bsY71xo:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=5ih7UsaOuQY:bsG_bsY71xo:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=5ih7UsaOuQY:bsG_bsY71xo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=5ih7UsaOuQY:bsG_bsY71xo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=5ih7UsaOuQY:bsG_bsY71xo:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/5ih7UsaOuQY" height="1" width="1"/&gt;</description>
 <pubDate>Tue, 20 Sep 2011 11:30:00 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">96 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-2010-branding-caixas-de-pesquisa-originais-apenas-com-css</feedburner:origLink></item>
<item>
 <title>Como restaurar um backup de SQL Server de uma base de dados de SharePoint</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/h8Tf3zNca0c/como-restaurar-um-backup-de-sql-server-de-uma-base-de-dados-de-sharepoint</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Existem vários métodos para fazer e restaurar &lt;em&gt;backups&lt;/em&gt; de conteúdo em SharePoint. &lt;a href="http://technet.microsoft.com/en-us/library/cc671616(office.12).aspx"&gt;O próprio SharePoint oferece várias ferramentas para &lt;em&gt;backup&lt;/em&gt;/restauro&lt;/a&gt;: tanto através da interface na &lt;em&gt;Central Administration&lt;/em&gt; como através da linha de comandos com a ferramenta &lt;em&gt;STSADM&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Neste artigo vou discutir uma abordagem diferente: como restaurar um backup de SQL Server de uma base de dados de SharePoint. É comum ter um plano programado de &lt;em&gt;backups&lt;/em&gt; num SQL Server, por isso é uma boa alternativa quando os outros métodos não se encontram disponíveis.&lt;/p&gt;
&lt;p&gt;O principal problema que vão encontrar é certificarem-se que a base de dados não está a ser usada quando quiserem fazer o restauro, porque o SharePoint tem muitos processos que acedem à base de dados, mesmo quando ninguém está a visitar o site.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Parem o &lt;em&gt;Windows SharePoint Services Timer&lt;/em&gt;
&lt;ul&gt;&lt;li&gt;Vão a &lt;em&gt;Administrative Tools&lt;/em&gt; e abram &lt;em&gt;Services&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Localizem o &lt;em&gt;Windows SharePoint Services Timer&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Vão a propriedades, certifiquem-se que &lt;em&gt;Manual&lt;/em&gt; é a opção selecionada para &lt;em&gt;Startup type&lt;/em&gt; e parem o serviço.&lt;/li&gt;
&lt;li&gt;Esperem alguns minutos até que todos os processos estejam concluídos.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Terminem os processos que estejam a aceder à base de dados
&lt;ul&gt;&lt;li&gt;Abram o &lt;em&gt;SQL Server Management Studio&lt;/em&gt; e liguem-se ao servidor da base de dados.&lt;/li&gt;
&lt;li&gt;Expandam &lt;em&gt;Management&lt;/em&gt; e abram o &lt;em&gt;Activity Monitor&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Vejam que processos estão a usar a vossa base de dados e esperem que eles terminem ou terminem-os manualmente.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Executem o script para restaurar o &lt;em&gt;backup&lt;/em&gt;
&lt;ul&gt;&lt;li&gt;Abram uma nova &lt;em&gt;query&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Usem o seguinte script, que muda o modo de acesso para um utilizador de cada vez e depois reverte a mudança no final.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;pre class="brush:sql;"&gt;
USE MASTER
ALTER DATABASE [DATABASE_NAME] SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
RESTORE DATABASE [DATABASE_NAME] FROM  DISK = 'D:\PATH\Backup.bak' WITH  FILE = 1,  NOUNLOAD,  REPLACE,  STATS = 10
ALTER DATABASE [DATABASE_NAME] SET MULTI_USER WITH ROLLBACK IMMEDIATE
GO&lt;/pre&gt;&lt;p&gt;Não se esqueçam de iniciar novamente o &lt;em&gt;Windows SharePoint Services Timer&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Vão a &lt;em&gt;Administrative Tools&lt;/em&gt; e abram &lt;em&gt;Services&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Localizem o &lt;em&gt;Windows SharePoint Services Timer&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Vão a propriedades, certifiquem-se que &lt;em&gt;Automatic&lt;/em&gt; é a opção selecionada para &lt;em&gt;Startup type&lt;/em&gt; e iniciem o serviço.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GrCOl6rixDTnjCxnkXYRELOEwAI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GrCOl6rixDTnjCxnkXYRELOEwAI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GrCOl6rixDTnjCxnkXYRELOEwAI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GrCOl6rixDTnjCxnkXYRELOEwAI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=h8Tf3zNca0c:foFEOPBiDME:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=h8Tf3zNca0c:foFEOPBiDME:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=h8Tf3zNca0c:foFEOPBiDME:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=h8Tf3zNca0c:foFEOPBiDME:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=h8Tf3zNca0c:foFEOPBiDME:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=h8Tf3zNca0c:foFEOPBiDME:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=h8Tf3zNca0c:foFEOPBiDME:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=h8Tf3zNca0c:foFEOPBiDME:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=h8Tf3zNca0c:foFEOPBiDME:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=h8Tf3zNca0c:foFEOPBiDME:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=h8Tf3zNca0c:foFEOPBiDME:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/h8Tf3zNca0c" height="1" width="1"/&gt;</description>
 <pubDate>Thu, 08 Sep 2011 17:20:51 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">95 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/como-restaurar-um-backup-de-sql-server-de-uma-base-de-dados-de-sharepoint</feedburner:origLink></item>
<item>
 <title>Como saber se o JavaScript está activo a partir do servidor em C#/.NET</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/-MyX6noiF1I/como-saber-se-o-javascript-est%C3%A1-activo-partir-do-servidor-em-cnet</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;O .NET não inclui uma maneira de detectar se o JavaScript está activo a partir do servidor (é possível detectar se JavaScript é suportado, mas o utilizador poderá tê-lo desactivado). É possível fazer isto usando várias técnicas. Neste artigo vou explicar como conseguir isto usando os PageMethods do .NET.&lt;/p&gt;
&lt;h2&gt;PageMethods em .NET&lt;/h2&gt;
&lt;p&gt;PageMethods, como o nome indica, são métodos que pertencem a uma página ASP.NET, mas com uma diferença - estes métodos podem ser chamados do lado do cliente, como se se tratassem de métodos de um Web Service, mas sem ter que fazer um.&lt;/p&gt;
&lt;p&gt;Um PageMethod tem de ser declarado &lt;em&gt;public&lt;/em&gt; e &lt;em&gt;static&lt;/em&gt; e marcado com o &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.services.webmethodattribute.aspx"&gt;atributo WebMethod&lt;/a&gt;. Além disso, é preciso incluir na página um &lt;a href="http://msdn.microsoft.com/en-us/library/bb344905.aspx"&gt;ScriptManager&lt;/a&gt; que tenha a propriedade &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.enablepagemethods.aspx"&gt;EnablePageMethods&lt;/a&gt; em &lt;em&gt;true&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Esta técnica permite chamar métodos do servidor a partir do cliente, mas sem ter o trabalho de construir um Web Service - o .NET fará tudo o que é necessário nos bastidores.&lt;/p&gt;
&lt;h2&gt;Detectar se o JavaScript está activo&lt;/h2&gt;
&lt;p&gt;A ideia desta solução é usar JavaScript para chamar um método do servidor que guardará numa variável de sessão se o JavaScript está activo. Se o JavaScript não estiver activo, o método nunca será chamado, portanto saberemos que não está activo.&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;Este é o código necessário:&lt;/p&gt;
&lt;pre class="brush:csharp;"&gt;
public class DetectJavascriptPage : System.Web.UI.Page {
	protected const string JAVASCRIPT_ENABLED_KEY = "JavascriptEnabled";

	public bool IsJavascriptEnabled { get { return GetJavascriptEnabled(); } }

	protected override void OnPreRender( EventArgs e ) {
		base.OnPreRender( e );

		// Verify that the startup script isn't already registered (postbacks)
		if (!this.ClientScript.IsStartupScriptRegistered("JavascriptTest_Startup"))
		{
			// Form the script to be registered at client side.
			StringBuilder sb = new StringBuilder();
			sb.Append("&amp;lt;script lang='javascript'&amp;gt;");
			sb.Append("PageMethods.SetJavascriptEnabled(true, SetJavascriptOnSucceeded, SetJavascriptOnFailed);");
			sb.Append("function SetJavascriptOnSucceeded() { }");
			sb.Append("function SetJavascriptOnFailed(error) { }");
			sb.Append("&amp;lt;/script&amp;gt;");

			// Register the startup script
			this.ClientScript.RegisterStartupScript(typeof(JavascriptTest), "JavascriptTest_Startup", sb.ToString());
		}
	}

	[WebMethod]
	public static void SetJavascriptEnabled(bool enabled)
	{
		if (HttpContext.Current.Session[JAVASCRIPT_ENABLED_KEY] != null)
		{
			HttpContext.Current.Session[JAVASCRIPT_ENABLED_KEY] = enabled;
		}
		else
		{
			HttpContext.Current.Session.Add(JAVASCRIPT_ENABLED_KEY, enabled);
		}
	}

	[WebMethod]
	public static bool GetJavascriptEnabled()
	{
		if (HttpContext.Current.Session[JAVASCRIPT_ENABLED_KEY] != null)
		{
			return (bool)HttpContext.Current.Session[JAVASCRIPT_ENABLED_KEY];
		}

		return false;
	}
}&lt;/pre&gt;&lt;p&gt;No &lt;em&gt;pre render&lt;/em&gt; inclui-se código JavaScript que irá chamar o método da página, que por si irá definir a variável de sessão. Para saber se o JavaScript está activo ou não, só é preciso chamar a propriedade &lt;em&gt;IsJavascriptEnabled&lt;/em&gt; que foi adicionada à classe da página.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SDV_tx8AKPeCh1xOS2UEwPW9AW0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SDV_tx8AKPeCh1xOS2UEwPW9AW0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SDV_tx8AKPeCh1xOS2UEwPW9AW0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SDV_tx8AKPeCh1xOS2UEwPW9AW0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-MyX6noiF1I:uTC8QrxiAE0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-MyX6noiF1I:uTC8QrxiAE0:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=-MyX6noiF1I:uTC8QrxiAE0:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-MyX6noiF1I:uTC8QrxiAE0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-MyX6noiF1I:uTC8QrxiAE0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=-MyX6noiF1I:uTC8QrxiAE0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-MyX6noiF1I:uTC8QrxiAE0:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=-MyX6noiF1I:uTC8QrxiAE0:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-MyX6noiF1I:uTC8QrxiAE0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=-MyX6noiF1I:uTC8QrxiAE0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=-MyX6noiF1I:uTC8QrxiAE0:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/-MyX6noiF1I" height="1" width="1"/&gt;</description>
 <pubDate>Thu, 25 Aug 2011 21:35:09 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">93 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/como-saber-se-o-javascript-est%C3%A1-activo-partir-do-servidor-em-cnet</feedburner:origLink></item>
<item>
 <title>SharePoint 2010 Branding: Mostrar a zona do titulo quando a ribbon esta expandida</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/MagQfdny5Kg/sharepoint-2010-branding-mostrar-zona-do-titulo-quando-ribbon-esta-expandida</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Por defeito, quando a &lt;em&gt;ribbon &lt;/em&gt;esta expandida a zona do título desaparece por completo. Isto é algo que habitualmente os clientes não gostam, por isso é algo que necessito quase sempre corrigir.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Ribbon &lt;/em&gt;colapsada:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-showtitle-1.PNG" style="width: 700px; height: 143px; " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Ribbon &lt;/em&gt;expandida: a zona do título desapareceu:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-showtitle-2.PNG" style="width: 700px; height: 189px; " /&gt;&lt;/p&gt;
&lt;p&gt;Portanto, precisamos substituir a declaração que esconde o título.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-showtitle-3.PNG" style="width: 700px; height: 131px; " /&gt;&lt;/p&gt;
&lt;p&gt;Como fazê-lo? Adicionando esta regra ao CSS:&lt;/p&gt;
&lt;pre class="brush:css;"&gt;
#s4-titlerow { 
    display: block !important; 
}&lt;/pre&gt;&lt;p&gt;Agora a zona do título estará sempre visível.  A ribbon ao abrir-se “empurra” o título para baixo:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://broculos.net/sites/default/files/content/sp2010-showtitle-4.PNG" style="width: 700px; height: 233px; " /&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MSI3prEWrpu6u-AmM3LdRM7RPv8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MSI3prEWrpu6u-AmM3LdRM7RPv8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MSI3prEWrpu6u-AmM3LdRM7RPv8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MSI3prEWrpu6u-AmM3LdRM7RPv8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MagQfdny5Kg:Qw3NamCOxIc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MagQfdny5Kg:Qw3NamCOxIc:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=MagQfdny5Kg:Qw3NamCOxIc:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MagQfdny5Kg:Qw3NamCOxIc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MagQfdny5Kg:Qw3NamCOxIc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=MagQfdny5Kg:Qw3NamCOxIc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MagQfdny5Kg:Qw3NamCOxIc:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=MagQfdny5Kg:Qw3NamCOxIc:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MagQfdny5Kg:Qw3NamCOxIc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=MagQfdny5Kg:Qw3NamCOxIc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=MagQfdny5Kg:Qw3NamCOxIc:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/MagQfdny5Kg" height="1" width="1"/&gt;</description>
 <pubDate>Mon, 08 Aug 2011 07:00:08 +0000</pubDate>
 <dc:creator>dsilva</dc:creator>
 <guid isPermaLink="false">84 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-2010-branding-mostrar-zona-do-titulo-quando-ribbon-esta-expandida</feedburner:origLink></item>
<item>
 <title>SharePoint BDC: Criar um ADF com o BDC Definition Editor da Microsoft</title>
 <link>http://feedproxy.google.com/~r/broculospt/~3/2HneDwUtTds/sharepoint-bdc-criar-um-adf-com-o-bdc-definition-editor-da-microsoft</link>
 <description>&lt;div class="field field-name-body field-type-text-with-summary field-label-hidden"&gt;&lt;div class="field-items"&gt;&lt;div class="field-item even" property="content:encoded"&gt;&lt;p&gt;Business Data Catalog (BDC) permite-lhe integrar uma base de dados externa num ambiente SharePoint. Para fazer isso, é preciso criar um Application Definition File (ADF) e importá-lo para o SharePoint.&lt;/p&gt;
&lt;p&gt;Um ADF é basicamente um ficheiro XML com a informação necessária para descrever as entidades e métodos de acesso à base de dados. Existem algumas aplicações a pagar que ajudam a gerar os ADFs, mas a própria Microsoft fornece uma ferramente gratuita para o mesmo efeito.&lt;/p&gt;
&lt;p&gt;Neste artigo vou descrever como obter esta ferramenta e alguns incómodos que encontrei pelo caminho.&lt;/p&gt;
&lt;h2&gt;Instalar o BDC Definition Editor&lt;/h2&gt;
&lt;p&gt;O BDC Definition Editor da Microsoft está incluído no &lt;a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=79"&gt;SDK do SharePoint Server 2007&lt;/a&gt;. Depois de instalar o SDK, podem encontrar o instalador do BDC Definition Editor em &lt;em&gt;"C:\Program Files\2007 Office System Developer Resources\Tools\BDC Definition Editor"&lt;/em&gt; (por omissão).&lt;/p&gt;
&lt;p&gt;Se querem instalar o BDC Definition Editor noutra máquina, podem copiar a pasta toda e correr a instalação noutro sítio. Os ambientes suportados são Windows Server 2003 (apenas na versão En-US) e Windows XP (apenas na versão En-US). O ficheiro que têm de correr é o setup.exe. Este ficheiro assegurará que todos os requisitos estão instalados e, se não estiverem, instala-los-á:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Microsoft .NET Framework 2.0&lt;/li&gt;
&lt;li&gt;Microsoft SQL Server 2005 Express Edition&lt;/li&gt;
&lt;li&gt;Windows Installer 3.1&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;São basicamente 90MB de instalação para uma ferramenta de 2MB. Fantástico...&lt;/p&gt;
&lt;p&gt;Assim que estiver instalado, podem encontrar a ferramenta no menu inicial do Windows em &lt;em&gt;ApplicationDefinitionDesigner.exe&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Criar o Application Definition File&lt;/h2&gt;
&lt;p&gt;Não quero perder muito tempo a explicar o uso do Application Definition Designer (também conhecido por BDC Definition Editor), porque é bastante simples de usar:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Começem por adicionar um novo sistema LOB (se já tiverem um ficheiro podem importá-lo também).&lt;/li&gt;
&lt;li&gt;Escolham &lt;em&gt;Connect to Database&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Escrevam a &lt;em&gt;connection string&lt;/em&gt; (se não tiverem bem a certeza do que escrever vejam alguns &lt;a href="http://www.connectionstrings.com/sql-server-2005"&gt;exemplos de connection strings para SQL Server 2005&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Vai aparecer uma listagem de todas as tabelas. Arrastem as tabelas necessárias e façam os ajustes necessários (e.g. remover alguns campos).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/content/application_definition_editor.png" style="width: 466px; height: 451px; " width="466" height="451" /&gt;&lt;/p&gt;
&lt;p&gt;Depois deste passo, criar o ADF é bastante simples. Basta usar o botão &lt;em&gt;Export&lt;/em&gt; e gravar o ficheiro.&lt;/p&gt;
&lt;h3&gt;Método Finder para a Business Data List web part&lt;/h3&gt;
&lt;p&gt;Antes de gravarem o ficheiro, deixem-me explicar um senão. Por razões que desconheço, o Application Definition Designer não gera um método necessário para o uso da Business Data List web part. Desta forma, se importarem o ficheiro ADF no seu estado actual, irão obter o seguinte erro na Business Data List web part:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;"There are no Business Data Types loaded in the Catalog"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;O bizarro é que isto pode ser facilmente corrigido. A web part precisa de um método Finder na entidade BDC, mas este não é criado por omissão. No entanto, dois outros métodos são gerados. Um desses métodos pode ser facilmeente alterado para ser do tipo Finder, em vez de ter de criar outro método.&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div id="gam-holder-Broculos_Articles_BTF_InlineLeft_468x60" class="gam-holder"&gt;
&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleAddSlot("ca-pub-8275061180575141", "Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;script type="text/javascript"&gt;
&lt;!--//--&gt;&lt;![CDATA[// &gt;&lt;!--
GA_googleFillSlot("Broculos_Articles_BTF_InlineLeft_468x60");
//--&gt;&lt;!]]&gt;
&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;Para corrigir isto, abram o Application Definition Designer. Para cada entidade que precisam de usar na Business Data List web part:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Expandam &lt;em&gt;Methods&lt;/em&gt; &amp;gt; &lt;em&gt;FindAll_EntityName&lt;/em&gt; &amp;gt; &lt;em&gt;Instances&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Escolham a instância (&lt;em&gt;FindAll_EntityName_Instance&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Na propriedade &lt;em&gt;MethodInstanceType&lt;/em&gt; escolham &lt;em&gt;Finder&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Uma última coisa que provavelmente vão querer fazer é adicionar alguns parâmetros de saída (i.e. alguns campos adicionais). Por omissão, o método só inclui a chave primária e mais nenhum campo, o que não é muito útil.&lt;/p&gt;
&lt;h3&gt;Usar autenticação SQL&lt;/h3&gt;
&lt;p&gt;Se precisam de usar autenticação SQL, vão precisar de adicionar umas propriedades à instância do vossos sistema LOB:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Escolham a vossa instância.&lt;/li&gt;
&lt;li&gt;Certifiquem-se que &lt;em&gt;AuthenticationMode&lt;/em&gt; é igual a &lt;em&gt;PassThrough&lt;/em&gt; e &lt;em&gt;DatabaseAccessProvider&lt;/em&gt; é igual a &lt;em&gt;SqlServer&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Abram a colecção de propriedades.&lt;/li&gt;
&lt;li&gt;Adicionem os seguintes parâmetros:
&lt;ul&gt;&lt;li&gt;RdbConnection Data Source: o endereço do servidor SQL&lt;/li&gt;
&lt;li&gt;RdbConnection Initial Catalog: o nome da base de dados&lt;/li&gt;
&lt;li&gt;RdbConnection User ID: o nome de utilizador&lt;/li&gt;
&lt;li&gt;RdbConnection Password: a palavra-chave&lt;/li&gt;
&lt;li&gt;RdbConnection Integrated Security: ponham False&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/content/adf_sql_authentication_properties.png" style="width: 585px; height: 315px; " width="585" height="315" /&gt;&lt;/p&gt;
&lt;h2&gt;Importar o ADF para o SharePoint&lt;/h2&gt;
&lt;p&gt;Agora é preciso importar o ADF para o SharePoint. É bastante simples:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Abram a Central Administration.&lt;/li&gt;
&lt;li&gt;Vão ao Shared Services Provider (SSP) da vossa aplicação.&lt;/li&gt;
&lt;li&gt;Em &lt;em&gt;Business Data Catalog&lt;/em&gt; escolham &lt;em&gt;Import application definition&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Naveguem para o vosso ficheiro e importem-no.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/content/ssp_business_data_catalog.png" style="width: 227px; height: 168px; " width="227" height="168" /&gt;&lt;/p&gt;
&lt;p&gt;Assim que estiver importado, podem verificar as entidades. Algo que provavelmente precisam de mudar são as permissões de acesso ao BDC. Podem fazê-lo individualmente para cada entidade, mas é bastante mais fácil alterar para todas ao mesmo tempo:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Na página da vossa aplicação BDC escolham &lt;em&gt;Manage Permissions&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Adicionem todas as contas necessárias com a opção &lt;em&gt;Add Users/Groups&lt;/em&gt; (é comum precisarem da conta &lt;em&gt;NT AUTHORITY\Authenticated Users&lt;/em&gt; com a permissão &lt;em&gt;Select in Clients&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Agora escolham &lt;em&gt;Copy all permissions to descendants&lt;/em&gt; (isto assegurará que as permissões sejam copiadas para todas as entidades).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.broculos.net/sites/default/files/content/bdc_permissions.png"&gt;&lt;img alt="" src="http://www.broculos.net/sites/default/files/resize/content/bdc_permissions-585x99.png" style="width: 585px; height: 99px; " width="585" height="99" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Usar as Business Data Catalog web parts&lt;/h2&gt;
&lt;p&gt;Agora que importaram o ADF e configuraram a vossa aplicação BDC, podem usar as BDC web parts que o SharePoint fornece (certifiquem-se que têm as features necessárias activas).&lt;/p&gt;
&lt;p&gt;Quando adicionam uma web part, vão encontrar na categoria Business Data várias web parts para se ligarem ao vosso BDC. Uma das mais comuns é a Business Data List web part. Assim que a adicionarem, precisam de editar as suas propriedades e escolher a entidade que querem mostrar.&lt;/p&gt;
&lt;p&gt;Também podem ligar uma Business Data List web part a uma Business Data Item web part, que mostra os detalhes de uma linha da tabela apenas. Para fazerem isso, primeiro adicionem a Business Data Item web part e depois vão ao menu de edição de contexto da Business Data List web part e escolham &lt;em&gt;Connections&lt;/em&gt; &amp;gt; &lt;em&gt;Send Selected Item To&lt;/em&gt; e seleccionem a instância da Business Data Item web part. Agora quando seleccionarem uma das linhas na Business Data List web part, os detalhes vão aparecer na Business Data Item web part.&lt;/p&gt;
&lt;h2&gt;Recursos&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.zimmergren.net/archive/2009/06/25/sharepoint-bdc-part-1-getting-started-with-the-business-data-catalog.aspx"&gt;SharePoint BDC Part 1: Getting Started with the Business Data Catalog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://demiliani.com/blog/archive/2008/07/14/6488.aspx"&gt;MOSS BDC and Business Data List Web Part&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.itsallaboutsharepoint.co.uk/2010/04/22/bdc-lobsysteminstance-for-sql-database-with-sql-authentication/"&gt;BDC LobSystemInstance for SQL database with SQL Authentication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6LCtS_O7SUbOmKs4CSi5Ceqa1GA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6LCtS_O7SUbOmKs4CSi5Ceqa1GA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6LCtS_O7SUbOmKs4CSi5Ceqa1GA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6LCtS_O7SUbOmKs4CSi5Ceqa1GA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=2HneDwUtTds:liY5zZMVEWc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=2HneDwUtTds:liY5zZMVEWc:dcEpXCkpeq4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=2HneDwUtTds:liY5zZMVEWc:dcEpXCkpeq4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=2HneDwUtTds:liY5zZMVEWc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=2HneDwUtTds:liY5zZMVEWc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=2HneDwUtTds:liY5zZMVEWc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=2HneDwUtTds:liY5zZMVEWc:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=2HneDwUtTds:liY5zZMVEWc:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=2HneDwUtTds:liY5zZMVEWc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?i=2HneDwUtTds:liY5zZMVEWc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/broculospt?a=2HneDwUtTds:liY5zZMVEWc:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/broculospt?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/broculospt/~4/2HneDwUtTds" height="1" width="1"/&gt;</description>
 <pubDate>Thu, 04 Aug 2011 21:03:42 +0000</pubDate>
 <dc:creator>nunof</dc:creator>
 <guid isPermaLink="false">91 at http://www.broculos.net</guid>
<feedburner:origLink>http://www.broculos.net/pt/artigo/sharepoint-bdc-criar-um-adf-com-o-bdc-definition-editor-da-microsoft</feedburner:origLink></item>
</channel>
</rss>

