Tag Archives: Android

Tidbits

Just some interesting bits and pieces I have come across recently:

Flat UI Colors: a neat website that displays a colour palette, allowing you to click on a colour to copy its value to the clipboard. #design

ColorHex #android App: a simple colour picking app that that also allows one to store favourite colours. #design

Butter Knife: an interesting view injection framework for #android, created by Jake Wharton who also developed the ActionbarSherlock framework.

Latest Android Dashboard Stats: personally, I was surprised to see that as much as 9.9% of devices still fall under the small, ldpi configuration. #android


#programming #object-orientation

I recently did a bit of a refresh on some principles and guidelines for object orientated programming:


#server-side

I spent a bit of time recently developing a simple REST web-service using Google go and Google App Engine. Here are some useful links and examples:

  • Gorca: a utility package for RESTful go applications on App Engine.
  • Home: a simple App Engine application using go and Angular JS.
  • RESTful web-services in go: useful information on developing RESTful web-services using Google go.

Anyone interested in developing web-service APIs that need to be consumed by mobile apps and the web, should definitely have a look at Google Cloud Endpoints… I also played around with this cool feature for Java and below are some useful links:

Advertisements

Webbits: a silly Android app for testing embedded web content.

Recently I found myself working with some server-side web content that would ultimately need to be pulled into an embedded browser within an Android app. Depending on the device, the embedded browser within the app could be of variable size, so the content being pulled would have to display properly.

I wanted a means to test the content within an embedded browser of different sizes, so I looked around (not for very long) for a test app that could help me out; after a little bit of looking and not finding what I wanted, I decided to just write my own silly app, called Webbits.

The app supports both phone and tablet and essentially allows a user to specify the dimensions of the embedded browser (WebView) and the URL to load. It’s very basic but did exactly what I needed. Below are some screenshots of Webbits:

Screenshot_2013-07-05-13-17-49

Phone portrait

device-2013-07-04-183752

Tablet landscape

device-2013-07-04-183939

Developed by 2bits, of course.

Hopefully, someday, somebody else may find this useful.

Android WebView flicker when using hardware acceleration on Android 3.0+

There is an Android bug where WebViews may present an ugly flicker when being used on 3.0+ devices with Hardware Acceleration enabled. I was busy with an update to an Android app I’m working on which makes use of a WebView that slides in and out (using this awesome Sliding Menu library), when I noticed the *delightful* surprise when sliding the WebView back in:

Not ideal, is it?

Not ideal, is it?

As much as I can’t believe this kind of bug still exists, especially considering it seems to have been around for some time, it lives with us and thus we need to use some kind of workaround.  I immediately turned to SO for help and found a possible workaround:

WebView “flashing” with white background if hardware acceleration is enabled (Android 3.0+)

The workaround involves using a method that is only available from API level 11 (HoneyComb), and considering my app is targeting a minimum level of 8 I used the following code:

/**
 * Initializes the WebView:
 * - Configures the WebView settings
 * - Adds a WebViewClient
 * - Custom config of the webview
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void initWebView()
{
	// Other init code
	
	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
	{
		// This is added as a work-around for the flicker which occurs in Android 3.0+
		// when hardware acceleration is enabled:
		// http://stackoverflow.com/questions/9476151/webview-flashing-with-white-background-if-hardware-acceleration-is-enabled-an
		getWebView().setLayerType(View.LAYER_TYPE_SOFTWARE, null);
	}
}

So pick your poison: reduced performance or flickering?

Android WebView Scaling

Just as it’s important for an Android developer to understand how to support multiple screen sizes, so too is it important to understand how the Android framework handles the scaling of the content in a WebView.

To demonstrate the scaling that takes place within a webview, I’m going to use a basic example of a webview that displays a local image and some text underneath it – as some additional information, the device used in this example is a Galaxy Nexus with an xhdpi screen (320 dpi) and resolution of 1280×720. Below is the HTML and CSS used and the result of the app run on the said device:

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="sample.css" />
    </head>
    <body>
        <img src="localImage.png"/>
        <p>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit<br>
            bla bla bla
        </p>
   </body>
</html>

the CSS…

img
{
    display: block;
    margin-left: auto;
    margin-right: auto;
}

p
{
	background-color: #E4E4E4;
	padding:1em;
	margin:0.5em;
	border-radius: 15px;
	font-size: 1em;
}

and finally the result…

Web content with default scaling.

Web content with default scaling.

Immediately it becomes obvious that the 300×200 local image has been scaled up considering the resolution of the device. Essentially what the Android framework is doing is assuming that the web content is targeted at an mdpi density (which Android treats as the base density), and as a result scales the content up accordingly for the xhdpi test device so that the drawn elements match the physical size they would appear on an mdpi display. Unless you explicitly specify the density you are targeting, Android will scale up/down accordingly.

To adjust the scaling performed by the Android framework, one can use the viewport meta tag to specify properties regarding screen density support:

<meta name="viewport" content="target-densitydpi=device-dpi" />

The Android docs explain the target-densitydpi property as follows:

You can use this to specify the target density for which the web page is designed, using the following values:

  • device-dpi – Use the device’s native dpi as the target dpi. Default scaling never occurs.
  • high-dpi – Use hdpi as the target dpi. Medium and low density screens scale down as appropriate.
  • medium-dpi – Use mdpi as the target dpi. High density screens scale up and low density screens scale down. This is also the default behavior.
  • low-dpi – Use ldpi as the target dpi. Medium and high density screens scale up as appropriate.
  •  – Specify a dpi value to use as the target dpi (accepted values are 70-400).

So if we use this information and modify our HTML to prevent default scaling:

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="sample.css" />
        <meta name="viewport" content="target-densitydpi=device-dpi" />
    </head>
    <body>
        <img src="localImage.png"/>
        <p>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit<br>
            bla bla bla
        </p>
   </body>
</html>

and run the test app again, we get:

Web content with no scaling

Web content with no scaling

One can now see that no scaling has taken place; the image is displayed as one would expect a 300×200 image on such a device, and the text is significantly smaller. Without the scaling it becomes obvious that the graphic and styles used are not suitable for the xhdpi device, so these would ultimately need to change yet still cater for other densities.

In many simple cases like our example, all we want is to be able to develop and test the web content against a specific test device to ensure that it looks correct, and then allow Android to scale up/down from there. To achieve this, one can declare the specific target density (or even the exact dpi) for which your content is being designed. The following demonstrates this using our example designed for the Galaxy Nexus (320 dpi):

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="sample.css" />
        <meta name="viewport" content="target-densitydpi=320" />
    </head>
    <body>
        <img src="localImage.png"/>
        <p>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit<br>
            bla bla bla
        </p>
   </body>
</html>

 

img
{
    display: block;
    margin-left: auto;
    margin-right: auto;
}

p
{
	background-color: #E4E4E4;
	padding:1em;
	margin:0.5em;
	border-radius: 15px;
	font-size: 2em;
}

With the CSS modified a bit for the higher density and a new higher resolution graphic, we see the following result:

Web content targeted at xhdpi

Web content targeted at xhdpi

We are now happy with the look of the web content on our device, and because we have told the Android framework the specific density we are targeting it will automatically scale up or down for devices with higher or lower densities respectively. The following is a screenshot of the same HTML/CSS and graphic on a lower density emulator:

Web content on an hdpi emulator

Web content on an hdpi emulator

Having said all of this, YMMV with this basic approach. Allowing Android to perform scaling like this may have undesirable results with certain aspects, such as image quality. A more in-depth method for dealing with web content and multiple screen sizes and densities is to provide specific styles/graphics for different densities using the CSS media feature; more information about this can be seen here.

Otto Event Bus for Android

In case you haven’t already checked out this cool framework, Otto is an event bus designed to help parts of your application communicate more effectively and in a more decoupled manner.

With respect to Android, one particular area where the Otto event bus can be really useful is in the passing of complex data objects between the Activity andFragment objects in your application. For instance, when passing a data object between two fragments, traditional methods relied on passing the object via the parent activity or by using the setTargetFragment()/getTargetFragment() methods of the Fragment class; a downside to these approaches is that it couples your fragments/activities to one another. Whilst one can use Interfaces to alleviate the coupling, it requires additional boilerplate code and if more than a single object is required one can be faced with handling the code and coupling of many Interfaces, which is often excessive. The following is a simple Java example of how Otto can simplify the communication amongst components and reduce coupling and boilerplate code.

We have a weather service which periodically needs to provide weather updates to various components. Without the use of Otto, the following is an example of how this could be achieved:

WeatherService Class

 public class WeatherService
{
	private String weatherDescription;
	private List<WeatherListener> listeners = new ArrayList<WeatherListener>();

	
	public void weatherHasBeenUpdatedFromSomewhere(String weatherDescription)
	{
		this.weatherDescription = weatherDescription;
		
		if (listeners != null)
		{
			for (WeatherListener listener : listeners)
			{
				listener.weatherUpdated(weatherDescription);
			}
		}
	}
	
	public void addListener(WeatherListener listener)
	{
		listeners.add(listener);
	}
}

This class has to maintain a list of listeners which it publishes updates to. Notice that although it isn’t coupled with any concrete class, it still has to know about an interface which does very little. Also notice how a large amount of the code is concerned with managing the listeners.
 
WeatherListener Interface


public interface WeatherListener
{
	public void weatherUpdated(String weatherDescription);
}

A simple listener interface. This is largely just boilerplate code given how little this interface achieves.
 
WeatherScreen Class


public class WeatherScreen implements WeatherListener, SomeOtherRandomService
{
	private String weatherDescription;

	@Override
	public void weatherUpdated(String weatherDescription)
	{
		this.weatherDescription = weatherDescription;
		
		// Do something...
	}

	@Override
	public void randomAction(RandomObject randomObject)
	{
		// Do something...
	}
}

Nothing fancy here, the WeatherScreen class listens for weather updates and possibly information from other services. One can easily see how it’s possible for these publisher/listener connections to result in a lot of unnecessary coupling and boilerplate code.

If we take the same example and use the Otto event bus to manage a lot of these connections, we end up with something like the following:

OttoWeatherService Class

public class OttoWeatherService
{
	private String weatherDescription;
	private Bus eventBus;
	
	public OttoWeatherService(Bus eventBus)
	{
		this.eventBus = eventBus;
		eventBus.register(this);
	}
	
	public void weatherHasBeenUpdatedFromSomewhere(String weatherDescription)
	{
		this.weatherDescription = weatherDescription;
		
		// post the updated weather on the event bus.
		eventBus.post(weatherDescription);
	}
	
	@Produce
	public String produceWeatherUpdate()
	{
		return weatherDescription;
	}
}

When the OttoWeatherService class receives an update, it posts an event on the bus to notify all subscribers. Note that the service class now has less responsibility as it no longer needs to be concerned with a list of listeners and is immediately decoupled from the interface. Also note that this class is a Producer, meaning that as soon as an interested subscriber registers on the bus it will receive the latest update.

OttoWeatherScreen Class

public class OttoWeatherScreen
{
	private String weatherDescription;
	private Bus eventBus;
	
	public OttoWeatherScreen(Bus eventBus)
	{
		this.eventBus = eventBus;
		eventBus.register(this);
	}
	
	@Subscribe
	public void weatherAvailable(String weatherDescription)
	{
		this.weatherDescription = weatherDescription;
		
		// Do something...
	}
	
	@Subscribe
	public void randomObjectAvailable(RandomObject randomObject)
	{
		// Do something...
	}
}

The WeatherScreen class now receives updates from the various services by subscribing for these updates/events on the bus. Otto results in less classes having to be created and less code concerned with connecting your components up, allowing the existing classes to focus on performing core functions.

The above was just one example of how Otto can reduce the complexity surrounding communications/connections in your application. Coupling is reduced but strongly typed event production/subscription is still maintained.
 
I’ve created an OttoSample Android project on GitHub that provides a simple demonstration of how the Otto event bus can be used to communicate an object between two fragments. Please note that this project also makes use of the Android Annotations framework for object/view dependency injection; I plan to discuss and provide feedback on this framework in the near future.

Android Action Bar Sherlock: Mimicking action item styling in a custom action bar.

When using Action Bar Sherlock in your project there may be times when you want to provide your own custom view for the action bar. As part of your custom view, you might also want to add your own action buttons which look and feel just like the standard action item views. For instance, the following is a simple custom action bar view with some title text on the left and a search button on the right; the aim here is to ensure that the search button behaves just like a standard action item.

Custom Action Bar view with search button

Custom Action Bar view with search button

When the search button on the right is selected, visually it should appear the same as a standard action item:

Custom Action Item with standard styling

Custom Action Item with standard styling

To accomplish this is fairly straightforward:

  • Define the style for your action bar button(s) in your styles.xml resource file:
 <style name="Widget.CustomSearch.ActionButton" parent="Widget.Sherlock.Light.ActionButton">
     </style>

This step isn’t entirely necessary as one could just reference the Widget.Sherlock.Light.ActionButton style directly in the custom layout below.

  • You then need to define a custom layout view for your action bar. In our case it is something like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/actionbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/app_name"
            android:textColor="@color/ab_custom_view_text_color"
            android:textSize="16sp"
            android:textStyle="bold" >
        </TextView>

        <TextView
            android:id="@+id/actionbar_subtitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/action_bar_subtitle"
            android:textColor="@color/ab_custom_view_text_color"
            android:textSize="11sp" >
        </TextView>
    </LinearLayout>

    <ImageView
        style="@style/Widget.CustomSearch.ActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:clickable="true"
        android:src="@drawable/ab_search" />

</RelativeLayout>

In this particular case a simple ImageView has been used to represent the search button. The important things to note here are: 1) our custom action button style (@style/Widget.CustomSearch.ActionButton) is applied to the view; and 2) the view is made clickable.

  • In your main Activity class, enable the use of a custom action bar view and apply your custom layout:

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		...

		// Allow custom view in action bar
		getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
		getSupportActionBar().setCustomView(
			R.layout.ab_custom_view);

		...
	}

Where R.layout.ab_custom_view is the layout resource defined in step 2.

Attaching source code to Android libraries.

Since Android Development Tools (ADT) r17, projects in eclipse would automatically add any libraries placed in the libs folder to your build path. This is a great feature but has a pretty horrible side effect in that one cannot attach source code to the libraries in the conventional way under the build path properties page. Fortunately, since the release of ADT r20, there seems to be a work-around which is explained nicely on the following site:

Attaching Source to Libraries in Eclipse

I found that once I had created my x.jar.properties file I had to close and reopen my eclipse project for this to work.