55 articles Tag android

New updates for Rainy Days: Hello Australia!

I just released a new update of Rainy Days, my radar weather app for Android. This version adds a few new features that have been requested and adds Australia to the supported countries as well.

Here’s a list of the new stuff:

  • Animation length adjustable: you can now select short, normal or long lengths for the animation. Shorter will load faster, while long will show you more frames.
  • New gestures: swipe from bezel to quickly scrub through the animation, double tap, hold and up/down to zoom (like in the Maps app).
  • If your location is shown on the map, and you are moving, the map will now move too so you don’t need to scroll yourself
  • Other fixes and tweaks (performance, battery usage, etc).

I’ve also created a small video demoing the gestures:

As always, you can dowload Rainy Days from the Google Play Store, enjoy!

Android Ant dependency management

Here’s a crazy idea I had yesterday: poor mans dependency management for your Android ant (and Eclipse) builds.
I could of course use maven, but I don’t. TL;DR; I think it’s too much hassle for my Android projects. I pull in library projects from source using mercurials’ subrepository feature and check the libs folder in to source control.

Anyway, I do like the dependency management part of a maven build, although I also might have some local dependencies that I just want to stick in my project and check in. So the idea was to hook in some form of dependency management into the normal Android ant build. Another requirement is that it should work fine with ADT. What I’ve come up with in the last few hours is here: https://bitbucket.org/hvisser/android-ant-dependencies and here on github: a build file that you can include into your normal ant.xml.

It uses the maven tasks for ant to manage dependencies. What this build file does for you when you execute “ant copy-dependencies” is manage the dependencies in the “libs” folder of your project. If you have non-managed jars, you just stick those in the “extra” folder. It will also extract library projects, apklibs, to a separate folder so you can include those as library project in Eclipse. Finally, it will copy over android-support-v4.jar to those library project, to make sure you are using the same version in all projects (the Android ant build and ADT check for that).

When setup, you can ignore the libs folder in your favorite version control system and on check out you just to a “ant copy-dependencies”, import the library projects and off you go.

Now I don’t know if I’m actually going to use this, but what do you think? Have I created a monster?

Please comment on the Google+ post

Correct Intent to compose an email on Android

Starting a compose window to write an email in your favorite email client on Android is easy.
It amazes me however that when you search for it on stackoverflow most first hitters are suggesting to use an intent with the mime type set to text/plain (or worse) See http://stackoverflow.com/questions/6450097/how-to-send-email-by-clicking-text-view-links/6450131#6450131http://stackoverflow.com/questions/7551600/how-can-i-send-an-email-through-my-exchange-activesync-mail-account or here http://stackoverflow.com/questions/10546252/unable-to-send-email-from-android-application-on-real-device for example.Being an intent, that code expresses that you like to perform a SEND action on ANYTHING that can handle text/plain or whatever mime type. So apps like Dropbox etc will rightfully also pop up.What you really want is to use a mailto: uri in the data, since that expresses that you want to….MAIL TO SOMEBODY. So you set up the intent like this:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("mailto:hugo@googleplus.com"));
// you can add extra's like subject, text, etc

I’ve been using this for ages (since Android 1.5) and it should work fine. Of course your favorite mail app should register for the mailto scheme, but I’m sure any decent mail app will.

I did find an answer on SO that actually mentions this, not all hope is lost: http://stackoverflow.com/questions/2007540/how-to-send-html-email

Don’t use text/plain if you want to send an email. A droid will die every time you do :(

A little tool for handling nine patch files, called 9tool

Here’s a little tool I wrote for handling 9patch images called 9tool. If you work with (a lot) of nine patch files in Android, you might find it handy too.

  • My workflow currently is something like this:
  • Get the xhdpi asset and make it a nine patch using draw9patch
  • Get the other states for the asset and do a 9tool copy on it to copy the nine patch area to those assets, then load those in draw9patch for some touch ups.
  • Now get the other assets for other dpis. 9tool copy the patches I made from the xhdpi assets to the other dpi variants, touch up using draw9patch again.

This saves me a bunch of manual drawing in draw9patch and makes me a happy camper!

The code is open source and as much in the public domain as it can be, so do with it what you like. I’ve only spent a couple of hours on it so there might be many bugs and it might be a bit messy. So far I haven’t lost any 9patches in the process though ;)

There’s a zipped build in the downloads section if you don’t want to build from source.

The tool is hosted on bitbucket here: https://bitbucket.org/hvisser/9tool

DPI Hell

Yesterday the DroidconNL conference started with a keynote from greetz.nl called “Pushing Development Boundries”. After some introductory talk from their marketing manager, this slide appeared on screen:

Dpihell

To which I responded:

I realise that might have sounded a bit harsh, so let me explain and give you some background. The last year I’ve been talking about “Embracing Fragmentation” at mdevcon, Mobile Down South and Apps World. The talk is about the challenges and opportunities developing and designing for the Android platform and showing what mechanisms are there to make it easy to deal with the “problem” of fragmentation, which honestly in my opinion as a professional Android developer, isn’t as huge as some people would like you to believe.

To me “hell” in the context of software implies something that is hard, complex, unpredictable, fragile and whatnot. Resolution and DPI on Android do not fall in this category for me. If you qualify these things as “hell” and you’re a professional Android developer, I think you need to read the rest of this post.

What’s this DPI thing anyway?

DPI is short for dots per inch, also known as pixels per inch or PPI. On iOS Apple calls things with a high PPI count “retina” to indicate that you can’t see the actual pixels on a screen since they are so close together that your eyes, or your retina, can’t see the individual pixels. In a way DPI tell you about the quality of a screen. Generally, when comparing screens of the same size, higher is better.

Now what’s the deal with resolution and DPI? Let’s say you have a 4 inch screen and a resolution of 1200×800 pixels. At the same time imagine a 10 inch tablet screen at 1200×800 pixels. Which screen would have the highest DPI? The 4 inch screen, since it literally packs more pixels / dots per inch. Get it? When designing a user interface this is important, for two reasons:

  1. You want your stuff make look good on any screen.
  2. You want your stuff have the same size on any screen.

How do we generally measure things on screens? Pixels. This works fine when all screens have the same DPI. Let’s say a screen has 100 dots per inch. That would mean that a line which is 100 pixels wide, would measure 1 inch exactly. Simple right? Now what happens if you draw that same line on a large screen, with the same resolution? There are less dots per inch, for example 50, so all of a sudden your 100 pixel line is now 2 inches wide. Not good!

On Android (and iOS for that matter) you don’t deal with pixels as the unit of measuring things. You deal with density independent pixels, or dips for short, or dp for even shorter. On iOS you’d call them points by the way. What measuring in dips gives you is a consistent unit that takes into account the DPI, which becomes essentially a scaling factor. Let’s say we’d call 50 dpi our “baseline” dpi at which 50 dips is exactly 1 inch. To make it show the same size on a 100 dpi device, we would take the scaling factor (twice the amount of pixels per inch) and draw it at 100 pixels, which would give us the same sized line. Why? Because 100 is twice 50, so our scaling factor is 2 and because 100 pixels at 100 dots per inch would be exactly 1 inch again. Confusing? Maybe, but the thing to remember is: you don’t deal with pixels. You tell the Android how large a thing should be in dips and Android will take into account the appropriate scaling factor, figure out the right amount of pixels and will make sure the thing you are drawing to the screen is the same size no matter what screen your app is running on. Same for iOS: you tell the OS how large the thing you are drawing to the screen is in points, the OS figures out how many pixels that would be for the screen (either the same amount or twice the amount for retina screens) and it will look the same size, no matter if you are running on a retina screen or a non-retina screen.

So that leaves us at DPI hell. I guess what the speaker was referring to is how to make your stuff look good on any screen. First of all, it’s good to know that Android currently has 5 DPI “buckets” that are relevant to developers. In order of lowest to highest DPI they are called ldpi, mdpi, hdpi, xhdpi and xxhdpi. As a contrast, iOS has two buckets: either non-retina or retina.

Like I said there’s a scaling involved when an app runs on various screens. Scaling stuff you draw yourself at runtime is usually not the issue. You are rendering that stuff when the app runs so things will always look good. But what if you include an image and that image should be scaled up or down to make it the proper size for the given dips and DPI?

In that case you have two options:

  1. You supply the image at a particular DPI and let Android deal with the scaling from that bucket to other buckets at runtime
  2. You supply a scaled version for one or more DPI buckets

One strategy could be to only supply the assets for the xhdpi bucket and let Android take care of the scaling. Depending on your assets and the version of Android you are targetting this might work fine. Usually though you need some tighter control over how images are scaled. A common strategy would be to supply assets for the mdpi, hdpi and xhdpi bucket and aditionally a launcher icon for the xxhdpi bucket. Since ldpi devices are rare, the Android platform would take care of scaling to ldpi by conveniently scaling down the hdpi asset by a factor of two. Likewise assets for the tvdpi bucket (hey! you said there we’re only 5 buckets! – I lied) should generally look fine when scaled by Android.

So you might be thinking: “wow, duplicating my assets for 3 different buckets AND creating 4 launcher icons seems like a lot of work”. Yes, it is. But I most certainly wouldn’t call it hell. Besides there are some great tools which help you to reduce the amount of work you need to do and Android has more mechanisms to reduce the number of bitmap assets in your project anyway.

One question remains: if it’s not hell, how should you approach this then? Here’s something that generally works when designing and scaling assets if you know the size in dips:

  1. Design your asset doubling the size in dips. If your image is 100×200 dips then in pixels you design it at 200×400 pixels. This is your xhdpi asset. This works because at xhdpi one dip is exactly 2 pixels, meaning the scaling factor is 2. At mdpi one dip is one pixel which is equally handy.
  2. Scale this asset down by 75%. This is your hdpi asset.
  3. Scale the xhdpi asset down to 50%. This is your mdpi asset.
  4. Put the assets in the correct resources folder within your project: drawable-xhdpi for xhdpi, drawable-hdpi for hdpi, drawable-mdpi for (yes!) mdpi.

I recommend starting from the highest DPI you need to the lowest, since scaling down from a higher resolution usually gives better results than scaling up from a lower resolution. I also recommend that for launcher icons, you use the excellent Android Asset Studio combined with an icon in svg format which will spit out the launcher icons in all DPI variations without even bothering scaling it yourself in your favorite asset creation tool.

Phew, that was a lot of text, just to explain it’s not hell, but seriously: if you are an Android developer you should know the rules to play by. If you know them, then making your apps look great isn’t hard. There’s a lot of information on the subject at d.android.com, for example on supporting multiple screens, which I encourage you to read.

I hope you found this post useful, please leave any feedback in the comments, Google Plus or tweet at me. Thanks!

Note to self: ListFragment and header views

While hacking on our FOOD! app for VHack Android I ran in to an issue.

FOOD! shows a couple of ListViews through ListFragment that have a header (the title) set on them. That all works pretty cool, but if I tried to add multiple ListFragment on the back stack it would crash on pressing the back key, with this exception:

java.lang.IllegalStateException: Cannot add header view to list — setAdapter has already been called.

The code for my ListFragment looks something like this:

The code crashes, because when you press back, the view is recreated through onCreateView and aparently the list is in some state that I’m not allowed to add the header.

So the big question is: WHY? First thing that popped to mind is that the ListView itself was recycled and somehow retained. This is not the case: if you debug ListFragment you’ll see that the ListView itself is null and the view is inflated.

The issue is that ListFragment will set the adapter on the ListView as part of it’s private ensureList() method that get’s called in onViewCreated. In most scenarios you would set up your adapter after creating the view add add it using the setListAdapter() method in the ListFragment (note: not on the ListView itself!). ListFragment keeps the adapter in a private member so that you could create the adapter before the list itself is created and everything would still work.

Now when you replace the fragment, the Fragment view is destroyed, but your ListFragment is still in memory, on the back stack. When you press back, that instance is used again and it’s life cycle methods like onViewCreated get called again. Then, as part of the ensureList() call, the adapter get’s set on the ListView (which is non-null now) and if you attempt to add a header view at that point…BOOM.

Fortunately there is a workaround for this: clearing the adapter when the view is destroyed, so that there won’t be an adapter to set when the view is recreated.

So one question remains: bug or feature? Keeping the adapter can be a good thing, since it will make the list show stuff when hitting back, no need to load or wait for the loading. You could even test if the adapter is non-null and skip loading all together. On the other hand, the fragment initialization is now different depending on if it’s newly created or if it is an existing instance coming back to life, which is bad thing. The root cause is that you can’t add a header view after the adapter is set, because ListView wraps the adapter you set in a special adapter for showing the headers, so you could argue that ListView is broken in that sense. I personally think it’s a bug. If I wanted to optimize and keep the adapter, then it would make sense to keep the adapter in a member variable that I control. Now it is done “under the covers” and you have to know the implementation details to fix the issue.

In any case, I hope this write up will help others running into the same issue, happy coding!

 

Countdown for SmartWatch

A while back the friendly folks over at Sony sent me a SmartWatch to play with. It’s a nice little gadget and I’ve created an app for it called Countdown

Countdown is a countdown timer that you control on your watch. When the time is up, the watch wakes up and vibrates for you to take action on whatever you’re counting down to.

Get it from the Play store and let me know what you think of it!

Rainy Days 2.3 released!

It has been a while since I’ve updated Rainy Days, but I think this update is a nice one ;)

In 2.3 I’ve added a few new features:

  • Sharing: you can now share the image you see in the app when you pause the animation
  • Updated layout for tablets and Android 4.0 devices
  • Hardware acceleration on devices that support it
  • New coverage: Alaska, Canada and Iceland. There’s even a composite showing US and Canada at the same time!
  • Futher tweaks and changes to make the app even faster

I’m very excited about the sharing option; now you can share the image to with your loved ones on Facebook, twitter, email! Just tap the screen once to pause, then select the share icon from the actionbar or use the menu to select the share option.

I mentioned the actionbar already. Rainy Days now fully supports the actionbar on Android 3.x and up. Previously it was already shown, but now the timestamp and the search, pause/play and share buttons are also shown in the actionbar. 

I hope you’ll enjoy this update. As always get it from the Google Play store.

Rd-new

Rainy Days eumetsat imagery currently offline

The imagery from the eumetsat source isn’t updating since yesterday 19:00 UTC, so unfortunately that means that Rainy Days currently is not displaying anything for the regions the eumetsat overlay covers. I hope this will be resolved soon, sorry for the inconvenience.

Update: Things are back to normal again! 

60 Android Hacks book review

Thanks to Manning and the Dutch Android User Group, I got the chance to review the book 60 Android Hacks by Carlos Sessa. This book is currently in Manning’s MEAP program, which means that it is not finished or edited, but you can already enjoy some of the chapters as the work progresses, which is great!

Like the title suspects, this book contains 60 useful hacks on various Android topics like layout, animation, views, but also tools and languages. I really like this format because these kinds of books are nice to use as a reference no matter if you are just starting Android development or if you are an experienced Android developer. Each chapter is organised describing a small problem, discussing the solution and then a brief summary of the solution. Awesome.

The word hacks in the title might sound like this book describes wierd cornercase kind of types of situations, but that’s not the case. It’s more like a recipe book which decribes how you can leverage Android mechanisms to create better apps, ranging from chapter 1 (pdf) which describes how to center a view using a LinearLayout’s weights to gems like chapter 17 (adding glowing effects to texts), which describes how to use a custom font and two TextViews to create a cool glowing digital clock.

Only a few chapters are available right now, but if you look at the list of chapters, this sure looks be a promising book with great to-the-point content, so go check it out here.