<?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 &#187; Android</title>
	<atom:link href="http://wangling.me/category/android/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>Tue, 15 May 2012 14:17:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<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<sup><a href="http://wangling.me/2009/08/whats-good-about-selectionargs-in-sqlite-queries/#footnote_0_149" id="identifier_0_149" class="footnote-link footnote-identifier-link" title="Of course, you don&amp;#8217;t want to do the subtraction of the latter.">1</a></sup>. 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>
<div class="footnotes"><ol ><li id="footnote_0_149" class="footnote">Of course, you don&#8217;t want to do the subtraction of the latter.</li></ol></div><div class="social">			<a href="https://twitter.com/share?url=http%3A%2F%2Fwangling.me%2F2009%2F08%2Fwhats-good-about-selectionargs-in-sqlite-queries%2F" class="twitter-share-button" data-url="http%3A%2F%2Fwangling.me%2F2009%2F08%2Fwhats-good-about-selectionargs-in-sqlite-queries%2F" data-text="What&#8217;s good about selectionArgs in SQLite queries" data-via="an0" data-count="none">Tweet</a>
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>			<script type="text/javascript" charset="utf-8">
(function(){
  var _w = 86 , _h = 18;
  var param = {
    url:"http%3A%2F%2Fwangling.me%2F2009%2F08%2Fwhats-good-about-selectionargs-in-sqlite-queries%2F",
    type:'6',
    count:'', /**是否显示分享数，1显示(可选)*/
    appkey:'', /**您申请的应用appkey,显示分享来源(可选)*/
    title:'What&#8217;s good about selectionArgs in SQLite queries', /**分享的文字内容(可选，默认为所在页面的title)*/
    pic:'', /**分享图片的路径(可选)*/
    ralateUid:'1676354212', /**关联用户的UID，分享微博会@该用户(可选)*/
    rnd:new Date().valueOf()
  }
  var temp = [];
  for( var p in param ){
    temp.push(p + '=' + encodeURIComponent( param[p] || '' ) )
  }
  document.write('<iframe allowTransparency="true" frameborder="0" scrolling="no" src="http://hits.sinajs.cn/A1/weiboshare.html?' + temp.join('&') + '" width="'+ _w+'" height="'+_h+'" style="margin-left:5px;"></iframe>')
})()
</script></div>]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2009/08/whats-good-about-selectionargs-in-sqlite-queries/feed/</wfw:commentRss>
		<slash:comments>3</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>
<div class="social">			<a href="https://twitter.com/share?url=http%3A%2F%2Fwangling.me%2F2009%2F08%2Fwhy-it-is-impossible-to-intercept-incoming-calls-on-android%2F" class="twitter-share-button" data-url="http%3A%2F%2Fwangling.me%2F2009%2F08%2Fwhy-it-is-impossible-to-intercept-incoming-calls-on-android%2F" data-text="Why it is impossible to intercept incoming calls on Android" data-via="an0" data-count="none">Tweet</a>
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>			<script type="text/javascript" charset="utf-8">
(function(){
  var _w = 86 , _h = 18;
  var param = {
    url:"http%3A%2F%2Fwangling.me%2F2009%2F08%2Fwhy-it-is-impossible-to-intercept-incoming-calls-on-android%2F",
    type:'6',
    count:'', /**是否显示分享数，1显示(可选)*/
    appkey:'', /**您申请的应用appkey,显示分享来源(可选)*/
    title:'Why it is impossible to intercept incoming calls on Android', /**分享的文字内容(可选，默认为所在页面的title)*/
    pic:'', /**分享图片的路径(可选)*/
    ralateUid:'1676354212', /**关联用户的UID，分享微博会@该用户(可选)*/
    rnd:new Date().valueOf()
  }
  var temp = [];
  for( var p in param ){
    temp.push(p + '=' + encodeURIComponent( param[p] || '' ) )
  }
  document.write('<iframe allowTransparency="true" frameborder="0" scrolling="no" src="http://hits.sinajs.cn/A1/weiboshare.html?' + temp.join('&') + '" width="'+ _w+'" height="'+_h+'" style="margin-left:5px;"></iframe>')
})()
</script></div>]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2009/08/why-it-is-impossible-to-intercept-incoming-calls-on-android/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>How content changes of ContentProvider propagate to ListView via Cursor</title>
		<link>http://wangling.me/2009/07/how-content-changes-of-contentprovider-propagate-to-listview-via-cursor/</link>
		<comments>http://wangling.me/2009/07/how-content-changes-of-contentprovider-propagate-to-listview-via-cursor/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 05:39:00 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://blog.wangling.me/?p=29</guid>
		<description><![CDATA[I know there must be an { Observable-&#62;Observer, Observable-&#62;Observer, &#8230; } chain from ContentProvider to ListView (or general AdapterView), but I didn&#8217;t know how exactly this chain is composed. I put by the itch to untangle the knot until recently I set out to implement an OrderedMergeCursor1, which should be a subclass of MergeCursor that [...]]]></description>
			<content:encoded><![CDATA[<p>I know there must be an { Observable-&gt;Observer, Observable-&gt;Observer, &#8230; } chain from ContentProvider to ListView (or general AdapterView), but I didn&#8217;t  know how exactly this chain is composed.</p>
<p>I put by the itch to untangle the knot until recently I set out to implement an OrderedMergeCursor<sup><a href="http://wangling.me/2009/07/how-content-changes-of-contentprovider-propagate-to-listview-via-cursor/#footnote_0_29" id="identifier_0_29" class="footnote-link footnote-identifier-link" title="I will talk about it in future post.">1</a></sup>, which should be a subclass of MergeCursor that merge-sorts pre-ordered cursors.</p>
<p>It turns out that the chain is quite long, and kinda entangled by the two content data concepts of Cursor: Content(ContentObservable-&gt;ContentObserver) and DataSet(DataSetObservable-&gt;DataSetObserver).</p>
<p>As I see it, Cursor&#8217;s Content is the source Cursor retrieves data from, while Cursor&#8217;s DataSet is the data Cursor has retrieved. It will be more clear in the notification chain below.</p>
<p>For simplicity, I will omit the enclosed ContentObservable/DataSetObservable of Cursor and Adapter, since they are just one more indirect layer without any real functionalities. You can think of Cursor and Adapter as Observable themselves.</p>
<p>Without further ado, here comes the untangled register chain and the opposite notification chain.</p>
<ul>
<li>Register Chain:<br />
    
<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;"><span style="color: #003399;">ListView</span>.<span style="color: #006633;">setAdapter</span><span style="color: #009900;">&#40;</span>CursorAdapter<span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
  Adapter.<span style="color: #006633;">registerDataSetObserver</span><span style="color: #009900;">&#40;</span>AdapterView.<span style="color: #006633;">AdapterDataSetObserver</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">^</span>
    <span style="color: #339933;">^</span>
CursorAdapter <span style="color: #339933;">&lt;-</span> CursorAdapter<span style="color: #009900;">&#40;</span><span style="color: #003399;">Context</span>, <span style="color: #003399;">Cursor</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
  <span style="color: #003399;">Cursor</span>.<span style="color: #006633;">registerContentObserver</span><span style="color: #009900;">&#40;</span>CursorAdapter.<span style="color: #006633;">ChangeObserver</span><span style="color: #009900;">&#41;</span>
  <span style="color: #003399;">Cursor</span>.<span style="color: #006633;">registerDataSetObserver</span><span style="color: #009900;">&#40;</span>CursorAdapter.<span style="color: #006633;">MyDataSetObserver</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">^</span>
    <span style="color: #339933;">^</span>
<span style="color: #003399;">Cursor</span> <span style="color: #339933;">&lt;-</span> ContentResolver.<span style="color: #006633;">query</span><span style="color: #009900;">&#40;</span>Uri, <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>, <span style="color: #003399;">String</span>, <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>, <span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
  ContentProvider.<span style="color: #006633;">query</span><span style="color: #009900;">&#40;</span>Uri, <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>, <span style="color: #003399;">String</span>, <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>, <span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
    AbstractCursor.<span style="color: #006633;">setNotificationUri</span><span style="color: #009900;">&#40;</span>ContentResolver, Uri<span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
      ContentResolver.<span style="color: #006633;">registerContentObserver</span><span style="color: #009900;">&#40;</span>Uri, <span style="color: #000066; font-weight: bold;">boolean</span>, AbstractCursor.<span style="color: #006633;">SelfContentObserver</span><span style="color: #009900;">&#41;</span></pre></div></td></tr></table></div>
  </li>
<li>Notification Chain:<br />
    
<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;">ContentResolver.<span style="color: #006633;">notifyChange</span><span style="color: #009900;">&#40;</span>Uri, ContentObserver<span style="color: #009900;">&#41;</span> <span style="color: #339933;">---&gt;</span>
AbstractCursor.<span style="color: #006633;">SelfContentObserver</span>.<span style="color: #006633;">onChange</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">boolean</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">---&gt;</span>
AbstractCursor.<span style="color: #006633;">onChange</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">boolean</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">---&gt;</span>
CursorAdapter.<span style="color: #006633;">ChangeObserver</span>.<span style="color: #006633;">onChange</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">boolean</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">---&gt;</span>
AbstractCursor.<span style="color: #006633;">requery</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">---&gt;</span>
CursorAdapter.<span style="color: #006633;">MyDataSetObserver</span>.<span style="color: #006633;">onChanged</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">---&gt;</span>
BaseAdapter.<span style="color: #006633;">notifyDataSetChanged</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">---&gt;</span>
AdapterView.<span style="color: #006633;">AdapterDataSetObserver</span>.<span style="color: #006633;">onChanged</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">---&gt;</span>
<span style="color: #003399;">View</span>.<span style="color: #006633;">requestLayout</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></div></td></tr></table></div>
  </li>
</ul>
<div class="footnotes"><ol ><li id="footnote_0_29" class="footnote">I will talk about it in future post.</li></ol></div><div class="social">			<a href="https://twitter.com/share?url=http%3A%2F%2Fwangling.me%2F2009%2F07%2Fhow-content-changes-of-contentprovider-propagate-to-listview-via-cursor%2F" class="twitter-share-button" data-url="http%3A%2F%2Fwangling.me%2F2009%2F07%2Fhow-content-changes-of-contentprovider-propagate-to-listview-via-cursor%2F" data-text="How content changes of ContentProvider propagate to ListView via Cursor" data-via="an0" data-count="none">Tweet</a>
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>			<script type="text/javascript" charset="utf-8">
(function(){
  var _w = 86 , _h = 18;
  var param = {
    url:"http%3A%2F%2Fwangling.me%2F2009%2F07%2Fhow-content-changes-of-contentprovider-propagate-to-listview-via-cursor%2F",
    type:'6',
    count:'', /**是否显示分享数，1显示(可选)*/
    appkey:'', /**您申请的应用appkey,显示分享来源(可选)*/
    title:'How content changes of ContentProvider propagate to ListView via Cursor', /**分享的文字内容(可选，默认为所在页面的title)*/
    pic:'', /**分享图片的路径(可选)*/
    ralateUid:'1676354212', /**关联用户的UID，分享微博会@该用户(可选)*/
    rnd:new Date().valueOf()
  }
  var temp = [];
  for( var p in param ){
    temp.push(p + '=' + encodeURIComponent( param[p] || '' ) )
  }
  document.write('<iframe allowTransparency="true" frameborder="0" scrolling="no" src="http://hits.sinajs.cn/A1/weiboshare.html?' + temp.join('&') + '" width="'+ _w+'" height="'+_h+'" style="margin-left:5px;"></iframe>')
})()
</script></div>]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2009/07/how-content-changes-of-contentprovider-propagate-to-listview-via-cursor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

