{"id":1544,"date":"2010-11-13T20:44:39","date_gmt":"2010-11-13T20:44:39","guid":{"rendered":"http:\/\/dalelane.co.uk\/blog\/?p=1544"},"modified":"2010-11-13T23:16:09","modified_gmt":"2010-11-13T23:16:09","slug":"you-need-to-ask-if-you-want-an-android-to-vibrate","status":"publish","type":"post","link":"https:\/\/dalelane.co.uk\/blog\/?p=1544","title":{"rendered":"You need to ask if you want an Android to vibrate"},"content":{"rendered":"<p>I posted a few days ago about a <a href=\"http:\/\/dalelane.co.uk\/blog\/?p=1530\">new little app I stuck in the Android Market<\/a>. An error report appeared from the app in the Market last night that I thought was interesting. <\/p>\n<p>The app does some stuff in the background then when it&#8217;s finished, it sticks a notification in the top status bar. In my code, I just use the default notification settings &#8211; LED flash, vibrate, etc. And on every Android I&#8217;ve tested it on, it&#8217;s been fine. <\/p>\n<p>But for one user, it caused the app to crash:<\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">Exception class java.lang.SecurityException\r\n\r\nSource method Parcel.readException()\r\n\r\njava.lang.RuntimeException: An error occured while executing doInBackground()\r\nat android.os.AsyncTask$3.done(AsyncTask.java:200)\r\nat java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)\r\nat java.util.concurrent.FutureTask.setException(FutureTask.java:124)\r\nat java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)\r\nat java.util.concurrent.FutureTask.run(FutureTask.java:137)\r\nat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)\r\nat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)\r\nat java.lang.Thread.run(Thread.java:1102)\r\nCaused by: java.lang.SecurityException: Requires VIBRATE permission\r\nat android.os.Parcel.readException(Parcel.java:1247)\r\nat android.os.Parcel.readException(Parcel.java:1235)\r\nat android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:368)\r\nat android.app.NotificationManager.notify(NotificationManager.java:110)\r\nat android.app.NotificationManager.notify(NotificationManager.java:90)\r\nat com.dalelane.lovefilm.data.ImageProcessService.publishUpdateNotification(ImageProcessService.java:281)\r\nat com.dalelane.lovefilm.data.ImageProcessService.access$0(ImageProcessService.java:234)\r\nat com.dalelane.lovefilm.data.ImageProcessService$ImageProcesser.doInBackground(ImageProcessService.java:215)\r\nat com.dalelane.lovefilm.data.ImageProcessService$ImageProcesser.doInBackground(ImageProcessService.java:1)\r\nat android.os.AsyncTask$2.call(AsyncTask.java:185)\r\nat java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)\r\n... 4 more<\/pre>\n<p><!--more-->It&#8217;s pretty obvious what the bug is &#8211; &#8220;java.lang.SecurityException: Requires VIBRATE permission&#8221; is a bit of a giveaway! <\/p>\n<p>I didn&#8217;t include <code>android.permission.VIBRATE<\/code> in the list of permissions that the app explicitly asks for on install. And on every Android I&#8217;ve tried that&#8217;s not caused a problem. <\/p>\n<p>But for one user, their phone kicked the app out for trying to use vibrate without permission. <\/p>\n<p>Thanks to them (whoever they are!) for clicking the &#8220;Report&#8230;&#8221; button and letting me know. They even added &#8220;HTC Desire Froyo&#8221; to the user comments, so I know which device this caused a problem on, too. <\/p>\n<p>I&#8217;ve <a href=\"http:\/\/dalelane.co.uk\/blog\/?p=1394\">talked about the Android Market developer site before<\/a> but it&#8217;s worth mentioning again &#8211; it&#8217;s very cool that it&#8217;s so easy for a user to let me know when there is a problem, and that I can push out a quick fix within 24 hours. And for users with devices running Android 2.2, it can even be updated automatically too. <\/p>\n<p>Moral of the story: don&#8217;t rely on testing to show you which permissions your app needs. Go through the <a href=\"http:\/\/developer.android.com\/reference\/android\/Manifest.permission.html\" target=\"_blank\">list of possible permissions yourself<\/a>, and include anything that you think your app uses. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>I posted a few days ago about a new little app I stuck in the Android Market. An error report appeared from the app in the Market last night that I thought was interesting. The app does some stuff in the background then when it&#8217;s finished, it sticks a notification in the top status bar. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[291,458],"class_list":["post-1544","post","type-post","status-publish","format-standard","hentry","category-code","tag-android","tag-market"],"_links":{"self":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1544","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1544"}],"version-history":[{"count":0,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1544\/revisions"}],"wp:attachment":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1544"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1544"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1544"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}