<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Pivotal Labs &#187; Joe Moore</title>
	<atom:link href="http://pivotallabs.com/author/joe/feed/" rel="self" type="application/rss+xml" />
	<link>http://pivotallabs.com</link>
	<description>Agility Developed</description>
	<lastBuildDate>Fri, 24 May 2013 05:20:56 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>How We Use tmux for Remote Pair Programming</title>
		<link>http://pivotallabs.com/how-we-use-tmux-for-remote-pair-programming/</link>
		<comments>http://pivotallabs.com/how-we-use-tmux-for-remote-pair-programming/#comments</comments>
		<pubDate>Tue, 17 Jul 2012 18:36:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[pair programming]]></category>
		<category><![CDATA[remote]]></category>
		<category><![CDATA[remote pair programming]]></category>
		<category><![CDATA[tmux]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/how-we-use-tmux-for-remote-pair-programming/</guid>
		<description><![CDATA[<p><p><strong><em>Update 07/18/2012:</strong></em> We have added tmux-vim autosaving support as a Vim plugin. It's available here: <a href="https://github.com/pivotal/tmux-config">https://github.com/pivotal/tmux-config</a></p>

<p><strong><em>Update 07/20/2012:</strong></em> There is a <a href="http://news.ycombinator.com/item?id=4260090">lively discussion on Hacker News</a> about this post in addition to the comments below. </p>

<p><a href="http://tmux.sourceforge.net/">tmux</a> is the cool kid on the block for remote pair programming, as long as you are using a terminal based editor such as Vim or Emacs.</p>

<p>There is <a href="https://www.google.com/webhp?sourceid=chrome-instant&#38;ie=UTF-8#hl=en&#38;output=search&#38;sclient=psy-ab&#38;q=tmux%20tutorial&#38;oq=&#38;gs_l=&#38;pbx=1&#38;fp=45c3b9a0a6db80f8&#38;bav=on.2,or.r_gc.r_pw.r_cp.r_qf.,cf.osb&#38;biw=1110&#38;bih=825">no shortage of tutorials and guides regarding how to use tmux</a>, thus my only introduction to tmux will be this: tmux is a terminal multiplexer and supports shared terminal usage.</p>

<p>Our large software project used tmux regularly for remote pair programming and settled on a configuration that has worked well for our team. Read on to learn about tmux's advantages and disadvantages vs. desktop screen sharing, why and how we used it, and how we addressed the many challenges of remote pairing using tmux.</p> <a href="http://pivotallabs.com/how-we-use-tmux-for-remote-pair-programming/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/how-we-use-tmux-for-remote-pair-programming/">How We Use tmux for Remote Pair Programming</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><strong><em>Update 07/18/2012:</strong></em> We have added tmux-vim autosaving support as a Vim plugin. It&#8217;s available here: <a href="https://github.com/pivotal/tmux-config">https://github.com/pivotal/tmux-config</a></p>
<p><strong><em>Update 07/20/2012:</strong></em> There is a <a href="http://news.ycombinator.com/item?id=4260090">lively discussion on Hacker News</a> about this post in addition to the comments below. </p>
<p><a href="http://tmux.sourceforge.net/">tmux</a> is the cool kid on the block for remote pair programming, as long as you are using a terminal based editor such as Vim or Emacs.</p>
<p>There is <a href="https://www.google.com/webhp?sourceid=chrome-instant&amp;ie=UTF-8#hl=en&amp;output=search&amp;sclient=psy-ab&amp;q=tmux%20tutorial&amp;oq=&amp;gs_l=&amp;pbx=1&amp;fp=45c3b9a0a6db80f8&amp;bav=on.2,or.r_gc.r_pw.r_cp.r_qf.,cf.osb&amp;biw=1110&amp;bih=825">no shortage of tutorials and guides regarding how to use tmux</a>, thus my only introduction to tmux will be this: tmux is a terminal multiplexer and supports shared terminal usage.</p>
<p>Our large software project used tmux regularly for remote pair programming and settled on a configuration that has worked well for our team. Read on to learn about tmux&#8217;s advantages and disadvantages vs. desktop screen sharing, why and how we used it, and how we addressed the many challenges of remote pairing using tmux.</p>
<h2>Advantages vs. Desktop Screen Sharing</h2>
<ul>
<li><strong>Fast!</strong> tmux has the least latency of any collaborative code editing we have used</li>
<li><strong>Addictive usage model:</strong> tmux&#8217;s multiple terminal pane usage model is very handy in general. Some of us now use tmux even when we are not remote pairing</li>
<li><strong>No extra heavyweight software:</strong> if you have tmux and <code>ssh</code> access you&#8217;re good to go</li>
</ul>
<h2>Disadvantages vs. Desktop Screen Sharing</h2>
<ul>
<li><strong>Requires <code>ssh</code></strong> access and thus possibly a VPN</li>
<li><strong>Extra overhead</strong> of learning and using tmux commands</li>
<li><strong>Lack of desktop friendly UX</strong>, such as mouse support, function keys,  ⌘ key</li>
<li><strong>Only for terminal based editors</strong>, such as Vim and Emacs</li>
<li>Might <strong>still need desktop screen sharing</strong> for GUI-based tools and tasks: shared web browser for web development, etc.</li>
</ul>
<h2>Why We Used It for Remote Pairing</h2>
<p>Due to network latency GUI-based desktop screen sharing was intolerably slow for coding. tmux made network latency a non issue. My personal experience was that tmux + Vim was so fast when working remotely that it was usually indistinguishable from coding locally.</p>
<h2>Monitor Setup</h2>
<p>We use two monitors: the iMac&#8217;s main 27&#8243; monitor and a large &#40;usually at least 24&#8243;&#41; LCD rotated vertically.</p>
<p>We usually had <a href="http://iterm.sourceforge.net/">iTerm</a> running a shared tmux session on the large 27&#8243; display and a desktop screen sharing session on the vertical display. The vertical display usually had the shared web browser visible since we were usually doing web development.</p>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/setup_1.jpg?48a6bc" alt="" /></p>
<h1>Challenges and How We Addressed Them</h1>
<p>Most of our in-office developers only used tmux when remote pairing: the majority of their development was in-person pair programming using <a href="http://code.google.com/p/macvim/">MacVim</a> and &#8220;normal&#8221; tabbed <a href="http://iterm.sourceforge.net/">iTerm</a>. The occasional switch to terminal-based Vim within tmux and a bunch of tmux terminal panes was the most challenging aspect of using tmux as part of our development stack. The major difference were:</p>
<ul>
<li>Automatic saving within MacVim was lost</li>
<li>No mouse support</li>
<li>Scrolling onerous in tmux</li>
<li>Copy-paste actions onerous in tmux</li>
<li>MacVim keymapping not fully supported in terminal Vim</li>
<li>Learning tmux specific commands</li>
</ul>
<p>Read on to see how &#40;or if&#41; we addressed the above challenges.</p>
<h2>Automatic Saving</h2>
<p>Once you have automatic saving it&#8217;s tough to give it up. Our buffers automatically saved whenever MacVim lost focus. After quite a bit of work we were able to add automatic Vim saving support within tmux. It&#8217;s not as good as MacVim&#8217;s autosave, but it&#8217;s pretty close. <strike>Please see <a href="https://github.com/pivotal/vim-config/pull/9">this Github pull request</a> for how to set up automatic saving. <em>&#40;Note, I&#8217;ll update this post as the pull request progresses.&#41;</em></strike></p>
<p><strong><em>Update 07/18/2012:</strong></em> Our tmux-vim automatic saving Vim plugin is available here: <a href="https://github.com/pivotal/tmux-config">https://github.com/pivotal/tmux-config</a>. We&#8217;ve also integrated it into our vim-config configuration here: <a href="https://github.com/pivotal/vim-config">https://github.com/pivotal/vim-config</a>.</p>
<h2>Mouse Support</h2>
<p>By default tmux has very little mouse support. We enabled significant mouse support within iTerm by customizing our <code>.tmux.conf</code>:</p>
<ul>
<li>Selecting tmux panes</li>
<li>Resizing tmux panes</li>
<li>Scrolling</li>
</ul>
<p><a href="https://github.com/Casecommons/casecommons_workstation/blob/master/templates/default/dot_tmux.conf.erb">See this <code>.tmux.conf</code> template for more</a>, but here&#8217;s the interesting section:</p>
<pre><code> # ~/.tmux.conf
 # Enable mouse support &#40;works in iTerm&#41;
 set-window-option -g mode-mouse on
 set-option -g mouse-select-pane on
 set-option -g mouse-resize-pane on
 set-option -g mouse-select-window on
</code></pre>
<p>Note that iTerm supports this configuration. We cannot vouch for Mac&#8217;s Terminal application&#8217;s level of mouse support.</p>
<h2>OS-Level Copy-Paste</h2>
<p>Highlighting with the mouse triggers tmux&#8217;s text selection, which is <em>not</em> OS X&#8217;s highlighting, and thus ⌘+c will not copy the highlighted text. Though we never fully solved this issue there is a workaround: hold down the ⌥ key &#40;ALT/Option&#41; while highlighting to trigger OS X&#8217;s selection &#8212; ⌘+c will now copy the text.</p>
<h4>tmux selection &#8212; OS X will not copy this</h4>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/tmux_highlight.jpg?48a6bc" alt="" /></p>
<h4>Holding ⌥ &#8212; OS X will copy this!</h4>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/altkey.jpg?48a6bc" alt="" /></p>
<p>Unfortunately this technique does not respect tmux&#8217;s panes and will select across the entire screen, but it&#8217;s better than nothing.</p>
<h2>MacVim vs. Terminal Vim Keybindings</h2>
<p>Why did MacVim and Vim have different keybindings if both use the <code>~/.vimrc</code> file? The answer is the ⌘ key. To ease the transition from RubyMine and TextMate to MacVim we mapped many common ⌘-based keybinding which were unavailable in terminal-based Vim. My personal advice is to stay away from the  ⌘ key if your team uses both MacVim and terminal Vim, but if that&#8217;s not possible at least make an extra <code>&lt;leader&gt; KEY</code> mapping for everything that uses ⌘.</p>
<p>Take a look at <a href="https://github.com/Casecommons/vim-config">our sophisticated <code>~/.vimrc</code></a> setup, including the <a href="https://github.com/Casecommons/vim-config/blob/master/init/keybindings.vim">keybindings file</a>, where ⌘ bindings are paired with non- ⌘ keybindings.</p>
<h2>Learning tmux-Specific Commands</h2>
<p>There&#8217;s no way around this one. Though mouse support means one can avoid the tmux-pane selection and scrolling commands I highly recommend learning tmux well if you are using it consistently.</p>
<p>In practice we only use a handful of tmux commands often:</p>
<ul>
<li><code>CTL+b %</code> &#8211; new <strong><em>vertical</strong></em> split</li>
<li><code>CTL+b "</code> &#8211; new <strong><em>horizontal</strong></em> split</li>
<li><code>CTL+b o</code> &#8211; switch to <strong><em>other</strong></em> pane. Repeat to cycle through.</li>
<li><code>CTL+b c</code> &#8211; <strong><em>create</strong></em> new tmux tab/window</li>
<li><code>CTL+b n/p/l</code> &#8211; switch to <strong><em>next</strong></em>, <strong><em>previous</strong></em>, or <strong><em>last</strong></em> tmux tab/windows</li>
<li><code>CTL+b [</code> &#8211; Enter <strong><em>scroll/copy mode</strong></em></li>
</ul>
<p>Here are a couple of fun ones: </p>
<ul>
<li><code>CTL+b SPACE</code> &#8211; <strong><em>change arrangement</strong></em> of panes. Repeat to cycle through various arrangements.</li>
<li><code>CTL+b w</code> &#8211; <strong><em>list</strong></em> tmux tabs/windows</li>
<li><code>CTL+b ,</code> &#8211; <strong><em>rename</strong></em> tmux tab/window</li>
</ul>
<p>Once your team gets the hang of it they might even prefer the multiple tmux-pane workflow to a multi-app, multi-tab setup.</p>
<h1>It&#8217;s a Fast Paced World</h1>
<p>With such a plethora of remote pairing software and configurations it&#8217;s impossible to keep up. We would love to hear about your own experiences remote pairing with tmux and how you might improve upon our own techniques and configurations.  Please post comments and let us know what you think.</p>
<p>The post <a href="http://pivotallabs.com/how-we-use-tmux-for-remote-pair-programming/">How We Use tmux for Remote Pair Programming</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/how-we-use-tmux-for-remote-pair-programming/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Integrating Remote Developers: Intuitive, Flexible Video Conferencing</title>
		<link>http://pivotallabs.com/integrating-remote-developers-foolproof-audio-setups/</link>
		<comments>http://pivotallabs.com/integrating-remote-developers-foolproof-audio-setups/#comments</comments>
		<pubDate>Fri, 13 Jul 2012 19:39:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[remote]]></category>
		<category><![CDATA[remote pair programming]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/integrating-remote-developers-foolproof-audio-setups/</guid>
		<description><![CDATA[<p><p>I recently blogged about about <a href="https://pivotallabs.com/users/joe/blog/articles/2191-integrating-remote-developers-into-large-teams">integrating remote developers with large development teams</a>. An important but finicky part of bridging the gap between remote developers and the rest of the team is video conferencing.</p>

<p>How hard can this be? It's Skype, right? While most techies know how to use Skype to make video calls, the difficulty is managing headsets, external microphones, external speakers, and switching between all of these frequently throughout the day. Despite what Apple might tell you, it does not "just work", especially Skype, which has a particularly baffling user interface.</p>

<p>Early in our large project's history the following scene played out frequently:</p>

<ol>
<li>Office developer sits down at a workstation and Skype's a remote developer.</li>
<li><strong><em>They can't hear each other!</strong></em></li>
<li>Office developer finds headset is unplugged, plugs it in to Skype laptop.</li>
<li><strong><em>Still can't hear!</strong></em></li>
<li>Office dev opens the Mac sound preferences, clicks around a bit.</li>
<li><strong><em>Still can't hear!</strong></em></li>
<li>Office dev dives into Skype sound preferences… Ah-ha! Select headset.</li>
<li><strong><em>Still can't hear!</strong></em></li>
<li>Remote developer starts messing with his own preferences, settings, cords…</li>
<li><strong><em>Bingo!</strong></em> Finally, they can hear each other, but suddenly…</li>
<li>Someone in the office needs to talk to both developers.</li>
<li>Office dev starts changing audio settings again, plugging/unplugging stuff…</li>
<li>After several minutes a group conversation can be held.</li>
<li>Group conversation is over. <strong><em>Go to Step 1.</strong></em></li>
</ol>

<h2>The Need: Intuitive, Flexible Video Conferencing</h2>

<p>Actually, it's mostly about the audio: the video usually works fine. We needed a means to easily switch between pairing-mode and group-conversation-mode -- that is, between headphones + mic and external speakers + external mic. Above all else we wanted to avoid constantly changing software preferences. We needed something as easy as pressing a button or plugging/unplugging a single jack.</p>

<p>So far we have found two solutions that work well:</p>

<ul>
<li>Solution 1: External Speakers with Headphone Input: An external microphone, external speakers <strong><em>with a headphone jack</strong></em>, and regular "music" headphones.</li>
<li>Solution 2: Seamless USB Audio Input Switching for Skype: An external microphone, external speakers, a USB headset, and <strong><em>a bit of special Mac and Skype configuration</strong></em>.</li>
</ul>

<p>Read on for more details.</p> <a href="http://pivotallabs.com/integrating-remote-developers-foolproof-audio-setups/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/integrating-remote-developers-foolproof-audio-setups/">Integrating Remote Developers: Intuitive, Flexible Video Conferencing</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>I recently blogged about about <a href="https://pivotallabs.com/users/joe/blog/articles/2191-integrating-remote-developers-into-large-teams">integrating remote developers with large development teams</a>. An important but finicky part of bridging the gap between remote developers and the rest of the team is video conferencing.</p>
<p>How hard can this be? It&#8217;s Skype, right? While most techies know how to use Skype to make video calls, the difficulty is managing headsets, external microphones, external speakers, and switching between all of these frequently throughout the day. Despite what Apple might tell you, it does not &#8220;just work&#8221;, especially Skype, which has a particularly baffling user interface.</p>
<p>Early in our large project&#8217;s history the following scene played out frequently:</p>
<ol>
<li>Office developer sits down at a workstation and Skype&#8217;s a remote developer.</li>
<li><strong><em>They can&#8217;t hear each other!</strong></em></li>
<li>Office developer finds headset is unplugged, plugs it in to Skype laptop.</li>
<li><strong><em>Still can&#8217;t hear!</strong></em></li>
<li>Office dev opens the Mac sound preferences, clicks around a bit.</li>
<li><strong><em>Still can&#8217;t hear!</strong></em></li>
<li>Office dev dives into Skype sound preferences… Ah-ha! Select headset.</li>
<li><strong><em>Still can&#8217;t hear!</strong></em></li>
<li>Remote developer starts messing with his own preferences, settings, cords…</li>
<li><strong><em>Bingo!</strong></em> Finally, they can hear each other, but suddenly…</li>
<li>Someone in the office needs to talk to both developers.</li>
<li>Office dev starts changing audio settings again, plugging/unplugging stuff…</li>
<li>After several minutes a group conversation can be held.</li>
<li>Group conversation is over. <strong><em>Go to Step 1.</strong></em></li>
</ol>
<h2>The Need: Intuitive, Flexible Video Conferencing</h2>
<p>Actually, it&#8217;s mostly about the audio: the video usually works fine. We needed a means to easily switch between pairing-mode and group-conversation-mode &#8212; that is, between headphones + mic and external speakers + external mic. Above all else we wanted to avoid constantly changing software preferences. We needed something as easy as pressing a button or plugging/unplugging a single jack.</p>
<p>So far we have found two solutions that work well:</p>
<ul>
<li>Solution 1: External Speakers with Headphone Input: An external microphone, external speakers <strong><em>with a headphone jack</strong></em>, and regular &#8220;music&#8221; headphones.</li>
<li>Solution 2: Seamless USB Audio Input Switching for Skype: An external microphone, external speakers, a USB headset, and <strong><em>a bit of special Mac and Skype configuration</strong></em>.</li>
</ul>
<p>Read on for more details.</p>
<h2>Solution 1: External Speakers with Headphone Input</h2>
<p>This solution relies upon a high quality external USB mic for both pairing and group conversations. Personally this worked fine for me &#8212; the background noise in the office was actually useful, not overwhelming, and I enjoyed hearing bits of the conversations going on in the office. Others might find the background noise annoying.</p>
<ol>
<li>
<p>Connect a high quality external mic &#40;such as a Blue Snowball&#41; and external speakers to the Skype machine. The speakers <strong><em>must have an external headphone jack.</strong></em></p>
<p><img title="" src="http://assets.pivotallabs.com/1468/original/av1.jpeg" alt="" /></p>
</li>
<li>
<p>Configure the Mac and Skype to use the Snowball mic</p>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/mac_audio.png?48a6bc" alt="" /></p>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/skype_audio.png?48a6bc" alt="" /></p>
</li>
<li>
<p><strong><em>When pair programming:</strong></em> plug your headphones of choice into headphone jack on speakers</p>
<p><img title="" src="http://assets.pivotallabs.com/1470/original/av3.jpeg" alt="" /></p>
</li>
<li>
<p><strong><em>For group conversations:</strong></em> unplug headphones. Voilà! Speakers will be live.</p>
<p><img title="" src="http://assets.pivotallabs.com/1471/original/av4.jpeg" alt="" /></p>
</li>
</ol>
<p>That&#8217;s it! Toggling between pairing and group conversations is as easy as unplugging the headphones.</p>
<h3>Pros</h3>
<ul>
<li>Simple setup</li>
<li>Intuitive to use</li>
<li>Uses external mic rather than headset mic &#8211; remote can hear background conversations</li>
</ul>
<h3>Cons</h3>
<ul>
<li>Uses external mic rather than headset mic &#8211; background noise possibly an issue.</li>
<li>Sharing in-ear headphones/earbuds is icky. People should probably use personal headphones.</li>
</ul>
<hr />
<h2>Solution 2: Seamless USB Audio Input Switching for Skype</h2>
<p>For a normal remote pairing scenario the computer&#8217;s audio priorities <strong><em>should</strong></em> be as follows:</p>
<ol>
<li>Headset microphone, headset headphones: remote pair programming.</li>
<li>External microphone, external speakers: group conversations including remote developer.</li>
<li>Internal microphone, internal speakers: default, no extra hardware.</li>
</ol>
<p>Managing this audio setup would be as easy as plugging and unplugging your USB headset. When pairing with a remote developer, plug in the headset for a quiet, private pairing experience. When a group of people arrives at your desk and need to speak with both you and the remote developer, simply unplug the headset to activate the external hardware. When the group conversation is over, plug the headset back in.</p>
<p>Simple. Intuitive. Low-overhead.</p>
<p>Unfortunately, your computer doesn&#8217;t know about these priorities. Also, Skype has its own audio input/output settings independent from the computer&#8217;s OS-controlled settings.</p>
<p>Luckily both the Mac OS and Skype are &#8220;trainable&#8221; and will respect the above priorities if you know how to teach them. Note that Skype takes a &#8220;hint&#8221; from your Mac on how to switch inputs and outputs. Thus, we must train them both at the same time. Here&#8217;s how:</p>
<ol>
<li>
<p>Open <strong><em>both</strong></em> the Mac <em>Sound</em> System Preferences and Skype&#8217;s Audio/Video preferences. No external Audio devices should be detected.</p>
<p><a href="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/1.png?48a6bc" title=""><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/1_small.png?48a6bc" alt="" /></a></p>
<p><em>&#40;Click for a larger image&#41;</em></p>
</li>
<li>
<p>Plug in the external mic. Once it is detected by both the Mac and Skype <strong><em>select the mic in both Mac and Skype preferences</strong></em>.</p>
<p><a href="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/2.png?48a6bc" title=""><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/2_small.png?48a6bc" alt="" /></a></p>
<p><em>&#40;Click for a larger image&#41;</em></p>
<p>Before continuing, <em>Close, then reopen the Skype Audio/Video preferences.</em> You know, just to make sure it sticks.</p>
</li>
<li>
<p>Plug in your USB headset. Once it is detected by both the Mac and Skype <strong><em>select the headset in both Mac and Skype preferences</strong></em>.</p>
<p><a href="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/3.png?48a6bc" title="Click for a larger image"><img title="Click for a larger image" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/3_small.png?48a6bc" alt="" /></a></p>
<p><em>&#40;Click for a larger image&#41;</em></p>
<p><em>Close, then reopen the Skype Audio/Video preferences.</em> Is this needed? I don&#8217;t know… maybe. It&#8217;s Skype.</p>
</li>
<li>
<p>Test the configuration: Unplug your USB Headset. Skype and your Mac <strong><em>should automatically switch to using the external mic</strong></em>. Plug the USB headset in again. Skype and your Mac <strong><em>should automatically switch to using the USB headset</strong></em> again.</p>
<p><a href="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/4.png?48a6bc" title=""><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/41.png?48a6bc" alt="" /></a></p>
<p><em>&#40;Click for a larger image&#41;</em></p>
<p>If it didn&#8217;t work, unplug everything, quit System Preferences and Skype, and start over.</p>
</li>
</ol>
<p>Overall this is my preferred audio setup, though it takes a couple of minutes to set up and can be confusing the first time. But, once it&#8217;s set up, the configuration is usually solid and you rarely have to touch it again. Also, unlike the headphones-jacked-into-speakers technique, the headset mic is fully utilized for the best audio quality. You can also plug external speakers into the computer&#8217;s headphone jack without confusing the computer or Skype.</p>
<h3>Pros:</h3>
<ul>
<li>Intuitive to use</li>
<li>Highest audio quality for both developers</li>
<li>No configuration changes after the first time</li>
</ul>
<h3>Cons</h3>
<ul>
<li>Confusing &#8220;training&#8221; process</li>
<li>New audio hardware might require re-training of Mac and Skype</li>
</ul>
<h2>What Do You Use?</h2>
<p>Do you use a cool A/V setup? Tell us about it! We love to try new things. We&#8217;re still on a quest to find the best iPad-based A/V configuration. With any luck we&#8217;ll report back on that soon.</p>
<p>The post <a href="http://pivotallabs.com/integrating-remote-developers-foolproof-audio-setups/">Integrating Remote Developers: Intuitive, Flexible Video Conferencing</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/integrating-remote-developers-foolproof-audio-setups/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Pair Programming Matrix</title>
		<link>http://pivotallabs.com/pair-programming-matrix/</link>
		<comments>http://pivotallabs.com/pair-programming-matrix/#comments</comments>
		<pubDate>Thu, 12 Jul 2012 22:20:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[pair programming]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/pair-programming-matrix/</guid>
		<description><![CDATA[<p><p><em>&#40;Update 07/17/2012: Added link to <a href="https://docs.google.com/spreadsheet/ccc?key=0AkuIWCNse5R5dFVHR1ZHZTF6VmdlUzhJa1NGbGRzOEE">Pair Programming Matrix Google Doc</a>&#41;</em></p>

<p>At Pivotal Labs we consider ourselves to be expert pair programmers, but sometimes even we need help. We identified &#40;thanks to a <a href="http://retrospectivewiki.org/index.php?title=Main_Page" title="Main Page - Agile Retrospective Resource Wiki">retrospective</a>&#41; that we were being very unbalanced in our pairings: some developers seemed to pair with each other often while rarely paring with others. We wanted a lightweight means of enforcing balanced pairing. That's when someone remembered the pairing matrix.</p> <a href="http://pivotallabs.com/pair-programming-matrix/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/pair-programming-matrix/">Pair Programming Matrix</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><em>&#40;Update 07/17/2012: Added link to <a href="https://docs.google.com/spreadsheet/ccc?key=0AkuIWCNse5R5dFVHR1ZHZTF6VmdlUzhJa1NGbGRzOEE">Pair Programming Matrix Google Doc</a>&#41;</em></p>
<p>At Pivotal Labs we consider ourselves to be expert pair programmers, but sometimes even we need help. We identified &#40;thanks to a <a href="http://retrospectivewiki.org/index.php?title=Main_Page" title="Main Page - Agile Retrospective Resource Wiki">retrospective</a>&#41; that we were being very unbalanced in our pairings: some developers seemed to pair with each other often while rarely paring with others. We wanted a lightweight means of enforcing balanced pairing. That&#8217;s when someone remembered the pairing matrix.</p>
<h1>Pair Programming Matrix</h1>
<p>A blog post titled <a href="http://alaverdyan.com/readme/2010/12/pair-programming-matrix-board/" title="Pair Programming Matrix / Board | An Agile ReadMe">&#8220;Pair Programming Matrix&#8221;</a> inspired us to try our own pairing matrix. It&#8217;s a grid with a cell intersecting each pair of developers. Here&#8217;s a photo from the original article:</p>
<p><a href="http://alaverdyan.com/readme/2010/12/pair-programming-matrix-board/" title="Pair Programming Matrix / Board | An Agile ReadMe"><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/matrix_original.jpg?48a6bc" alt="" /></a></p>
<p>We thought we would give it a try, only using a Google Spreadsheet with some fancy conditional formatting instead of a whiteboard</p>
<h2>Upshot</h2>
<p>Overall the pairing matrix serves it purpose: it helps us have much more balanced pairings. We&#8217;ve been using it for several months and will likely continue using it so long as it seems useful.</p>
<p>It strikes me that a pairing matrix would be a good way for team new to pair programming to add a bit of helpful structure. I would hesitate to add this structure if it&#8217;s unneeded: &#8220;if it ain&#8217;t broke, don&#8217;t fix it.&#8221;</p>
<h2>Pros</h2>
<ul>
<li>Exposes &#8220;holes&#8221; and &#8220;hot spots&#8221; when developers are not pairing together or pairing too often</li>
<li>Easy to use, reset</li>
<li>Can be a simple way for teams new to pairing to get started</li>
</ul>
<h2>Cons</h2>
<ul>
<li>Time off skews the matrix</li>
<li>Does not work well when team structure fluctuates often</li>
<li>Becomes unwieldily with larger teams</li>
</ul>
<h1>Examples</h1>
<p>Here are some screenshots of pairing matrices at different stages. Team structures changed and thus the featured developers were not always the same, but you get the idea.</p>
<h3>Early in the process. We already have a hot spot!</h3>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/matrix_mid1_copy.png?48a6bc" alt="" /></p>
<h3>Pairings are starting to even out.</h3>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/matrix_mid_2_copy.png?48a6bc" alt="" /></p>
<h3>Over time we were much more balanced.</h3>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/matrix_early_copy.png?48a6bc" alt="" /></p>
<h3>Eventually we needed to reset.</h3>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/matrix_late_copy.png?48a6bc" alt="" /></p>
<h3>Too big!! We abandoned this and made the team smaller.</h3>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/matrix_huge_copy.png?48a6bc" alt="" /></p>
<h2>Make Your Own Matrix</h2>
<p>By popular demand, I have made a blank, read-only copy of our pairing matrix, complete with conditional formatting. Feel free to duplicate it and modify the copy. Please post your own modifications and optimizations in the comments. </p>
<p><strong>Link:</strong> <strong><a href="https://docs.google.com/spreadsheet/ccc?key=0AkuIWCNse5R5dFVHR1ZHZTF6VmdlUzhJa1NGbGRzOEE">Pair Programming Matrix Google Doc</a></strong></p>
<p><a href="https://docs.google.com/spreadsheet/ccc?key=0AkuIWCNse5R5dFVHR1ZHZTF6VmdlUzhJa1NGbGRzOEE"><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/pair_programming_matrix.jpg?48a6bc" alt="" /></a></p>
<p>The post <a href="http://pivotallabs.com/pair-programming-matrix/">Pair Programming Matrix</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/pair-programming-matrix/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Integrating Remote Developers into Large Teams</title>
		<link>http://pivotallabs.com/integrating-remote-developers-with-a-large-team/</link>
		<comments>http://pivotallabs.com/integrating-remote-developers-with-a-large-team/#comments</comments>
		<pubDate>Thu, 12 Jul 2012 20:15:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[pair programming]]></category>
		<category><![CDATA[remote]]></category>
		<category><![CDATA[remote pair programming]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/integrating-remote-developers-with-a-large-team/</guid>
		<description><![CDATA[<p><p>I'm obsessed with remote pair programming and remote collaboration. <a href="https://pivotallabs.com/talks/143-remote-pair-programming-people-and-technology">I've even given tech talks about remote pair programming</a>. Most teams with which I've worked remotely are small -- usually around four to six team members total -- but for the past 10 months I have remote paired on a project of up to 30 developers. While the majority of the team was co-located in our NYC office, five of us were remote. Over that time we have tried many different remote collaboration and pairing setups and feel we've settled on a configuration that supports daily pair rotation with minimum overhead.</p> <a href="http://pivotallabs.com/integrating-remote-developers-with-a-large-team/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/integrating-remote-developers-with-a-large-team/">Integrating Remote Developers into Large Teams</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m obsessed with remote pair programming and remote collaboration. <a href="https://pivotallabs.com/talks/143-remote-pair-programming-people-and-technology">I&#8217;ve even given tech talks about remote pair programming</a>. Most teams with which I&#8217;ve worked remotely are small &#8212; usually around four to six team members total &#8212; but for the past 10 months I have remote paired on a project of up to 30 developers. While the majority of the team was co-located in our NYC office, five of us were remote. Over that time we have tried many different remote collaboration and pairing setups and feel we&#8217;ve settled on a configuration that supports daily pair rotation with minimum overhead.</p>
<h1>Daily Standup Meetings</h1>
<p>We set up a team Skype account and paid for <a href="http://www.skype.com/intl/en-us/features/allfeatures/group-video-calls/" title="Group Video Chat Online - Group Video Calling - 3 Way Chat - Skype">Skype group video</a>. Each morning the team would gather for standup in a large conference room and call us from the group video account.</p>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/standup_med.png?48a6bc" alt="" /></p>
<p>It can be difficult for the remote members to hear everyone in such a large room. We used a <a href="http://www.bluemic.com/snowball/" title="Blue Microphones | Snowball - The World's First Professional USB Mic">Blue Snowball mic</a> to aid with this, and it worked well so long as nobody unplugged it.</p>
<p>We had a team whiteboard where we would list technical tips, tricks, and cries for help. Every day someone would send the group a photo of the board. I&#8217;m sure we could have come up with a more technical solution but this has worked well for us, though it does take some extra effort.</p>
<p><img title="" src="http://assets.pivotallabs.com/1478/original/standup.jpeg" alt="" /></p>
<p>If remote team members had items for the standup board they would simply speak up towards the end of the meeting; a scribe was taking notes and emailed them to everyone afterwards.</p>
<h1>Dedicated Workstations</h1>
<p>We settled on having dedicated remote pairing workstations in the NYC office, one for each remote developer. This is a departure from the norm. At Pivotal we swich pairing stations frequently and nobody &#40;or everybody&#41; &#8220;owns&#8221; a particular machine. For practical reasons the remote person really needed to own a single station to make remote pairing as efficient as possible.</p>
<h2>Minimizing Setup Overhead</h2>
<p>Remote pair programming often requires a bit of setup: configuring Screen Sharing, setting up <a href="http://tmux.sourceforge.net/" title="tmux"><code>tmux</code></a>, launching and logging in to Skype, etc. With dedicated remote pairing stations this setup can be done once early in the project and &#40;usually&#41; left alone. Time spent on this overhead is minimized, and pairing could start immediately.</p>
<h2>Virtual Presence</h2>
<p>At Pivotal Labs, our offices have an open floor plan. To find someone you need only stand up and look around for them. But what about when you need to talk to Joe-in-Atlanta? Who&#8217;s he pairing with today?</p>
<p>A dedicated workstation for each remote developer becomes their virtual presence in the office. Everyone on the team knows where to find Joe-in-Atlanta. This is important not only for other developers, but also for product manager, project managers, designers &#8212; the entire team. My station was called &#8220;Little Atlanta&#8221; and we referenced it often in conversations: &#8220;Joe, I need to talk to you after standup today. I&#8217;ll meet you at Little Atlanta in a few minutes.&#8221;</p>
<h1>Extreme Remote Pairing!</h1>
<p>Occasionally two remote developers would remote pair for the day. What did we do then? We usually chose one of our dedicated NYC office stations and paired through that machine rather than our local &#40;that is, home&#41; machines. Why? Just as if we were physically in the office we wanted other developers to be able to see what we were doing and help us if needed.</p>
<p>We made ourselves available by setting up a group Skype call between ourselves and the workstation &#8220;Skype laptop&#8221; and letting everyone know where we could be found. This worked very well. Using this video conference we could ask for help and team members could seek us out as well.</p>
<p><img title="" src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/07/joe_and_joey_med.png?48a6bc" alt="" /></p>
<h1>Resources</h1>
<ul>
<li><a href="http://www.skype.com/intl/en-us/features/allfeatures/group-video-calls/" title="Group Video Chat Online - Group Video Calling - 3 Way Chat - Skype">Group Video Chat from Skype</a></li>
<li><a href="http://tmux.sourceforge.net/" title="tmux">tmux</a> &#8212; terminal sharing for terminal-based pair programming</li>
<li><a href="http://amazon.com/dp/B000EOPQ7E" title="Amazon.com: Blue Microphones Snowball USB Microphone (White): Musical Instruments">Snowball USB Microphone</a></li>
<li><a href="http://remotepairprogramming.com/training-skype-and-your-mac-to-automatically" title="Training Skype to Automatically Switch Between Audio/Video Inputs - Remote Pair Programming">Training Skype to Automatically Switch Between Audio/Video Inputs</a></li>
<li><a href="http://remotepairprogramming.com/my-office-remote-presence-setup" title="My Office Remote Presence Setup - Remote Pair Programming">Antoher &#8220;Skype Laptop&#8221; setup </a></li>
</ul>
<p>The post <a href="http://pivotallabs.com/integrating-remote-developers-with-a-large-team/">Integrating Remote Developers into Large Teams</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/integrating-remote-developers-with-a-large-team/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Introducing Android IntelliJ Starter and Android CI</title>
		<link>http://pivotallabs.com/introducing-android-intellij-starter-and-android-ci/</link>
		<comments>http://pivotallabs.com/introducing-android-intellij-starter-and-android-ci/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 13:33:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[robolectric]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/introducing-android-intellij-starter-and-android-ci/</guid>
		<description><![CDATA[<p><p>We have been doing quite a bit of Android development over the last year and a half at Pivotal Labs. Over time we have compiled a set of go-to tools, and libraries, and configuration settings that help make our development process as productive as possible. We are excited to publish two open source projects, each with the goal of helping new Android development projects hit the ground running: <a href="https://github.com/pivotal/AndroidIntelliJStarter">Android IntelliJ Starter</a> and <a href="https://github.com/pivotal/AndroidCI">Android CI</a>.</p> <a href="http://pivotallabs.com/introducing-android-intellij-starter-and-android-ci/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/introducing-android-intellij-starter-and-android-ci/">Introducing Android IntelliJ Starter and Android CI</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>We have been doing quite a bit of Android development over the last year and a half at Pivotal Labs. Over time we have compiled a set of go-to tools, and libraries, and configuration settings that help make our development process as productive as possible. We are excited to publish two open source projects, each with the goal of helping new Android development projects hit the ground running: <a href="https://github.com/pivotal/AndroidIntelliJStarter">Android IntelliJ Starter</a> and <a href="https://github.com/pivotal/AndroidCI">Android CI</a>.</p>
<h2>Android IntelliJ Starter</h2>
<p>Android IntelliJ Starter &#40;<a href="https://github.com/pivotal/AndroidIntelliJStarter">github project here</a>&#41; is a &#8220;template&#8221; <a href="http://www.jetbrains.com/idea/" title="IntelliJ IDEA :: Best Java IDE to do more high-quality code in less time">IntelliJ 10.5</a> project created to bootstrap Android development in IntelliJ. Our goal: start test-driving your new Android project within minutes, not hours &#40;or days&#41; using the <a href="https://github.com/pivotal/robolectric">Robolectric</a> framework for testing and <a href="http://code.google.com/p/roboguice/" title="roboguice -Google Guice on Android - Google Project Hosting">Robojuice</a> framework for dependency-injection. In addition to the starter application and unit tests many other supporting libraries are provided, including <a href="http://code.google.com/android/c2dm/" title="Android Cloud to Device Messaging Framework - Google Projects for Android">C2DM push notification</a> libraries with a stubbed-out, documented C2DM implementation class. </p>
<p>Android IntelliJ Starter represents hard earned configuration knowledge as well: getting all these tools to work seamlessly in IntelliJ and on the command line using <code>ant</code> is no small feat. We&#8217;ve even provided instructions on how to remove the extra tools and libraries &#8212; configuration by deletion.</p>
<h2>Android CI</h2>
<p>Android CI <a href="https://github.com/pivotal/AndroidCI">&#40;github project here&#41;</a> is intended to bootstrap Android continuous integration using <a href="http://jenkins-ci.org/">Jenkins-CI</a> &#40;formerly Hudson&#41;. This project is a stripped-down version of Jenkins&#8217; configuration directory, which is <code>~/.jenkins</code> by default.</p>
<p>Android CI ships with one preconfigured job: running tests and building .apks for Android IntelliJ Starter. If your project starts as a clone or fork of Android IntelliJ Starter then Android CI&#8217;s configuration will work well for you with only a few simple changes.</p>
<h2>Help Us Improve</h2>
<p>At Pivotal Labs we are committed to making Android development as productive as possible. We will add more functionality to both projects over time and we encourage others to fork, enhance, send us pull requests, and to use the <em>Issues</em> tab on each Github project&#8217;s page to notify us of problems so we can fix them promptly.</p>
<p>The post <a href="http://pivotallabs.com/introducing-android-intellij-starter-and-android-ci/">Introducing Android IntelliJ Starter and Android CI</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/introducing-android-intellij-starter-and-android-ci/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fast Android Debugging with IntelliJ</title>
		<link>http://pivotallabs.com/fast-android-debugging-with-intellij/</link>
		<comments>http://pivotallabs.com/fast-android-debugging-with-intellij/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 19:41:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/fast-android-debugging-with-intellij/</guid>
		<description><![CDATA[<p><p>Sure, you can launch your Android app in IntelliJ's debugger, but that's slow. IntelliJ allows you to dynamically attach the debugger to a running device using the "Attach debugger to Android process" button. That's fast!</p>

<p><img title="attach debugger to android process" src="http://assets.pivotallabs.com/1075/original/debug1.jpg" alt="" /></p>

<p><img title="attach debugger to android process" src="http://assets.pivotallabs.com/1076/original/debug2.jpg" alt="" /></p> <a href="http://pivotallabs.com/fast-android-debugging-with-intellij/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/fast-android-debugging-with-intellij/">Fast Android Debugging with IntelliJ</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Sure, you can launch your Android app in IntelliJ&#8217;s debugger, but that&#8217;s slow. IntelliJ allows you to dynamically attach the debugger to a running device using the &#8220;Attach debugger to Android process&#8221; button. That&#8217;s fast!</p>
<p><img title="attach debugger to android process" src="http://assets.pivotallabs.com/1075/original/debug1.jpg" alt="" /></p>
<p><img title="attach debugger to android process" src="http://assets.pivotallabs.com/1076/original/debug2.jpg" alt="" /></p>
<p>The post <a href="http://pivotallabs.com/fast-android-debugging-with-intellij/">Fast Android Debugging with IntelliJ</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/fast-android-debugging-with-intellij/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Tidbits 6/23/2011: Tabs and Colors</title>
		<link>http://pivotallabs.com/android-tidbits-6-23-2011-tabs-and-colors/</link>
		<comments>http://pivotallabs.com/android-tidbits-6-23-2011-tabs-and-colors/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 14:19:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/android-tidbits-6-23-2011-tabs-and-colors/</guid>
		<description><![CDATA[<p><h3>Pivotal Android Tabs</h3>

<p>We have published a simple Android project that illustrates how to use tabs in an Android app: <code>TabActivity</code>, <code>TabHost</code>, <code>TabWidget</code>, and <code>android:divider</code>.  Thank you <a href="https://pivotallabs.com/users/rrichard/blog">Pivot Ryan</a>, the original author, for taking the time to write and open source this. Check it out, fork it, and enjoy -- <a href="https://github.com/pivotal/Pivotal-Android-Tabs">https://github.com/pivotal/Pivotal-Android-Tabs</a></p>

<p><img title="" src="http://assets.pivotallabs.com/1031/original/tabs1.jpg" alt="Tabs 1" /></p>

<p><img title="" src="http://assets.pivotallabs.com/1032/original/tabs2.jpg" alt="Tabs 2" /></p>

<h3>See Hex'd Colors</h3>

<p>IntelliJ trick: in a <code>colors.xml</code> file, place your cursor on a hex value and hold down <code>Shift</code>.  You'll see a large preview of the color. </p>

<p><img title="" src="http://assets.pivotallabs.com/1033/original/screen_shot_2011_06_22_at_1.35.16_pm_1.png" alt="Hex colors in IntelliJ" /></p>

<h3>Colors and States</h3>

<p>&#40;Repost from the <a href="https://pivotallabs.com/users/ifisher/blog/articles/1760-standup-6-22-2011-cache-bust-revisited">6/22/2011 Standup blog</a>&#41;: You can use a selector drawable to set Android text color for the various states &#40;focused, selected, etc.&#41; using a drawable xml file. IntelliJ will complain and say this is invalid syntax but the application will use the file as you would expect. This only seems to work for the <code>android:textColor</code> attribute in <code>TextViews</code>.</p> <a href="http://pivotallabs.com/android-tidbits-6-23-2011-tabs-and-colors/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/android-tidbits-6-23-2011-tabs-and-colors/">Android Tidbits 6/23/2011: Tabs and Colors</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<h3>Pivotal Android Tabs</h3>
<p>We have published a simple Android project that illustrates how to use tabs in an Android app: <code>TabActivity</code>, <code>TabHost</code>, <code>TabWidget</code>, and <code>android:divider</code>.  Thank you <a href="https://pivotallabs.com/users/rrichard/blog">Pivot Ryan</a>, the original author, for taking the time to write and open source this. Check it out, fork it, and enjoy &#8212; <a href="https://github.com/pivotal/Pivotal-Android-Tabs">https://github.com/pivotal/Pivotal-Android-Tabs</a></p>
<p><img title="" src="http://assets.pivotallabs.com/1031/original/tabs1.jpg" alt="Tabs 1" /></p>
<p><img title="" src="http://assets.pivotallabs.com/1032/original/tabs2.jpg" alt="Tabs 2" /></p>
<h3>See Hex&#8217;d Colors</h3>
<p>IntelliJ trick: in a <code>colors.xml</code> file, place your cursor on a hex value and hold down <code>Shift</code>.  You&#8217;ll see a large preview of the color. </p>
<p><img title="" src="http://assets.pivotallabs.com/1033/original/screen_shot_2011_06_22_at_1.35.16_pm_1.png" alt="Hex colors in IntelliJ" /></p>
<h3>Colors and States</h3>
<p>&#40;Repost from the <a href="https://pivotallabs.com/users/ifisher/blog/articles/1760-standup-6-22-2011-cache-bust-revisited">6/22/2011 Standup blog</a>&#41;: You can use a selector drawable to set Android text color for the various states &#40;focused, selected, etc.&#41; using a drawable xml file. IntelliJ will complain and say this is invalid syntax but the application will use the file as you would expect. This only seems to work for the <code>android:textColor</code> attribute in <code>TextViews</code>.</p>
<p>The post <a href="http://pivotallabs.com/android-tidbits-6-23-2011-tabs-and-colors/">Android Tidbits 6/23/2011: Tabs and Colors</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/android-tidbits-6-23-2011-tabs-and-colors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Tidbits 6/22/2011: Hiding Header Views</title>
		<link>http://pivotallabs.com/android-tidbits-6-22-2011-hiding-header-views/</link>
		<comments>http://pivotallabs.com/android-tidbits-6-22-2011-hiding-header-views/#comments</comments>
		<pubDate>Wed, 22 Jun 2011 15:01:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/android-tidbits-6-22-2011-hiding-header-views/</guid>
		<description><![CDATA[<p><p>Android <a href="http://developer.android.com/reference/android/widget/ListView.html#addHeaderView(android.view.View, java.lang.Object, boolean">ListView#addHeaderView and ListView#addFooterView</a> methods are strange: you have to add the header and footer Views before you set the <code>ListView</code>'s adapter so the <code>ListView</code> can take the headers and footers into consideration -- you get an exception otherwise.  Here we add a <code>ProgressBar</code> &#40;spinner&#41; as the <code>headerView</code>:</p>

<pre><code>// spinner is a ProgressBar
listView.addHeaderView&#40;spinner&#41;;
</code></pre>

<p>We'd like to be able to show and hide that spinner at will, but removing it outright is dangerous because we'd never be able to add it again without destroying the <code>ListView</code> -- remember, we can't <code>addHeaderView</code> after we've it's adapter:</p>

<pre><code>listView.removeHeaderView&#40;spinner&#41;; //dangerous!
</code></pre>

<p>So let's hide it!  Turns out that's hard, too.  Just hiding the spinner view itself results in an empty, but still visible, header area.</p> <a href="http://pivotallabs.com/android-tidbits-6-22-2011-hiding-header-views/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/android-tidbits-6-22-2011-hiding-header-views/">Android Tidbits 6/22/2011: Hiding Header Views</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Android <a href="http://developer.android.com/reference/android/widget/ListView.html#addHeaderView(android.view.View, java.lang.Object, boolean">ListView#addHeaderView and ListView#addFooterView</a> methods are strange: you have to add the header and footer Views before you set the <code>ListView</code>&#8216;s adapter so the <code>ListView</code> can take the headers and footers into consideration &#8212; you get an exception otherwise.  Here we add a <code>ProgressBar</code> &#40;spinner&#41; as the <code>headerView</code>:</p>
<pre><code>// spinner is a ProgressBar
listView.addHeaderView&#40;spinner&#41;;
</code></pre>
<p>We&#8217;d like to be able to show and hide that spinner at will, but removing it outright is dangerous because we&#8217;d never be able to add it again without destroying the <code>ListView</code> &#8212; remember, we can&#8217;t <code>addHeaderView</code> after we&#8217;ve it&#8217;s adapter:</p>
<pre><code>listView.removeHeaderView&#40;spinner&#41;; //dangerous!
</code></pre>
<p>So let&#8217;s hide it!  Turns out that&#8217;s hard, too.  Just hiding the spinner view itself results in an empty, but still visible, header area.</p>
<hr />
<h2><img src="http://assets.pivotallabs.com/1029/original/spinner.jpg" alt="" />    </h2>
<p>Now try to hide the spinner:</p>
<pre><code>spinner.setVisibility&#40;View.GONE&#41;;
</code></pre>
<p>Result: header area still visible with an ugly space:</p>
<hr />
<p><img src="http://assets.pivotallabs.com/1030/original/space.jpg" alt="" />  </p>
<hr />
<p>The solution is to put the progress bar in a <code>LinearLayout</code> that wraps it&#8217;s content, and hiding the content.  That way the wrapping <code>LinearLayout</code> will collapse when its content is hidden, resulting in a headerView that is technically still present, but 0dip high:</p>
<pre><code>  &lt;LinearLayout
      xmlns:a="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"&gt;
    &lt;!-- simplified --&gt;
      &lt;ProgressBar
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/&gt;
  &lt;/LinearLayout&gt;
</code></pre>
<p>Then, set the layout as the header:</p>
<pre><code>spinnerLayout = getLayoutInflater&#40;&#41;.inflate&#40;R.layout.header_view_spinner, null&#41;;
listView.addHeaderView&#40;spinnerLayout&#41;;
</code></pre>
<p>And when we need to hide it, hide the layout&#8217;s content, not the layout:</p>
<pre><code>    spinnerLayout.findViewById&#40;R.id.spinner&#41;.setVisibility&#40;View.GONE&#41;;
</code></pre>
<p>Now the header disappears from view.  No more ugly space at the top!</p>
<p>The post <a href="http://pivotallabs.com/android-tidbits-6-22-2011-hiding-header-views/">Android Tidbits 6/22/2011: Hiding Header Views</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/android-tidbits-6-22-2011-hiding-header-views/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Tidbits 6/21/2011: Unregister? Nah!</title>
		<link>http://pivotallabs.com/android-tidbits-6-21-2011-unregister-nah/</link>
		<comments>http://pivotallabs.com/android-tidbits-6-21-2011-unregister-nah/#comments</comments>
		<pubDate>Tue, 21 Jun 2011 16:51:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[c2dm]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/android-tidbits-6-21-2011-unregister-nah/</guid>
		<description><![CDATA[<p><h3>C2DM Unregister Issues</h3>

<p>It turns out when you follow the <a href="http://code.google.com/android/c2dm/index.html#unregistering" title="Android Cloud to Device Messaging Framework - Google Projects for Android">client-side C2DM unregistration process</a>, this does not guarantee that those registration tokens are permanently unregistered for that device.  </p>

<p>If we unregister as specified above and then send a push notification to that <code>registration_id</code>, the server receives an <a href="http://code.google.com/android/c2dm/index.html#push" title="Android Cloud to Device Messaging Framework - Google Projects for Android"><code>Error=NotRegistered</code></a> as expected. </p>

<p>But, unexpectedly, when that device <a href="http://code.google.com/android/c2dm/index.html#registering" title="Android Cloud to Device Messaging Framework - Google Projects for Android">re-register with C2DM</a> &#40;and getting a new <code>registration_id</code>&#41;, the old <code>registration_id</code> is <strong><em>reactivated as well</strong></em> and can receive push notifications and does not result in a server-side <code>Error=NotRegistered</code>.</p>

<p>The end result: we implemented our server-side API to take both the new and old <code>registration_id</code>s when the Android client successfully registers with C2DM, allowing us to manually delete the old <code>registration_id</code>.</p>

<h3>Drawable XML Files</h3>

<p>Prefixing the name of a drawable xml file with "active_" seems to prevent android from using that drawable at all.</p> <a href="http://pivotallabs.com/android-tidbits-6-21-2011-unregister-nah/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/android-tidbits-6-21-2011-unregister-nah/">Android Tidbits 6/21/2011: Unregister? Nah!</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<h3>C2DM Unregister Issues</h3>
<p>It turns out when you follow the <a href="http://code.google.com/android/c2dm/index.html#unregistering" title="Android Cloud to Device Messaging Framework - Google Projects for Android">client-side C2DM unregistration process</a>, this does not guarantee that those registration tokens are permanently unregistered for that device.  </p>
<p>If we unregister as specified above and then send a push notification to that <code>registration_id</code>, the server receives an <a href="http://code.google.com/android/c2dm/index.html#push" title="Android Cloud to Device Messaging Framework - Google Projects for Android"><code>Error=NotRegistered</code></a> as expected. </p>
<p>But, unexpectedly, when that device <a href="http://code.google.com/android/c2dm/index.html#registering" title="Android Cloud to Device Messaging Framework - Google Projects for Android">re-register with C2DM</a> &#40;and getting a new <code>registration_id</code>&#41;, the old <code>registration_id</code> is <strong><em>reactivated as well</strong></em> and can receive push notifications and does not result in a server-side <code>Error=NotRegistered</code>.</p>
<p>The end result: we implemented our server-side API to take both the new and old <code>registration_id</code>s when the Android client successfully registers with C2DM, allowing us to manually delete the old <code>registration_id</code>.</p>
<h3>Drawable XML Files</h3>
<p>Prefixing the name of a drawable xml file with &#8220;active_&#8221; seems to prevent android from using that drawable at all.</p>
<p>The post <a href="http://pivotallabs.com/android-tidbits-6-21-2011-unregister-nah/">Android Tidbits 6/21/2011: Unregister? Nah!</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/android-tidbits-6-21-2011-unregister-nah/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Syncing IntelliJ Android .apk Files Using Dropbox</title>
		<link>http://pivotallabs.com/syncing-intellij-android-apk-files-using-dropbox/</link>
		<comments>http://pivotallabs.com/syncing-intellij-android-apk-files-using-dropbox/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 20:26:00 +0000</pubDate>
		<dc:creator>Joe Moore</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[remote]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/syncing-intellij-android-apk-files-using-dropbox/</guid>
		<description><![CDATA[<p><p>During a typical day of Android development we compile Android applications &#40;<em>.apk</em> files&#41; dozens of times, deploying to emulators and devices simply by pressing the Run button in IntelliJ.  This is great for our in-office developers, but it's more difficult for our remote-pairing developers to install those same .apks on their own emulators and phones.  As a remote developer, I wanted seamless, instant access to all .apks we build during development.  Using Dropbox and some IntelliJ configuration changes I now have all .apks we build available for me to install on my local emulators and phones just seconds after we build them on our development machines, 2500 miles away.</p> <a href="http://pivotallabs.com/syncing-intellij-android-apk-files-using-dropbox/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/syncing-intellij-android-apk-files-using-dropbox/">Syncing IntelliJ Android .apk Files Using Dropbox</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>During a typical day of Android development we compile Android applications &#40;<em>.apk</em> files&#41; dozens of times, deploying to emulators and devices simply by pressing the Run button in IntelliJ.  This is great for our in-office developers, but it&#8217;s more difficult for our remote-pairing developers to install those same .apks on their own emulators and phones.  As a remote developer, I wanted seamless, instant access to all .apks we build during development.  Using Dropbox and some IntelliJ configuration changes I now have all .apks we build available for me to install on my local emulators and phones just seconds after we build them on our development machines, 2500 miles away.</p>
<h3>Dropbox</h3>
<p>Many developers already know about <a href="http://www.dropbox.com/" title="Dropbox - Simplify your life">Dropbox</a>, the fast, super-secure file sharing service. I installed Dropbox on all of our machines and created Dropbox directories for each machine our team uses.  They happened to be named after streets in San Francisco, Boulder, and Atlanta.</p>
<p><img src="http://assets.pivotallabs.com/1022/original/_users_pivotal_dropbox.jpg" alt="Dropbox dir" /></p>
<h3>Symlinks</h3>
<p>Next, on each machine, create an <strong>apk</strong> symlink to the appropriate Dropbox directory within IntellJ&#8217;s <code>ide_bulid</code> directory.</p>
<pre><code>~/workspace/PivotalAndroid$ ln -s ~/Dropbox/PivotalAndroid/grafton_apks ide_build/production/PivotalAndroid/apk
</code></pre>
<p>Next, tell IntelliJ to output .apks to that directory.  We have to be careful here, especially if you check your <code>.iml</code> file and <code>.idea</code> directory into source control.  You can select <em>Project Structure => Facets => &#40;Your Android Module&#41; => Compiler => APK Path:</em>, but this will follow the symlink you created and change your project&#8217;s .iml file to include the machine-specific Dropbox directory, and thus a merge conflict on each machine.  </p>
<p><img src="http://assets.pivotallabs.com/1021/original/project_structure_1_1.jpg" alt="" /></p>
<p><strong><em>Instead</strong></em>, you can manually edit the appropriate value in your .iml:</p>
<pre><code>&lt;!-- old value: --&gt;
&lt;option name="APK_PATH" value="" /&gt;

&lt;!-- new value, where '/apk/' is the symlink to Dropbox: --&gt;
&lt;option name="APK_PATH" value="/ide_build/production/PivotalAndroid/apk/PivoalAndroid.apk" /&gt;
</code></pre>
<p><strong><em>Note:</strong></em> IntelliJ will sometimes reset <code>APK_PATH</code> back to either the default or to the Dropbox dir.  Watch for this and fix the path again when needed.  We run into this once per week or so.</p>
<h3>Result: Updates Galore!</h3>
<p>Now I have .apk files streaming in from three different development machines; as a bonus, each development machine is synced with each other, so we all have access to all .apks. Whenever I want to install the latest .apk from another pair &#40;or my own&#41; onto my local test phone I simply pass the machine name into a script: </p>
<pre><code>#!/usr/bin/env ruby
system "adb -d install -r ~/Dropbox/PivotalAndroid/#{ARGV[0]}-apks/PivotalAndroid.apk"
</code></pre>
<p>Thus, <code>scripts/apk cedar</code> installs the latest .apk file created on our machine named &#8220;cedar&#8221;.</p>
<p>The post <a href="http://pivotallabs.com/syncing-intellij-android-apk-files-using-dropbox/">Syncing IntelliJ Android .apk Files Using Dropbox</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/syncing-intellij-android-apk-files-using-dropbox/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic (Feed is rejected)
Page Caching using apc
Database Caching using apc
Object Caching 1191/1287 objects using apc

 Served from: pivotallabs.com @ 2013-05-24 04:46:15 by W3 Total Cache -->