Android Archive

Both Google and Apple are entering the smartwatch market: Google with the operating system “Google Wear”, Apple with a custom iOS version and the corresponding hardware. This will be the first serious attempts to establish this new market. Initially, the key application are fitness, social networks and the controlling of apps. But why shouldn’t smartwatches be used also in the industrial sector – similar to phones and tablets?

Our newest app is available now: earaction.

Earaction is an application for smartphones that is used for noise awareness among young people. Especially this target group is often not aware of causes and effects of too much noise – that is why hearing impairments are quite common at a young age already.

The app provides information about the sensory organ of hearing. It will alert you to potential hearing damage and important preventive measures. A simple hearing test evaluates your hearing performance and strengthens your awareness of this highly sensitive organ. Particular emphasis is placed on a simple representation of complex acoustic physics. With interactive listening experiences, knowledge and more understanding of noise and decibels are taught. You can compare, for example, the hearing capabilities of a healthy and of a damaged ear.

The application was created by us in collaboration with the University of Munich and the Bavarian State Ministry of the Environment and Public Health. It is available on Google Play:

android_app_on_play_large

We have published an article in the new issue of mobileDeveloper (5/2012, pp. 60-64): ‘In Kontakt treten’ (Making Contact). The topic of the article is how to retrieve addresses from a mobile device in a new way (using the ContactsContract).

MobileDeveloper is one of the leading German magazines for developers who write programs for smart phones and tablet computers.

Augmented Reality may have great potential – however, the introduction of this new technique has been rather slow so far.

Now Auto-Bild has developed in collaboration with Metaio a new app for iOS/Android, that adds interactive content to its articles. The app responds to code symbols contained in the articles, and launches the associated content.

If you are a reader of Auto-Bild, don’t miss this (free) app.

Auto-Bild is one of the major German car magazines. More information is available at the Auto-Bild website.

For details about augmented reality, see this article.

During my last project I’ve encountered two problems which caused my app to crash which I did not expect to happen because the exact same code was working within other activities. These crashes were triggered by simple things like a press on the search button of the mobile phone or the creation of a dialog. When analyzing this behavior I’ve identified a nested TabHost View (a TabHost containing another TabHost which contains the Activity) as the cause for the crashes.

One TabHost contains another TabHost. The last TabHost contains the actual content.The problematic setup is shown in the picture to the left. As you can see the outer TabHost contains a Tab which Activity itself is the inner TabHost. The content of this TabHost will be placed between both tabs. So this is a design which doesn’t seem to be so out of the world.

In the following I’m going to point out the two problems and the solutions which I’ve found so that you might be able to solve similar problems. To demonstrate the problems I’ve created an example project which causes the errors and one which contains the proposed solutions where the functions are working.

If you are looking for a way to implement location based services within your android application without using the web services of Google, you might be interested in the CloudMade web services. These web services provide functions like geocoding, searching for objects which are close to a given coordinate, retrieving map tiles as images and even to create a full route from a start point via several transit points to an end point.

To provide these services, CloudMade relies on the collaborative OpenStreetMap (OSM) project which follows the same principles as Wikipedia to create a free map.

To ensure an easy usage of the web services, CloudMade provides several libraries for the iPhone and other programming languages. The provided Java API is using an old implementation of the Apache HTTP Client which makes it unusable for Android devices. That’s why I’ve created a port of the lightweight CloudMade Java API which can be used on android devices.

The core of this library is the com.appsolut.api.cloudmade.CMClient which hides the HTTP communication of the different calls from the developer. The methods within this class are well documented and I will only give short overview of the most important methods:

public GeoResults find(String query, int results, int skip, BBox bbox, boolean bboxOnly, boolean returnGeometry, boolean returnLocation)

This method provides the geocoding functionality:

public GeoResult findClosest(String object_type, Point point) throws ObjectNotFoundException

If you want to find a certain object which is close to a point you can use this method:

public byte[] getTile(double latitude, double longitude, int zoom, int styleId, int size)

This method will return a png image of a map tile. For example, this might return a tile which looks like the following:

 

An example tile retrieved from the CloudMade web service

public Route route(Point start, Point end, RouteType routeType, List<Point> transitPoints, RouteTypeModifier typeModifier, String lang, MeasureUnit units) throws RouteNotFoundException

Using this method it is possible to create a route.

There exists also an android test project which can be used to ensure that everything works fine. You can also take a look at the test cases to see an example of how to use the library.

You can download or browse the source code at our repository at Google Code (http://code.google.com/p/android-cloudmade-api/) or use svn to check it out.

For more information you can refer to the following links:

If you are having trouble with this port feel free to ask questions.

Please Note:
It is important that you create your own API key when you are using the CloudMade web services. Please refer to the CloudMade FAQ for more information on this topic.

by Kevin Kratzer

In this post I will introduce a library which you can use to display elements from any java.util.Collection (e.g. LinkedList, ArrayList, HashSet, Queue, Stack, TreeSet,…) within a ListView or a Spinner. It’s even possible to use this library to implement any layout you want for your entries (e.g. a multi-line entry, an entry with including an image, etc…).

So this library is a very generic approach to display various data sets with custom layouts in a Spinner or a ListView.

To demonstrate the basic usage of this adapter I’ve created a simple example application which is using the library for a spinner adapter for a HashSet of UUIDs and a list adapter to display the single parts of the UUID together with an image.

Feel free to download the library and to reuse it within your own projects. You can also examine the source code at our Google code repository (http://code.google.com/p/android-collections-list-and-spinner-adapter/) by browsing the source or by checking it out using svn.

Basic Usage

Initialization

To ensure an easy usage of the library the CollectionsAdapter provides constructors which are closely related to the default android ArrayAdapter. The basic usage includes the use of the adapter with a simple TextView resource id or with a layout resource id and a TextView resource id which is located within this layout. When you are using this methods the objects toString method will be used to populate the give TextView element with text.

The corresponding constructors of the com.appsolut.adapter.collections. CollectionsAdapter<E>  class have the following signature:

public CollectionsAdapter(Context context, int textViewResourceId, Collection<E> content)
public CollectionsAdapter(Context context, int layoutResourceId, int textViewResourceId, Collection<E> content)

Where the parameters should be:

    • context – The context for the adapter. This could be your Activity.
    • layoutResourceId – If you are using the constructor which also uses a give layout resource id this parameter should point to this layout.
    • textViewResourceId – The resource id which is referring to the text view element used to fill in the text.
    • content – The collection containing the data. The collection can be modified afterwards.

 

In the example project this is demonstrated by the adapter for the spinner:

final Set<UUID> spinnerContent = new HashSet<UUID>();
for(int i = 0; i < 10; i++) {
	spinnerContent.add(UUID.randomUUID());
}
final CollectionsAdapter<UUID> spinnerAdapter = new CollectionsAdapter<UUID>(this, android.R.layout.simple_spinner_item, spinnerContent);
final Spinner spinner = (Spinner)findViewById(R.id.exampleSpinner);
spinner.setAdapter(spinnerAdapter);

Modifying the Data

If you later on want to modify the data you can either do this directly within the corresponding collection and then calling the notifyDataSetChanged() of the adapter to signal that you have modified the data or you can use the provided methods within the adapter which will take care of this. The signature of these methods is just like within the Collection interface:

      • public boolean add(E object)
      • public boolean addAll(Collection<? extends E> c)
      • public boolean remove(E object)
      • public boolean removeAll(Collection<?> c)
      • public void clear()

The boolean return value of the add and remove methods indicate if the data of your collection has been actually changed by the method call.

So as you can see the basic usage of the adapter is very simple.

 

Defining custom Layouts

If you want to use custom layouts within the adapter you can use the third available constructor of the com.appsolut.adapter.collections. CollectionsAdapter<E> class:

public CollectionsAdapter(Context context, Collection<E> content, ICollectionsAdapterViewFactory<E> viewFactory)

This constructor requires a context, the collection which will be used as data basis for the adapter and an com.appsolut.adapter.collections.view.ICollectionsAdapterViewFactory<E> viewFactory. The ICollectionsAdapterViewFactory<E> interface defines a method which will be called to display an element. During this method call you can create your own layout:

public View getView(int position, View convertView, ViewGroup parent, E item, LayoutInflater inflater, Context context)

If you have already created custom views for an adapter the method should look familiar to you. There are just some new parameters which ensure an easy creation of the view. If custom views within an adapter are completely new you should check out my previous posting on this topic first (http://xinfo.de/2011/03/using-custom-layouts-for-spinner-or-listview-entries-in-android/) and the return here.

So let’s take a look at the parameters of the method:

      • position – indicates the position of the element within the data set which should be displayed
      • convertView – “The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view.” – taken from the original Android API
      • parent – The parent view to which you should attach your view
      • item – The item which should be displayed by this view
      • inflater – The layout inflater service used to inflate xml layouts
      • context – The current context

In the example project I’ve implemented such an ICollectionsAdapterViewFactory which will populate a layout consisting of an ImageView and two TextViews:

public class NumberedViewFactory<T> implements
		ICollectionsAdapterViewFactory<T> {

	@Override
	public View getView(int position, View convertView,
			ViewGroup parent, T item, LayoutInflater inflater,
			Context context) {
		View layoutView;
		if (convertView == null) {
			layoutView = inflater.inflate(R.layout.listview_entry, parent, false);
		} else {
			layoutView = convertView;
		}
		final TextView segmentText = (TextView)layoutView.findViewById(R.id.textSegment);
		segmentText.setText(item.toString());

		final TextView segmentNumber = (TextView)layoutView.findViewById(R.id.segmentNumber);
		segmentNumber.setText(Integer.toString(position) + ". ");

		final ImageView imageView = (ImageView)layoutView.findViewById(R.id.image);
		if(position%2 == 0) {
			imageView.setBackgroundResource(android.R.drawable.presence_online);
		} else {
			imageView.setBackgroundResource(android.R.drawable.presence_invisible);
		}

		return layoutView;
	}

}

Summary

I hope you can use this flexible library to populate your ListViews and Spinners with various data sets. If you have any problems or suggestions on how to improve this library feel free to post comments.

by Kevin Kratzer