{"id":1869,"date":"2013-10-10T18:17:40","date_gmt":"2013-10-10T06:17:40","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=1869"},"modified":"2014-08-03T17:14:16","modified_gmt":"2014-08-03T05:14:16","slug":"developing-an-appwidget-part-4","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/1869\/","title":{"rendered":"Developing an AppWidget &#8211; Part 4"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><h2>Keep On Running&#8230;<\/h2>\n<p>Some may have noticed that I updated my <a href=\"https:\/\/www.deltics.co.nz\/blog\/posts\/1855\">previous post<\/a> with a footnote describing an issue with my battery widget not resuming it&#8217;s updates after the phone went into (and came out of) deep sleep.  I got to the bottom of that and can now happily report that my widget seems 100% reliable and the solution is not contributing to any additional battery drain.<\/p>\n<p>This is what I did&#8230;<\/p>\n<p><!--more--><\/p>\n<h3>Specialised Services<\/h3>\n<p>I think I may have mentioned <a href=\"https:\/\/www.deltics.co.nz\/blog\/posts\/1791\">near the beginning of this series<\/a>, that <strong>Services<\/strong> were a potentially complex area on Android.  Even with this simple widget exercise I have learned quite a bit about them and still I think I have only scratched the surface.<\/p>\n<p>I already refactored my code once to avoid using a deprecated method that I inadvertently adopted from an out of date example.  I have now learned that for my needs, I should in fact be using a different <strong>Service<\/strong> <strong>class<\/strong> entirely!<\/p>\n<p>Specifically, an <strong>IntentService<\/strong>.<\/p>\n<p>The main difference between this and the <strong>Service<\/strong> class I was using previously, is that an <strong><a href=\"http:\/\/developer.android.com\/reference\/android\/app\/IntentService.html\">IntentService<\/a><\/strong> does not run on the main application thread, but on it&#8217;s own worker thread, created by the system automatically when any intents are passed to it for handling.<\/p>\n<p>Something led me to believe that an IntentService is &#8220;<em>long lived<\/em>&#8221; which, is the key to ensuring that my update schedule survived the device going into &#8220;deep sleep&#8221;.<\/p>\n<p>To switch to an IntentService was relatively straightforward.<\/p>\n<p><em><strong>Update:<\/strong> Everything that follows is indeed how I switched to an <strong>IntentService<\/strong>.  But it turns out this created a different problem which leads me to suspect that an IntentService does not function how I was led to believe and issn&#8217;t actually appropriate.  Just bear that in mind.<\/em><\/p>\n<p>First of all of course, I needed to derive from the <strong>IntentService<\/strong> class itself.<\/p>\n<p>Then I again had to change the method being used to implement the service call.  Previously I was using <code>onStartCommand()<\/code>.  This now needs to change to <code>onHandleIntent()<\/code>.<\/p>\n<p>There was one other change that I needed to make but I didn&#8217;t discover this until trying to install my updated widget.  Had I read the <a href=\"http:\/\/developer.android.com\/guide\/components\/services.html\">guide to implementing services<\/a> I would have known about it.  But I hadn&#8217;t.<\/p>\n<p>That other thing is that the service requires a parameterless constructor to be implemented.  Why this is the case for an IntentService and not for a Service, I haven&#8217;t yet thought about.  I am sure there is an explanation.  But for now, all I need to know is that I need to implement such a constructor and it must call the inherited constructor that takes a service name as a parameter.<\/p>\n<p>So first, the parameterless constructor:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  constructor UpdateService;\r\n  begin\r\n    inherited constructor('UpdateService');\r\n  end;\r\n<\/pre>\n<p>Note that constructors are not named in Java.  The token <strong>constructor<\/strong>, as opposed to the usual <strong>method<\/strong> declaration is all that we need.  As I think I may have mentioned, you have the option of using <strong>Create<\/strong> (but <em>only<\/em> Create) to name your constructors if you wish (and this may be important for classes intended for cross-platform use) but in this case, I chose not.<\/p>\n<p>The change of <code>onStartCommand<\/code> to <code>onHandleIntent<\/code> involves only changing the method signatures.  The implementation is not affected at all:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  method UpdateService.onHandleIntent(aIntent: Intent);\r\n<\/pre>\n<p>As far as I can tell, this deals with the issue of my widget updates surviving deep sleep, and importantly, without any adverse affect on battery drain that I have observed.<\/p>\n<p><em><strong>Update:<\/strong> This seems to be true, but is not actually functioning how I intended and so I shall revisit this change.<\/em><\/p>\n<p>But there is something else that I haven&#8217;t yet taken care of (<em><strong>Update:<\/strong> which the IntentService had an adverse affect on &#8211; i.e. it broke it!<\/em>), that I left a hint about in that previous post, and I shall be making that the subject of <del>my truly final post in this series later this evening<\/del> another post soon.<\/p>\n<h2>UPDATE<\/h2>\n<p><strong>Take everything above with a pinch of salt.<\/strong><\/p>\n<p>In preparing the next post I discovered that things were not behaving quite as I thought and I need to do some more research before I can say definitively that I have found the correct approach for dealing with both the issue of surviving sleep and the subject of what was to be my next post.<\/p>\n<p>Hey ho.  It&#8217;s all learning, right ?  \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> Keep On Running&#8230; Some may have noticed that I updated my previous post with a footnote describing an issue with my battery widget not resuming it&#8217;s updates after the phone went into (and came out of) deep sleep. I got to the bottom of that and can now happily report that my widget seems 100% [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[212,205,4,180],"tags":[153,233,181,232],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-u9","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1791,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1791\/","url_meta":{"origin":1869,"position":0},"title":"Developing and Debugging an AppWidget &#8211; Part 2","date":"30 Sep 2013","format":false,"excerpt":"In the first instalment of this series, I implemented the basic framework of a new appwidget and established a means by which I could debug the widget code. Now it's time to add some code worth debugging. You may recall that the aim of my widget is to display the\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screenshot_2013-09-30-20-03-27.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1873,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1873\/","url_meta":{"origin":1869,"position":1},"title":"Developing an AppWidget &#8211; Part 5","date":"13 Oct 2013","format":false,"excerpt":"In my previous post I explained how I believed I had solved a problem with my widget, only to discover that it created a different problem in the process. I had believed that IntentService based services were long-lived, but in fact this is not the case. However, the change remains\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1774,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1774\/","url_meta":{"origin":1869,"position":2},"title":"Developing and Debugging an AppWidget &#8211; Part 1","date":"29 Sep 2013","format":false,"excerpt":"With my external HDD trials and tribulations behind me, I have finally been able to complete a project I started last weekend - implementing an Android AppWidget. Along the way I have learned some more about both Android and Oxygene and what can be involved with working with the two\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"Adding the xml folder","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-09-29-at-15.08.09-.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1855,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1855\/","url_meta":{"origin":1869,"position":3},"title":"Developing an AppWidget &#8211; Part 3","date":"08 Oct 2013","format":false,"excerpt":"Well Behaved Widgetry When we left it, my battery widget was working but wasn't particularly well behaved. There was nothing much wrong with the functionality, but plenty wrong with the implementation. Despite their impressive specifications, mobile devices have one very limiting factor. Battery Life. Indeed, the impressive specifications are part\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1896,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1896\/","url_meta":{"origin":1869,"position":4},"title":"Getting Published in the Play Store (Google Apps)","date":"14 Oct 2013","format":false,"excerpt":"Well, this went far more smoothly than I had anticipated. At the XE5 World Tour event in Auckland, Brian Hamilton, creator of the iWD app, told us that getting his approved took about a week (if I recall correctly), and he had to submit a video showing how his app\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1817,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1817\/","url_meta":{"origin":1869,"position":5},"title":"Getting the Battery Level on Android With Delphi","date":"01 Oct 2013","format":false,"excerpt":"Over the past few days I posted a two part series showing how to obtain the current battery level as part of the implementation of an Android AppWidget using Oxygene. As far as I can tell AppWidgets simply aren't possible using Delphi but reading the battery is quite straightforward Android\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1869"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=1869"}],"version-history":[{"count":6,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1869\/revisions"}],"predecessor-version":[{"id":2238,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1869\/revisions\/2238"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=1869"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=1869"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=1869"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}