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

<channel>
	<title>Wangling</title>
	<atom:link href="http://wangling.me/feed/" rel="self" type="application/rss+xml" />
	<link>http://wangling.me</link>
	<description>I&#039;m Wang Ling. I&#039;m wangling you.</description>
	<lastBuildDate>Sun, 18 Jul 2010 02:29:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Defects of KVO</title>
		<link>http://wangling.me/2010/07/defects-of-kvo/</link>
		<comments>http://wangling.me/2010/07/defects-of-kvo/#comments</comments>
		<pubDate>Sat, 17 Jul 2010 15:12:13 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://wangling.me/?p=272</guid>
		<description><![CDATA[KVO(Key-Value Observing) is a very nice programming facility from Apple. Working together with KVC(Key-Value Coding), it makes the life of Apple developers a lot easier and happier. However, I recently found some annoying problems of KVO while building some reusable programming components ^(I&#8217;ll open source as much as possible when ready.)$ for Voodo and future [...]]]></description>
			<content:encoded><![CDATA[<p>KVO(<a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html">Key-Value Observing</a>) is a very nice programming facility from Apple. Working together with KVC(<a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html">Key-Value Coding</a>), it makes the life of Apple developers a lot easier and happier.</p>
<p>However, I recently found some annoying problems of KVO while building some reusable programming components ^(I&#8217;ll open source as much as possible when ready.)$ for <a href="http://iwonderphone.com/voodo/">Voodo</a> and future iOS projects.</p>
<h4>Observers can not be queried</h4>
<p>Observers are stored in dictionaries ^(See NSKeyValueObserving protocol&#8217;s <a href="https://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html#//apple_ref/occ/instm/NSObject/observationInfo">observationInfo</a>.)$, so it should be very easy to query whether an object A is a registered observer of object B. But one can&#8217;t do that.</p>
<h4>Unregistering an unregistered observer throws exception</h4>
<p>One can not query whether A is an observer of B in the first place, and can neither try to unregister it from B when one wants to ensure that A is unregistered from B. It is just ridiculous! And why is removing a nonexistent observer so fatal while removing a nonexistent entry from a collection is reasonably ignored? ^(See NSMutableArray&#8217;s <a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html#//apple_ref/occ/instm/NSMutableArray/removeObject:">removeObject:</a> and NSMutableDictionary&#8217;s <a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSMutableDictionary_Class/Reference/Reference.html#//apple_ref/occ/instm/NSMutableDictionary/removeObjectForKey:">removeObjectForKey:</a>)$</p>
<h4>Observers/observees don&#8217;t auto-dissolve the KVO relationship in dealloc</h4>
<p>It can be easily done in KVO framework code since it already has the data structure keeping the observer-observee relationship information, and is very reasonable things to do &#8211; when any part of a relationship is gone the relationship is ended. Without the auto-unregistration, developers&#8217; responsibility is unnecessarily heavier. In fact, it is no easy work in cases where observers outlive observees, because an observee needs to notify its observers of its death so the observers can detach themselves from the dying observee. ^(Normally it is the observers that are doing the KVO relationship management and it is the job of whoever did the connection to do the disconnection, but vice versa)$</p>
<h3>All in all</h3>
<p>KVO leaves some extra, tedious, and burdensome relationship management work to us while it could be easily and efficiently done at the root of itself. ^(Well, as Appler eskimo1 said in <a href="https://devforums.apple.com/message/259690#259690">devforums</a>, it is harder than one might think because <q>KVO needs to be both thread safe and GC clean, and must be careful to not impact the performance of code that isn&#8217;t using it</q>.)$</p>
<p>The KVO relationship management is especially stressful for observers watching many dynamic observees which is not unusual for generic components &#8211; <a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UINavigationController_Class/Reference/Reference.html">UINavigationController</a> and <a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITabBarController_Class/Reference/Reference.html">UITabBarController</a> both manage a dynamic group of UIViewControllers and may observe some properties of them. It is even worse in my component because not only the observee but also the observed properties of them are dynamic. May Apple save me (and you?).</p>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2010/07/defects-of-kvo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to Rock and Roll Your Apps</title>
		<link>http://wangling.me/2010/07/how-to-rock-and-roll-your-apps/</link>
		<comments>http://wangling.me/2010/07/how-to-rock-and-roll-your-apps/#comments</comments>
		<pubDate>Fri, 16 Jul 2010 06:12:54 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[UIKit]]></category>

		<guid isPermaLink="false">http://wangling.me/?p=256</guid>
		<description><![CDATA[I mean, how to rock and rotate interfaces in your UIKit based apps. Apple taught me most I need to know about how to manage the interface orientation, but still left some dark corners that I had to explore by myself. Now that I&#8217;ve seen the whole landscape, I want to share it with you. [...]]]></description>
			<content:encoded><![CDATA[<p>I mean, how to rock and rotate interfaces in your UIKit based apps.</p>
<p>Apple taught me most I need to know about how to <a href="https://developer.apple.com/iphone/library/featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP40007457-CH101-SW3">manage the interface orientation</a>, but still left some dark corners that I had to explore by myself. Now that I&#8217;ve seen the whole landscape, I want to share it with you.</p>
<p>Read the <a href="https://developer.apple.com/iphone/library/featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html">documentation</a> first if you haven&#8217;t yet. After that, you should know how to write the rotation code to respond to orientation changes, if only you are notified of the orientation changes in the first place.</p>
<p>Your view controller is always notified of the orientation changes if it is the frontmost view controller &#8211; the only view controller, the top modal view controller, the top view controller in the top navigation controller, or the current selected view controller in top tab bar controller. In these cases, simply following the documentation by implementing your rotation logic in those view rotation methods ^(<a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/willRotateToInterfaceOrientation:duration:"><code>willRotateToInterfaceOrientation:duration:</code></a>, <a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/willAnimateRotationToInterfaceOrientation:duration:"><code>willAnimateRotationToInterfaceOrientation:duration:</code></a>,  and <a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/didRotateFromInterfaceOrientation:"><code>didRotateFromInterfaceOrientation:</code></a>)$ is enough.</p>
<p>However, no view rotation message will be sent to your view controller if the rotation occurs when it is not in the frontmost. Well, it is very reasonable behavior though, since its view is invisible then. Laziness is a great virtue here. What&#8217;s the point of rotating the invisible view under the hood except for consuming more battery, especially considering that the interface may be rotated back to its original orientation? What makes it a problem is the fact that these messages will neither be sent to your view controller when it becomes the frontmost one later. Your view controller will be <strong>never</strong> aware of the orientation changes that happen when it is not in the frontmost! One example for better understanding:</p>
<ol>
<li>A is the current selected view controller in a tab bar controller and the device is in portrait orientation.</li>
<li>View controller B is selected in the tab bar controller.</li>
<li>The device is rotated to landscape orientation.</li>
<li>A is selected again.</li>
</ol>
<p>See the problem? The orientation is portrait at first, and view controller A presents its view correctly; the orientation becomes landscape later, but A does not know that and still presents a portrait view when it returns to the frontmost.</p>
<p>In fact, the example could be reduced to a simpler one:</p>
<ol>
<li>B is the current selected view controller in a tab bar controller and the device is in portrait orientation.</li>
<li>The device is rotated to landscape orientation.</li>
<li>View controller A is selected.</li>
</ol>
<p>The example can be easily extended to view controllers managed by a navigation controller. ^(The situation of modal view controllers is different. The rotation messages will be properly sent to the concerning view controllers. I don&#8217;t know why Apple can&#8217;t treat them the same way.)$ The problem is reduced to: view controller A initially sets up its view in portrait mode and relies on the code in view rotation methods to adjust the view to new orientations, but view rotation messages are never sent to A so it never rotates its view.</p>
<p>It is clear now that not only view rotation methods should have code for adjusting view for different orientations, but also the initial view setting up code should be orientation dependent. And that&#8217;s Apple didn&#8217;t tell us.</p>
<p>Finally, here is my way to attack this problem:</p>
<ul>
<li>Factor the orientation-dependent layout code into a method, naturally called <code>(void)layoutView:(UIInterfaceOrientation)orientation</code>.</li>
<li>Call <code>layoutView:</code> in both <a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewWillAppear:"><code>viewWillAppear:</code></a> and <a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/willAnimateRotationToInterfaceOrientation:duration:"><code>willAnimateRotationToInterfaceOrientation:duration:</code></a>.</li>
</ul>
<p>May this article help you rotate your apps nicely and may your apps rock.</p>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2010/07/how-to-rock-and-roll-your-apps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Documentation Set Generation Tool in Xcode is Wanted</title>
		<link>http://wangling.me/2010/07/documentation-set-generation-tool-in-xcode-is-wanted/</link>
		<comments>http://wangling.me/2010/07/documentation-set-generation-tool-in-xcode-is-wanted/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 02:30:50 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://wangling.me/?p=250</guid>
		<description><![CDATA[Documentation set generation tool in Xcode to generate documentation sets in the style of Apple Developer Documentation is necessary for a prosperous Apple developer community. The current HeaderDoc and Doxygen are both far from Apple standard. HeaderDoc is obviously not favored by developers. Doxygen is better and even officially advocated by Apple, but still tedious [...]]]></description>
			<content:encoded><![CDATA[<p>Documentation set generation tool in Xcode to generate documentation sets in the style of Apple Developer Documentation is necessary for a prosperous Apple developer community. The current <a href="http://developer.apple.com/opensource/tools/headerdoc.html">HeaderDoc</a> and <a href="http://www.stack.nl/~dimitri/doxygen/index.html">Doxygen</a> are both far from Apple standard.</p>
<p>HeaderDoc is obviously <a href="http://stackoverflow.com/questions/174315/how-do-you-document-your-source-code-in-xcode">not favored by developers</a>. Doxygen is better and even <a href="http://developer.apple.com/tools/creatingdocsetswithdoxygen.html">officially advocated by Apple</a>, but still tedious to use and just can&#8217;t generate Apple standard documentations(see a nice example <a href="http://dysart.cs.byu.edu/CHDataStructures/">here</a>). <a href="http://github.com/mattball/doxyclean">Doxyclean</a> is very helpful in converting Doxygen output to resemble Apple Developer Documentation, but seems not capable to generate Xcode Documentation Sets. Following the work of Doxyclean, <a href="http://github.com/tomaz/appledoc">appledoc</a> supplements some missing features like Xcode Documentation Set generation.</p>
<p>To sum up, there are several third-party tools doing the work that should be better done by Apple in Apple way. Even though they can do their best to generate very Apple like documentations, they can not offer the smooth integration in Xcode that is otherwise possible if it is done by Apple.</p>
<p>So, I&#8217;ve posted a bug report(Problem ID: 8193210) to request such a Documentation Set generation tool. If you also want it, please go to duplicate a <a href="http://bugreport.apple.com/">bug report</a> with following content:</p>
<blockquote><p>I vote for bug report ‘8193210′.</p>
<p>Summary:<br />
Documentation set generation tool in Xcode to generate documentation set in the style of Apple Developer Documentation is necessary for a prosperous Apple developer community. The current HeaderDoc and doxygen are both far from the Apple standard.</p>
<p>Steps to Reproduce:</p>
<p>Expected Results:</p>
<p>Actual Results:</p>
<p>Regression:</p>
<p>Notes:
</p></blockquote>
<p>Read <a href="http://finbarrbrady.com/2010/07/help-us-get-international-promo-codes/">this article</a> to learn why and how to vote for a bug report. ^(Surely I&#8217;ve voted this &#8220;international promo codes&#8221; bug report since I&#8217;m from China.)$</p>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2010/07/documentation-set-generation-tool-in-xcode-is-wanted/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>说说 Mac 下的截屏软件</title>
		<link>http://wangling.me/2010/03/%e8%af%b4%e8%af%b4-mac-%e4%b8%8b%e7%9a%84%e6%88%aa%e5%b1%8f%e8%bd%af%e4%bb%b6/</link>
		<comments>http://wangling.me/2010/03/%e8%af%b4%e8%af%b4-mac-%e4%b8%8b%e7%9a%84%e6%88%aa%e5%b1%8f%e8%bd%af%e4%bb%b6/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 07:37:11 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[中文]]></category>
		<category><![CDATA[Voodo]]></category>

		<guid isPermaLink="false">http://blog.wangling.me/?p=200</guid>
		<description><![CDATA[刚完成了 Voodo 2 的开发，正在写用户手册，其中用到不少截图。 对 app 自身的截图，用真机 + Xcode 就能完美解决，但是对截图做注释就需额外的工具来完成。 一说到对图片进行操作，大家容易先想到 Photoshop, Illustrator，OmniGraffle 等重器，轻一点的也是 Acorn，Pixelmator 等。 这些专业的图片编辑软件确实强大，有些功能只有它们能提供。比如，我试了一圈，最终发现还是 Illustrator 里的 gradient 强大，是唯一一个直接支持 ellipse gradient 效果的，于是在对截图做聚光效果时都是用的 Illustrator。 既然我在对 Voodo 2 做截图时用的是 Xcode，后续工作是图片注释，为什么还需要截屏软件呢？ 这是因为，其实大多截屏软件都自带注释功能，足以应付绝大多数需求；而且因为 Voodo 有同步 Google Calendar 的功能，我需要对 Google Calendar 上的操作进行一些截图。 下面就我用过的一些截屏软件做一个简单的比较（排名无明显先后）： Snagit Snagit 不愧是老牌领头羊，beta 就已经多方面超越其他先入场的小弟了，操作的灵活性，注释工具都是最好的。beta 版免费使用，很爽。 没有单独的 Full Screen Capture，那是因为根本不需要，人家的 All-in-One Capture 太帅了，自动识别 Full Screen，Window，甚至 Region [...]]]></description>
			<content:encoded><![CDATA[<p>刚完成了 <a href="http://blog.iwonderphone.com/2010/03/27/try-voodo-2-early-and-win-promo-code/">Voodo 2</a> 的开发，正在写用户手册，其中用到不少截图。</p>
<p>对 app 自身的截图，用真机 + Xcode 就能完美解决，但是对截图做注释就需额外的工具来完成。</p>
<p>一说到对图片进行操作，大家容易先想到 Photoshop, Illustrator，OmniGraffle 等重器，轻一点的也是 Acorn，Pixelmator 等。</p>
<p>这些专业的图片编辑软件确实强大，有些功能只有它们能提供。比如，我试了一圈，最终发现还是 Illustrator 里的 gradient 强大，是唯一一个直接支持 ellipse gradient 效果的，于是在对截图做聚光效果时都是用的 Illustrator。<br />
<img src="http://blog.wangling.me/wp-content/uploads/2010/03/inactive_search_bar.png" alt="" title="Inactive Search Bar" width="320" height="460" class="aligncenter size-full wp-image-204" /></p>
<p>既然我在对 <a href="http://iwonderphone.com/voodo/">Voodo</a> 2 做截图时用的是 Xcode，后续工作是图片注释，为什么还需要截屏软件呢？</p>
<p>这是因为，其实大多截屏软件都自带注释功能，足以应付绝大多数需求；而且因为 <a href="http://iwonderphone.com/voodo/">Voodo</a> 有同步 Google Calendar 的功能，我需要对 Google Calendar 上的操作进行一些截图。</p>
<p>下面就我用过的一些截屏软件做一个简单的比较（排名无明显先后）：</p>
<h3><a href="http://www.techsmith.com/snagitmac/">Snagit</a></h3>
<p>Snagit 不愧是老牌领头羊，beta 就已经多方面超越其他先入场的小弟了，操作的灵活性，注释工具都是最好的。beta 版免费使用，很爽。<br />
<a href="http://blog.wangling.me/wp-content/uploads/2010/03/Snagit.png"><img src="http://blog.wangling.me/wp-content/uploads/2010/03/Snagit.png" alt="" title="Snagit" width="893" height="710" class="aligncenter size-full wp-image-215" /></a></p>
<p>没有单独的 Full Screen Capture，那是因为根本不需要，人家的 All-in-One Capture 太帅了，自动识别 Full Screen，Window，甚至 Region in Window，还有 Capture Scrolling Area 能对需要滚动才能看全的页面做完整的截图。<br />
<a href="http://blog.wangling.me/wp-content/uploads/2010/03/Snagit-Capturing.png"><img src="http://blog.wangling.me/wp-content/uploads/2010/03/Snagit-Capturing.png" alt="" title="Snagit-Capturing" width="890" height="754" class="aligncenter size-full wp-image-214" /></a></p>
<p>Share 功能尚未成型，暂时只内嵌了 Email 功能。相信正式版肯定会有完善的 Share 功能，看看 <a href="http://www.techsmith.com/">TechSmith</a> 的其他软件就知道了，何况人家还拥有自己的专业多媒体资源分享网站 <a href="http://www.screencast.com/">Screencast.com</a>。</p>
<h3><a href="http://www.ambrosiasw.com/utilities/snapzprox/">Snapz Pro X</a></h3>
<p>Snapz Pro X 没有注释功能，也不带 Share。但就截图的一个“截”字来说，Snapz Pro X 确实可算是最强悍的，算是名副其实。看一个它特有的截图功能：<br />
<a href="http://blog.wangling.me/wp-content/uploads/2010/03/Snapz-Pro-X.png"><img src="http://blog.wangling.me/wp-content/uploads/2010/03/Snapz-Pro-X.png" alt="" title="Snapz Pro X" width="610" height="214" class="aligncenter size-full wp-image-208" /></a></p>
<p>其实把它放到这里并不完全合适，因为 Snapz Pro X 同时还是强大的 Screencast 录制软件。我购买它就是为了给 <a href="http://iwonderphone.com/voodo/">Voodo</a> 录制 <a href="http://blog.iwonderphone.com/2010/03/27/try-voodo-2-early-and-win-promo-code/">demo</a> 及 <a href="http://iwonderphone.com/voodo/">promo video</a>，配合着 iMovie 做的后期制作，一般的效果都能达到。</p>
<h3><a href="http://skitch.com/">Skitch</a></h3>
<p>Skitch 的 UI 设计相当独特，类似一个相框，上传分享特别方便（skitch.com，flickr，Mobile Me 等一应俱全），截图质量和注释工具都不错，而且免费。性价比最高，估计是目前最普及的截图软件。我一般都通过 Skitch 上传到 <a href="http://skitch.com/an00na/nhdsx/iphone-simulator">skitch.com</a> 秀图给别人看。<br />
<a href="http://blog.wangling.me/wp-content/uploads/2010/03/Skitch-Capturing.png"><img src="http://blog.wangling.me/wp-content/uploads/2010/03/Skitch-Capturing.png" alt="" title="Skitch-Capturing" width="508" height="892" class="aligncenter size-full wp-image-210" /></a><br />
<a href="http://blog.wangling.me/wp-content/uploads/2010/03/Skitch.png"><img src="http://blog.wangling.me/wp-content/uploads/2010/03/Skitch.png" alt="" title="Skitch" width="543" height="910" class="aligncenter size-full wp-image-211" /></a></p>
<h3><a href="http://www.realmacsoftware.com/littlesnapper/">LittleSnapper</a></h3>
<p>LittleSnapper 可能是最眼熟的一个名字。软件本身 UI 也算清爽，功能也算齐全，支持多种 Share 方式，包括 flickr，但上手感觉不利索，不像名字取的那样 little。<br />
<a href="http://blog.wangling.me/wp-content/uploads/2010/03/LittleSnapper.png"><img src="http://blog.wangling.me/wp-content/uploads/2010/03/LittleSnapper.png" alt="" title="LittleSnapper" width="958" height="668" class="aligncenter size-full wp-image-220" /></a></p>
<p>我特别不喜欢它的截图方式，定位不如其他三个的十字交叉线来的方便：<br />
<img src="http://blog.wangling.me/wp-content/uploads/2010/03/LittleSnapper-Capturing.png" alt="" title="LittleSnapper-Capturing" width="385" height="741" class="aligncenter size-full wp-image-219" /></p>
<p>不过，LittleSnapper 也有亮点：1) 组织管理功能比较强大，适合剪贴报爱好者；2）强大的网页截图功能，它自带 HTML 解析器，能定位到 Element，适合网页设计者。<br />
<a href="http://blog.wangling.me/wp-content/uploads/2010/03/LittleSnapper-Websnap.png"><img src="http://blog.wangling.me/wp-content/uploads/2010/03/LittleSnapper-Websnap.png" alt="" title="LittleSnapper-Websnap" width="1050" height="747" class="aligncenter size-full wp-image-226" /></a></p>
<h3>系统自带</h3>
<p>最后，不得不说，其实 Mac 系统自带的截图功能对付日常工作已经绰绰有余，截图质量更是没得说。再配上 Preview 做点简单的注释，80%的活都能应付。<br />
<a href="http://blog.wangling.me/wp-content/uploads/2010/03/System-Screen-Capture.png"><img src="http://blog.wangling.me/wp-content/uploads/2010/03/System-Screen-Capture.png" alt="" title="System Screen Capture" width="602" height="817" class="aligncenter size-full wp-image-232" /></a><br />
<a href="http://blog.wangling.me/wp-content/uploads/2010/03/Preview-Annotation.png"><img src="http://blog.wangling.me/wp-content/uploads/2010/03/Preview-Annotation.png" alt="" title="Preview Annotation" width="730" height="900" class="aligncenter size-full wp-image-229" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2010/03/%e8%af%b4%e8%af%b4-mac-%e4%b8%8b%e7%9a%84%e6%88%aa%e5%b1%8f%e8%bd%af%e4%bb%b6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>联通连不通─VPN</title>
		<link>http://wangling.me/2010/03/china-unicom-vpn/</link>
		<comments>http://wangling.me/2010/03/china-unicom-vpn/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 07:03:14 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[中文]]></category>
		<category><![CDATA[freedom]]></category>

		<guid isPermaLink="false">http://blog.wangling.me/?p=196</guid>
		<description><![CDATA[打洞、翻墙已经渐渐成了中国高端网民的基本生存技能。 VPN 就是翻墙的一种利器。但是要自己搭一个VPN实属不易，如果你用的是联通（原网通）的ADSL，可能更麻烦一点。 PPTP VPN 比较简单，没有特殊安全性需求的，推荐优先选择这种。搭建方法直接参照此文就行。一个 pptpd 就搞定了。注意别忘了打开 Masquerading/NAT。 我在浙江老家（电信 ADSL）的时候，就用以上配置轻松搞定了 PPTP VPN，终于可以在 iPhone 上玩 Tweetie 和 Facebook 了。 结果一回北京，PPTP VPN 马上不好使了：能够正常连接上，但是很快就会无法访问网络，并且 ping 报错 No buffer space available。 我不是网络专家，网络技术相当业余，无法确认是联通 ADSL 的问题，还是办理宽带时附赠的华为 EchoLife HG527-a 路由器的问题（有其他 ADSL 路由器的朋友可以帮忙试验一下），但总之是联通让我的 VPN 连不通了。 我本想用别的 PPTP VPN 试验一下，好确认不是我自己 VPN 的问题，但是一时间没找到可供试用的 VPN（有 PPTP VPN 的朋友可以帮忙试验一下）。于是，我又折腾了两天，搭了个 L2TP/IPsec VPN，终于又能逍遥游了。 搭建 L2TP/IPsec VPN 的方法请见此文。 可能遇到的问题和解决方法： [...]]]></description>
			<content:encoded><![CDATA[<p>打洞、翻墙已经渐渐成了中国高端网民的基本生存技能。</p>
<p>VPN 就是翻墙的一种利器。但是要自己搭一个VPN实属不易，如果你用的是联通（原网通）的ADSL，可能更麻烦一点。</p>
<p>PPTP VPN 比较简单，没有特殊安全性需求的，推荐优先选择这种。搭建方法直接参照<a href="http://www.sharedknowhow.com/2008/09/linux-vpn-server-installation-for-use-with-iphone/">此文</a>就行。一个 pptpd 就搞定了。注意别忘了打开 Masquerading/NAT。</p>
<p>我在浙江老家（电信 ADSL）的时候，就用以上配置轻松搞定了 PPTP VPN，终于可以在 iPhone 上玩 Tweetie 和 Facebook 了。</p>
<p>结果一回北京，PPTP VPN 马上不好使了：能够正常连接上，但是很快就会无法访问网络，并且 ping 报错 No buffer space available。</p>
<p>我不是网络专家，网络技术相当业余，无法确认是联通 ADSL 的问题，还是办理宽带时附赠的华为 EchoLife HG527-a 路由器的问题（有其他 ADSL 路由器的朋友可以帮忙试验一下），但总之是联通让我的 VPN 连不通了。</p>
<p>我本想用别的 PPTP VPN 试验一下，好确认不是我自己 VPN 的问题，但是一时间没找到可供试用的 VPN（有 PPTP VPN 的朋友可以帮忙试验一下）。于是，我又折腾了两天，搭了个 L2TP/IPsec VPN，终于又能逍遥游了。</p>
<p>搭建 L2TP/IPsec VPN 的方法请见<a href="http://adamantsys.com/blog/alternate-path/l2tp-ipsec-server-setup-for-linux">此文</a>。</p>
<p>可能遇到的问题和解决方法：</p>
<ol>
<li>连接不上，/var/log/auth.log 中有类似如下记录：
<pre wrap="true">Mar 10 11:01:36 hostname pluto[14061]: ERROR: asynchronous network error report on eth0 (sport=4500) for message to your.client.ip.address port 4500, complainant your.server,ip.address: No route to host [errno 113, origin ICMP type 3 code 1 (not authenticated)]</pre>
<p>在 ipsec.conf 中加上 leftnexthop=your.server.gateway.ip 应该可以解决。</li>
<li>连接不上，/var/log/system 中有类似如下记录：
<pre wrap="true">Mar 11 14:44:20 hostname pppd[4407]: The remote system is required to authenticate itself
Mar 11 14:44:20 hostname pppd[4407]: but I couldn't find any suitable secret (password) for it to use to do so.</pre>
<p>这是由于验证过程中未使用 l2tp-secrets 中的密码（至于为何如此我不懂，另请高人解释），而是使用 pptp（L2TP/IPsec 也是要走 pptp 的）的密码，所以需要在 /etc/ppp/chap-secrets 中设置密码（具体请见上面如何搭建 PPTP VPN）。</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2010/03/china-unicom-vpn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>天朝土人水深火热木有金</title>
		<link>http://wangling.me/2010/01/sky-earth-water-fire-wood-metal/</link>
		<comments>http://wangling.me/2010/01/sky-earth-water-fire-wood-metal/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 05:04:17 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[中文]]></category>

		<guid isPermaLink="false">http://blog.wangling.me/2010/01/%e5%a4%a9%e6%9c%9d%e5%9c%9f%e4%ba%ba%e6%b0%b4%e6%b7%b1%e7%81%ab%e7%83%ad%e6%9c%a8%e6%9c%89%e9%87%91/</guid>
		<description><![CDATA[求下联。 注：我不懂对对子，只是在乱吟。]]></description>
			<content:encoded><![CDATA[<p>求下联。</p>
<p>注：我不懂对对子，只是在乱吟。</p>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2010/01/sky-earth-water-fire-wood-metal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wedding Voodo</title>
		<link>http://wangling.me/2010/01/wedding-voodo/</link>
		<comments>http://wangling.me/2010/01/wedding-voodo/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 04:55:39 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Voodo]]></category>

		<guid isPermaLink="false">http://blog.wangling.me/?p=187</guid>
		<description><![CDATA[中文版 Today is a big day in my life for two things. First, my first iPhone app &#8211; Voodo &#8211; debuts on the App Store. Second, my Wedding with J will take place tonight. While we&#8217;ve received so many sincere blessings and gifts, I think it&#8217;s my responsibility to prepare the best gift for my [...]]]></description>
			<content:encoded><![CDATA[<p><a id="wedding-voodoo-English" href="#wedding-voodoo-Chinese">中文版</a></p>
<p>Today is a big day in my life for two things.</p>
<p>First, my first iPhone app &#8211; <a href="http://iwonderphone.com/voodo/">Voodo</a> &#8211; debuts on the <a href="http://itunes.com/apps/voodo">App Store</a>.</p>
<p>Second, my Wedding with J will take place tonight.</p>
<p>While we&#8217;ve received so many sincere blessings and gifts, I think it&#8217;s my responsibility to prepare the best gift for my bride, our wedding, and our future life. So I purposely scheduled the debut date of Voodo for today.</p>
<p>I am so excited that I can hardly wait for the moment to come.</p>
<div id="language-divider">Chinese Version Below<br />
<hr />以上是<a id="wedding-voodoo-Chinese" href="#wedding-voodoo-English">英文版</a></div>
<p></p>
<h2>婚礼上的魔术（Voodoo）</h2>
<p>今天是个好日子、大日子。</p>
<p>我的第一个 iPhone app ─ <a href="http://iwonderphone.com/voodo/">Voodo</a> ─ 正式登陆 <a href="http://itunes.com/apps/voodo">App Store</a>.</p>
<p>今晚是我和佳的婚礼。</p>
<p>我们收到了许多诚挚的祝福和礼物。但是，我觉得，我有责任和义务为我的新娘、我们的婚礼、以及我们未来的生活，精心准备一份最好的礼物。所以，我特意将 Voodo 的上架日期定为今天。</p>
<p>真是兴奋不已，迫不及待那一刻的到来。</p>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2010/01/wedding-voodo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What&#8217;s good about selectionArgs in SQLite queries</title>
		<link>http://wangling.me/2009/08/whats-good-about-selectionargs-in-sqlite-queries/</link>
		<comments>http://wangling.me/2009/08/whats-good-about-selectionargs-in-sqlite-queries/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 07:29:52 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://blog.wangling.me/?p=149</guid>
		<description><![CDATA[The Android API for querying SQLite databases supports two styles of queries: query&#40;uri, projection, selection = &#34;column=&#34; + value, selectionArgs = null, sortOrder&#41; query&#40;uri, projection, selection = &#34;column=?&#34;, selectionArgs = &#123; value_as_string &#125;, sortOrder&#41; Obviously, the first one is more straightforward and convenient. Then what&#8217;s good about the second one? Let me try to sell [...]]]></description>
			<content:encoded><![CDATA[<p>The Android API for querying SQLite databases supports two styles of queries:</p>
<ol>
<li><span class="code">query<span style="color: #009900;">&#40;</span>uri, projection, selection <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;column=&quot;</span> <span style="color: #339933;">+</span> value, selectionArgs <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span>, sortOrder<span style="color: #009900;">&#41;</span></span></li>
<li><span class="code">query<span style="color: #009900;">&#40;</span>uri, projection, selection <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;column=?&quot;</span>, selectionArgs <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> value_as_string <span style="color: #009900;">&#125;</span>, sortOrder<span style="color: #009900;">&#41;</span></span></li>
</ol>
<p>Obviously, the first one is more straightforward and convenient. Then what&#8217;s good about the second one?</p>
<p>Let me try to sell the goodness of <code>selectionArgs</code> via a simple example.</p>
<p>Suppose you are querying contacts with phone number, say, &#8220;+8612345678901&#8243;. With the first style, you get the WHERE clause <span class="code"><span style="color: #0000ff;">&quot;number=+8612345678901&quot;</span></span> which is the result of string concatenation &#8216;<span class="code"><span style="color: #0000ff;">&quot;number=&quot;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;+8612345678901&quot;</span></span>&#8216;.</p>
<p>It is easy to see that <em>phone numbers</em> are not <em>pure numbers</em>, i.e., they are not <em>numeric</em>. For example, the number &#8220;(010) 87654321 &#8221; and &#8220;010-87654321-001&#8243;, are valid phone numbers, but are neither valid <em>integer</em> nor <em>real</em> numbers ^(Of course, you don&#8217;t want to do the subtraction of the latter.)$. Thus, the the type of the number column (storage class in SQLite&#8217;s idiom) is TEXT.</p>
<p>From this nonnumeric phone number string raises a problem, a quite subtle one. With its <a href="http://www.sqlite.org/datatype3.html">dynamic type system、column affinity and type conversion</a>, SQLite will try to convert &#8220;+8612345678901&#8243; to a text string. But the express &#8220;+8612345678901&#8243; is numeric originally, because it has no quote marks surrounding it, and numeric values are operated according numeric rules first. So it is first normalized to &#8220;8612345678901&#8243;, and then the normalized value is converted to a text string &#8220;<strong>&#8216;</strong>8612345678901<strong>&#8216;</strong>&#8220;. </p>
<p>So the query that is really fed into the SQLite engine is something like this:<br />

<div class="my_codebox"><table><tr><td class="code"><div class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> contacts_table <span style="color: #993333; font-weight: bold;">WHERE</span> number<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'8612345678901'</span></div></td></tr></table></div></p>
<p>But as a text string, &#8217;8612345678901&#8242; can not be matched with &#8216;+8612345678901&#8242;, and the query fails.</p>
<p>We were suffering this kind of adversity until <code>selectionArgs</code> came to save the day.</p>
<p>With the second style, Android SQL query builder will replace <strong>?</strong>s in <code>selection</code> with the values from <code>selectionArgs</code>, in order that they appear in the selection. The values must be <span class="code"><span style="color: #003399;">String</span></span> and will be treated as text strings by SQLite, i.e., they must be converted to their <span class="code"><span style="color: #003399;">String</span></span> representation first if they are not <span class="code"><span style="color: #003399;">String</span></span>, and will be quoted automatically when replacing the <strong>?</strong>s. So the query that is fed into the SQLite engine is something like this:<br />

<div class="my_codebox"><table><tr><td class="code"><div class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> contacts_table <span style="color: #993333; font-weight: bold;">WHERE</span> number<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'+8612345678901'</span></div></td></tr></table></div></p>
<p>At this point, it doesn&#8217;t matter whether the underlying column type is really TEXT or not, because whatever the TEXT value is derived from, it can be correctly cast back to the original column type. The key point is that TEXT can be losslessly converted to any other types, but not necessarily vice versa as shown above.</p>
<p>In fact, we can stick to the first style by manually simulating the works done by Android SQL query builder this way:<br />

<div class="my_codebox"><table><tr><td class="code"><div class="java" style="font-family:monospace;">query<span style="color: #009900;">&#40;</span>uri, projection, selection <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;column=&quot;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;'&quot;</span> <span style="color: #339933;">+</span> value <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;'&quot;</span>, selectionArgs <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span>, sortOrder<span style="color: #009900;">&#41;</span></div></td></tr></table></div></p>
<p>But as you can see, it is such a tedious concatenation with just one query column, you don&#8217;t want to imagine the mess with more complex queries, do you?</p>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2009/08/whats-good-about-selectionargs-in-sqlite-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why it is impossible to intercept incoming calls on Android</title>
		<link>http://wangling.me/2009/08/why-it-is-impossible-to-intercept-incoming-calls-on-android/</link>
		<comments>http://wangling.me/2009/08/why-it-is-impossible-to-intercept-incoming-calls-on-android/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 14:15:48 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://blog.wangling.me/?p=143</guid>
		<description><![CDATA[For last several weeks, I&#8217;ve been struggling to intercept (not only get notice of) incoming calls on Android, but finally I have to admit that I failed. Actually, I&#8217;m doomed to fail, because it is just Mission Impossible. For the time being, a BroadcastReceiver for "android.intent.action.PHONE_STATE" is the only chance for application developers to generally [...]]]></description>
			<content:encoded><![CDATA[<p>For last several weeks, I&#8217;ve been struggling to intercept (not only get notice of) incoming calls on Android, but finally I have to admit that I failed.</p>
<p>Actually, I&#8217;m doomed to fail, because it is just <em>Mission Impossible</em>.</p>
<p>For the time being, a <code>BroadcastReceiver</code> for <code>"android.intent.action.PHONE_STATE"</code> is the only chance for application developers to generally probe for incoming calls. However, it comes <em>too late</em>.</p>
<p>Here is why.</p>
<p>
<div class="my_codebox"><table><tr><td class="code"><div class="java" style="font-family:monospace;"><pre style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RIL</span>.<span style="color: #006633;">RILReceiver</span>.<span style="color: #006633;">run</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>                                               <span style="color: #339933;">+---+</span> 
                                       android.<span style="color: #006633;">net</span>.<span style="color: #006633;">LocalSocket</span>.<span style="color: #006633;">getInputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;-----------------------|</span>   <span style="color: #339933;">|</span>
                                                                  <span style="color: #339933;">/</span>                                     <span style="color: #339933;">|</span>   <span style="color: #339933;">|</span>
                                                                 <span style="color: #339933;">|</span>                                      <span style="color: #339933;">|</span>   <span style="color: #339933;">|</span>
                                                                 v                                      <span style="color: #339933;">|</span> R <span style="color: #339933;">|</span>
  com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RIL</span>.<span style="color: #006633;">readRilMessage</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">InputStream</span>, <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>                            <span style="color: #339933;">|</span> A <span style="color: #339933;">|</span>
  com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RIL</span>.<span style="color: #006633;">processResponse</span><span style="color: #009900;">&#40;</span>Parcel<span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>                                       <span style="color: #339933;">|</span> D <span style="color: #339933;">|</span>
  <span style="color: #000000; font-weight: bold;">Case</span> 1<span style="color: #339933;">:</span> Unsolicited Commands <span style="color: #339933;">-</span> Incoming Call                                                          <span style="color: #339933;">|</span> I <span style="color: #339933;">|</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RIL</span>.<span style="color: #006633;">processUnsolicited</span><span style="color: #009900;">&#40;</span>Parcel<span style="color: #009900;">&#41;</span>                                   <span style="color: #339933;">|</span> O <span style="color: #339933;">|</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">BaseCommands</span>.<span style="color: #006633;">mCallStateRegistrants</span>.<span style="color: #006633;">notifyRegistrants</span><span style="color: #009900;">&#40;</span>AsyncResult<span style="color: #009900;">&#41;</span>    <span style="color: #339933;">|</span>   <span style="color: #339933;">|</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">CallTracker</span>.<span style="color: #006633;">sendMessage</span><span style="color: #009900;">&#40;</span>Message<span style="color: #009900;">&#41;</span>                                 <span style="color: #339933;">|</span>   <span style="color: #339933;">|</span>
                                                        <span style="color: #339933;">|</span>                                               <span style="color: #339933;">|</span>   <span style="color: #339933;">|</span>
                                                        <span style="color: #339933;">|</span>                                               <span style="color: #339933;">|</span> S <span style="color: #339933;">|</span>
                                                        v                                               <span style="color: #339933;">|</span> Y <span style="color: #339933;">|</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">CallTracker</span>.<span style="color: #006633;">handleMessage</span><span style="color: #009900;">&#40;</span>Message<span style="color: #009900;">&#41;</span>                               <span style="color: #339933;">|</span> S <span style="color: #339933;">|</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">CallTracker</span>.<span style="color: #006633;">pollCallsWhenSafe</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>                                  <span style="color: #339933;">|</span> T <span style="color: #339933;">|</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RIL</span>.<span style="color: #006633;">getCurrentCalls</span><span style="color: #009900;">&#40;</span>Message<span style="color: #009900;">&#41;</span>                                     <span style="color: #339933;">|</span> E <span style="color: #339933;">|</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RIL</span>.<span style="color: #006633;">send</span><span style="color: #009900;">&#40;</span>RILRequest<span style="color: #009900;">&#41;</span>                                             <span style="color: #339933;">|</span> M <span style="color: #339933;">|</span>
                                                     <span style="color: #339933;">|</span>                                                  <span style="color: #339933;">|</span>   <span style="color: #339933;">|</span>
                                                     <span style="color: #339933;">|</span>                                                  <span style="color: #339933;">|</span>   <span style="color: #339933;">|</span>
                                                     v                                                  <span style="color: #339933;">|</span>   <span style="color: #339933;">|</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RIL</span>.<span style="color: #006633;">RILSender</span>.<span style="color: #006633;">handleMessage</span><span style="color: #009900;">&#40;</span>Message<span style="color: #009900;">&#41;</span>                             <span style="color: #339933;">|</span>   <span style="color: #339933;">|</span>
                               android.<span style="color: #006633;">net</span>.<span style="color: #006633;">LocalSocket</span>.<span style="color: #006633;">getOutputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">----------------&gt;|</span>   <span style="color: #339933;">|</span>
                                                                                                        <span style="color: #339933;">+---+</span>    
  <span style="color: #000000; font-weight: bold;">Case</span> 2<span style="color: #339933;">:</span> Solicited Commands <span style="color: #339933;">-</span> <span style="color: #003399;">Request</span> Call Info
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RIL</span>.<span style="color: #006633;">processSolicited</span><span style="color: #009900;">&#40;</span>Parcel<span style="color: #009900;">&#41;</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RIL</span>.<span style="color: #006633;">findAndRemoveRequestFromList</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">RILRequest</span>.<span style="color: #006633;">mResult</span>.<span style="color: #006633;">sendToTarget</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
                                                           <span style="color: #339933;">|</span>
                                                           <span style="color: #339933;">|</span>
                                                           v
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">CallTracker</span>.<span style="color: #006633;">handleMessage</span><span style="color: #009900;">&#40;</span>Message<span style="color: #009900;">&#41;</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">CallTracker</span>.<span style="color: #006633;">handlePollCalls</span><span style="color: #009900;">&#40;</span>AsyncResult<span style="color: #009900;">&#41;</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">GSMPhone</span>.<span style="color: #006633;">notifyNewRingingConnection</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Connection</span><span style="color: #009900;">&#41;</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">PhoneBase</span>.<span style="color: #006633;">notifyNewRingingConnectionP</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Connection</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
      com.<span style="color: #006633;">android</span>.<span style="color: #006633;">phone</span>.<span style="color: #006633;">CallNotifier</span>.<span style="color: #006633;">sendMessage</span><span style="color: #009900;">&#40;</span>Message<span style="color: #009900;">&#41;</span>
                                           <span style="color: #339933;">|</span>
                                           <span style="color: #339933;">|</span>
                                           v
      com.<span style="color: #006633;">android</span>.<span style="color: #006633;">phone</span>.<span style="color: #006633;">CallNotifier</span>.<span style="color: #006633;">handleMessage</span><span style="color: #009900;">&#40;</span>Message<span style="color: #009900;">&#41;</span>
      com.<span style="color: #006633;">android</span>.<span style="color: #006633;">phone</span>.<span style="color: #006633;">CallNotifier</span>.<span style="color: #006633;">onNewRingingConnection</span><span style="color: #009900;">&#40;</span>AsyncResult<span style="color: #009900;">&#41;</span>
      com.<span style="color: #006633;">android</span>.<span style="color: #006633;">phone</span>.<span style="color: #006633;">PhoneUtils</span>.<span style="color: #006633;">showIncomingCallUi</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;----------------</span> Users see incoming call
&nbsp;
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">CallTracker</span>.<span style="color: #006633;">updatePhoneState</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">gsm</span>.<span style="color: #006633;">GSMPhone</span>.<span style="color: #006633;">notifyPhoneStateChanged</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">telephony</span>.<span style="color: #006633;">DefaultPhoneNotifier</span>.<span style="color: #006633;">notifyPhoneState</span><span style="color: #009900;">&#40;</span>Phone<span style="color: #009900;">&#41;</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">server</span>.<span style="color: #006633;">TelephonyRegistry</span>.<span style="color: #006633;">notifyCallState</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span>, <span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span>
    com.<span style="color: #006633;">android</span>.<span style="color: #006633;">server</span>.<span style="color: #006633;">TelephonyRegistry</span>.<span style="color: #006633;">broadcastCallStateChanged</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span>, <span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;---</span> Too late to interfere</pre></div></td></tr></table></div></p>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2009/08/why-it-is-impossible-to-intercept-incoming-calls-on-android/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Weasel Words &#8220;May Not Function Properly&#8221;</title>
		<link>http://wangling.me/2009/07/weasel-words-may-not-function-properly/</link>
		<comments>http://wangling.me/2009/07/weasel-words-may-not-function-properly/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 13:22:49 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[DropBox]]></category>
		<category><![CDATA[SugarSync]]></category>

		<guid isPermaLink="false">http://blog.wangling.me/?p=117</guid>
		<description><![CDATA[As a Mac user and developer, I&#8217;ve been looking for good alternatives to DropBox for on-line backup and sync, since I found myself dragging all kinds of configure files and directories into DropBox and then linking to them from their original paths. This move-and-link scheme is just too awkward to bear as more and more [...]]]></description>
			<content:encoded><![CDATA[<p>As a Mac user and developer, I&#8217;ve been looking for good alternatives to <a href="https://www.getdropbox.com/">DropBox</a> for on-line backup and sync, since I found myself dragging all kinds of configure files and directories into <strong>DropBox</strong> and then linking to them from their original paths. This move-and-link scheme is just too awkward to bear as more and more scattered files and directories are involved.</p>
<p>Today, I stumbled upon <a href="https://www.sugarsync.com/">SugarSync</a> which seems very promising. The most outstanding advantage of <strong>SugarSync</strong> over <strong>DropBox</strong> is its flexibility to backup/sync any folders. You can see the detailed comparison between <strong>SugarSync</strong> and other prominent competitors <a href="https://www.sugarsync.com/sync_comparison.html">here</a>.</p>
<p>However, just before I set out to download <a href="https://www.sugarsync.com/downloads/SugarSyncManager.dmg">SugarSync Manager 1.6.2 for Mac (Beta)</a>, I glimpsed the <a href="http://support.sugarsync.com/ics/support/default.asp?deptID=4579&#038;task=knowledge&#038;questionID=361">Known Issues</a> ^(The more software you use, especially <a href="http://www.codinghorror.com/blog/archives/001289.html">the more software you develop, the more wary of software you are</a>.)$, and one of them scared the pants off me. It said:</p>
<blockquote><p>If you are using a mac that has been formatted with a <em>case-sensitive</em> filesystem instead of the default case-insensitive filesystem, SugarSync <strong>may not function properly</strong> due to incorrect case of paths.</p></blockquote>
<p>I am definitely one of those implied idiots that formatted their effeminate Macs with <em>Case-Sensitive</em> filesystems just to show more masculine. Fine, in fact, I am a 6-year-old Linux user. Whatsoever, what on earth makes you developers resist <em>case-sensitivity</em> so much that you prefer to turn down your peer Unix developers ^(I don&#8217;t think Windows users care about <em>case-sensitivity</em> because they never have one, and aren&#8217;t all Unix (before Mac OS X) users developers?)$? Are you as <a href="http://www.google.com/search?q=adobe+not+support+case+sensitive">arrogant as Adobe</a>?</p>
<p>I am also a coward who dare not to take a risk. What do you mean by &#8220;<strong>may not function properly</strong>&#8220;? ^(Maybe, by &#8220;may not&#8221; instead of &#8220;will not&#8221;, they mean it works well even on <em>case-sensitive</em> filesystems only if there are not any files or directories distinguishable only by case?)$ Will it damage my original data, or just refuse to backup them? And why don&#8217;t you just say &#8220;SugarSync does not support <em>case-sensitive</em> filesystems (right now), so do not use SugarSync on them.&#8221;?</p>
<p>What if I took the risk and lost my data? So then you can disclaim &#8220;We have warned you that it <strong>may not function properly</strong>. You made the decision. You take the responsibility.&#8221;?</p>
<p>I think there are some basic moral code that a <strong>properly functioning</strong> vendor should follow:</p>
<ul>
<li>For cases where your product function perfectly, proudly announce them and dutifully guarantee them.</li>
<li>For cases where your product does not function perfectly, describe the deficiencies clearly.</li>
<li>For cases you are not sure, confess candidly that even you are not sure and advise users against using it in those cases.</li>
<li>Never make any cunning disclaimers, because, you see, weasel words &#8220;<strong>may not function properly</strong>&#8220;, or even hurt your prospects.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2009/07/weasel-words-may-not-function-properly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->