<?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>Jeffrey Sambells &#187; Android</title>
	<atom:link href="http://jeffreysambells.com/category/android/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeffreysambells.com</link>
	<description>Geek out AFK</description>
	<lastBuildDate>Sun, 05 Feb 2012 17:00:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>&#9734; Android ADK Resources</title>
		<link>http://jeffreysambells.com/posts/2011/05/18/android-adk-resources/</link>
		<comments>http://jeffreysambells.com/posts/2011/05/18/android-adk-resources/#comments</comments>
		<pubDate>Wed, 18 May 2011 16:00:55 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[How-To]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=1288</guid>
		<description><![CDATA[So, I&#8217;ve been playing with the Android Open Accessory Development Kit (ADK) and have realized there&#8217;s mot much out there in terms of available resources. Here&#8217;s the list of what I&#8217;ve found so far, I&#8217;ll add to it as I find more: Official Android ADK Guides Official Google Android ADK page ADK Components Getting Started [...]<p><a href="http://jeffreysambells.com/posts/2011/05/18/android-adk-resources/">&#9734; Permalink</a></p>]]></description>
			<content:encoded><![CDATA[<p>So, I&#8217;ve been playing with the Android Open Accessory Development Kit (ADK) and have realized there&#8217;s mot much out there in terms of available resources. Here&#8217;s the list of what I&#8217;ve found so far, I&#8217;ll add to it as I find more:</p>

<h2>Official Android ADK Guides</h2>

<ul>
<li><a href="http://developer.android.com/guide/topics/usb/adk.html">Official Google Android ADK page</a>

<ul>
<li><a href="http://developer.android.com/guide/topics/usb/adk.html#components">ADK Components</a></li>
<li><a href="http://developer.android.com/guide/topics/usb/adk.html#getting-started">Getting Started with the ADK</a></li>
<li><a href="http://developer.android.com/guide/topics/usb/adk.html#how">How an Accessory Communicates with an Android-powered Device in Accessory Mode</a></li>
<li><a href="http://developer.android.com/guide/topics/usb/adk.html#firmware">How the ADK board communicates with an Android-powered Device in Accessory Mode</a></li>
</ul></li>
</ul>

<h2>Related Android Guides</h2>

<ul>
<li><a href="http://developer.android.com/guide/topics/usb/accessory.html">USB Accessory Dev Guide</a></li>
<li><a href="http://developer.android.com/sdk/win-usb.html">Android USB driver</a></li>
</ul>

<h2>Videos</h2>

<ul>
<li><a href="http://www.youtube.com/watch?v=s7szcpXf2rE">Google I/O Session Video: Android Open Accessory API and Development Kit (ADK)</a></li>
</ul>

<h2>Arduino</h2>

<ul>
<li><a href="http://arduino.cc/en/Reference/HomePage">Arduino Language Reference</a></li>
<li><a href="http://arduino.cc/en/Reference/Libraries">Arduino Library Reference</a></li>
<li><a href="http://blog.makezine.com/arduino">Makezine Arduino Page</a></li>
</ul>

<h2>Hardware</h2>

<h3>Android Specific Components</h3>

<ul>
<li><a href="http://www.rt-net.jp/shop/index.php?main_page=product_info&amp;cPath=3_4&amp;products_id=1">RT Corp</a></li>
<li><a href="http://www.microchip.com/android">Microchip</a></li>
<li><a href="https://store.diydrones.com/ProductDetails.asp?ProductCode=BR-PhoneDrone">DIY Drones</a></li>
</ul>

<h3>Arduino Components</h3>

<ul>
<li><a href="http://arduino.cc/en/Main/Hardware">Boards</a></li>
<li><a href="http://www.makershed.com/SearchResults.asp?Cat=43">Maker Shed</a></li>
</ul>

<h2>Examples</h2>

<ul>
<li><a href="http://www.youtube.com/watch?v=Ub7newiu930">Robot from Google IO</a></li>
<li><a href="http://www.youtube.com/watch?v=GrE_JO5rXKA">5,000-pound labyrinth from Google IO</a></li>
<li><a href="http://www.youtube.com/watch?v=XEe3dYBj7RE">ADK Components</a></li>
</ul>

<p>Have any more that I missed? Add a comment and I&#8217;ll update the list.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2011/05/18/android-adk-resources/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#9734; Understanding the demokit.pde Arduino Sketch</title>
		<link>http://jeffreysambells.com/posts/2011/05/17/understanding-the-demokit-pde-arduino-sketch/</link>
		<comments>http://jeffreysambells.com/posts/2011/05/17/understanding-the-demokit-pde-arduino-sketch/#comments</comments>
		<pubDate>Tue, 17 May 2011 15:31:23 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=1274</guid>
		<description><![CDATA[Examples are great ways to learn a new language or technology. To demonstrate the functionality of the Android Open Accessory ADK, the kit comes with a demo Arduino Sketch that demonstrates how the device communicates with the Arduino Base Board and Android Demo Shield. Unfortunately I have yet to find any good documentation on the [...]<p><a href="http://jeffreysambells.com/posts/2011/05/17/understanding-the-demokit-pde-arduino-sketch/">&#9734; Permalink</a></p>]]></description>
			<content:encoded><![CDATA[<p>Examples are great ways to learn a new language or technology. To demonstrate the functionality of the Android Open Accessory ADK, the kit comes with a demo Arduino Sketch that demonstrates how the device communicates with the Arduino Base Board and Android Demo Shield. Unfortunately I have yet to find any good documentation on the example and how it works so I thought I&#8217;d comment on the file for those that may not understand.</p>

<p>The post is in &#8220;blog&#8221; format with paragraphs shoved into the middle of code. For reference you can <a href="https://gist.github.com/975769">find the original <code>demokit.pde</code> file over in this Gist</a>.</p>

<h2>demokit.pde</h2>

<p>The Arduino language is based on C/C++ so the file starts off with the typical headers you&#8217;ll need for the various libraries used in the sketch (servos, LEDs, capacitive touch, USB, etc).</p>

<pre><code>#include &lt;Wire.h&gt;
#include &lt;Servo.h&gt;
#include &lt;Max3421e.h&gt;
#include &lt;Usb.h&gt;
</code></pre>

<p>These two are the ones you added to the Arduino application libraries <a href="http://a.arduino.com">when you set up your system for ADK development</a>.</p>

<pre><code>#include &lt;AndroidAccessory.h&gt;
#include &lt;CapSense.h&gt;
</code></pre>

<p>Next, you&#8217;ll  see several &#8216;#define&#8217; constants. These indicate which pins are attached to which features on the Android Demo Shield. If you look at the shield, you&#8217;ll notice each pin has a corresponding number. For example <code>#define LED3_RED 2</code> indicates that the third LED&#8217;s red component pin is using #2 on the shield.</p>

<p><figure><img src="http://jeffreysambells.com/wordpress/wp-content/uploads/2011/05/LED3_RED.png" alt="LED3 Red pin location" title="LED3_RED" /></figure></p>

<p>Technically you don&#8217;t need to do this and you could just use <code>2</code> throughout your code but defining a constant makes it much easier to read and understand the code when you use <code>LED3_RED</code> instead of referring to the board to see what pin <code>2</code> is.</p>

<pre><code>#define  LED3_RED       2
#define  LED3_GREEN     4
#define  LED3_BLUE      3

#define  LED2_RED       5
#define  LED2_GREEN     7
#define  LED2_BLUE      6

#define  LED1_RED       8
#define  LED1_GREEN     10
#define  LED1_BLUE      9

#define  SERVO1         11
#define  SERVO2         12
#define  SERVO3         13

#define  TOUCH_RECV     14
#define  TOUCH_SEND     15

#define  RELAY1         A0
#define  RELAY2         A1

#define  LIGHT_SENSOR   A2
#define  TEMP_SENSOR    A3

#define  BUTTON1        A6
#define  BUTTON2        A7
#define  BUTTON3        A8

#define  JOY_SWITCH     A9      // pulls line down when pressed
#define  JOY_nINT       A10     // active low interrupt input
#define  JOY_nRESET     A11     // active low reset output
</code></pre>

<p>Now it&#8217;s time to identify the actual accessory. Read my previous post on <a href="http://jeffreysambells.com/posts/2011/05/15/identifying-your-android-usb-accessory/">&#8220;Identifying Your Android USB Accessory
&#8220;</a> for more information but you can see here that the <code>demokit.pde</code> file identifies itself as version 1.0 of the Google DemoKit accessory.</p>

<pre><code>AndroidAccessory acc("Google, Inc.",
             "DemoKit",
             "DemoKit Arduino Board",
             "1.0",
             "http://www.android.com",
             "0000000012345678");
</code></pre>

<p>Now, all that&#8217;s left to do is initialize a few variables, setup the environment and then start the loop that will continuously run to evaluate the IO for the Arduion board.</p>

<pre><code>// Define an array for the servos
Servo servos[3];

// Initiate the touch sensor
// 10M ohm resistor on demo shield
CapSense   touch_robot = CapSense(TOUCH_SEND, TOUCH_RECV);

// Run the initial setup on the board
void setup();

// Loop and check for IO 
void loop();
</code></pre>

<h3>Initialization</h3>

<p>The <code>pinMode()</code> method is used to initialize the input and output pins on the Android Demo Shield. It configures the specified pin to behave either as an <code>INPUT</code> or an <code>OUTPUT</code>. Arduino pins default to <code>INPUT</code> so the mode doesn&#8217;t need to be explicitly set but its usually a good idea to do it anyway so that your code is clear and understandable.</p>

<p>For example, the <code>init_buttons</code> function identifies the pins for <code>BUTTON1</code>, <code>BUTTON2</code>, <code>BUTTON3</code> and <code>JOY_SWITCH</code> as input connections.</p>

<pre><code>void init_buttons()
{

    pinMode(BUTTON1, INPUT);
    pinMode(BUTTON2, INPUT);
    pinMode(BUTTON3, INPUT);
    pinMode(JOY_SWITCH, INPUT);
</code></pre>

<p>To identify the state of the buttons, a pin configured as an INPUT can have a <code>HIGH</code> or <code>LOW</code> value. Writing a <code>HIGH</code> value with will enable an internal 20K pullup resistor. Writing LOW will disable the pullup. The pullup resistor acts as a known value when no other input is present (such as when pressing the button). Later you can use <code>digitalRead()</code> to check the value to determine if the button has been pressed or not.</p>

<pre><code>    digitalWrite(BUTTON1, HIGH);
    digitalWrite(BUTTON2, HIGH);
    digitalWrite(BUTTON3, HIGH);
    digitalWrite(JOY_SWITCH, HIGH);
}
</code></pre>

<p>Output pins, such as the relays in <code>init_relays()</code> are also configured using the <code>pinMode()</code> function however no default value needs to be written to the relays because it is always told to be either on or off.</p>

<pre><code>// Initializes the relays as outputs
void init_relays()
{
    pinMode(RELAY1, OUTPUT);
    pinMode(RELAY2, OUTPUT);
}
</code></pre>

<p>The <code>digitalWrite()</code> method can also take varying values as inputs. For example, you may want to write an integer between 1 and 255 to represent the brightness of an LED. The <code>init_leds()</code> function sets all the LED pins as outputs and presets their output value to 1 (or bright).</p>

<pre><code>// Initialize the LED outputs
void init_leds()
{

    digitalWrite(LED1_RED, 1);
    digitalWrite(LED1_GREEN, 1);
    digitalWrite(LED1_BLUE, 1);

    pinMode(LED1_RED, OUTPUT);
    pinMode(LED1_GREEN, OUTPUT);
    pinMode(LED1_BLUE, OUTPUT);

    digitalWrite(LED2_RED, 1);
    digitalWrite(LED2_GREEN, 1);
    digitalWrite(LED2_BLUE, 1);

    pinMode(LED2_RED, OUTPUT);
    pinMode(LED2_GREEN, OUTPUT);
    pinMode(LED2_BLUE, OUTPUT);

    digitalWrite(LED3_RED, 1);
    digitalWrite(LED3_GREEN, 1);
    digitalWrite(LED3_BLUE, 1);

    pinMode(LED3_RED, OUTPUT);
    pinMode(LED3_GREEN, OUTPUT);
    pinMode(LED3_BLUE, OUTPUT);
}
</code></pre>

<p>The joystick controls are little tricker so I&#8217;m not going to go into it in this post. If you&#8217;re interested see the <code>init_joystick()</code> and related functions at the bottom of the <a href="https://gist.github.com/975769"><code>demokit.pde</code> file that comes with the kit</a>.</p>

<pre><code>void init_joystick(int threshold);
</code></pre>

<h3>Setup</h3>

<p>Now that all the necessary helper functions are defined we can look at the setup function. The <code>setup()</code> function begins serial communications with the device and then calls all the initialization methods you saw earlier.</p>

<pre><code>// These are a few variables to hold the state of the buttons.
byte b1, b2, b3, b4, c;

// Setup the board
void setup()
{
    // Begin communications.
    Serial.begin(115200);
    Serial.print("\r\nStart");

    init_leds();
    init_relays();
    init_buttons();
    init_joystick( 5 );
</code></pre>

<p>Next, <code>setup()</code> calibrates the capacitive touch sensor and sets the servos to their initial positions of 90 degrees.</p>

<pre><code>    // autocalibrate OFF
    touch_robot.set_CS_AutocaL_Millis(0xFFFFFFFF);

    servos[0].attach(SERVO1);
    servos[0].write(90);
    servos[1].attach(SERVO2);
    servos[1].write(90);
    servos[2].attach(SERVO3);
    servos[2].write(90);
</code></pre>

<p>Lastly, <code>setup()</code> assigns the current <code>HIGH</code> or <code>LOW</code> value of the buttons to <code>b1</code>, <code>b2</code>, <code>b3</code> and  <code>b4</code>. During the <code>loop</code> execution, these values will be compared to the values in the loop and used to determine if the button&#8217;s state has changed since the last loop.</p>

<pre><code>    b1 = digitalRead(BUTTON1);
    b2 = digitalRead(BUTTON2);
    b3 = digitalRead(BUTTON3);
    b4 = digitalRead(JOY_SWITCH);
    c = 0;
</code></pre>

<p>Now the setup power&#8217;s on the accessory.</p>

<pre><code>    acc.powerOn();
}
</code></pre>

<h3>Loop</h3>

<p>The <code>loop()</code> function is the heart beat of the Arduino Base Board. After creating and executing the <code>setup()</code> function, which is responsible for initializing the initial values, the loop begins it&#8217;s magic and loops consecutively, allowing the sketch to analyze and respond accordingly.</p>

<p>The loop in <code>demokit.pde</code> has two main responsibilities. First, if the device is connected, it will read any input and write output to the device as necessary. Second, if no device is connected it will reset all the initial values to await a new device connection.</p>

<pre><code>void loop()
{
    byte err;
    byte idle;
    static byte count = 0;
    byte msg[3];
    long touchcount;
</code></pre>

<p>Here it looks for a connection.</p>

<pre><code>    if (acc.isConnected()) {

        int len = acc.read(msg, sizeof(msg), 1);
        int i;
        byte b;
        uint16_t val;
        int x, y;
        char c0;
</code></pre>

<p>If the length of the input buffer from the attached Android device is greater than zero, the loop process the input command to determine what it should do.</p>

<pre><code>        if (len &gt; 0) {
</code></pre>

<p>The message format can be seen in the DemoKit Android App that also comes with the kit. If you take a look at the <code>sendCommand()</code> method in the <code>com.google.android.DemoKit.DemoKitActivity</code> class.  You&#8217;ll see something like this:</p>

<pre><code>...
buffer[0] = command;
buffer[1] = target;
buffer[2] = (byte) value; 
...
</code></pre>

<p>In the case of a LED or Servo command, the <code>command</code>&#8216;s value is <code>2</code> (<code>DemoKitActivity.LED_SERVO_COMMAND</code>), followed by the <code>target</code> and the <code>value</code> to associate with the target.</p>

<p>For example, you can see in the following code that the red, green and blue pins for each LED are updated, but only when <code>msg[0]</code> is 2 (<code>0x2</code>). The LED pin to update is defined in <code>msg[1]</code> (<code>0x0</code> thru <code>0x8</code> respectively) and the value is set using <code>msg[2]</code> and <code>analogWrite()</code>.</p>

<p>In the case of the value for a LED, the lower the value the brighter the light (or the higher the value the more black and darker the light). The DemoKit app on the Android device sends 255 when it wants a full bright light so the value is subtracted from  255 to set the appropriate value for &#8220;bright&#8221;.</p>

<pre><code>            // Assumes only one command per packet.
            if (msg[0] == 0x2) {
                if (msg[1] == 0x0)
                    analogWrite(LED1_RED, 255 - msg[2]);
                else if (msg[1] == 0x1)
                    analogWrite(LED1_GREEN, 255 - msg[2]);
                else if (msg[1] == 0x2)
                    analogWrite(LED1_BLUE, 255 - msg[2]);
                else if (msg[1] == 0x3)
                    analogWrite(LED2_RED, 255 - msg[2]);
                else if (msg[1] == 0x4)
                    analogWrite(LED2_GREEN, 255 - msg[2]);
                else if (msg[1] == 0x5)
                    analogWrite(LED2_BLUE, 255 - msg[2]);
                else if (msg[1] == 0x6)
                    analogWrite(LED3_RED, 255 - msg[2]);
                else if (msg[1] == 0x7)
                    analogWrite(LED3_GREEN, 255 - msg[2]);
                else if (msg[1] == 0x8)
                    analogWrite(LED3_BLUE, 255 - msg[2]);
</code></pre>

<p>The servo output uses the same <code>command</code> and is processed in the same if condition however setting the servo position is a little different. You can read more in the <a href="http://www.arduino.cc/en/Reference/Servo">Servo library</a> but the basics here are that the servo&#8217;s <a href="http://arduino.cc/en/Reference/ServoWrite"><code>write()</code> method</a> takes an angle for the servo and the <a href="http://www.arduino.cc/en/Reference/Map"><code>map()</code> method</a> is used to re-map the input value from one range (0-255) to another (0-180).</p>

<pre><code>                else if (msg[1] == 0x10)
                    servos[0].write(map(msg[2], 0, 255, 0, 180));
                else if (msg[1] == 0x11)
                    servos[1].write(map(msg[2], 0, 255, 0, 180));
                else if (msg[1] == 0x12)
                    servos[2].write(map(msg[2], 0, 255, 0, 180));

            } else if (msg[0] == 0x3) {
</code></pre>

<p>For the two relays on the Android Demo Shield, <code>msg[2]</code> is simply compared for a <code>HIGH</code> or <code>LOW</code> value and the board is updated accordingly.</p>

<pre><code>                if (msg[1] == 0x0)
                    digitalWrite(RELAY1, msg[2] ? HIGH : LOW);
                else if (msg[1] == 0x1)
                    digitalWrite(RELAY2, msg[2] ? HIGH : LOW);

            }

        }
</code></pre>

<p>At this point in the loop, all the input messages have been processed so the loop switches to checking all the output pins and sending any necessary messages to the device.  The message type for output is set to 1 and each individual output is checked.</p>

<pre><code>        msg[0] = 0x1;
</code></pre>

<p>For example, in the following code the state of <code>BUTTON1</code> is read into <code>b</code> and compared to <code>b1</code>. Earlier you saw how the read value of the pin associated with <code>BUTTON1</code> could be either <code>HIGH</code> or <code>LOW</code>. If the value of <code>b</code> differs from the value of <code>b1</code> (defined in <code>setup()</code> or in the previous run of the loop) then the state of the button has changed and the appropriate message is sent back to the connected Android device. At the same time, <code>b</code> is assigned to <code>b1</code> to indicate the new state for the next loop.</p>

<pre><code>        b = digitalRead(BUTTON1);
        if (b != b1) {
            msg[1] = 0;
            msg[2] = b ? 0 : 1;
            acc.write(msg, 3);
            b1 = b;
        }

        // Check button 2
        b = digitalRead(BUTTON2);
        if (b != b2) {
            msg[1] = 1;
            msg[2] = b ? 0 : 1;
            acc.write(msg, 3);
            b2 = b;
        }

        // Check button 3
        b = digitalRead(BUTTON3);
        if (b != b3) {
            msg[1] = 2;
            msg[2] = b ? 0 : 1;
            acc.write(msg, 3);
            b3 = b;
        }

        // Check for a press on the joystick button.
        b = digitalRead(JOY_SWITCH);
        if (b != b4) {
            msg[1] = 4;
            msg[2] = b ? 0 : 1;
            acc.write(msg, 3);
            b4 = b;
        }
</code></pre>

<p>Once all the digital reads for the buttons have completed, the demokit uses an <code>analogRead()</code> to determine the current values of the temperature sensor, the light sensor, the joystick and the capacitive touch sensor. At first I was confused by the use of a switch statement here until I realized the expense of an analog read. It takes about 100 microseconds to read an analog input, so the maximum reading rate is 10,000 times a second. That&#8217;s pretty good but we don&#8217;t want to slow things down unnecessarily, especially when environmental variables such as temperature and ambient light are not changing dramatically at a rapid pace. The <code>switch</code> and <code>count++ % 0x10</code> condition allows the loop to reduce the frequency of analog reads and only sample one analog read per loop.</p>

<pre><code>        switch (count++ % 0x10) {
        case 0:
            val = analogRead(TEMP_SENSOR);
            msg[0] = 0x4;
            msg[1] = val &gt;&gt; 8;
            msg[2] = val &amp; 0xff;
            acc.write(msg, 3);
            break;

        case 0x4:
            val = analogRead(LIGHT_SENSOR);
            msg[0] = 0x5;
            msg[1] = val &gt;&gt; 8;
            msg[2] = val &amp; 0xff;
            acc.write(msg, 3);
            break;

        case 0x8:
            read_joystick(&amp;x, &amp;y);
            msg[0] = 0x6;
            msg[1] = constrain(x, -128, 127);
            msg[2] = constrain(y, -128, 127);
            acc.write(msg, 3);
            break;

        case 0xc:
            touchcount = touch_robot.capSense(5);

            c0 = touchcount &gt; 750;

            if (c0 != c) {
                msg[0] = 0x1;
                msg[1] = 3;
                msg[2] = c0;
                acc.write(msg, 3);
                c = c0;
            }

            break;
        }
    } else {
</code></pre>

<p>As mentioned earlier, when a device is not connected (or was disconnected) the loop resets the outputs to the default values.</p>

<pre><code>        analogWrite(LED1_RED, 255);
        analogWrite(LED1_GREEN, 255);
        analogWrite(LED1_BLUE, 255);
        analogWrite(LED2_RED, 255);
        analogWrite(LED2_GREEN, 255);
        analogWrite(LED2_BLUE, 255);
        analogWrite(LED3_RED, 255);
        analogWrite(LED3_GREEN, 255);
        analogWrite(LED3_BLUE, 255);
        servos[0].write(90);
        servos[0].write(90);
        servos[0].write(90);
        digitalWrite(RELAY1, LOW);
        digitalWrite(RELAY2, LOW);
    }
</code></pre>

<p>Then the loop ends by delaying for a few milliseconds.</p>

<pre><code>    delay(10);
}
</code></pre>

<p>The <a href="https://gist.github.com/975769">remainder of the file</a> deals with the IO of the joystick. You can just take it as is and I&#8217;ll leave it until another post.</p>

<p>Hopefully this was a little helpful getting you started with the ADK and the demokit example.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2011/05/17/understanding-the-demokit-pde-arduino-sketch/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#9734; Identifying Your Android USB Accessory</title>
		<link>http://jeffreysambells.com/posts/2011/05/15/identifying-your-android-usb-accessory/</link>
		<comments>http://jeffreysambells.com/posts/2011/05/15/identifying-your-android-usb-accessory/#comments</comments>
		<pubDate>Mon, 16 May 2011 03:49:07 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=1260</guid>
		<description><![CDATA[When you create your first Android USB Accessory with the Android ADK, one of the first things you&#8217;ll need to do is identify your accessory when you connect it to your Android device. Within the Arduino sketch for your accessory, you identify your accessory in the AndroidAccessory object. AndroidAccessory(const char *manufacturer, const char *model, const [...]<p><a href="http://jeffreysambells.com/posts/2011/05/15/identifying-your-android-usb-accessory/">&#9734; Permalink</a></p>]]></description>
			<content:encoded><![CDATA[<p>When you create your first Android USB Accessory with the Android ADK, one of the first things you&#8217;ll need to do is identify your accessory when you connect it to your Android device. Within the Arduino sketch for your accessory, you identify your accessory in the <code>AndroidAccessory</code> object.</p>

<pre><code>AndroidAccessory(const char *manufacturer,
                 const char *model,
                 const char *description,
                 const char *version,
                 const char *uri,
                 const char *serial);
</code></pre>

<p>For example, the DemoKit app that comes with the ADK identifies itself as version 1.0 of the Google DemoKit accessory:</p>

<pre><code>AndroidAccessory acc("Google, Inc.",
                 "DemoKit",
                 "DemoKit Arduino Board",
                 "1.0",
                 "http://www.android.com",
                 "0000000012345678");
</code></pre>

<p>You&#8217;re own app might looks something like this:</p>

<pre><code>AndroidAccessory acc("My App Company",
                 "CoolAccessory",
                 "CoolAccessory Arduino Board",
                 "1.0",
                 "http://www.example.com/CoolAccessory",
                 "0000000012345678");
</code></pre>

<p>The three key one&#8217;s you&#8217;ll need to remember are <code>manufacturer</code>, <code>model</code> and <code>version</code> as you&#8217;ll need to define these in you&#8217;re Android app so that the device can notify your app when your accessory is connected.</p>

<p>When you create your Android app, there&#8217;s a few steps you need to take. First, not every Android-powered device supports the USB accessory APIs. In fact, the Android Open Accessory ADK is only supported by Android OS 3.1 and 2.3.4 platforms. To identify that your app has USB features, you need to include a <code>&lt;uses-feature&gt;</code> element in your manifest to declare that your application uses the <code>android.hardware.usb.accessory</code> feature.</p>

<pre><code> &lt;uses-feature android:name="android.hardware.usb.accessory" /&gt;
</code></pre>

<p>Next, if you&#8217;re using the add-on library, add a <code>&lt;uses-library&gt;</code> element with <code>com.android.future.usb.accessory</code> for the USB accessory library.</p>

<pre><code>&lt;uses-library android:name="com.android.future.usb.accessory" /&gt;
</code></pre>

<p>and set the minimum SDK of the application to API Level 10. If you&#8217;re using <code>theandroid.hardware.usb package</code> then the <code>&lt;uses-library&gt;</code> isn&#8217;t necessary and you only need to set the minimum SDK to 12 .</p>

<p>Lastly, you&#8217;ll want your application to be notified when your accessory is attached. Specify an <code>&lt;intent-filter&gt;</code> and <code>&lt;meta-data&gt;</code> element pair for the <code>android.hardware.usb.action.USB_ACCESSORY_ATTACHED</code> intent in your main activity. Overall your manifest should look something like this:</p>

<pre><code>&lt;manifest ...&gt;
Â  Â  &lt;uses-feature android:name="android.hardware.usb.accessory" /&gt; 
Â  Â  &lt;uses-sdk android:minSdkVersion="&lt;version&gt;" /&gt;
Â  Â  ...
Â  Â  &lt;application&gt;
Â  Â  Â    &lt;uses-library android:name="com.android.future.usb.accessory" /&gt;
Â  Â  Â  Â  &lt;activity ...&gt;
Â  Â  Â  Â  Â  Â  ...
Â  Â  Â  Â  Â  Â  &lt;intent-filter&gt;
Â  Â  Â  Â  Â  Â  Â  Â  &lt;action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /&gt;
Â  Â  Â  Â  Â  Â  &lt;/intent-filter&gt;
Â  Â  Â  Â  Â  Â  &lt;meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
Â  Â  Â  Â  Â  Â  Â  Â  android:resource="@xml/accessory_filter" /&gt;
Â  Â  Â  Â  &lt;/activity&gt;
Â  Â  &lt;/application&gt;
&lt;/manifest&gt;
</code></pre>

<p>The <code>&lt;meta-data&gt;</code> element references an XML resource file that includes the <code>manufacturer</code>, <code>model</code> and <code>version</code> you defined earlier in your Arduino sketch. Create an <code>accessory_filter.xml</code> resource file in the <code>res/xml/</code> directory with a <code>&lt;usb-accessory&gt;</code> element to identify your accessory.</p>

<pre><code>&lt;resources&gt;
    &lt;usb-accessory model="CoolAccessory" manufacturer="My App Company" version="1.0"/&gt;
&lt;/resources&gt;
</code></pre>

<p>Now, when you connect your accessory to the device android will send an intent to open an appropriate application. The best part is that more than one application can respond to a given intent so multiple apps could optionally respond for the same accessory.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2011/05/15/identifying-your-android-usb-accessory/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#9734; Android Open Accessory API and Development Kit</title>
		<link>http://jeffreysambells.com/posts/2011/05/13/android-open-accessory-api-and-development-kit/</link>
		<comments>http://jeffreysambells.com/posts/2011/05/13/android-open-accessory-api-and-development-kit/#comments</comments>
		<pubDate>Sat, 14 May 2011 02:21:05 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[How-To]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=1248</guid>
		<description><![CDATA[<p><figure title=""><img src="http://jeffreysambells.com/wordpress/wp-content/uploads/2011/05/IMG_2026-600x448.jpg" class="attachment-h5bp-post-image wp-post-image" alt="The parts of the Android ADK" title="Google IO Android ADK Arduino and Shield" /></figure></p>A co-worker was lucky enough to be invited to Google IO this year to promote our Lozzal Android app. That went great but while there, he snagged me one of the Android Open Accessory API and Development Kits (ADK)! Though he got to keep the sweet, sweet tablet which kills my idea of a home [...]<p><a href="http://jeffreysambells.com/posts/2011/05/13/android-open-accessory-api-and-development-kit/">&#9734; Permalink</a></p>]]></description>
			<content:encoded><![CDATA[<p><figure title=""><img src="http://jeffreysambells.com/wordpress/wp-content/uploads/2011/05/IMG_2026-600x448.jpg" class="attachment-h5bp-post-image wp-post-image" alt="The parts of the Android ADK" title="Google IO Android ADK Arduino and Shield" /></figure></p><p>A co-worker was lucky enough to be invited to <a href="http://www.google.com/events/io/2011/">Google IO</a> this year to promote our <a href="https://market.android.com/details?id=com.lozzal">Lozzal Android app</a>. That went great but while there, he snagged me one of the <a href="http://a.android.com">Android Open Accessory API and Development Kits (ADK)</a>! Though he got to <a href="http://news.cnet.com/8301-30685_3-20061487-264.html">keep the sweet, sweet tablet</a> which kills my idea of a home automation panel on the kitchen wall.</p>

<p>I&#8217;m pretty excited about the Android ADK, especially since it&#8217;s based on one of the Maker&#8217;s favourite platform&#8212;Arduino. If you&#8217;re not sure why this is so awesome, I suggest reading the Makezine post on <a href="http://blog.makezine.com/archive/2011/05/why-google-choosing-arduino-matters-and-the-end-of-made-for-ipod-tm.html">Why Google Choosing Arduino Matters</a>. I looked into building external devices with iOS a few moths back but quickly discovered Apple requires special chipsets&#8211;which can&#8217;t be easily obtained by little indy hardware developers like myself. Now, with an easily accessible platform and relatively cheap hardware components, I have lots of projects I want to dive right into.</p>

<p>For those that didn&#8217;t get one, here&#8217;s a quick demo of what the Android ADK hardware includes (Sorry about the audio, didn&#8217;t have a mic):</p>

<iframe width="600" height="480" src="http://www.youtube.com/embed/XEe3dYBj7RE" frameborder="0" allowfullscreen></iframe>

<p>Included in the kit:</p>

<ul>
<li>A USB micro-controller board that is based on the Arduino Mega2560</li>
<li>Android Accessory demo Shield

<ul>
<li>Joystick</li>
<li>3 Buttons</li>
<li>3 RGB LEDs</li>
<li>Temperature Sensor</li>
<li>Light Sensor</li>
<li>Capacitive touch sensor</li>
<li>2 relays (24 VOC, 1A max)</li>
<li>2 servos (though the board has three connectors)</li>
</ul></li>
<li>AC Adapter</li>
<li>USB cable</li>
</ul>

<p>Before creating this demo video I only spent about 10 min <a href="http://developer.android.com/guide/topics/usb/adk.html">installing and setting up</a> the Arduino software, Android ADK components and the DemoKit app on the phone.  The initial setup is quite easy and you can be playing in minutes.</p>

<p>My only complaint (if you can call it that) is it would have been awesome to have more IO sensors, maybe IR (tv remote!), sound, or NFC on there. I guess it&#8217;s time I investigate all the other great <a href="http://www.arduino.cc/en/Main/ArduinoShields">Arduino shields</a> and see what else I can do.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2011/05/13/android-open-accessory-api-and-development-kit/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#9734; Debugging and sniffing mobile device traffic</title>
		<link>http://jeffreysambells.com/posts/2011/03/15/debugging-and-sniffing-mobile-device-traffic/</link>
		<comments>http://jeffreysambells.com/posts/2011/03/15/debugging-and-sniffing-mobile-device-traffic/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 18:31:12 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[BlackBerry]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=1199</guid>
		<description><![CDATA[So, you&#8217;re developing you&#8217;re mobile web app when suddenly things start to go awry on the device. Request don&#8217;t seem to be sending out properly and your responses just don&#8217;t seem to be right. In a desktop environment you could easily pop open your web inspector to see what&#8217;s going on as network requests are [...]<p><a href="http://jeffreysambells.com/posts/2011/03/15/debugging-and-sniffing-mobile-device-traffic/">&#9734; Permalink</a></p>]]></description>
			<content:encoded><![CDATA[<p>So, you&#8217;re developing you&#8217;re mobile web app when suddenly things start to go awry on the device. Request don&#8217;t seem to be sending out properly and your responses just don&#8217;t seem to be right. In a desktop environment you could easily pop open your web inspector to see what&#8217;s going on as network requests are sent and received but in a mobile environment what are you to do? Well don&#8217;t fret, if you&#8217;ve got a Mac (or a PC with similar functionality) sniffing out device traffic is as easy as a few clicks.</p>

<p>The basic idea is that you&#8217;ll share your desktop&#8217;s internet connection with your mobile device and then watch any traffic you want from your desktop. This involves a few simple steps:</p>

<ol>
<li>Share your desktop&#8217;s internet connection.</li>
<li>Use the shared connection from your mobile device.</li>
<li>Sniff your traffic.</li>
</ol>

<h2>Sharing your desktop internet connection with your mobile device</h2>

<p>In a Mac environment this is easy (and you should be able to <a href="http://support.microsoft.com/kb/306126">do something similar in Windows</a>). The only requirement is that you&#8217;ll need a wireless card (comes built-in to all modern Macs) and you&#8217;ll need a second internet connection such as the ethernet port (since your wireless card will be occupied sharing your connection). Once you have these, simply go to:</p>

<p>Apple Menu > System Preferences&#8230; > Sharing (under Internet &amp; Wireless)</p>

<p>In this pane, click on the <strong>&#8220;Internet Sharing&#8221;</strong> text but don&#8217;t check the box yet. Select <strong>Ethernet</strong> from <strong>&#8220;Share your connection from&#8221;</strong> and then check the box next to <strong>AirPort</strong> in <strong>&#8220;To computers using&#8221;</strong>. Now check the box next to &#8220;Internet Sharing&#8221; on the left. It should look something like this:</p>

<p><figure><img src="http://jeffreysambells.com/wordpress/wp-content/uploads/2011/03/Screen-shot-2011-03-15-at-1.36.32-PM-600x491.png" alt="" title="Apple's Internet Sharing Settings" class="wp-image-1202" /></figure></p>

<p>This tells your mac to take the incoming Internet connection on your Ethernet port and send it out to other connected devices on your wireless AirPort port. If everything went well you&#8217;ll also notice the icon for your AirPort connection looks like a little arrow pointing up:</p>

<p><img src="http://jeffreysambells.com/wordpress/wp-content/uploads/2011/03/Screen-shot-2011-03-15-at-1.37.20-PM.png" alt="" title="Screen shot 2011-03-15 at 1.37.20 PM" class="wp-image-1203"/>.</p>

<p><strong>NOTE: This creates an OPEN network without a password that anyone can connect to. If you&#8217;re in an area where you would rather have a private network, select the &#8220;AirPort Options&#8230;&#8221; button in the sharing pane and adjust settings as necessary before you start up your shared connection.</strong></p>

<h2>Connecting to the your shared connection from your mobile device.</h2>

<p>Now you can connect any Wi-Fi device to your shared network including other computers, iPhones, iPads, Android phones, whatever.</p>

<p>For an iOS device, simple go to:</p>

<p>Settings.app > Wi-Fi</p>

<p>and select your shared network (in my case &#8220;Jeffrey Sambellsâ€™s MacBook Pro&#8221;).</p>

<p>For Android you can find similar settings in Settings > Wireless &amp; Networks > Wi-Fi Settings.</p>

<p>Once you&#8217;re connected to your shared Wi-Fi your mobile device will act as usual but all it&#8217;s traffic will be routing through your desktop computer&#8211;perfect for sniffing.</p>

<p><em>TIP: I find it&#8217;s often a good idea to enable Airplane mode on your mobile device so that you can be sure the requests will go over Wi-Fi instead of the cell network. To do this, just turn on Airplane mode in settings and then enable just Wi-Fi to connect to your shared connection.</em></p>

<h2>Sniffing your mobile traffic.</h2>

<p>Now comes the fun part. Since all the traffic from your device is now routing through your shared network, you can watch that network and see what&#8217;s going on.</p>

<p>I&#8217;ve found the easiest way to do this is using an app like <a href="http://www.tuffcode.com/index.html">HTTPScoop</a>. If you set HTTPScoop watch your AirPort interface and then hit Scoop you&#8217;ll get a list of all the HTTP connections that occur to and from the mobile device:</p>

<p><figure><img src="http://jeffreysambells.com/wordpress/wp-content/uploads/2011/03/Screen-shot-2011-03-15-at-2.07.29-PM-600x240.png" alt="" title="HTTPScoop List" class="wp-image-1204" /></figure></p>

<p>and you can inspect each request for headers, raw data and the content of the request:</p>

<p><figure><img src="http://jeffreysambells.com/wordpress/wp-content/uploads/2011/03/Screen-shot-2011-03-15-at-2.07.55-PM-600x276.png" alt="" title="HTTP Inspection" class="wp-image-1205" /></figure></p>

<p>This is <strong>very</strong> useful for debugging you app&#8217;s requests and response as well as poking to see how other apps (including Apple&#8217;s built in apps) communicate with the network. Every wonder how map tiles load into the Maps.app? Or maybe you&#8217;re curious what info all your installed apps are sending out about you. Know you can find out.</p>

<p>If you need deeper details about the network traffic, there&#8217;s <a href="http://www.google.com/search?ie=UTF-8&amp;q=mac+os+x+packet+sniffing">a number of other apps you can use</a> that provide more details packet analysis.</p>

<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2011/03/15/debugging-and-sniffing-mobile-device-traffic/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#9734; XML Attributes for Custom Views and Layouts in Android OS SDK</title>
		<link>http://jeffreysambells.com/posts/2010/10/28/custom-views-and-layouts-in-android-os-sdk/</link>
		<comments>http://jeffreysambells.com/posts/2010/10/28/custom-views-and-layouts-in-android-os-sdk/#comments</comments>
		<pubDate>Thu, 28 Oct 2010 17:51:32 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=1096</guid>
		<description><![CDATA[One of the nifty features of the Android OS SDK is the ability to add custom components to your layouts. This lets you alter the behaviour of existing components or create your very own specialized components. Typically you would extend any of the existing Android views or layouts and override various methods to achieve whatever [...]<p><a href="http://jeffreysambells.com/posts/2010/10/28/custom-views-and-layouts-in-android-os-sdk/">&#9734; Permalink</a></p>]]></description>
			<content:encoded><![CDATA[<p>One of the nifty features of the Android OS SDK is the ability to add custom components to your layouts. This lets you alter the behaviour of existing components or create your very own specialized components.</p>

<p>Typically you would extend any of the existing Android views or layouts and override various methods to achieve whatever you want to do:</p>

<pre><code>package com.example;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;

public class MyLayout extends LinearLayout {

    public MyLayout(Context context) {
        super(context);
    }

    public MyLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void onFinishInflate() {
        super.onFinishInflate();

        // Your fancy code...

    }

}
</code></pre>

<p>Then in your layout XML files you can use these new objects by specifying the class path in the XML node:</p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#fff"&gt;

    &lt;com.example.MyLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" /&gt;

&lt;/RelativeLayout&gt;
</code></pre>

<p>I&#8217;ve done this several times in my Android projects but I didn&#8217;t realize until recently that you can also specify your own attributes. To do so, you list what attributes are available in the attrs.xml file. For example, let&#8217;s say we want to create a <code>text</code> attribute for the <code>MyLayout</code> class. In <code>res/values/attrs.xml</code> you  declare <code>text</code> as a string attribute that is styleable for the <code>MyLayout</code> class:</p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
     &lt;declare-styleable name="MyLayout"&gt;
        &lt;attr name="text" format="string" /&gt;
    &lt;/declare-styleable&gt;
&lt;/resources&gt;
</code></pre>

<p>Now you can add a new namespace (for example <code>myapp</code>) to your layout XML file and declare your own properties using that namespace:</p>

<pre><code><?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:myapp="http://schemas.android.com/apk/res/com.example"
    android:id="@+id/root"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#fff"&gt;

    &lt;com.example.MyLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        myapp:text="My Special Text String"/&gt;

&lt;/RelativeLayout&gt;
</code></pre>

<p>All that&#8217;s left to do is read and apply the attributes when your custom component is created in <code>MyLayout(Context context, AttributeSet attrs)</code>:</p>

<pre><code>package com.example;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import com.example.R;

public class MyLayout extends LinearLayout {

    private String mText;

    public MyLayout(Context context) {
        super(context);
    }

    public MyLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.MyLayout);
        CharSequence s = a.getString(R.styleable.MyLayout_text);
        if (s != null) {
            mText = s.toString();
        }
        a.recycle();
    }

    @Override
    public void onFinishInflate() {
        super.onFinishInflate();

        // Your fancy code suing the mText property...

    }   
}
</code></pre>

<p>This ability to customize your object from the layout XML files comes in especially handy when providing different layouts for different devices or orientations.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2010/10/28/custom-views-and-layouts-in-android-os-sdk/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>&#9734; Direct Download Link Structure for Mobile App Stores</title>
		<link>http://jeffreysambells.com/posts/2010/09/08/direct-download-link-structure-for-mobile-app-stores/</link>
		<comments>http://jeffreysambells.com/posts/2010/09/08/direct-download-link-structure-for-mobile-app-stores/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 01:15:33 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Advertising]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[BlackBerry]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=736</guid>
		<description><![CDATA[Marketing and distributing your mobile apps can be tricky. One of the easiest but lesser know ways is to provide mobile users with the appropriate download links for their respective stores. Most mobile OSes provide special protocols or URLs that will launch the appropriate store apps when selected. Of course, the disadvantage is that not [...]]]></description>
			<content:encoded><![CDATA[<p>Marketing and distributing your mobile apps can be tricky. One of the easiest but lesser know ways is to provide mobile users with the appropriate download links for their respective stores. Most mobile OSes provide special protocols or URLs that will launch the appropriate store apps when selected.</p>

<p>Of course, the disadvantage is that not all these links will work for all devices so its best to selectively display them depending on the mobile OS. That aside, the link structure is relatively simple.</p>

<h2>iTunes (iOS) App Store</h2>

<p>To link to the iTunes app store from any iOS device, or web browser, simply link to <code>http://itunes.com/app/YourAppName</code> for example <a href="http://itunes.com/app/FlipFrog">http://itunes.com/app/FlipFrog</a>. This will either launch the appropriate app store application (iTunes on your computer, App Store on an iOS device) or display the product page in the web browser.</p>

<h2>Android</h2>

<p>To link to the Android Market from an Android device, use the <code>market://</code> protocol and your package name like this: <code>market://details?id=your.package.name</code>, for example <a href="market://details?id=com.lozzal">market://details?id=com.lozzal</a>. This will launch the Market application on an Android mobile device but unfortunately won&#8217;t do anything in a regular web browser (not even in Chrome).</p>

<p>If you like, you can also link directly to a market search page using 
<code>market://search?q=pname:your.package.name</code> (for example <a href="market://search?q=pname:com.lozzal">market://search?q=pname:com.lozzal</a>) which may be useful if you have a number of different apps or want to provide similar alternatives.</p>

<h2>BlackBerry</h2>

<p>To link to the BlackBerry App World from a BlackBerry device or in any web browser, link to
<code>http://appworld.blackberry.com/webstore/content/your_app_id</code>, for example <a href="http://appworld.blackberry.com/webstore/content/8160">http://appworld.blackberry.com/webstore/content/8160</a>. This will display the detail page in the browser and provide the appropriate direct download links for the device.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2010/09/08/direct-download-link-structure-for-mobile-app-stores/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#9734; Decoding Polylines from Google Maps Direction API with Java</title>
		<link>http://jeffreysambells.com/posts/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java/</link>
		<comments>http://jeffreysambells.com/posts/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java/#comments</comments>
		<pubDate>Thu, 27 May 2010 16:44:20 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Maps]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Directions]]></category>
		<category><![CDATA[GeoPoint]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Polyline]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=661</guid>
		<description><![CDATA[I&#8217;ve been integrating the new Google Maps Directions api into an Android app and couldn&#8217;t find a Java decoder for the Encoded Polyline Algorithm Format. After a little bit of grunt work here&#8217;s a working method that will convert an encoded result such as this: }wjiGtdpcNrAlBJZ into a nice GeoPoint array list: private List&#60;GeoPoint&#62; decodePoly(String [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been integrating the new <a href="http://code.google.com/apis/maps/documentation/directions/">Google Maps Directions api</a> into an Android app and couldn&#8217;t find a Java <em>decoder</em> for the <a href="http://code.google.com/apis/maps/documentation/utilities/polylinealgorithm.html">Encoded Polyline Algorithm Format</a>. After a little bit of grunt work here&#8217;s a working method that will convert an encoded result such as this:</p>

<pre><code> }wjiGtdpcNrAlBJZ
</code></pre>

<p>into a nice GeoPoint array list:</p>

<pre><code>private List&lt;GeoPoint&gt; decodePoly(String encoded) {

    List&lt;GeoPoint&gt; poly = new ArrayList&lt;GeoPoint&gt;();
    int index = 0, len = encoded.length();
    int lat = 0, lng = 0;

    while (index &lt; len) {
        int b, shift = 0, result = 0;
        do {
            b = encoded.charAt(index++) - 63;
            result |= (b &amp; 0x1f) &lt;&lt; shift;
            shift += 5;
        } while (b &gt;= 0x20);
        int dlat = ((result &amp; 1) != 0 ? ~(result &gt;&gt; 1) : (result &gt;&gt; 1));
        lat += dlat;

        shift = 0;
        result = 0;
        do {
            b = encoded.charAt(index++) - 63;
            result |= (b &amp; 0x1f) &lt;&lt; shift;
            shift += 5;
        } while (b &gt;= 0x20);
        int dlng = ((result &amp; 1) != 0 ? ~(result &gt;&gt; 1) : (result &gt;&gt; 1));
        lng += dlng;

        GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6),
             (int) (((double) lng / 1E5) * 1E6));
        poly.add(p);
    }

    return poly;
}
</code></pre>

<p>If you need an encoder (or other decoders) check out Mark McClure&#8217;s page <a href="http://facstaff.unca.edu/mcmcclur/googlemaps/encodepolyline/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>&#9734; Android vs iPhone development decisions</title>
		<link>http://jeffreysambells.com/posts/2010/05/20/android-vs-iphone-development-decisions/</link>
		<comments>http://jeffreysambells.com/posts/2010/05/20/android-vs-iphone-development-decisions/#comments</comments>
		<pubDate>Fri, 21 May 2010 04:34:15 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=646</guid>
		<description><![CDATA[Release early, release often (sometimes abbreviated RERO) is a software development philosophy that emphasizes the importance of early and frequent releases in creating a tight feedback loop between developers and users. &#8212; Wikipedia To begin let me say that I&#8217;m both a web developer and a mobile application developer and I LOVE the &#8220;release early, [...]]]></description>
			<content:encoded><![CDATA[<blockquote>
  <p>Release early, release often (sometimes abbreviated RERO) is a software development philosophy that emphasizes the importance of early and frequent releases in creating a tight feedback loop between developers and users.</p>
</blockquote>

<p>&#8212; Wikipedia</p>

<p>To begin let me say that I&#8217;m both a web developer and a mobile application developer and I LOVE the &#8220;release early, release often&#8221; philosophy for web development. RERO allows me to make quick updates and improvements and add great new features for all my users. RERO is great. It&#8217;s awesome. It works and all the developers and users using the application are happy.</p>

<p>On the other hand, I loath RERO when it comes to SDK&#8217;s. It&#8217;s just a flawed and utterly terrible idea when there&#8217;s no clear and very accessible upgrade path for end users. As a web developer, I would not be happy if Microsoft decided to release IE9, IE10 and IE11 in the span of a year. My workload would more than triple, my user base would fragment and I&#8217;d be endlessly adding kludges for each new version. Unfortunately this is what&#8217;s starting to happen with the Android SDK and, as a mobile developer, I&#8217;m starting to get worried.</p>

<h2>Android OS</h2>

<p>To understand how RERO can harm adoption let&#8217;s take a look at the <em>public</em> Android SDK release schedule:</p>

<ul>
<li>API Level 2, Android 1.1 &#8212; February 2009</li>
<li>API Level 3, Android 1.5 &#8212; April 2009</li>
<li>API Level 4, Android 1.6 &#8212; September 2009</li>
<li>API Level 5, Android 2.0 &#8212; October 2009</li>
<li>
<ul>
<li>API Level 6, Android 2.01 &#8212; December 2009</li>
</ul></li>
<li>API Level 7, Android 2.1 &#8212; January 2009</li>
<li>API Level 8, Android 2.2 &#8212; May 2009</li>
</ul>

<p>Wow. In the past fifteen months (a little over a year) there have been seven public releases of different versions of the Android SDK. That doesn&#8217;t include carrier or manufacturer revisions with different user interfaces. It&#8217;s not that I&#8217;m not happy with the advancements of the SDK. They&#8217;re all wonderful and obviously the Android team is working really hard but there&#8217;s a problem. If we take a look at Google&#8217;s published Platform Versions stats and we can see where developers have a tough decision:</p>

<p><img src="http://jeffreysambells.com/wordpress/wp-content/uploads/2010/05/chart.png" alt="" title="Android Platform Chart" width="460" height="250" class="aligncenter size-full wp-image-648" />
&#8212; <a href="http://developer.android.com/resources/dashboard/platform-versions.html">Source</a></p>

<p>More than 50% of the Android install base is still using version 1.6 or less. As a developer what should I do? If I choose to take advantage of the latest and greatest SDK I get less than half of the devices! But still, the bigger problem is there is no clear and easy upgrade path for those bottom 50% to get the newer OS version. Neither of my Google supplied development phones (which are only a year old) can be upgraded without a lot of illicit hacking and deep developer knowledge.</p>

<p>The Android OS is in deep trouble until there&#8217;s an easy way to upgrade the OS on every device that runs it.</p>

<h2>iPhone OS</h2>

<p>Now contrast this situation with iPhone OS. Apple has been lambasted by developers for their tight control and strict NDA rules regarding beta releases but in comparison to the situation with Android isn&#8217;t it better? The NDA period allows the SDK to be flushed out, before it is &#8220;publicly&#8221; available so that there is one complete well oiled version that all developers can target across a large set of devices.</p>

<p>The <em>public</em> iPhone SDK release timeline is also much longer:</p>

<ul>
<li>SDK 1.0 &#8211; June 2007 (not public)</li>
<li>SDK 2.0 &#8211; July 2008</li>
<li>SDK 3.0 &#8211; June 2009</li>
<li>
<ul>
<li>SDK 3.1 &#8211; September 2009</li>
</ul></li>
<li>
<ul>
<li>
<ul>
<li>SDK 3.1.2 &#8211; October 2009</li>
</ul></li>
</ul></li>
<li>
<ul>
<li>
<ul>
<li>SDK 3.1.3 &#8211; February 2010</li>
</ul></li>
</ul></li>
<li>SDK 3.2 &#8211; April 2010</li>
</ul>

<p>Major iPhone releases are spaced a year apart (with a few minor releases in-between) allowing developers to actually develop and release an app before the SDK changes.</p>

<p>The iPhone has another big advantage and it solves the problem of distribution as I alluded to earlier. iPhone users use iTunes to sync their devices and add content. The process of syncing the device also checks for updates and allows <em>all</em> iPhone OS devices (iPhones, iPod Touches, iPads) to download the latests version of the OS. As a result the March 2010 iPhone Platform Versions stats look very developer friendly:</p>

<p><img src="http://jeffreysambells.com/wordpress/wp-content/uploads/2010/05/Screen-shot-2010-05-20-at-4.01.22-PM.png" alt="" title="iPhone Platform Chart" width="439" height="310" class="aligncenter size-full wp-image-650" />
&#8212; <a href="http://metrics.admob.com/wp-content/uploads/2010/04/AdMob-Mobile-Metrics-Mar-10.pdf">Source</a></p>

<p>That&#8217;s only 5% of users who have NOT upgraded to at least 3.0 and 86% who are using one of the latest two (as of March) 3.1 minor versions. How great is that? Not only does 3.1 contain great features, I can actually use them and hit 86% of my users right away.</p>

<h2>The Result</h2>

<p>Recent trends are showing that Android OS based devices are passing Appleâ€™s iPhone OS devices to be the No. 2 smartphone operating system in the U.S.&#8212;After RIM&#8217;s Blackberry OS:</p>

<ul>
<li>RIMâ€™s BlackBerry OS at 36 percent;</li>
<li>Android at 28 percent;</li>
<li>Apple at 21 percent.</li>
</ul>

<p>&#8212;<a href="http://www.npd.com/press/releases/press_100510.html">source</a></p>

<p>I say as a developer I don&#8217;t care. The number of devices per OS is a great marketing number for Google and Apple to fight over but as a developer&#8212;who wants to get the most out of the SDK&#8212;I care about the <em>version</em> of the OS on the devices. If I want to use the latest and greatest SDK&#8217;s I&#8217;ll take Apple&#8217;s 80% of 21% over Google&#8217;s 30% of 28%.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2010/05/20/android-vs-iphone-development-decisions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>&#9734; Android TextView with Auto Sized Content</title>
		<link>http://jeffreysambells.com/posts/2010/04/04/android-textview-with-auto-sized-content/</link>
		<comments>http://jeffreysambells.com/posts/2010/04/04/android-textview-with-auto-sized-content/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 04:08:41 +0000</pubDate>
		<dc:creator>Jeffrey Sambells</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[User Interface]]></category>
		<category><![CDATA[TextView]]></category>

		<guid isPermaLink="false">http://jeffreysambells.com/?p=461</guid>
		<description><![CDATA[While working on an Android project lately I was looking for a solution to auto-size text in a TextView similar to the way the iPhone ADK allows you to select &#8220;fit text to box&#8221;. I couldn&#8217;t find any reference to something similar in the Android SDK so I had to roll my own TextView subclass. [...]]]></description>
			<content:encoded><![CDATA[<p>While working on an Android project lately I was looking for a solution to auto-size text in a <code>TextView</code> similar to the way the iPhone ADK allows you to select &#8220;fit text to box&#8221;. I couldn&#8217;t find any reference to something similar in the Android SDK so I had to roll my own <code>TextView</code> subclass.</p>

<p>Now all I have to do is call <code>setFitTextToBox(true)</code> on the <code>TextFitTextView</code> after allocation. Enjoy!</p>

<pre><code>public class TextFitTextView extends TextView {

    static final String TAG = "TextFitTextView";
    boolean fit = false;

    public TextFitTextView(Context context) {
        super(context);
    }

    public TextFitTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextFitTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setFitTextToBox( Boolean fit ) {
        this.fit = fit;
    }

    protected void onDraw (Canvas canvas) {
        super.onDraw(canvas);
        if (fit) _shrinkToFit();
    }

    protected void _shrinkToFit() {

        int height = this.getHeight();
        int lines = this.getLineCount();
        Rect r = new Rect();
        int y1 = this.getLineBounds(0, r);
        int y2 = this.getLineBounds(lines-1, r);

        float size = this.getTextSize();
        if (y2 &gt; height &amp;&amp; size &gt;= 8.0f) {
            this.setTextSize(size - 2.0f);
            _shrinkToFit();
        }

    }
}
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://jeffreysambells.com/posts/2010/04/04/android-textview-with-auto-sized-content/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

