<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkQASXg9eyp7ImA9Wx5QGUU.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759</id><updated>2010-09-08T14:12:28.663-07:00</updated><title>My Brain Hurts</title><subtitle type="html">Mobile development code, ramblings, and opinions.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.koushikdutta.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>160</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/MyBrainHurts" /><feedburner:info uri="mybrainhurts" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by/3.0/" /><entry gd:etag="W/&quot;DkIFRXw_eyp7ImA9Wx5QEk0.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-6265132046784824590</id><published>2010-08-18T19:23:00.002-07:00</published><updated>2010-08-30T14:41:54.243-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-30T14:41:54.243-07:00</app:edited><title>Droid X Recovery (and Droid 2 too!)</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_1Q1cgK2sxXk/TGyVwFTeDaI/AAAAAAAAAgw/miGn9sABdnA/s1600/logo2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 238px; height: 400px;" src="http://1.bp.blogspot.com/_1Q1cgK2sxXk/TGyVwFTeDaI/AAAAAAAAAgw/miGn9sABdnA/s400/logo2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5506941097657372066" /&gt;&lt;/a&gt;
&lt;br/&gt;
&lt;br/&gt;
Well, this was a bitch.
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Caveats:&lt;/span&gt;
&lt;br/&gt;
This is not a *real* recovery. The way this recovery works is by hijacking portions of your boot process during system initialization and starting into recovery instead. So, if you hose your system *COMPLETELY* you will need to SBF. Specifically, if your logwrapper, logwrapper.bin, or hijack binary are missing from /system/bin, you will be screwed.
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Do I have to be rooted to run this?&lt;/span&gt;
&lt;br/&gt;
Yes.
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;So can we now install custom ROMs?&lt;/span&gt;
&lt;br/&gt;
Yes, but you can't replace the kernel or boot image. But really, once you have access to /system, anything is possible. It will just take a little hackery.
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;How does this work?&lt;/span&gt;
&lt;br/&gt;
When your device boots up, there is a init.rc script in your boot image that runs various components found in /system. The Droid X recovery bootstrap mimics the "logwrapper" binary. The hijacker then looks for "/data/.recovery_mode", and if it finds it, it unmounts /system to prevent android from starting. It then starts up recovery instead.
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;How do I boot into recovery?&lt;/span&gt;
&lt;br/&gt;
You can manually create the /data/.recovery_mode via a terminal file and simply reboot, and you will be in recovery. Or you can use the handy Droid X Recovery Bootstrap application to reboot into recovery.
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;What if my phone won't boot? How do I get into recovery without the app?&lt;/span&gt;
&lt;br/&gt;
When the hijacker runs, it will automatically create the "/data/.recovery_mode" file after it finishes. This tells the system that the next time it boots, it should boot into recovery. But, when the system starts, the Droid X Recovery Bootstrap will then delete that file when Android is fully started, to prevent you from booting into recovery. So what does this mean? If you fail to boot, simply pull your battery, and your next boot will be into recovery (unless your /system is *really* hosed, in which case you need to SBF).
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;How do I fix my phone if I really mess it up?&lt;/span&gt;
&lt;br/&gt;
Use an SBF. Google it. &lt;a href=" http://twitter.com/b16a2smith/status/21544626803"&gt;http://twitter.com/b16a2smith/status/21544626803&lt;/a&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Why does the Droid X Recovery Bootstrap start on boot?&lt;/span&gt;
&lt;br/&gt;
As mentioned above, it needs to log that your phone booted successfully and recovery mode is not necessary. It also replaces your "adb daemon" with one that has root permissions, allowing for easier usage of the adb command.
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Will this work with ROM Manager?&lt;/span&gt;
&lt;br/&gt;
Yep! But you must run the Bootstrap app and leave it installed.
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Is this open source?
&lt;br/&gt;
&lt;/span&gt;Yep.
&lt;br/&gt;
Recovery: &lt;a href="http://github.com/koush/android_bootable_recovery"&gt;http://github.com/koush/android_bootable_recovery&lt;/a&gt;
&lt;br/&gt;
Droid X Bootstrap: &lt;a href="http://github.com/koush/DroidXBootstrap"&gt;http://github.com/koush/DroidXBootstrap&lt;/a&gt;
&lt;br/&gt;
Droid X Hijack: &lt;a href="http://github.com/koush/android_vendor_motorola_droidx"&gt;http://github.com/koush/android_vendor_motorola_droidx&lt;/a&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;OK STOP TALKING, WHERE DO I GET IT?&lt;/span&gt;
&lt;br/&gt;
You can donate and grab it for $2 off the Android Market (search for Droid X Recovery Bootstrap or Droid 2 Recovery Bootstrap), or you can download it for free here:
&lt;br/&gt;
&lt;a href="http://koush.tandtgaming.com//motorola/droidx/DroidXBootstrap.apk"&gt;Droid X Recovery Bootstrap&lt;/a&gt;
&lt;br/&gt;
&lt;a href="http://koush.tandtgaming.com//motorola/droid2/Droid2Bootstrap.apk"&gt;Droid 2 Recovery Bootstrap&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-6265132046784824590?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/iWIaNiUJOCXgGxwB9Qy6NbjII8E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iWIaNiUJOCXgGxwB9Qy6NbjII8E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/iWIaNiUJOCXgGxwB9Qy6NbjII8E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iWIaNiUJOCXgGxwB9Qy6NbjII8E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=kfOTz9IlFuM:aL4FI_Lfvx0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=kfOTz9IlFuM:aL4FI_Lfvx0:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=kfOTz9IlFuM:aL4FI_Lfvx0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=kfOTz9IlFuM:aL4FI_Lfvx0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/kfOTz9IlFuM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/6265132046784824590/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=6265132046784824590" title="55 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/6265132046784824590?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/6265132046784824590?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/kfOTz9IlFuM/droid-x-recovery.html" title="Droid X Recovery (and Droid 2 too!)" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_1Q1cgK2sxXk/TGyVwFTeDaI/AAAAAAAAAgw/miGn9sABdnA/s72-c/logo2.png" height="72" width="72" /><thr:total>55</thr:total><feedburner:origLink>http://www.koushikdutta.com/2010/08/droid-x-recovery.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUMSHs-eip7ImA9WxFbEE0.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-5122185531288620534</id><published>2010-07-01T09:01:00.000-07:00</published><updated>2010-07-01T09:04:49.552-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-01T09:04:49.552-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="LOL" /><title>What good are ROMs and Themes without a Recovery?</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_1Q1cgK2sxXk/TCy8Du2tbGI/AAAAAAAAAe4/t_aBtrfxUG4/s1600/RECOVERY.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 271px; height: 400px;" src="http://2.bp.blogspot.com/_1Q1cgK2sxXk/TCy8Du2tbGI/AAAAAAAAAe4/t_aBtrfxUG4/s400/RECOVERY.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5488968818160921698" /&gt;&lt;/a&gt;

&lt;font size=10&gt;&lt;center&gt;Vote &lt;a href="http://alldroid.org/SiteSurveys.aspx"&gt;Koush&lt;/a&gt;.&lt;/center&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-5122185531288620534?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/l-ydXkQVp2ST5T4Y5MejxEMbao4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/l-ydXkQVp2ST5T4Y5MejxEMbao4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/l-ydXkQVp2ST5T4Y5MejxEMbao4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/l-ydXkQVp2ST5T4Y5MejxEMbao4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=DR2yhURkLwM:m7SnGcjwC0w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=DR2yhURkLwM:m7SnGcjwC0w:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=DR2yhURkLwM:m7SnGcjwC0w:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=DR2yhURkLwM:m7SnGcjwC0w:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/DR2yhURkLwM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/5122185531288620534/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=5122185531288620534" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5122185531288620534?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5122185531288620534?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/DR2yhURkLwM/what-good-are-roms-and-themes-without.html" title="What good are ROMs and Themes without a Recovery?" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_1Q1cgK2sxXk/TCy8Du2tbGI/AAAAAAAAAe4/t_aBtrfxUG4/s72-c/RECOVERY.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.koushikdutta.com/2010/07/what-good-are-roms-and-themes-without.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YMSXk9fSp7ImA9WxFWEkU.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-5946985085294016967</id><published>2010-05-30T21:44:00.000-07:00</published><updated>2010-05-30T21:46:28.765-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-30T21:46:28.765-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Android Mono" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="Mono" /><title>More Progress on Writing Android Applications in Mono</title><content type="html">&lt;center&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/NUi-ZrkbCuo&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/NUi-ZrkbCuo&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-5946985085294016967?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8Mt7JYI4DYTG5eEBIjdMqBu8-CU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8Mt7JYI4DYTG5eEBIjdMqBu8-CU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8Mt7JYI4DYTG5eEBIjdMqBu8-CU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8Mt7JYI4DYTG5eEBIjdMqBu8-CU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=sBMqj0BaYDE:6mwy6mH3P-Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=sBMqj0BaYDE:6mwy6mH3P-Y:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=sBMqj0BaYDE:6mwy6mH3P-Y:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=sBMqj0BaYDE:6mwy6mH3P-Y:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/sBMqj0BaYDE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/5946985085294016967/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=5946985085294016967" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5946985085294016967?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5946985085294016967?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/sBMqj0BaYDE/more-progress-on-writing-android.html" title="More Progress on Writing Android Applications in Mono" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>10</thr:total><feedburner:origLink>http://www.koushikdutta.com/2010/05/more-progress-on-writing-android.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QDQHw6cSp7ImA9WxFXEU4.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-846776537501380452</id><published>2010-05-17T13:41:00.000-07:00</published><updated>2010-05-17T14:22:51.219-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-17T14:22:51.219-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Android Mono" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="Mono" /><title>Mono on Android: State of the Union</title><content type="html">Having mostly finished up my surprisingly successful ROM Manager and ClockworkMod Recovery, I finally turned my attentions back to &lt;a href="http://github.com/koush/androidmono"&gt;androidmono&lt;/a&gt;. Though Miguel recently announced the &lt;a href="http://tirania.org/blog/archive/2010/Feb-17.html"&gt;MonoDroid&lt;/a&gt; project, there's still room for a open source/hobbyist version. :) (And I need something to work on when I am bored)
&lt;br/&gt;
When I put the project down a few months ago, I had very rough bindings to the Java API. I recently dumped the approach I took (albeit very cool), in favor of using &lt;a href="http://jni4net.sourceforge.net/"&gt;jni4net&lt;/a&gt;. jni4net is a similar project that allows embedding a JVM into Microsoft's CLR, or vice versa. It only took a little bit of tweaking to make it work on Dalvik with Mono (I also hacked off a lot of unnecessary stuff that jni4net provides). So the following file:
&lt;br/&gt;
&lt;pre class="githubfile" file="jni/MonoJavaBridge/HelloWorld/HelloWorldActivity.cs" repository="androidmono" user="koush" branch="devel"&gt;&lt;/pre&gt;
&lt;br/&gt;
Gives you this activity:
&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1Q1cgK2sxXk/S_Guly9cdHI/AAAAAAAAAeg/b0jaPJVvyg8/s1600/5554_android-2.1-1.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 230px;" src="http://3.bp.blogspot.com/_1Q1cgK2sxXk/S_Guly9cdHI/AAAAAAAAAeg/b0jaPJVvyg8/s320/5554_android-2.1-1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5472346986589746290" /&gt;&lt;/a&gt;
&lt;br/&gt;
(Note: the code above is being displayed from my github repo and may change and leave the image out of date.)
&lt;br/&gt;
I hacked up a Java/C# project to reflect on the Android SDK jar and create a &lt;a href="http://github.com/koush/androidmono/tree/devel/jni/MonoJavaBridge/android/"&gt;C# android project&lt;/a&gt; that binds to the Java APIs via JNI. So, how it sort of works:&lt;br/&gt;
&lt;list&gt;
&lt;li&gt;Create a class library and start coding up your services and activities.&lt;/li&gt;
&lt;li&gt;Create a matching Java project (using the Android template as found on github) that uses the same namespace as your C# project.&lt;/li&gt;
&lt;li&gt;Create "native" method stubs for all the overridden methods on your C#/&lt;a href="http://github.com/koush/androidmono/blob/devel/jni/MonoJavaBridge/HelloWorld/Android/src/com/koushikdutta/helloworld/HelloWorldActivity.java"&gt;Java doppleganger&lt;/a&gt; types. See &lt;a href="http://github.com/koush/androidmono/blob/devel/jni/MonoJavaBridge/HelloWorld/Android/src/com/koushikdutta/helloworld/HelloWorldActivity.java"&gt;here&lt;/a&gt; for an example.&lt;/li&gt;
&lt;li&gt;The native methods get bound to the C# implementations at runtime automagically at runtime.&lt;/li&gt;
&lt;/list&gt;
&lt;br/&gt;
There's still a lot of work left to do: MonoDevelop template and plugin, a tool to create Java dopplegangers for each C# object via reflection, soft debugger support, translating Java's "OnSomeEvent" interfaces into true C# events/delegates, convenence extension methods, support for constructors (a Java constructor can not be "native"), and more. I wouldn't even say this is in Alpha stages yet, but it *works*.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-846776537501380452?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZWtGHydK5dfmpVZD4QY14yYLvWw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZWtGHydK5dfmpVZD4QY14yYLvWw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZWtGHydK5dfmpVZD4QY14yYLvWw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZWtGHydK5dfmpVZD4QY14yYLvWw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=MvMx4DR0Q9E:2lDjSFN8cHI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=MvMx4DR0Q9E:2lDjSFN8cHI:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=MvMx4DR0Q9E:2lDjSFN8cHI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=MvMx4DR0Q9E:2lDjSFN8cHI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/MvMx4DR0Q9E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/846776537501380452/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=846776537501380452" title="18 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/846776537501380452?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/846776537501380452?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/MvMx4DR0Q9E/mono-on-android-state-of-union.html" title="Mono on Android: State of the Union" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_1Q1cgK2sxXk/S_Guly9cdHI/AAAAAAAAAeg/b0jaPJVvyg8/s72-c/5554_android-2.1-1.jpg" height="72" width="72" /><thr:total>18</thr:total><feedburner:origLink>http://www.koushikdutta.com/2010/05/mono-on-android-state-of-union.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8MR3YzfSp7ImA9WxFbFEg.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-6441544914338492105</id><published>2010-03-22T00:52:00.000-07:00</published><updated>2010-07-06T15:54:46.885-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-06T15:54:46.885-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ROM Manager" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="Recovery" /><title>ROM Manager and Third Party ROMs</title><content type="html">First, you'll then want to get yourself listed in the list of developers in ROM Manager:
&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_1Q1cgK2sxXk/S6c_TAlcmnI/AAAAAAAAAdY/liWj6_Hi7NQ/s1600-h/developerlist.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 192px; height: 320px;" src="http://2.bp.blogspot.com/_1Q1cgK2sxXk/S6c_TAlcmnI/AAAAAAAAAdY/liWj6_Hi7NQ/s320/developerlist.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5451395469762402930" /&gt;&lt;/a&gt;
&lt;br /&gt;
To do that, create a JavaScript file that looks like this to describe where to find information about your ROMs:
&lt;br/&gt;
&lt;br/&gt;
&lt;pre class="githubfile" file="samples/developer.js" repository="ROMManagerManifest" user="koush" branch="gh-pages"&gt;&lt;/pre&gt;
&lt;br/&gt;
&lt;br/&gt;
Make sure that the URL you provide for your ROM list above will not ever need to change. I don't like doing extra work! Send me that JavaScript you just created. I'll need to add it to the &lt;a href="http://www.clockworkmod.com/ROMManagerManifest/manifests.js"&gt;ROM Manager master manifest&lt;/a&gt; (which has the list of all the developers and their respective ROM list URLs) before it will show up in ROM Manager. The best way to send it to me is by &lt;a href="http://github.com/koush/ROMManagerManifest/issues"&gt;opening an issue on ROMManagerManifest on Github&lt;/a&gt;. If you are super awesome, you can fork, edit the manifest, and send me a pull request. Email also works (see the link at the bottom of this post), but I may lose your message.
&lt;br /&gt;
&lt;br /&gt;
Now, you'll want to describe your list of ROMs that the user sees when they click you:
&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_1Q1cgK2sxXk/S6c_x6FP-YI/AAAAAAAAAdg/nL-znqTivnQ/s1600-h/romlist.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 192px; height: 320px;" src="http://4.bp.blogspot.com/_1Q1cgK2sxXk/S6c_x6FP-YI/AAAAAAAAAdg/nL-znqTivnQ/s320/romlist.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5451396000592689538" /&gt;&lt;/a&gt;
&lt;br /&gt;
To do that, you need to create another JavaScript file that will live at the URL you provided. It should look something like &lt;a href="http://github.com/koush/ROMManagerManifest/raw/gh-pages/samples/simplemanifest.js"&gt;this&lt;/a&gt;:
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="githubfile" file="samples/simplemanifest.js" repository="ROMManagerManifest" user="koush" branch="gh-pages"&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
And that's it! Your ROM is now listed in ROM Manager!
&lt;br /&gt;
&lt;br /&gt;
But, if you want to use the more advanced features of ROM Manager, such as download mirroring, and ROM customization, check out this manifest:
&lt;br /&gt;
&lt;pre class="githubfile" file="samples/manifest.js" repository="ROMManagerManifest" user="koush" branch="gh-pages"&gt;&lt;/pre&gt;
&lt;br /&gt;
Note that you can do cool things that install a sequence of installation zip files. "choices" makes a user choose between several zips (use a URL of "" for no action). Only one of those choices will be installed. You can also have multiple choice selections. And "addons" lets the user choose any number of additional zips to install. You can view &lt;a href="http://github.com/koush/ROMManagerManifest/raw/gh-pages/cyanogenmod.js"&gt;my manifest&lt;/a&gt; for a full sample.
&lt;br /&gt;
&lt;br /&gt;
Finally, to register your ROM for OTA updates, you need to edit your /system/build.prop in your ROM to include your Developer ID ro.modversion (as mentioned above) so ROM Manager can identify the version of your ROM. This is optional as well, but why not get OTA updates if it's just a couple lines of settings!
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;
ro.rommanager.developerid=cyanogen
&lt;br /&gt;
ro.modversion=CyanogenMod-5.0.5-Droid&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
And that's it! Once you upload that file, your ROM will now be available to other Premium users!
&lt;br /&gt;
Good luck, and let me know if you encounter any bugs or need help!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-6441544914338492105?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/uqxAtnMXTFZvQ8hPSfoYACMU9hE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uqxAtnMXTFZvQ8hPSfoYACMU9hE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/uqxAtnMXTFZvQ8hPSfoYACMU9hE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uqxAtnMXTFZvQ8hPSfoYACMU9hE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=FmojmojoGOQ:ojHWBHQWX48:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=FmojmojoGOQ:ojHWBHQWX48:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=FmojmojoGOQ:ojHWBHQWX48:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=FmojmojoGOQ:ojHWBHQWX48:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/FmojmojoGOQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/6441544914338492105/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=6441544914338492105" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/6441544914338492105?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/6441544914338492105?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/FmojmojoGOQ/rom-manager-and-third-party-roms.html" title="ROM Manager and Third Party ROMs" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_1Q1cgK2sxXk/S6c_TAlcmnI/AAAAAAAAAdY/liWj6_Hi7NQ/s72-c/developerlist.png" height="72" width="72" /><thr:total>13</thr:total><feedburner:origLink>http://www.koushikdutta.com/2010/03/rom-manager-and-third-party-roms.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMCRn44fSp7ImA9Wx5TEUs.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-6274470004145090828</id><published>2010-02-26T10:24:00.001-08:00</published><updated>2010-07-26T09:07:47.035-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-26T09:07:47.035-07:00</app:edited><title>ROM Manager and Clockwork Recovery Image</title><content type="html">ROM Manager is a Android front end to the Clockwork Recovery image.

&lt;center&gt;&lt;img src="http://1.bp.blogspot.com/_1Q1cgK2sxXk/S5Vu8K5NWdI/AAAAAAAAAc4/XevWKEHfl8g/s320/screenshot1268046508600-20100308-031048.jpg" /&gt;&lt;/center&gt;

Features of the recovery image include Nandroid backup, adb shell, mount USB storage, advanced update.zip options (ignore asserts and signature checks), and file browser (so you can place your zips in subdirectories and organize them). 
&lt;br/&gt;

&lt;br/&gt;
&lt;center&gt;&lt;img src="http://2.bp.blogspot.com/_1Q1cgK2sxXk/S4gS54XsfBI/AAAAAAAAAco/-WpfrhaAWNA/s320/main.png" /&gt;    &lt;img src="http://3.bp.blogspot.com/_1Q1cgK2sxXk/S4gTB09ZPAI/AAAAAAAAAcw/pC0y1NESpnI/s320/directory.png"/&gt;&lt;/center&gt;
&lt;br/&gt;
The easiest way, by far, to install the recovery is by downloading ROM Manager off the market. But for those that would prefer a manual installation, you can grab the APK and recovery image below.
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://koush.tandtgaming.com//recoveries/RomManager.apk"&gt;ROM Manager&lt;/a&gt; (&lt;a href="http://gh-pages.clockworkmod.com/ROMManagerManifest/CHANGELOG.txt"&gt;Changelog&lt;/a&gt;)
&lt;br/&gt;
&lt;br/&gt;
Don't see your phone? Email me if you want to help me get it working!
&lt;br/&gt;
&lt;iframe src="http://gh-pages.clockworkmod.com/ROMManagerManifest/index.html" height="250"&gt;&lt;/iframe&gt;
&lt;br/&gt;
And of course, all the source can be found on &lt;a href="http://github.com/koush/android_bootable_recovery"&gt;Github&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-6274470004145090828?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sVRHf7KYTMd6eUL0U6mSMupkqYs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sVRHf7KYTMd6eUL0U6mSMupkqYs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sVRHf7KYTMd6eUL0U6mSMupkqYs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sVRHf7KYTMd6eUL0U6mSMupkqYs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=GG4jifMbgqQ:NFWipQSBu9Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=GG4jifMbgqQ:NFWipQSBu9Y:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=GG4jifMbgqQ:NFWipQSBu9Y:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=GG4jifMbgqQ:NFWipQSBu9Y:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/GG4jifMbgqQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/6274470004145090828/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=6274470004145090828" title="176 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/6274470004145090828?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/6274470004145090828?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/GG4jifMbgqQ/clockwork-recovery-image.html" title="ROM Manager and Clockwork Recovery Image" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_1Q1cgK2sxXk/S5Vu8K5NWdI/AAAAAAAAAc4/XevWKEHfl8g/s72-c/screenshot1268046508600-20100308-031048.jpg" height="72" width="72" /><thr:total>176</thr:total><feedburner:origLink>http://www.koushikdutta.com/2010/02/clockwork-recovery-image.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQBQH85eyp7ImA9WxBWGEo.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-468540574883313089</id><published>2010-02-11T00:49:00.000-08:00</published><updated>2010-02-11T00:52:31.123-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-11T00:52:31.123-08:00</app:edited><title>Working Vendor Configuration for Motorola Sholes (Droid)</title><content type="html">I had a spare Droid (two actually) sitting on my desk at work, so I spent some time hacking up a working vendor configuration for the phone. Took me a few days, but it all worked! &lt;a href="http://alldroid.org/viewtopic.php?f=210&amp;amp;t=2260"&gt;I ended up flashing Android 2.1r2 to it.&lt;/a&gt; &lt;div&gt;Happy Hacking! Head on over to my &lt;a href="http://github.com/koush/android_vendor_motorola_sholes-open"&gt;sholes-open Github repository.&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-468540574883313089?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bfcOgjzsisQHlqXDf62LPFGic0c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bfcOgjzsisQHlqXDf62LPFGic0c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bfcOgjzsisQHlqXDf62LPFGic0c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bfcOgjzsisQHlqXDf62LPFGic0c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=iObdi-gUxsQ:Ogd5FV3UUgI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=iObdi-gUxsQ:Ogd5FV3UUgI:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=iObdi-gUxsQ:Ogd5FV3UUgI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=iObdi-gUxsQ:Ogd5FV3UUgI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/iObdi-gUxsQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/468540574883313089/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=468540574883313089" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/468540574883313089?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/468540574883313089?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/iObdi-gUxsQ/working-vendor-configuration-for.html" title="Working Vendor Configuration for Motorola Sholes (Droid)" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.koushikdutta.com/2010/02/working-vendor-configuration-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AASXszeip7ImA9WxBWEU8.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-1724529792048445409</id><published>2010-02-01T20:22:00.001-08:00</published><updated>2010-02-02T06:42:28.582-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-02T06:42:28.582-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Klaxon" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><title>Klaxon 4.0 for Android</title><content type="html">&lt;p&gt;Klaxon for Android has gone through another rigorous update! This time, I integrated the new Desk Clock from Eclair (Nexus One) into the application. The result is the customizability of Klaxon that users have come to love, with a brand spanking new and polished UI.&lt;/p&gt;  &lt;p&gt;For those of you curious how to get the Weather widget on your desk clock, Google &lt;a href="http://lmgtfy.com/?q=genie+widget"&gt;“genie widget”&lt;/a&gt; for the third party application found on the Nexus One.&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://lh3.ggpht.com/_1Q1cgK2sxXk/S2eoiVFaDkI/AAAAAAAAAZs/drTut8UIRkU/s1600-h/deskclock%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="deskclock" border="0" alt="deskclock" src="http://lh4.ggpht.com/_1Q1cgK2sxXk/S2eoiyQ9HRI/AAAAAAAAAZw/of29ehN9cOs/deskclock_thumb.png?imgmax=800" width="148" height="244" /&gt;&lt;/a&gt; &lt;a href="http://lh3.ggpht.com/_1Q1cgK2sxXk/S2eojTwuNuI/AAAAAAAAAZ0/LzvzYCzdhVE/s1600-h/alarms%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="alarms" border="0" alt="alarms" src="http://lh6.ggpht.com/_1Q1cgK2sxXk/S2eojrqk2bI/AAAAAAAAAZ4/KyB3Bf7rjDM/alarms_thumb.png?imgmax=800" width="148" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://lh6.ggpht.com/_1Q1cgK2sxXk/S2eoj1MvdXI/AAAAAAAAAZ8/ZgEWb-x_0Eg/s1600-h/edit%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="edit" border="0" alt="edit" src="http://lh3.ggpht.com/_1Q1cgK2sxXk/S2eokCsvW3I/AAAAAAAAAaA/t8iN03lMPao/edit_thumb.png?imgmax=800" width="148" height="244" /&gt;&lt;/a&gt;&amp;#160;&lt;a href="http://lh4.ggpht.com/_1Q1cgK2sxXk/S2eoktfOpBI/AAAAAAAAAaE/oETdrovmzK8/s1600-h/alarm%5B8%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="alarm" border="0" alt="alarm" src="http://lh4.ggpht.com/_1Q1cgK2sxXk/S2eolMtMHDI/AAAAAAAAAaI/2BFvMVCuXkc/alarm_thumb%5B2%5D.png?imgmax=800" width="148" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-1724529792048445409?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yBctVpnYNrhTamAuaXokHG6vzW0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yBctVpnYNrhTamAuaXokHG6vzW0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yBctVpnYNrhTamAuaXokHG6vzW0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yBctVpnYNrhTamAuaXokHG6vzW0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=Yg3uZqP1Hxo:puQle2_PQT4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=Yg3uZqP1Hxo:puQle2_PQT4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=Yg3uZqP1Hxo:puQle2_PQT4:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=Yg3uZqP1Hxo:puQle2_PQT4:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/Yg3uZqP1Hxo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/1724529792048445409/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=1724529792048445409" title="21 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/1724529792048445409?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/1724529792048445409?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/Yg3uZqP1Hxo/klaxon-40-for-android.html" title="Klaxon 4.0 for Android" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>21</thr:total><feedburner:origLink>http://www.koushikdutta.com/2010/02/klaxon-40-for-android.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUNSX85fyp7ImA9WxBXEEo.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-7514608891957835770</id><published>2010-01-21T02:51:00.001-08:00</published><updated>2010-01-21T03:11:38.127-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-21T03:11:38.127-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Android Mono" /><category scheme="http://www.blogger.com/atom/ns#" term="Hacking" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="Mono" /><title>Android.dll</title><content type="html">&lt;p align="center"&gt;&lt;a href="http://lh6.ggpht.com/_1Q1cgK2sxXk/S1gxuqrPP9I/AAAAAAAAAZc/KnTbEauZI3o/s1600-h/androidmono%5B5%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="androidmono" border="0" alt="androidmono" src="http://lh4.ggpht.com/_1Q1cgK2sxXk/S1gxvDbHw2I/AAAAAAAAAZk/hH8jvY_L-IY/androidmono_thumb%5B3%5D.png?imgmax=800" width="647" height="406" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Picture above represents the results of 3 sleepless nights. No, I didn’t rewrite the Android framework. I generated a bunch of proxy classes to access them from Mono though. Rough idea of how it works: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Java application reflects through Android framework SDK jar and outputs an XML file that represents the object model. &lt;/li&gt;    &lt;li&gt;C# application generates thousands of code files of said object model. (This is similar to &lt;a href="http://jni4net.sourceforge.net"&gt;jni4net&lt;/a&gt;, but that doesn’t work on anything but Windows). &lt;/li&gt;    &lt;li&gt;Tag all the methods with the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimplattribute.aspx"&gt;[MethodImpl(MethodImplOptions.InternalCall)]&lt;/a&gt; attribute. &lt;/li&gt;    &lt;li&gt;Implement the method calls at runtime with a combination of dynamically created expression tree delegates and mono_add_internal_call. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The class contents actually have no code, so the total dll size is pretty small (800k). Here’s what the LinearLayout “implementation” looks like:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;namespace android.widget 
{ 
    public class LinearLayout : android.view.ViewGroup
    { 
        public class LayoutParams : android.view.ViewGroup.MarginLayoutParams
        { 
            [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
            public virtual extern java.lang.String debug(java.lang.String arg0); 
            [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
            public extern LayoutParams(android.content.Context arg0, android.util.AttributeSet arg1); 
            [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
            public extern LayoutParams(int arg0, int arg1); 
            [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
            public extern LayoutParams(int arg0, int arg1, float arg2); 
            [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
            public extern LayoutParams(android.view.ViewGroup.LayoutParams arg0); 
            [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
            public extern LayoutParams(android.view.ViewGroup.MarginLayoutParams arg0); 
            [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
            internal extern LayoutParams(); 
        } 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern void setGravity(int arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        protected override extern void onLayout(bool arg0, int arg1, int arg2, int arg3, int arg4); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public override extern int getBaseline(); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        protected override extern void onMeasure(int arg0, int arg1); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        protected override extern bool checkLayoutParams(android.view.ViewGroup.LayoutParams arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern new android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        protected virtual extern new android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        protected virtual extern new android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams(); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern bool isBaselineAligned(); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern void setBaselineAligned(bool arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern int getBaselineAlignedChildIndex(); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern void setBaselineAlignedChildIndex(int arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern float getWeightSum(); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern void setWeightSum(float arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern void setOrientation(int arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern int getOrientation(); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern void setHorizontalGravity(int arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public virtual extern void setVerticalGravity(int arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public extern LinearLayout(android.content.Context arg0, android.util.AttributeSet arg1); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        public extern LinearLayout(android.content.Context arg0); 
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] 
        internal extern LinearLayout(); 
    } 
} &lt;/pre&gt;

&lt;p&gt;A year of on and off hacking coming to fruition soon…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-7514608891957835770?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_phA2d98mr701BJECTuDY3wjwsw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_phA2d98mr701BJECTuDY3wjwsw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_phA2d98mr701BJECTuDY3wjwsw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_phA2d98mr701BJECTuDY3wjwsw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=qMiZqIQnlIo:WStzRFjOd-E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=qMiZqIQnlIo:WStzRFjOd-E:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=qMiZqIQnlIo:WStzRFjOd-E:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=qMiZqIQnlIo:WStzRFjOd-E:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/qMiZqIQnlIo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/7514608891957835770/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=7514608891957835770" title="32 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/7514608891957835770?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/7514608891957835770?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/qMiZqIQnlIo/androiddll.html" title="Android.dll" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>32</thr:total><feedburner:origLink>http://www.koushikdutta.com/2010/01/androiddll.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIEQn0_eCp7ImA9WxNaGE0.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-5653880897071381085</id><published>2009-12-02T18:31:00.001-08:00</published><updated>2009-12-02T18:31:43.340-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-02T18:31:43.340-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Android Mono" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="Mono" /><title>Building Mono using the Android NDK</title><content type="html">&lt;p&gt;I finally got around to looking at the &lt;a href="http://developer.android.com/sdk/ndk/1.5_r1/index.html"&gt;Android NDK&lt;/a&gt; yesterday. It is basically a subset of the Android Source build environment, but it has all the bits necessary to compile Mono. It only took a bit of finagling with the Android.mk to make everything work right. Building for Android is pretty easy now; the longest part is actually downloading and building the mcs assemblies. There’s a script to handle that though. &lt;/p&gt;  &lt;p&gt;The &lt;a href="http://github.com/koush/androidmono"&gt;androidmono&lt;/a&gt; repository has updated instructions.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-5653880897071381085?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NxvMWAouuYoccVoIoAqYCnu30-Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NxvMWAouuYoccVoIoAqYCnu30-Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NxvMWAouuYoccVoIoAqYCnu30-Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NxvMWAouuYoccVoIoAqYCnu30-Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=YEwbJZQ6nXc:uI5I9IBweew:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=YEwbJZQ6nXc:uI5I9IBweew:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=YEwbJZQ6nXc:uI5I9IBweew:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=YEwbJZQ6nXc:uI5I9IBweew:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/YEwbJZQ6nXc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/5653880897071381085/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=5653880897071381085" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5653880897071381085?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5653880897071381085?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/YEwbJZQ6nXc/building-mono-using-android-ndk.html" title="Building Mono using the Android NDK" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>10</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/12/building-mono-using-android-ndk.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEDQHkyfSp7ImA9WxNaF08.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-5093412910323493399</id><published>2009-12-01T20:23:00.001-08:00</published><updated>2009-12-01T20:37:51.795-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-01T20:37:51.795-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Android Mono" /><category scheme="http://www.blogger.com/atom/ns#" term="Mono" /><title>Mono 2.5 for Android Released</title><content type="html">&lt;p&gt;On and off over the last few weeks, I’ve been working on getting the Mono 2.6 branch, and its super awesome soft debugger, working on Android. I’ve also spent some time documenting and cleaning up the currently horrendous build process involved (I was really the only one that knew how to do it). Anyways, the Android Market now has the current 2.6 branch of Mono available for download (2.6 is not complete yet, hence the reason I am referring to it at 2.5). This release supports Cupcake, Donut, and Eclair!&lt;/p&gt; &lt;p&gt;The project is hosted on Github in the &lt;a href="http://github.com/koush/androidmono"&gt;androidmono&lt;/a&gt; repository.&lt;/p&gt; &lt;p&gt;For those interested in building/hacking this themselves, here are the instructions:&lt;/p&gt;&lt;pre class="githubfile" user="koush" repository="androidmono" file="README.txt"&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-5093412910323493399?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WR4J9SvW5_oYcXiRW26XQ3sBPm8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WR4J9SvW5_oYcXiRW26XQ3sBPm8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WR4J9SvW5_oYcXiRW26XQ3sBPm8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WR4J9SvW5_oYcXiRW26XQ3sBPm8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=cPAQV8oTOP0:Y6MO3rCYaOc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=cPAQV8oTOP0:Y6MO3rCYaOc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=cPAQV8oTOP0:Y6MO3rCYaOc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=cPAQV8oTOP0:Y6MO3rCYaOc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/cPAQV8oTOP0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/5093412910323493399/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=5093412910323493399" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5093412910323493399?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5093412910323493399?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/cPAQV8oTOP0/mono-25-for-android-released.html" title="Mono 2.5 for Android Released" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>12</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/12/mono-25-for-android-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIMRnwzeyp7ImA9WxNUGU4.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-7812434310126086253</id><published>2009-11-11T01:09:00.001-08:00</published><updated>2009-11-11T01:09:47.283-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-11T01:09:47.283-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Android Mono" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="Mono" /><title>Developing and Debugging .NET applications on Android with Mono(Develop)</title><content type="html">&lt;p&gt;Lots of cool stuff has been happening in Mono recently! First &lt;a href="http://monotouch.net/"&gt;MonoTouch&lt;/a&gt; was released, which allows the development of iPhone applications in C#/MonoDevelop. The catch was that there was no debugger support. To address this glaring problem, Mono released created and released a &lt;a href="http://mono-project.com/Soft_Debugger"&gt;Soft-Mode Debugger&lt;/a&gt;, which is basically an in-process debugger that lives in the runtime. After peeking at the code, I realized that porting this to make it work on Android would be a cinch! The result: you can now create a console application in MonoDevelop, deploy it to an Android emulator or device, and debug:&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://lh3.ggpht.com/_1Q1cgK2sxXk/Svp_K4b1-SI/AAAAAAAAAYk/38AZu0CXTxY/s1600-h/md-android%5B3%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="md-android" border="0" alt="md-android" src="http://lh4.ggpht.com/_1Q1cgK2sxXk/Svp_Lbbs7hI/AAAAAAAAAYo/zLH6-Elq91g/md-android_thumb%5B1%5D.jpg?imgmax=800" width="400" height="377" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.koushikdutta.com/2009/02/monodalvik-interop.html"&gt;I blogged a while ago&lt;/a&gt; that I was working on an interop layer for Mono to allow it to utilize the Android SDK. This is mostly complete. Once I write up a tool to generate convenient wrapper classes, writing full blown applications for Android will become a reality!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-7812434310126086253?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZzvERW3__5_Dwp2c60UqYZkHsD4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZzvERW3__5_Dwp2c60UqYZkHsD4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZzvERW3__5_Dwp2c60UqYZkHsD4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZzvERW3__5_Dwp2c60UqYZkHsD4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=rOFolCbwy9k:rvGZ9X4pRzA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=rOFolCbwy9k:rvGZ9X4pRzA:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=rOFolCbwy9k:rvGZ9X4pRzA:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=rOFolCbwy9k:rvGZ9X4pRzA:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/rOFolCbwy9k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/7812434310126086253/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=7812434310126086253" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/7812434310126086253?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/7812434310126086253?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/rOFolCbwy9k/mono-and-monodevelop-on-android.html" title="Developing and Debugging .NET applications on Android with Mono(Develop)" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>10</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/11/mono-and-monodevelop-on-android.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUFQnkycSp7ImA9WxNSEUg.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-4803345706651207733</id><published>2009-08-24T16:40:00.001-07:00</published><updated>2009-08-24T16:40:13.799-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-24T16:40:13.799-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="HTC" /><title>Build Configuration for the HTC Magic</title><content type="html">&lt;p align="center"&gt;&lt;a href="http://lh6.ggpht.com/_1Q1cgK2sxXk/SpMk2shk9AI/AAAAAAAAAYE/mm8CjYAML1I/s1600-h/MyTouchWhite%5B5%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="MyTouchWhite" border="0" alt="MyTouchWhite" src="http://lh6.ggpht.com/_1Q1cgK2sxXk/SpMk3fHRMmI/AAAAAAAAAYI/R9Tw9dcRpDE/MyTouchWhite_thumb%5B1%5D.png?imgmax=800" width="117" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;A few days ago, I released &lt;a href="http://www.koushikdutta.com/2009/08/build-configuration-for-t-mobile.html"&gt;build scripts&lt;/a&gt; that would allow developers to make images that target the T-Mobile MyTouch. I finally got a hold of a regular Magic (a Sapphire 32A) and have created a &lt;a href="http://github.com/koush/platform_vendor_htc_magic-open/tree/master"&gt;corresponding project&lt;/a&gt; to support building for this device. So, this will now work:&lt;/p&gt;  &lt;pre class="brush: bash;"&gt;. build/envsetup.sh
lunch htc_magic-eng
make&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Please note the instructions regarding cherry-picking certain changes from Donut into your Android repository. The Sapphire 32A uses HTC’s kernel offsets in the boot.img, and not Google’s. Without those changes, your phone will not boot.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-4803345706651207733?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ddRJoKTOh40gDcUl-qUu9H1X-xs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ddRJoKTOh40gDcUl-qUu9H1X-xs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ddRJoKTOh40gDcUl-qUu9H1X-xs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ddRJoKTOh40gDcUl-qUu9H1X-xs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=IlRSNt79MOA:6zKu1OlAVqw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=IlRSNt79MOA:6zKu1OlAVqw:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=IlRSNt79MOA:6zKu1OlAVqw:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=IlRSNt79MOA:6zKu1OlAVqw:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/IlRSNt79MOA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/4803345706651207733/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=4803345706651207733" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/4803345706651207733?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/4803345706651207733?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/IlRSNt79MOA/build-configuration-for-htc-magic.html" title="Build Configuration for the HTC Magic" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>14</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/08/build-configuration-for-htc-magic.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcNR386eSp7ImA9WxNTGEQ.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-6859078767865097130</id><published>2009-08-21T16:23:00.001-07:00</published><updated>2009-08-21T16:41:36.111-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-21T16:41:36.111-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="HTC" /><title>Build Configuration for the T-Mobile MyTouch</title><content type="html">&lt;p align="center"&gt;&lt;a href="http://lh4.ggpht.com/_1Q1cgK2sxXk/So8sgOhAINI/AAAAAAAAAX8/LUz_shUPQ6U/s1600-h/MyTouchWhite2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="MyTouchWhite" border="0" alt="MyTouchWhite" src="http://lh5.ggpht.com/_1Q1cgK2sxXk/So8shQ6wXQI/AAAAAAAAAYA/1R6Li-p2s2c/MyTouchWhite_thumb.png?imgmax=800" width="117" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The HTC Dream is the only supported Android development device. But, it is possible to do development on other devices, by cannibalizing the various drivers that you can find on them. This usually involves modifying/repacking an official update.zip. However, with a little work, it is possible to use the Android build system to create legitimate fastboot images!&lt;/p&gt;  &lt;p&gt;After following the instructions to retrieve the &lt;a href="http://github.com/koush/platform_vendor_htc_mytouch-open/tree/master"&gt;MyTouch build configuration&lt;/a&gt; and extracting the proprietary bits from a running device, you can do the following to build images for the MyTouch:&lt;/p&gt;  &lt;pre class="brush: bash;"&gt;. build/envsetup.sh
lunch htc_mytouch-eng
make&lt;/pre&gt;

&lt;p&gt;There is also a mkupdatezip script available in the Downloads section of the repository to assist in creating update.zip files as well!&lt;/p&gt;

&lt;p&gt;The images will then be found in out/target/product/mytouch-open. A build configuration for the Magic will be coming soon! (It is the same board as the MyTouch, a Sapphire, but different enough to need a separate config.)&lt;/p&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;p&gt;The general process in creating this board makefile was basically the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Start with the Dream build config (dream-open).&lt;/li&gt;

  &lt;li&gt;Extract the kernel from a running device and replace it.&lt;/li&gt;

  &lt;li&gt;Modify the extract-files.sh script to adb pull the correct proprietary files. &lt;/li&gt;

  &lt;li&gt;Modify the .mk files to reference the proper proprietary files.&lt;/li&gt;

  &lt;li&gt;Grab the wlan.ko off the device and replace the one at the repository root.&lt;/li&gt;
&lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-6859078767865097130?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zzX0s7Jyi6n-YdkQXi6oH-oJCyA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zzX0s7Jyi6n-YdkQXi6oH-oJCyA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zzX0s7Jyi6n-YdkQXi6oH-oJCyA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zzX0s7Jyi6n-YdkQXi6oH-oJCyA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=vkdQ4TrKkNg:OhRsCNf95HI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=vkdQ4TrKkNg:OhRsCNf95HI:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=vkdQ4TrKkNg:OhRsCNf95HI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=vkdQ4TrKkNg:OhRsCNf95HI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/vkdQ4TrKkNg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/6859078767865097130/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=6859078767865097130" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/6859078767865097130?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/6859078767865097130?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/vkdQ4TrKkNg/build-configuration-for-t-mobile.html" title="Build Configuration for the T-Mobile MyTouch" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>11</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/08/build-configuration-for-t-mobile.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04FR386fip7ImA9WxNTGEQ.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-1615864783383408438</id><published>2009-08-21T16:04:00.001-07:00</published><updated>2009-08-21T16:05:16.116-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-21T16:05:16.116-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MVP" /><title>MVP!</title><content type="html">&lt;p align="center"&gt;&lt;a href="http://lh6.ggpht.com/_1Q1cgK2sxXk/So8n3P3KO6I/AAAAAAAAAX0/Bx2x3OwVclg/s1600-h/images%5B2%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="images" border="0" alt="images" src="http://lh4.ggpht.com/_1Q1cgK2sxXk/So8n4VmTbPI/AAAAAAAAAX4/F7xhhK7S71o/images_thumb.jpg?imgmax=800" width="86" height="133" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I got a recognized as a Microsoft Most Valuable Professional for my work over the past year and a half with Windows Mobile. I get access to lots of super awesome benefits, juicy gossip, and top secret NDA stuff! Cool!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-1615864783383408438?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7xnjqlgqZm3oc9kT39IbhFtQnWQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7xnjqlgqZm3oc9kT39IbhFtQnWQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7xnjqlgqZm3oc9kT39IbhFtQnWQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7xnjqlgqZm3oc9kT39IbhFtQnWQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=_-ArFTfO6Iw:vDc52-B31AI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=_-ArFTfO6Iw:vDc52-B31AI:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=_-ArFTfO6Iw:vDc52-B31AI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=_-ArFTfO6Iw:vDc52-B31AI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/_-ArFTfO6Iw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/1615864783383408438/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=1615864783383408438" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/1615864783383408438?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/1615864783383408438?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/_-ArFTfO6Iw/mvp.html" title="MVP!" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>8</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/08/mvp.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMDQHY8fCp7ImA9WxJREUQ.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-5603867674923379978</id><published>2009-05-12T23:51:00.001-07:00</published><updated>2009-05-12T23:51:11.874-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-12T23:51:11.874-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="shrinkimage" /><title>Command Line Image Shrinker (shrinkimage)</title><content type="html">&lt;p align="center"&gt;&lt;a href="http://lh5.ggpht.com/_1Q1cgK2sxXk/Sgpt3UDVnTI/AAAAAAAAAXs/tS1l6RhGQzE/s1600-h/mario_hit-and-shrink%5B3%5D.jpg"&gt;&lt;img title="mario_hit-and-shrink" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="307" alt="mario_hit-and-shrink" src="http://lh4.ggpht.com/_1Q1cgK2sxXk/Sgpt337yX1I/AAAAAAAAAXw/FrajX1htU9Q/mario_hit-and-shrink_thumb%5B1%5D.jpg?imgmax=800" width="306" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;One of the most tedious things I seem to do on a regular basis, for both blogging and developing, is downloading an image off of Google Image Search and shrinking it. Having to do a scale a lot of images to a similar size can become really annoying. I ended up writing a command line tool to shrink an image given a percent or a maximum dimension. Probably won’t be useful for many, but who knows!&lt;/p&gt;  &lt;p&gt;Grab &lt;a href="https://github.com/koush/shrinkimage/tree"&gt;shrinkimage&lt;/a&gt; off of GitHub.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-5603867674923379978?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/IMlBq7KK7Dm9kBT8TYzDHQaLqLA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IMlBq7KK7Dm9kBT8TYzDHQaLqLA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/IMlBq7KK7Dm9kBT8TYzDHQaLqLA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IMlBq7KK7Dm9kBT8TYzDHQaLqLA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=3PKZMdz839o:yn2G9BPzxsM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=3PKZMdz839o:yn2G9BPzxsM:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=3PKZMdz839o:yn2G9BPzxsM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=3PKZMdz839o:yn2G9BPzxsM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/3PKZMdz839o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/5603867674923379978/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=5603867674923379978" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5603867674923379978?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5603867674923379978?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/3PKZMdz839o/command-line-image-shrinker-shrinkimage.html" title="Command Line Image Shrinker (shrinkimage)" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>8</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/05/command-line-image-shrinker-shrinkimage.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8FRX48eyp7ImA9WxFTFEk.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-5013442339122191721</id><published>2009-05-12T22:18:00.001-07:00</published><updated>2010-04-04T22:53:34.073-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-04T22:53:34.073-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="github" /><category scheme="http://www.blogger.com/atom/ns#" term="GithubProjects" /><category scheme="http://www.blogger.com/atom/ns#" term="SyntaxHighlighter" /><category scheme="http://www.blogger.com/atom/ns#" term="Code" /><title>GitHub Is Pretty Magical</title><content type="html">&lt;p&gt;Warning: Weak browsers (aka Internet Explorer) may not be able to render this blog entry in its glory. Use a real browser!&lt;/p&gt; &lt;p&gt;If you browse on over to the &lt;a href="http://www.koushikdutta.com/2008/07/code.html"&gt;Code and Applications&lt;/a&gt; section of this site, you will notice that it takes a little time to load. That’s because that entire page is being dynamically generated by your browser via the &lt;a href="http://develop.github.com/"&gt;GitHub (JSON) APIs&lt;/a&gt;. What you see on that page is a live, up to the minute, list of every public project in my GitHub repository.&lt;/p&gt; &lt;p&gt;And here’s the JavaScript code that does it:&lt;/p&gt; &lt;div style="position: relative; height: 400px; max-height: 400px; overflow: auto"&gt;&lt;pre class="githubfile" file="githubprojects.js" repository="GithubProjects" user="koush" branch="gh-pages"&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But that’s not really the magical part. Here’s the code that inserted the code above into this page:&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;pre class="githubfile" file="githubprojects.js" repository="GithubProjects" user="koush"&amp;gt;&amp;lt;/pre&amp;gt;&lt;/pre&gt;
&lt;p&gt;The first bit of JavaScript code you see above is a live view of the file that is checked into my GitHub repository… and your browser is using the GitHub API to view it, highlight it (using &lt;a href="http://alexgorbatchev.com/"&gt;SyntaxHighlighter&lt;/a&gt;), and then render it to your screen. Kudos to Github for a fantastic API!&lt;/p&gt;
&lt;p&gt;I wrote GithubProjects up today as an exercise in learning jquery, AJAX, and some other Web 2.0 acronyms. Of course, all of this code is available in my &lt;a href="https://github.com/koush/GithubProjects/tree"&gt;GithubProjects repository&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-5013442339122191721?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AN3T395HCiglOogO3FkRwSr85uI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AN3T395HCiglOogO3FkRwSr85uI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AN3T395HCiglOogO3FkRwSr85uI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AN3T395HCiglOogO3FkRwSr85uI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=nzoeO24I5_k:pU9rVM9Rrdc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=nzoeO24I5_k:pU9rVM9Rrdc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=nzoeO24I5_k:pU9rVM9Rrdc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=nzoeO24I5_k:pU9rVM9Rrdc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/nzoeO24I5_k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/5013442339122191721/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=5013442339122191721" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5013442339122191721?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5013442339122191721?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/nzoeO24I5_k/github-is-pretty-magical.html" title="GitHub Is Pretty Magical" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/05/github-is-pretty-magical.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUFRX88eCp7ImA9WxJREUw.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-7111215223701771950</id><published>2009-05-12T01:16:00.001-07:00</published><updated>2009-05-12T01:16:54.170-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-12T01:16:54.170-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods" /><title>Extension Methods to Die For</title><content type="html">&lt;p&gt;This will be a running blog entry that I’ll update periodically when I have new ideas.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.koushikdutta.com/2009/04/converting-enumerations-to-user.html"&gt;Enum.ToUserString();&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;string.IsNullOrEmpty:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;public static bool IsNullOrEmpty(this string str)&lt;br /&gt;{&lt;br /&gt;    return string.IsNullOrEmpty(str);&lt;br /&gt;}&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-7111215223701771950?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ht5FuhId4gpZEgUU7pRq_tErO1c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ht5FuhId4gpZEgUU7pRq_tErO1c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ht5FuhId4gpZEgUU7pRq_tErO1c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ht5FuhId4gpZEgUU7pRq_tErO1c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=KK_OGv6wOeA:3ZVQmQiipJM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=KK_OGv6wOeA:3ZVQmQiipJM:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=KK_OGv6wOeA:3ZVQmQiipJM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=KK_OGv6wOeA:3ZVQmQiipJM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/KK_OGv6wOeA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/7111215223701771950/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=7111215223701771950" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/7111215223701771950?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/7111215223701771950?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/KK_OGv6wOeA/extension-methods-to-die-for.html" title="Extension Methods to Die For" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/05/extension-methods-to-die-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQNSHg_fCp7ImA9WxJSGU4.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-9142685172127700142</id><published>2009-05-09T20:55:00.001-07:00</published><updated>2009-05-09T22:29:59.644-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-09T22:29:59.644-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Android Mono" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="Mono" /><title>Android’s Linker makes Baby Jesus Cry</title><content type="html">&lt;p&gt;release-1.0 branch:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;pre class="brush: cpp;"&gt;static int open_library(const char *name)&lt;br /&gt;{&lt;br /&gt;    int fd;&lt;br /&gt;    char buf[512];&lt;br /&gt;    const char **path;&lt;br /&gt;&lt;br /&gt;    TRACE(&amp;quot;[ %5d opening %s ]\n&amp;quot;, pid, name);&lt;br /&gt;&lt;br /&gt;    if(strlen(name) &amp;gt; 256) return -1;&lt;br /&gt;    if(name == 0) return -1;&lt;br /&gt;&lt;br /&gt;    fd = open(name, O_RDONLY);&lt;br /&gt;    if(fd != -1) return fd;&lt;br /&gt;&lt;br /&gt;    for(path = sopaths; *path; path++){&lt;br /&gt;        sprintf(buf,&amp;quot;%s/%s&amp;quot;, *path, name);&lt;br /&gt;        fd = open(buf, O_RDONLY);&lt;br /&gt;        if(fd != -1) return fd;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return -1;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;cupcake branch:&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;/* TODO: Need to add support for initializing the so search path with&lt;br /&gt; * LD_LIBRARY_PATH env variable for non-setuid programs. */&lt;br /&gt;static int open_library(const char *name)&lt;br /&gt;{&lt;br /&gt;    int fd;&lt;br /&gt;    char buf[512];&lt;br /&gt;    const char **path;&lt;br /&gt;&lt;br /&gt;    TRACE(&amp;quot;[ %5d opening %s ]\n&amp;quot;, pid, name);&lt;br /&gt;&lt;br /&gt;    if(name == 0) return -1;&lt;br /&gt;    if(strlen(name) &amp;gt; 256) return -1;&lt;br /&gt;&lt;br /&gt;    if ((name[0] == '/') &amp;amp;&amp;amp; ((fd = _open_lib(name)) &amp;gt;= 0))&lt;br /&gt;        return fd;&lt;br /&gt;&lt;br /&gt;    for (path = sopaths; *path; path++) {&lt;br /&gt;        snprintf(buf, sizeof(buf), &amp;quot;%s/%s&amp;quot;, *path, name);&lt;br /&gt;        if ((fd = _open_lib(buf)) &amp;gt;= 0)&lt;br /&gt;            return fd;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return -1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;Summary: Android’s linker used to look in the current working directory to resolve library references. Now it doesn’t. (And it never used LD_LIBRARY_PATH at all) This is really only annoying for 3rd party command line applications which have references to libraries that aren’t part of the standard Android build (and contained in /system/lib). I need to figure out how to make gcc, et al, create binaries that store the full path to the libraries they reference, rather than just the base file name...&lt;/p&gt;

&lt;p&gt;Edit: I tried patching it to use LD_LIBRARY_PATH, but calling getenv from within the linker would always return NULL. Not sure why. So I did the next best thing and added “.” to the list of search paths. I think that is default behavior anyways on other Linux based systems (will verify later). Submitted the change, hope it gets accepted.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-9142685172127700142?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/VpvPct_5OUgJ3Bg-uAhW62aM76c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VpvPct_5OUgJ3Bg-uAhW62aM76c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/VpvPct_5OUgJ3Bg-uAhW62aM76c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VpvPct_5OUgJ3Bg-uAhW62aM76c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=KsGzvD_un6g:5Amv7BYGtB0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=KsGzvD_un6g:5Amv7BYGtB0:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=KsGzvD_un6g:5Amv7BYGtB0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=KsGzvD_un6g:5Amv7BYGtB0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/KsGzvD_un6g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/9142685172127700142/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=9142685172127700142" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/9142685172127700142?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/9142685172127700142?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/KsGzvD_un6g/androids-linker-makes-baby-jesus-cry.html" title="Android’s Linker makes Baby Jesus Cry" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/05/androids-linker-makes-baby-jesus-cry.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIARH0zfyp7ImA9WxJSFkg.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-7584477045735425084</id><published>2009-05-06T17:02:00.001-07:00</published><updated>2009-05-06T17:02:25.387-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-06T17:02:25.387-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dumb" /><title>I Need a Bigger Desk at Home</title><content type="html">&lt;p align="center"&gt;So I have room for more gadgets.&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://lh3.ggpht.com/_1Q1cgK2sxXk/SgIlDhhCSPI/AAAAAAAAAXk/vUHpR3LpJoo/s1600-h/IMG_1231%5B5%5D.jpg"&gt;&lt;img title="IMG_1231" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="507" alt="IMG_1231" src="http://lh5.ggpht.com/_1Q1cgK2sxXk/SgIlEMYCUTI/AAAAAAAAAXo/WgIXJKCFR44/IMG_1231_thumb%5B3%5D.jpg?imgmax=800" width="381" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-7584477045735425084?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xw6LNIv_40neILqYi1tdtSourDA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xw6LNIv_40neILqYi1tdtSourDA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xw6LNIv_40neILqYi1tdtSourDA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xw6LNIv_40neILqYi1tdtSourDA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=3r56n7kooR4:7fcUiAR1hWU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=3r56n7kooR4:7fcUiAR1hWU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=3r56n7kooR4:7fcUiAR1hWU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=3r56n7kooR4:7fcUiAR1hWU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/3r56n7kooR4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/7584477045735425084/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=7584477045735425084" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/7584477045735425084?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/7584477045735425084?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/3r56n7kooR4/i-need-bigger-desk-at-home.html" title="I Need a Bigger Desk at Home" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>8</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/05/i-need-bigger-desk-at-home.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYCQHo9cSp7ImA9WxJRFEw.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-857015141182330007</id><published>2009-05-05T22:54:00.001-07:00</published><updated>2009-05-15T11:29:21.469-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-15T11:29:21.469-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Xcode" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><category scheme="http://www.blogger.com/atom/ns#" term="OSx86" /><category scheme="http://www.blogger.com/atom/ns#" term="Hackintosh" /><title>Breakpoints Not Working When Debugging in Xcode on a Voodoo Kernel Hackintosh</title><content type="html">&lt;p&gt;&lt;a href="http://www.koushikdutta.com/2009/04/building-hackintosh-from-to-k.html"&gt;I recently built and OSx86 machine&lt;/a&gt;, but I had never actually tried doing any (native) development[0] on it as I had been using my MacBook for that purpose. Tonight I finally fired up Xcode on the new desktop, created an iPhone application, and found that my breakpoints, which were being correctly set and detected, were not ever actually being hit. It was as if they were being ignored completely.&lt;/p&gt;  &lt;p&gt;After Googling around for some hints as to why this would happen, on a hunch I tried debugging a C application that targeted the OSx86 machine itself: same issue, no breakpoints were hit. My desktop and laptop have the exact same applications and tool chains, and the only real difference between the two machines from a software standpoint was the kernel. This led me to believe that the Voodoo kernel used on the desktop had some debugging issues. Doing a search on this &lt;a href="http://www.google.com/url?sa=U&amp;amp;start=1&amp;amp;q=http://code.google.com/p/xnu-dev/issues/detail%3Fid%3D134&amp;amp;ei=EiQBSs_oEofqtAOs2e3pBQ&amp;amp;usg=AFQjCNHLayyvIr-M84lCzGdfB-RMDfhVnw"&gt;confirmed my suspicion&lt;/a&gt;, as the Voodoo team has an open bug on this exact issue. Luckily, a few searches down, I also found a workaround that happens to fix the issue for Intel based machines.&lt;/p&gt;  &lt;p&gt;When starting your system, enter the following as one of your boot flags:&lt;/p&gt;  &lt;p&gt;std_dyld=1&lt;/p&gt;  &lt;p&gt;From the voodoo kernel documention:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;std_dyld=    
On-the-ﬂy opcode patching requires an elaborate technique to patch dynamic     
libraries. Because of this, the kernel includes its own specialized copy of dyld, and     
chooses the best one depending on your CPU. Use this option to force the kernel to     
use standard dyld (pass value 1) or its specialized copy. (pass value 0), regardless of     
your CPU type. Note: AMD insta$s might fail to function if you specify this boot-ﬂag!&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;While Googling, I saw numerous forum posts about this issue on OSx86 machines, with no one realizing there is a workaround. So hopefully this post matches enough keywords to save someone an hour or two of searching. :)&lt;/p&gt;&lt;p&gt;Edit/Note: If you are booting off a kernel on your EFI partition, make sure that it is named "mach_kernel" and that a copy of that exact kernel is available at /mach_kernel on your system partition. (I had issues with VMWare not working until I did this, and suspect it may cause issues with XCode too)&lt;/p&gt;  &lt;p&gt;[0] I have been using it to do Android development, and have no issues debugging the Dalvik VM. But I am guessing the Dalvik VM on an emulator/device does not require the same low level kernel hooks on the host.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-857015141182330007?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/j0jI5UmON9J0KCEQJWUkkhEq8e0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/j0jI5UmON9J0KCEQJWUkkhEq8e0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/j0jI5UmON9J0KCEQJWUkkhEq8e0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/j0jI5UmON9J0KCEQJWUkkhEq8e0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=swQPo4oB0YI:2UFw32WE_B4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=swQPo4oB0YI:2UFw32WE_B4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=swQPo4oB0YI:2UFw32WE_B4:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=swQPo4oB0YI:2UFw32WE_B4:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/swQPo4oB0YI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/857015141182330007/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=857015141182330007" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/857015141182330007?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/857015141182330007?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/swQPo4oB0YI/breakpoints-not-working-when-debugging.html" title="Breakpoints Not Working When Debugging in Xcode on a Voodoo Kernel Hackintosh" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>12</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/05/breakpoints-not-working-when-debugging.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UMRHk4fCp7ImA9WxJSE0U.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-3028167901318761545</id><published>2009-05-03T15:21:00.001-07:00</published><updated>2009-05-03T15:21:25.734-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-03T15:21:25.734-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Klaxon" /><category scheme="http://www.blogger.com/atom/ns#" term="Screenshot" /><title>Klaxon and Screenshot – Android 1.5 Version</title><content type="html">&lt;p&gt;Quick update: I have made fixes to both Klaxon and Screenshot to support Android 1.5. However, I am still hearing reports from users that Klaxon does not work on &lt;strong&gt;Haykuro&lt;/strong&gt; builds; the device goes into a reboot loop. Haykuro does not have a build based off the T-Mobile OTA update, so I can not provide support for his build- I believe he is using older/pre-release cupcake pieces in his current builds. Once he updates, I may look into the issue further.&lt;/p&gt;  &lt;p&gt;I am currently running JF 1.5, and have no issues with either application. Unfortunately, I can not spend my time supporting every fork/tweaked version of Android (Haykuro, DudeOfLife, etc, etc). The only supported builds will be Retail and JF.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-3028167901318761545?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/94A53tCjkXAv7PEYE8kkfZDCOyc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/94A53tCjkXAv7PEYE8kkfZDCOyc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/94A53tCjkXAv7PEYE8kkfZDCOyc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/94A53tCjkXAv7PEYE8kkfZDCOyc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=YFo9_lunXQE:Uj2_nlnxLX4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=YFo9_lunXQE:Uj2_nlnxLX4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=YFo9_lunXQE:Uj2_nlnxLX4:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=YFo9_lunXQE:Uj2_nlnxLX4:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/YFo9_lunXQE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/3028167901318761545/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=3028167901318761545" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/3028167901318761545?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/3028167901318761545?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/YFo9_lunXQE/klaxon-and-screenshot-android-15.html" title="Klaxon and Screenshot – Android 1.5 Version" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>12</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/05/klaxon-and-screenshot-android-15.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YEQHo6fip7ImA9WxJSEk8.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-5652604188091080540</id><published>2009-04-28T14:01:00.001-07:00</published><updated>2009-05-01T17:45:01.416-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-01T17:45:01.416-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Code" /><title>Converting Enumerations to User Readable Strings in .NET</title><content type="html">&lt;p&gt;Suppose you have the following scenario: You have a function that can return multiple return types codes via an enum value. For each of those enum values, you want to inform the user the result of the operation by some user friendly string. &lt;/p&gt;  &lt;p&gt;A common implementation I see is some sort of switch statement that resolves enumerations to a string by way of a switch statement or hash table or something. And whenever that string is needed, call into said method. &lt;/p&gt;  &lt;p&gt;And although this is viable, this creates a disconnect between the enum and it’s actual string literal definition. In addition, for each new enumeration value, that giant switch statement needs to be updated with a new string value. If there were only a clean way to map an enum to a string value automatically… and there is! With clever usage of attributes, reflection, and extension methods, one can do something like this:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Linq.Expressions;&lt;br /&gt;&lt;br /&gt;namespace EnumString&lt;br /&gt;{&lt;br /&gt;    [AttributeUsage(AttributeTargets.Field)]&lt;br /&gt;    class EnumStringAttribute : Attribute&lt;br /&gt;    {&lt;br /&gt;        string myValue;&lt;br /&gt;        public EnumStringAttribute(string value)&lt;br /&gt;        {&lt;br /&gt;            myValue = value;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public override string ToString()&lt;br /&gt;        {&lt;br /&gt;            return myValue.ToString();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static class ExtensionMethods&lt;br /&gt;    {&lt;br /&gt;        public static string ToUserString(this Enum enumeration)&lt;br /&gt;        {&lt;br /&gt;            var type = enumeration.GetType();&lt;br /&gt;            var field = type.GetField(enumeration.ToString());&lt;br /&gt;            var enumString = (from attribute in field.GetCustomAttributes(true) where attribute is EnumStringAttribute select attribute).FirstOrDefault();&lt;br /&gt;            if (enumString != null)&lt;br /&gt;                return enumString.ToString();&lt;br /&gt;            return enumeration.ToString();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    enum AuthenticationResult&lt;br /&gt;    {&lt;br /&gt;        [EnumString(&amp;quot;This username is not registered.&amp;quot;)]&lt;br /&gt;        NotRegistered,&lt;br /&gt;        [EnumString(&amp;quot;Incorrect password.&amp;quot;)]&lt;br /&gt;        BadPassword,&lt;br /&gt;        [EnumString(&amp;quot;Logging in...&amp;quot;)]&lt;br /&gt;        Success,&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(AuthenticationResult.BadPassword.ToUserString());&lt;br /&gt;            Console.WriteLine(AuthenticationResult.NotRegistered.ToUserString());&lt;br /&gt;            Console.WriteLine(AuthenticationResult.Success.ToUserString());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;&lt;font face="Verdana"&gt;Delaring string values can simply be done inline, and the usage is simple as well! Just call the new extension method to get your user friendly string!&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;(Of course, for localization, you may want to map the enum to a string resource rather than a hard coded string value; but a similar approach can be used.)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-5652604188091080540?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/m3mF141O-UZN6PFWFDzfLoqluNQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m3mF141O-UZN6PFWFDzfLoqluNQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/m3mF141O-UZN6PFWFDzfLoqluNQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m3mF141O-UZN6PFWFDzfLoqluNQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=IzVgk5AT8Jo:5ugmoUZtPkc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=IzVgk5AT8Jo:5ugmoUZtPkc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=IzVgk5AT8Jo:5ugmoUZtPkc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=IzVgk5AT8Jo:5ugmoUZtPkc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/IzVgk5AT8Jo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/5652604188091080540/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=5652604188091080540" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5652604188091080540?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5652604188091080540?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/IzVgk5AT8Jo/converting-enumerations-to-user.html" title="Converting Enumerations to User Readable Strings in .NET" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>10</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/04/converting-enumerations-to-user.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MHRX48fCp7ImA9WxJTGU0.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-2526880251655220863</id><published>2009-04-28T02:03:00.001-07:00</published><updated>2009-04-28T02:03:54.074-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-28T02:03:54.074-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><title>Language Mavens, Tool Mavens</title><content type="html">&lt;p align="center"&gt;&lt;a href="http://lh6.ggpht.com/_1Q1cgK2sxXk/SfbGcSsenwI/AAAAAAAAAXc/1gbKq8sXKGo/s1600-h/mvn%5B3%5D.png"&gt;&lt;img title="mvn" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="175" alt="mvn" src="http://lh3.ggpht.com/_1Q1cgK2sxXk/SfbGczp5K-I/AAAAAAAAAXg/HCFHshUb_EU/mvn_thumb%5B1%5D.png?imgmax=800" width="269" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Recently, a fellow coworker referred me to an article by Oliver Steele about &lt;a href="http://osteele.com/archives/2004/11/ides"&gt;Language Mavens and Tool Mavens&lt;/a&gt;. The synopsis is that there are two types of deveopers: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Language Mavens are those that leverage a features of the best language to complete the task at hand; the IDEs/tools used do not matter so much. &lt;/li&gt;    &lt;li&gt;And conversely, Tool Mavens leverage the power of mature, full featured development tools to complete their tasks: an integrated editor, debugger, code refactoring, etc. The language itself does not matter because, it is just the same old set of classes and methods with slightly different names.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Naturally, this led to a bit of introspection, which resulted in the diagram that you can see above: I think I am somewhat between both camps, in that I choose and tend to use a variety of languages on a frequent basis to get my work done. But I find myself more so gravitating towards the languages with the richer tools, because they make suit &lt;em&gt;my &lt;/em&gt;programming habits better.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The tool I &lt;em&gt;require&lt;/em&gt; a language to have before I even consider touching it is an integrated debugger. Well, to qualify that statement, I require that for applications with complex execution paths and sustained runtimes. That means for bash, Ruby, Perl, and JavaScript, it doesn’t matter, because printf debugging will suffice. [1] However, if you follow this blog, you may have read about &lt;a href="http://www.koushikdutta.com/2009/01/mono-on-android-with-gratuitous-shaky.html"&gt;my work on porting Mono to Android&lt;/a&gt;. Although Mono has a great integrated x86_64 debugger, none exists for the ARM platform. Doing development using Mono on Android is not really a viable option to me until the debugger exists (or I get around to implementing it myself).&lt;/p&gt;  &lt;p&gt;The other tool I &lt;em&gt;prefer &lt;/em&gt;a language have is auto complete (aka content assist). It’s purpose is two-fold: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;When learning a new language/API/platform, content assist severely lowers the learning curve. Instead of hunting down method signatures, class names, and descriptions on Google, it is built into my editor. This ultimately saves me a significant amount of time.&lt;/li&gt;    &lt;li&gt;Eventually, when I master the language, auto complete serves a different purpose: it reduces the amount I need to type by a little under 50%. [0] This is interesting, because a language without code completion would need to be able to complete a task in half the lines over a language that does support it before it actually becomes a more efficient use of my time.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;Languages&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;As Steele’s article states, C# and Visual Studio, as with everything with Microsoft, is an exception to the rule. The new languages (and features) are released at the same time as the tools. And generally, I find myself getting more excited about the languages aspects, than the tools. For example, with VS 2010 (which should be in beta very shortly I hear), we will get: F#, Dynamic Language Runtime (Iron*!), and full expression tree support in C# (to support the DLR and the new dynamic keyword). [2]&lt;/p&gt;  &lt;p&gt;Lately, in various projects, I find myself wanting to do more in the way of code generation. Be it code being generated from a model or modifying/creating new code at run time. So that is what spurred my desire to learn Ruby and Python (of which I currently favor Ruby). Though I don’t think this is something I can not live without.&lt;/p&gt;  &lt;p&gt;As for language features that are to-die-for, I find it hard to cope without closures and generics, of which Java has neither. [3] The lack of generics is why I also did not really adopt C# over C++ (templates) until version 2. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Where do you fall as a language/tool maven, and why?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;[0] I did this by recording my keystroke count using a free Windows application, and disregarded keystrokes for any navigation or correction keys: backspace, delete, and arrows. Then I compared the results versus the character count of the code written. &lt;/p&gt;  &lt;p&gt;[1] Incidentally, I realized I have learned around 5 new languages in the past year. Though I can only claim proficiency in one, the language with the best tools: Java.&lt;/p&gt;  &lt;p&gt;[2] Using expression trees in C# to Frankenstein together some new code at runtime seems like there could be infinite Lisp-ish possibilities. Though you can dynamically create new code at runtime using Ruby/JavaScript, you can’t modify or access the expression trees themselves like Lisp. C# doesn’t allow you to look at any expression tree at runtime either, but it does provide language integrated support for &lt;em&gt;building&lt;/em&gt; expression trees (and has in a primitive form since C# 3), which can have a similar effect.&lt;/p&gt;  &lt;p&gt;[3] &lt;a href="http://java.sun.com/docs/books/tutorial/java/generics/erasure.html"&gt;Type erasure&lt;/a&gt; is not what I would call a real implementation of generics. &lt;a href="http://www.roseindia.net/javatutorials/anonymous_innerclassestutorial.shtml"&gt;Anonymous inner classes&lt;/a&gt; are not closures.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-2526880251655220863?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ped3rxKBtDSiZ-dlZMKnDJBH85s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ped3rxKBtDSiZ-dlZMKnDJBH85s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ped3rxKBtDSiZ-dlZMKnDJBH85s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ped3rxKBtDSiZ-dlZMKnDJBH85s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=HrSr42f_JFQ:6RfETBmRU_E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=HrSr42f_JFQ:6RfETBmRU_E:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=HrSr42f_JFQ:6RfETBmRU_E:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=HrSr42f_JFQ:6RfETBmRU_E:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/HrSr42f_JFQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/2526880251655220863/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=2526880251655220863" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/2526880251655220863?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/2526880251655220863?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/HrSr42f_JFQ/language-mavens-tool-mavens.html" title="Language Mavens, Tool Mavens" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/04/language-mavens-tool-mavens.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUENQHw6eyp7ImA9WxJTFEk.&quot;"><id>tag:blogger.com,1999:blog-8001170587821659759.post-5428508281728270125</id><published>2009-04-22T17:40:00.001-07:00</published><updated>2009-04-22T17:48:11.213-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-22T17:48:11.213-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gitweb" /><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="SyntaxHighlighter" /><title>Gitweb Line Highlighting</title><content type="html">&lt;p align="center"&gt;&lt;a href="http://lh3.ggpht.com/_1Q1cgK2sxXk/Se-48xPQjCI/AAAAAAAAAXU/gMKE7CF5Svc/s1600-h/codehighlight%5B3%5D.png"&gt;&lt;img title="codehighlight" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="270" alt="codehighlight" src="http://lh3.ggpht.com/_1Q1cgK2sxXk/Se-49LS7jNI/AAAAAAAAAXY/8mcDGOmZOUA/codehighlight_thumb%5B1%5D.png?imgmax=800" width="476" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I made a few more changes today to support line highlighting of gitweb blobs. Like SyntaxHighlighter, the line highlighting is also completely JavaScript driven. When you highlight a line, it updates the fragment portion of the URL in your browser. Then when you send the URL (with the fragment) to someone, they will see the same highlighted code. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://home.koushikdutta.com:81/cgi-bin/gitweb/gitweb.cgi?p=TiledMaps.git;a=blob;f=TiledMaps/GraphicsRenderer.cs;h=c80293b961d5b9b4beba00b53f9e85acc5ff7769;hb=HEAD#12,13,"&gt;Click here for a sample of code highlighting.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Fun exercise in my quest to catch up and learn JavaScript, CSS, et al.&lt;/p&gt;  &lt;p&gt;I couldn’t do this by modifying the query string, because that causes a browser reload when changing window.location. I could perhaps have made a “create hyperlink” button that puts the hyperlink with a modified query string into your paste buffer, but that isn’t as easy as just copying the address out of your browser address bar.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8001170587821659759-5428508281728270125?l=www.koushikdutta.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PZh_i2yODfglieq00Bh-ldMlx90/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PZh_i2yODfglieq00Bh-ldMlx90/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PZh_i2yODfglieq00Bh-ldMlx90/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PZh_i2yODfglieq00Bh-ldMlx90/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=4GworSW0ISo:U3iiFEXXPKI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=4GworSW0ISo:U3iiFEXXPKI:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/MyBrainHurts?a=4GworSW0ISo:U3iiFEXXPKI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MyBrainHurts?i=4GworSW0ISo:U3iiFEXXPKI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MyBrainHurts/~4/4GworSW0ISo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.koushikdutta.com/feeds/5428508281728270125/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8001170587821659759&amp;postID=5428508281728270125" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5428508281728270125?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8001170587821659759/posts/default/5428508281728270125?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyBrainHurts/~3/4GworSW0ISo/gitweb-code-highlighting.html" title="Gitweb Line Highlighting" /><author><name>Koush</name><uri>http://www.blogger.com/profile/11049460148325973407</uri><email>koushikdutta@hotmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="13427599047107360757" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.koushikdutta.com/2009/04/gitweb-code-highlighting.html</feedburner:origLink></entry></feed>
