Archive for the 'tech tips' Category

tech: Google Play store updates and Android system permissions

In the office we’re working on an Android app which isn’t your usual app: it has Android system permissions and because of that we work with a handset OEM to get it pre-loaded on their handsets in the system partition.

The slow rate of ROM OTA updates from OEMs being what they are, we wanted a faster way to deploy updates to our app, so the obvious choice is to also publish our app into the Play store and let Android’s Play services automatically update it from there. Except for one problem: when we published APK updates to the Play store, the handsets would never automatically download the update and install it. Try as we might to debug that, we couldn’t figure out why our app wasn’t getting updated by Play Services like all the other apps. We even got Google to investigate a bit, but never got a solution. So we ended up building a service into our app that would monitor for an updated version being available (via separate metadata that we uploaded to a server) that would then notify the user of the update being available, and then expecting the user to manually click on that to download the update. Yuck.

Fast forward a while, and we rewrite our app so it no longer needs Android system permissions. It still is signed by the same key. As soon as we publish the 2nd version without the system permissions to the Play store, we notice that the Play services update is working.

So that leads us to believe that when an Android app has system permissions, Play services won’t update it automatically. I don’t expect many developers are using system permissions, but FYI for those that are.

 

tech tips marcelk 24 Feb 2016 No Comments

tech: Nexus 7 battery runs out while sleeping

So I’ve had my Nexus 7 tablet for a while (a good companion to my iPhone ;-), and one of the things I’ve noticed is that the battery gets sucked dry while it is sleeping. I’ll start off with a fully-charged battery, then unplug it and use it for 5 minutes, and put it on the table, but don’t plug it back in. 24 hours later the battery is 1/3 to 1/2 used up. Wait 2-3 days and the battery is completely drained. Argh! Why is this happening?

I finally did some research, and found both the problem and the solution.

The hint on the problem came from a forum post I read. First, in the Settings app select the Battery – this will bring up the Battery view. At the top of the Battery view is a line graph that shows your battery level over time. Although there is no visual cue that you can do this, touch this graph. Now it brings up the History Details view for the battery. What you’ll see now is a larger line graph for your battery level over time, but more importantly is a breakout by category of what is using your battery: you should see entries for Wi-Fi, GPS, Screen, etc. Next to each entry is a segmented bar graph that shows when these entries were active over this time period. On my Nexus 7, the obvious top consumer of the battery was the Wi-Fi: it had a solid bar that indicated it was constantly in use, even while the tablet was asleep. There are no breaks in that bar. The line graph of the battery level showed approximately a 45 degree slope for the battery level, basically the battery getting sucked dry, apparently by the Wi-Fi. What is going on here?

Back in the main page of the Settings app, select Wi-Fi. Now select the rightmost icon in the top bar, the icon with the 3 vertical dots (like an ellipsis). That should bring up a context menu, one of the options is titled “Advanced”, meaning Advanced Wi-Fi Settings: select it and you’ll get a new screen. On this screen, one of the options is “Keep Wi-Fi on during sleep”. It is currently set to “Always”. Eh? That’s not what I want. Is that why my battery is draining during sleep, and the battery history indicates that the Wi-Fi is the function doing the draining? You betcha. Click on the “Keep Wi-Fi on during sleep” line and select a more reasonable value, such as “Only when plugged in”. Now back out of the Systems app. You’re done.

Now when I leave my Nexus 7 asleep and unplugged for a 24-hour period, the battery drains only a few percentage points, not 30% or 50%. This is the behavior I want.

I checked the same setting on my friend’s Nexus 7, and it had the same default. Why did Google choose to use this default? Maybe they want system updates to be downloaded in the background while the tablet is sleeping. Or maybe they don’t want the Wi-Fi to take 15 seconds to re-associate with the base station when I wake it up. Well, whatever the reason, it’s not worth my battery getting sucked dry when it is sleeping while it’s not plugged in. Bad default, Google.

But if that is the worst pain point on this tablet, then take that as a compliment. It is a good little machine.

tech tips marcelk 23 Jul 2014 No Comments

tech: Raspberry Pi as a print server

I admit it. I’m late to the party. But it’s still quite a good party. Raspberry Pi is tasty.

My wife upgraded her Mac to Mavericks, and then the shared printer stopped working. The printer is hosted on a WinXP system. (Yeah, I know XP is going out of service really soon, getting it upgraded is on my to-do list. It’s turned into the kids’ PC so I don’t invest much in it.) So Apple apparently made some changes in Mavericks so that it doesn’t play well with SMB on WinXP. That laser is our family workhorse printer. She’s frustrated she can’t print to it. I’m not going to be able to get to the XP upgrade for a month or two, so what to do until then?

Aha! Use a Raspberry Pi as a standalone print server. I would like an excuse to get an R-Pi and play with it. So I go online and order the model B with an SD card preinstalled with NOOBS, a nice long USB power cable to go with the power supply, and a case. $87 with tax and shipping, more than I expected.

It arrived this morning. I assembled the case – the most difficult part was peeling off the protective film. Except that the power connector was just a hair too big to fit through the case – get out the Dremmel tool and grind a little bit of the acrylic plastic away on the case, and after a couple tries it fits fine. I found a really good article at HowToGeek on general setup of the R-Pi. I plug the HDMI cable into my PC monitor, ethernet into my home router, power into the wall, and USB into the and keyboard and mouse. Select Raspberian. After some apt-get work to fetch the latest software and install CUPS, it’s ready for customization. Now get sshd running on it using raspi-config, so I can remotely login without a physically-attached monitor/keyboard/mouse, now I can reuse one of the USB ports to connect my printer. It is really cool that a Linux machine running X11 costs only $35 and isn’t much bigger than a credit card (except for the thickness). I give it a static IP on my home network, since it is a server.

I follow more helpful instructions on configuring CUPS locally on the R-Pi, then try printing a test page locally from the CUPS admin panel. The first try using the “Foomatic/foo2zjs-z1” recommended driver (built-in) didn’t result in anything happening , I then tried the “CUPS+Gutenprint v5.2.9” driver (built-in) and it works! No need to download a ppd file from HP.

From a Mac, now in the Settings for “Print & Scan”, click on plus sign to add a printer, and it shows up automatically as a Bonjour printer. Sweet! That was painless.

Now to get it printing from a WinXP client – changing it from a local printer to a remote printer. First delete the local printer. Using the bartbania site listed above it suggested that I define the printer on XP using it’s share name of \\192.168.1.99:631\printers\HP_LaserJet_1022. But that fails to add the printer. A bit more searching and I find the CUPS docs that suggest the other radio button to add it to XP with a remote URI of http://192.168.1.99:631/printers/HP_LaserJet_1022. That works! IPP was first added to Windows in XP. So now it’s working from both Mac and Windows clients. Mission accomplished.

Bonus points: I can print from my iOS device using AirPrint! It turns out that AirPrint is just an an extension to IPP, and CUPS seems to handle it fine. I’ve printed from my iPhone and from my wife’s iPad. It should work for any iOS app that is AirPrint enabled. I didn’t have to do any more work than what is already described above.

More bonus points: it’s not much more work to enable this printer for Google Cloud Print. Just follow these instructions. Basically you need to just install Chromium and do some configuration with it, before you unplug the keyboard, mouse, and HDMI.

Now tuck this little box neatly away next to the printer. But in a way that I can still see the LEDs. Maybe sometime in the future I’ll attach a USB disk drive as use it as a NAS or DLNA server.

cool stuff that doesn't cost much &tech tips marcelk 04 Jan 2014 1 Comment

tech: mobile OS stats across the world

I stumbled into gs.statcounter.com, and poked at the mobile OS data there (collected over the last 3 months). It really hit me how there is tremendous variation of device OS market share from country to country.

Here are some samples.

Range extremes:

  • iOS: 68% in Denmark, 1% in India
  • Android: 91% in South Korea, 6% in Somalia
  • Blackberry: 39% in St Martin, 1% in Thailand
  • Windows Phone: 23% in Finland, 1% in India
  • Series 40: 60% in Liberia, 1% in Austria
  • Symbian: 36% in Oman, 1% in Columbia

Basically no iOS or Android:

  • South Africa: Blackberry and Series 40 (Nokia) lead with a combined 60%, Android has 14%, iOS has 3%

Two western European countries where Android and iOS distribution is flip-flopped:

  • Spain: 70% Android, 25% iOS
  • Sweden: 62% iOS, 35% Android

Not the “usual” presence from a North America perspective:

  • Pakistan: 39% Series 40, 17% Symbian

And here is another view via Kantar / TNW.

So those of us in North America or western Europe who assume you understand the device OSs which are out there worldwide, think again.

tech tips marcelk 03 Dec 2013 1 Comment

tech: Android and Java 7

After not having built any Android apps for a few weeks, I returned to an attempt at that. Things went fine, until I tried to run my app on a device. The app crashed immediately upon startup with the following error in logcat:

E/AndroidRuntime( 6844): FATAL EXCEPTION: main
E/AndroidRuntime( 6844): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{org.apache.marcelk/org.apache.marcelk.junk}: java.lang.ClassNotFoundException: Didn't find class "org.apache.marcelk.junk" on path: /data/app/org.apache.marcelk-1.apk

Huh? That’s my activity class. I’m sure it’s there. So I look in my Android project directory and there in the classes dir is org/apache/marcelk/junk.class. So why is it complaining it can’t find it?

If I look just 3 lines higher in logcat, I see the first indication that something went wrong:

I/ActivityManager( 476): Start proc org.apache.marcelk for activity org.apache.marcelk/.junk: pid=6844 uid=10065 gids={50065, 3003, 1028}
W/dalvikvm( 6844): Unable to resolve superclass of Lorg/apache/marcelk/junk; (97)

My superclass is CordovaActivity, so that is present, correct? The cordova jar which contains CordovaActivity is in my libs directory in my project. But did it make it into classes.dex? That’s hard to tell, classes.dex is not a zip file like the apk that I can easily peek in to. Running the command “strings classes.dex | grep CordovaActivity” isn’t conclusive, would be nice if there was something that was. Aha! Look in the Android SDK’s build-tools/android-4.3 directory and there is a cool utility – run this:

dexdump classes.dex

Indeed, my junk class references CordovaActivity as a superclass, but CordovaActivity is not present in classes.dex. Why isn’t it there?

I did build the project with the Cordova CLI tooling, which [in this case, unfortunately] masks output from the commands it fires. So maybe there is something being masked which is important. The Cordova project basically has an Android project in my_project/platforms/android, so run “ant clean” and “ant debug” there. Hmm, now I’m seeing 140 warnings like this:

[dx] trouble processing:
bad class file magic (cafebabe) or version (0033.0000)

And the CordovaActivity is one of those classes that it warns about. Indeed, the first 4 bytes of a class file are 0xCAFEBABE, so it must not like the version number. Version “0033.0000” is the java major/minor version in hex. 0x33 = 51 decimal. So let’s check that: I unzip cordova.jar and run “javap -verbose org.apache.cordova.CordovaActivity”, and sure enough it reports major version 51 and minor version 0. The class file layout indicates:

Java 5 = 49
Java 6 = 50
Java 7 = 51

So CordovaActivity was compiled with Java 7. Does dex have problems with Java 7? According to this article, yes. Dex likes only Java 5 and Java 6. If dex sees a Java 7-compiled class, it will silently omit it. Aha! Problem indentified. Now to fix it.

Now that you mention it, I did recently change my JAVA_HOME on my workstation to point to a Java 7 JDK instead of a Java 6 one. So where in the docs on developer.android.com does it say that you can’t use Java 7? Nowhere, according to what I’ve seen. Pfffft!

On my Mac, I simply change JAVA_HOME in ~/.bash_profile to be:

export JAVA_HOME=`/usr/libexec/java_home -v 1.6`

since I have both Java 6 and 7 installed, then I do an “ant clean” in my project directory, go back to the Cordova source and do an “ant clean” and “ant jar”, copy the cordova jar to my project, then go back to my project to do an “ant debug”. It works!

I’ll capture this experience here, in hopes that it will help someone else in the future. For the record, this was using Android SDK Tools 22.2.1 and Platform Tools 18.0.1 and API 18.

Update: OK, in the System Requirements section it does say JDK 6, but I usually interpret that to be the minimum level, not the maximum level.

And, specifically the Oracle JDK must be used due to a dependency on the sun.security package. The IBM JDK or Apache Harmony can’t be used.

Update November 2014:

The ADT as of version 22.6 now supports Java 7. And Android 5 (Lollipop) requires Java 7.

tech tips marcelk 06 Nov 2013 No Comments

tech: software development principles

After working on a project for a while with Agile and analyzing why some things went wrong, I came up with the following guidelines for our team. I printed them out and posted it on my cube wall so I would see it multiple times daily. I see these as supplements to or applications of the Agile principles. I don’t think these are unique to our project, so I’ll share them with anyone who can get value from them. Here is my list:

Do the right thing, even when it takes more time than the easy thing. In the best case, not doing the right thing creates debt. It is better to do a few things well than a lot of things poorly.

Obey the model. Perfectly. Models exist to provide rules of operation. Where rules exist, assumptions get made. When the model is deviated from, even in small amounts, assumptions get broken, unexpected behavior occurs, and complexity ensues.

Always keep it simple. Complexity is our #1 enemy. We must be diligently fighting this enemy wherever it silently creeps in. It is much easier to achieve the *-abilities when the thing is simple.

Prioritize. And revisit the priorities. Start with the understanding that you can’t complete everything. Work on the most important things first. Front-load the risky items. Priorities will help you decide what to leave undone. Revisit the priorities periodically to check if they need to be adjusted, especially due to new information.

Make the best customer experience. Don’t trade “what is best for the customer” with “what is easy for us”.

Think hard. And ask for advice. Challenge yourself to come up with a better plan, even after you’ve come up with a good plan. Benefit from the knowledge and diversity of those around you. There is value in personal interactions.

[Update 12 Dec 2014:] Any task which is more than trivially repeated, especially if accuracy is important, and can be reasonably automated, must be automated. The only way to scale without a huge increase in human resource cost and human errors is to automate. This also frees you up from the mundane to focus on high-value items. In the long run, the investment will not only be worth it, it will be necessary.

[Update 15 Dec 2014:] Break up the story into bite-size pieces. If the size of the story is too big, you won’t get it done, and it will just keep rolling over iterations. The way to eat an elephant is one bite at a time.

tech tips marcelk 03 Jul 2013 No Comments

tech: Apple’s UDID ban and Cordova

Recently Apple came out with a news article saying that starting 01 May 2013 they will no longer approve apps for the App Store that access the device’s UDID. So the question immediately follows for app developers that use Cordova, is that with Cordova’s device.uuid value, it looks suspiciously like that value is being generated from the now banned UDID, which will keep their app from getting approved by Apple. Is this the case or not?

The long answer is that it used to. Up until Cordova 1.7, when running on iOS, the device.uuid value was the UDID. So if you are using Cordova 1.6 or older, then you are affected. But in Cordova 1.7 the computation for the device.uuid value was changed: basically at that point instead of using the [UIDevice uniqueIdentifier] value, it switched to using the filesystem path to the resource bundle. Near the end of that filesystem path is a nice GUID (not UDID) which is specific to the app on that device. It’s not the UDID. Then in Cordova 1.9, it changed again. If there is an [NSUserDefaults standardUserDefaults] value for the key “CDVUUID” that was previously created, it will use that. If a value for that key doesn’t exist, it will create one, store it in standardUserDefaults, and use it going forward.

There is some good reading material in the Jira ticket.

If you are still are in need of a device-specific identifier instead of the one that Cordova self-manufactures, Shaz has done a good job explaining some of the alternatives in his forum post.

tech tips marcelk 26 Mar 2013 2 Comments

tech: O’Reilly webcasts

A coworker pointed out to me today that O’Reilly media has ongoing webcasts on a number of current technical topics. After browsing through the very interesting slides for optimization of mobile web sites, I was impressed and will be going back often to see what is coming up. Nice job, Tim, you may convince me to buy some more books.

tech tips marcelk 25 Feb 2013 No Comments

tech: installing Couchdb on RHEL the easy way

Thinking of installing Couchdb on Linux using the source? You’ll be at it for a while, there are lots of dependencies. And if you don’t do it right, couchdb doesn’t have great debug info that helps you find what went wrong.

If you have RHEL / CentOS / Fedora, I came across this great set of instructions that uses Fedora’s EPEL repository to make installing couchdb a simple single invocation of yum. Yup, no compilations of source, and the pre-reqs are taken care of for you. It’s definitely the way to go.

It won’t install the bleeding edge version. But for my purposes, I’m OK with that.

tech tips marcelk 22 Feb 2013 No Comments

tech: Instagram, I thought we were friends?

This analysis of the new intellectual property policy of Instagram claims that Instagram can sell your pictures without any compensation or permission from you, and they limit their liability should they disclosure your content.

Honestly, I never really got around to using Instagram. But I just deleted the app from my phone. How my intellectual property is handled matters, even if you have a cool free service.

I will be very surprised if they don’t reverse this within the next week or two.

Update on Dec 19: Instagram will be clarifying the language around some of the terms previously interpreted as onerous. So yeah, some backpedaling and a partial reversal. I’m glad there are people other than me that can read and parse these legal documents, and help me understand what they mean.

tech tips marcelk 18 Dec 2012 No Comments

Next Page »