Month: August 2014

Google MapView not appearing in my app when using a debug build from two different sources

Today I got to the bottom of an issue that I’d semi been looking into for a week or so. I am doing some development using Google Map v2 and I noticed that it was working fine when I ran the debug build direct from Android Studio, the map displayed perfectly. However, when I deployed the debug apk created from either Jenkins or another development machine the maps didn’t appear at all. I had the Google logo in the bottom left corner and that was it.

It felt like a map api key issue but I couldn’t quite work out what. It was only when I noticed that I was getting a warning when deploying the app from another development machine saying “re-installation failed due to different application signature” that I put two and two together.

The issue was my original machine had the debug.keystore file in .android however, on the other machine the debug.keystore would be different. So the fix was to take my debug.keystore and put it into source control along with my release.keystore file and update the app gradle build config to use the one from source control with the following configuration.

signingConfigs {
  debug {
    storeFile file(“keystore/debug.keystore”)
  }

release {
    storeFile file(“keystore/release-key.keystore”)
    storePassword “*********”
    keyAlias “my_alias_name”
    keyPassword “******”
  }
}

Adding Jenkins build number into your Android application

Today I was trying to get the Jenkins build number into my Android app for display, however, I couldn’t find any tutorials on how to do this. I have pieced together a few things and put them together below.

Getting the Jenkins build number into Gradle build system

So, Android uses two fields for versioning, these appear in the app’s build.gradle file.

versionCode – The unique version that android uses to distinguish between versions of an app.

versionName – This is more of a human readable and flexible build number that is what I’d like to display. By default this is hard coded to “1.0” and I’d like to make it “1.0.” + JENKINS_BUILD_NUMBER.

Jenkins exposes the current build number as a system environment variable so we need to access this in the build script using the following code. Put this in the defaultConfig section for now (I’m sure there might be a better place but this works for me):

ext.buildNumber = System.getenv("BUILD_NUMBER") ?: "dev"

This code above sets the buildNumber variable to the jenkins build number if it is not null, otherwise it sets it to “dev”. I did this so that we can distinguish between development builds and continuous integration builds.

I then updated versionNumber with the following code:

versionName "0.1.$buildNumber"

This now makes the Jenkins build number and our application version accessible to our application.

Getting the version name from the build system into my app
If you are using the Gradle build system there is an addition class available to your application that allows you to get the configured version number.

Add BuildConfig.VERSION_NAME to where ever you need to retrieve the current version name from. For example, I have a TextView in the settings screen of my application and I set the version name with the code below.


final TextView versionName = (TextView) findViewById(R.id.versionNameText);
versionName.setText(BuildConfig.VERSION_NAME);

That’s it.

Installing Gradle on Ubuntu 14

Today I tried to install gradle using apt-get and it failed with the message

Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies.
gradle : Depends: libgradle-plugins-java (= 1.4-2ubuntu1) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

Being a bit of a novice I had no idea how to resolve this. I tried sudo apt-get install libgradle-plugins-java but that couldn’t be resolved either.

After a bit of digging I needed to do the following to add a repository to apt-get so it could get all the dependencies.

sudo add-apt-repository ppa:cwchien/gradle
sudo apt-get update
sudo apt-get install gradle

How to customise a ListView in an Android application

Whilst working on an Android application I came across the situation where I wanted to style the items in a list view in a different way to the default. e.g. Create compound fields for each row and change the size of the font and the weight etc. This customisation I thought would be handled by the ListView in the layout however, it doesn’t. This article will explain how to customise the view and why it is like this.

The ListView layout tag is there to define the ListView container and nothing else. By default you can use one of the default adapters to insert content into the ListView, however, as soon as you want to move away from the default implementations you’ll need to write a little code and create another layout file to handle the layout of the row.

Create a layout file for the row

In Android Studio right click on main/res/layout and select New->Layout Resource File call it row.xml


<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:layout_width=\"match_parent\"
android:layout_height=\"match_parent\"
android:orientation=\"vertical\" >

<TextView android:layout_width=\"wrap_content\"
android:layout_height=\"wrap_content\"
android:text=\"Column 1\"
android:id=\"@+id/column1\"/>

<TextView
android:layout_width=\"wrap_content\"
android:layout_height=\"wrap_content\"
android:id=\"@+id/column2\"/>
</LinearLayout>

Add a ListView component to your existing main layout file if you haven’t already. e.g.


<ListView
android:id=\"@+id/listview\"
android:layout_width=\"fill_parent\"
android:layout_height=\"fill_parent\" >
</ListView>

Now you need to create a new class that extends the BaseAdapter that we will use to configure our ListView in the activity with the customised ListView row layout.


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

/**
* This class is responsible for overriding the Adapter for the ListView to enable us to replace the
* default row layout with our one.
*/
public class ListAdapter extends BaseAdapter {
Context context;
String[] data;

private static LayoutInflater inflater = null;

public CommentListAdapter(Context context, String[] data) {
this.context = context;
this.data = data;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
return data.length;
}

@Override
public Object getItem(int position) {
return data[position];
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = inflater.inflate(R.layout.comment_row, null);
}

TextView text = (TextView) view.findViewById(R.id.text);
text.setText(data[position]);

return view;
}
}

The final step is to add some code to your onCreate method in your Activity that configures the ListView component with the adapter defined above. This connects the activity, with the custom list adapter that connects your custom list row layout.


listview = (ListView) findViewById(R.id.listview);
listview.setAdapter(new ListAdapter(this, new String[] { \"Line 1\", \"Line 2\" }));