Posts Tagged ‘Android’

Android – INSTALL_FAILED_INSUFFICIENT_STORAGE

Monday, January 23rd, 2012

If you work with the Android Emulator and deploy to it for a while you may receive the following error message in the LogCat View.

Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE

The reason for this is that the emulator default to 64MB for internal storage.

You can override this in the Eclipse launch configuration for your Android application with the additional parameter -partition-size 1024.

Alternative you can add the following line to the “config.ini” file of you AVD definition. This file is stored in the user folder in .android/avd and then under your specific device definition. For example:

hw.lcd.density=160
sdcard.size=200M
skin.name=HVGA
skin.path=platforms/android-15/skins/HVGA
hw.cpu.arch=arm
abi.type=armeabi-v7a
hw.cpu.model=cortex-a8
vm.heapSize=48
snapshot.present=true
hw.ramSize=512
image.sysdir.2=system-images/android-15/armeabi-v7a/
image.sysdir.1=add-ons/addon-google_apis-google_inc_-15/images/armeabi-v7a/
disk.dataPartition.size=1024

I hope this helps. I have also ask the Android development team to increase the default value: Bug report.

Android SQLite and ContentProvider Book available for the Kindle

Wednesday, January 18th, 2012

Today I released my new Android SQLite and ContentProvider book for the Kindle device.

This book demonstrates how you can develop Android applications using the integrated SQLite database. It also demonstrates how to use and create ContentProvider for accessing data. ContentProviders are Java classes which allow to share data between applications. They also provide a structured interface to access data. The tutorials of this book have been developed and tested with Android 4.0.3, API Level 15.

The book assumes that you are already familiar with the Android Development Tools for Eclipse and with creating simple Android applications.

You find the book in all Amazon stores:

Android SQLite and ContentProvider Book in Amazon USA
Android SQLite and ContentProvider Book in Amazon Germany
Android SQLite and ContentProvider Book in Amazon UK
Android SQLite and ContentProvider Book in Amazon France
Android SQLite and ContentProvider Book in Amazon ES
Android SQLite and ContentProvider Book in Amazon IT

Content Description:

The first chapter gives an introduction into SQLite and using SQlite on Android.

The second chapter introduces the main SQLite classes and how to use them. It also gives examples how to create and run queries to your database.

The third chapter contains a tutorial in which you create a new Android project which uses SQLite to store its data. In the tutorial you will use a wrapper class (data access object) which handles the access to the database.

In the fourth chapter we look at ContentProviders. It explains what a ContentProvider is, how you can access existing ones and how to define your own one.

In this chapter you also learn how to define a ContentProviders only visible to your application and learn about threading safety with ContentProvider.

The next chapter is a tutorial which shows how to access an existing ContentProvider. You create an Android application which access the data from the “People” application .

The sixth chapter explains the Loader API which was introduced in Android 3.0. Loader loads the data asynchronously. Activities should use this new API to manage their database connection (Cursor).

The seventh chapter is a tutorial in which you create an application to manage your tasks. You create your own ContentProvider for accessing the SQLite database and use the Loader API for accessing and managing the database Cursor.

Accessing the SQLite database directly on the command line is part of the eighth chapter.

The content of the book is similar to the online version.

I’m again surprised how much work it is to convert my website content into a book format. I hope you like this book.

Making the Android SDK source code available in Eclipse

Tuesday, January 10th, 2012

As of Android 4.0 the integration of the Android SDK source code is much easier.

You can just download the source code via the Android SDK Manager. The sources are downloaded to the source directory located in “path_to_android_sdk/sources/android-xx”. xx is the api level number (15 for 4.0.3). You can then add the source code as a source attachment to your android.jar.

I included this info in my Android Tutorial.

Thanks to Ed Burnette for pointing that out on Google+.

Kudos also the the ADT team which made this great improvement in development experience.

Android – Going down with Style

Tuesday, August 16th, 2011

Android allows to use styles and themes to define the appearance of the user interface. This blog entry will demonstrate how to use styles in your application.

First create a new Android project “de.vogella.android.styles.simple” with the following main.xml layout file.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TableLayout android:layout_height="wrap_content"
		android:stretchColumns="1" android:id="@+id/tableLayout1"
		android:layout_width="fill_parent">
		<TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content"
			android:layout_height="wrap_content">
			<TextView android:text="User" android:id="@+id/textView1"
				android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
			<EditText android:id="@+id/editText1" android:layout_width="wrap_content"
				android:layout_height="wrap_content">
				<requestFocus></requestFocus>
			</EditText>
		</TableRow>
		<TableRow android:id="@+id/tableRow2" android:layout_width="wrap_content"
			android:layout_height="wrap_content">
			<TextView android:text="Password" android:id="@+id/textView2"
				android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
			<EditText android:id="@+id/editText2" android:layout_width="wrap_content"
				android:layout_height="wrap_content"></EditText>
		</TableRow>
	</TableLayout>
</LinearLayout>

This gives us the following wounderful UI.

Lets make the UI a bit nicer. The typical way would be to set attributes to the elements in the UI until we are fine with the result. In addition to this approach you can also define styles which you can assign to the elements. This way you only have to set common attributes once and can later change the look in one central place.

To start create the XML file “styles.xml” under /res/xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="text">
        <item name="android:padding">4dip</item>
        <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
        <item name="android:textColor">#000000</item>
    </style>
    <style name="layout">
        <item name="android:background">#C0C0C0</item>
    </style>
</resources>

You now assign the style attribute to your elements, for example to the text elements via style=”@style/text”.

If you apply the style to your text elements and layout you receive.

I hope this helps.

You find me also on Twitter and Google+.

Android: how to filter a ListView based on an EditText field

Tuesday, July 26th, 2011

Android has very good support for displaying lists via the Android ListView class.

A typical setup for a list is that you want to have a filter field on the top of your list and this input into this field should filter the content of the list. Here is a small example showing how to do this.

Create for this example the project “de.vogella.android.list.filter” with the activity “ListFilterDemoActivity”. Create the following layout:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<EditText android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:id="@+id/filterText">
		<requestFocus></requestFocus>
	</EditText>
	<ListView android:layout_height="wrap_content" android:id="@+id/android:list"
		android:layout_width="fill_parent"></ListView>
</LinearLayout>

Create your adapter class.

package de.vogella.android.list.filter;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.ArrayAdapter;
import android.widget.EditText;

public class ListFilterDemoActivity extends ListActivity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, android.R.id.text1,
				getModel());
		setListAdapter(adapter);
		EditText filterEditText = (EditText) findViewById(R.id.filterText);
		filterEditText.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				adapter.getFilter().filter(s.toString());
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			@Override
			public void afterTextChanged(Editable s) {
			}
		});
	}

	private List<String> getModel() {
		List<String> list = new ArrayList<String>();
		list.add("Linux");
		list.add("Windows7");
		list.add("Suse");
		list.add("Eclipse");
		list.add("Ubuntu");
		list.add("Solaris");
		list.add("Android");
		list.add("iPhone");
		return list;
	}
}

You find more information about ListViews in the Android ListView Tutorial

I hope this helps.

You find me also on Twitter and .

Update: Change to use the standard filter of adapter. Thanks Charles Zhang for the suggestion.

Android: Activity Lifecycle and Threads

Tuesday, July 12th, 2011

Android is allowed to destroy your activity at anytime. Also a configuration change will restart your activity to load the right resources for this configuration.

If you use Threads in your Android program you should save them. Nothing is more annoying then having a running download, flipping the phone and finding that the download was canceled.

Based on my Creating Bitmaps from the internet via Apache HttpClient example here is an Activity which saves the Thread which downloads the image and also makes sure the dialog is correctly re-created after restart.

package de.vogella.android.threadslifecycle;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;

public class ThreadsLifecycleActivity extends Activity {
	// Static so that the thread access the latest attribute
	private static ProgressDialog dialog;
	private static ImageView imageView;
	private static Bitmap downloadBitmap;
	private static Handler handler;
	private Thread downloadThread;

	/** Called when the activity is first created. */

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// Create a handler to update the UI
		handler = new Handler();
		// get the latest imageView after restart of the application
		imageView = (ImageView) findViewById(R.id.imageView1);
		// Did we already download the image?
		if (downloadBitmap != null) {
			imageView.setImageBitmap(downloadBitmap);
		}
		// Check if the thread is already running
		downloadThread = (Thread) getLastNonConfigurationInstance();
		if (downloadThread != null && downloadThread.isAlive()) {
			dialog = ProgressDialog.show(this, "Download", "downloading");
		}
	}

	public void resetPicture(View view) {
		if (downloadBitmap != null) {
			downloadBitmap = null;
		}
		imageView.setImageResource(R.drawable.icon);
	}

	public void downloadPicture(View view) {
		dialog = ProgressDialog.show(this, "Download", "downloading");
		downloadThread = new MyThread();
		downloadThread.start();
	}

	// Save the thread
	@Override
	public Object onRetainNonConfigurationInstance() {
		return downloadThread;
	}

	// dismiss dialog if activity is destroyed
	@Override
	protected void onDestroy() {
		if (dialog != null && dialog.isShowing()) {
			dialog.dismiss();
			dialog = null;
		}
		super.onDestroy();
	}

	// Utiliy method to download image from the internet
	static private Bitmap downloadBitmap(String url) throws IOException {
		HttpUriRequest request = new HttpGet(url.toString());
		HttpClient httpClient = new DefaultHttpClient();
		HttpResponse response = httpClient.execute(request);

		StatusLine statusLine = response.getStatusLine();
		int statusCode = statusLine.getStatusCode();
		if (statusCode == 200) {
			HttpEntity entity = response.getEntity();
			byte[] bytes = EntityUtils.toByteArray(entity);

			Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0,
					bytes.length);
			return bitmap;
		} else {
			throw new IOException("Download failed, HTTP response code "
					+ statusCode + " - " + statusLine.getReasonPhrase());
		}
	}

	static public class MyThread extends Thread {
		@Override
		public void run() {
			try {
				// Simulate a slow network
				try {
					new Thread().sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				downloadBitmap = downloadBitmap("http://www.vogella.de/img/lars/LarsVogelArticle7.png");
				handler.post(new MyRunnable());
			} catch (IOException e) {
				e.printStackTrace();
			} finally {

			}
		}
	}

	static public class MyRunnable implements Runnable {
		public void run() {
			imageView.setImageBitmap(downloadBitmap);
			dialog.dismiss();
		}
	}
}

If you run this you can test via CNTR+F11 to trigger a configuration change. You find more details in my Android Threads, Handlers and AsyncTask – Tutorial .

I big thanks to Mark Murphy who spotted a memory leak in the first version of the example.

I hope this helps. You find me also on Twitter. My profile can be found .

Android SoundPool – How to check if sound file is loaded?

Monday, June 27th, 2011

SoundPool loads the sound asynchronously. Before API level 8 where was no standard way of checking if a sound had been loaded before using it.

As of API 8 Android allows to check if the loading has been completed via OnLoadCompleteListener.

Below you find a small example how to use this. It will start playing the sound once the finger touches the display. For the full description please see Sounds with Android.


package de.vogella.android.soundpool;

import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class PlaySound extends Activity implements OnTouchListener {
	private SoundPool soundPool;
	private int soundID;
	boolean loaded = false;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		View view = findViewById(R.id.textView1);
		view.setOnTouchListener(this);
		// Set the hardware buttons to control the music
		this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
		// Load the sound
		soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
		soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
			@Override
			public void onLoadComplete(SoundPool soundPool, int sampleId,
					int status) {
				loaded = true;
			}
		});
		soundID = soundPool.load(this, R.raw.sound1, 1);

	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			// Getting the user sound settings
			AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
			float actualVolume = (float) audioManager
					.getStreamVolume(AudioManager.STREAM_MUSIC);
			float maxVolume = (float) audioManager
					.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
			float volume = actualVolume / maxVolume;
			// Is the sound loaded already?
			if (loaded) {
				soundPool.play(soundID, volume, volume, 1, 0, 1f);
				Log.e("Test", "Played sound");
			}
		}
		return false;
	}
}

I hope this helps.

You find me also on Twitter and Google+.

Creating Bitmaps from the internet via Apache HttpClient

Tuesday, June 21st, 2011

Last week I blogged about the Android DownloadManager. As a result I received the question how to create a bitmap from internet ressources the “normal” way. ;-)

Here is a small example which uses the Apache HttpClient in Android to download a png file and create a bitmap from it. This bitmap will then be assigned to a ImageView.

Here is the layout file “main.xml”.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<Button android:text="Click to start download" android:onClick="downloadPicture"
		android:layout_height="wrap_content" android:layout_width="wrap_content" />
	<ImageView android:src="@drawable/icon" android:id="@+id/imageView1"
		android:layout_height="match_parent" android:layout_width="match_parent"></ImageView>
</LinearLayout>

package de.vogella.android.bitmap.httpdownload.simple;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class DownloadExampleActivity extends Activity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

	}

	public void downloadPicture(View view) {
		final ProgressDialog dialog = ProgressDialog.show(this, "Download",
				"downloading");
		dialog.show();
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					final Bitmap downloadBitmap = downloadBitmap("http://www.vogella.de/img/lars/LarsVogelArticle7.png");
					final ImageView imageView = (ImageView) findViewById(R.id.imageView1);
					runOnUiThread(new Runnable() {
						@Override
						public void run() {
							imageView.setImageBitmap(downloadBitmap);
						}
					});

				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					dialog.dismiss();
				}
			}
		}).start();

	}

	private Bitmap downloadBitmap(String url) throws IOException {
		HttpUriRequest request = new HttpGet(url.toString());
		HttpClient httpClient = new DefaultHttpClient();
		HttpResponse response = httpClient.execute(request);

		StatusLine statusLine = response.getStatusLine();
		int statusCode = statusLine.getStatusCode();
		if (statusCode == 200) {
			HttpEntity entity = response.getEntity();
			byte[] bytes = EntityUtils.toByteArray(entity);

			Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0,
					bytes.length);
			return bitmap;
		} else {
			throw new IOException("Download failed, HTTP response code "
					+ statusCode + " - " + statusLine.getReasonPhrase());
		}
	}
}

Also add the permission to use the internet to your app.

Hope this helps. A introduction to Networking with Android can be found here.

You find me also on Twitter.

Creating Android applications via the command line and Apache Ant

Wednesday, March 16th, 2011

Android projects can be created either with the ADT Plugin for Eclipse or via the command line. This blog entry explains how to do this via the command line.

You find the related command line program “android” in the folder “tools” of your Android SDK installation. Add this folder to your path and run the following command>

android create project --target "Google Inc.:Google APIs:8" --path de.vogella.android.commandline --activity TestActivity --package de.vogella.android.commandline

I assume except –target all other options are clear. To see potential targets use the command

android list targets

To compile your program you can use Apache Ant. You need of course to have Ant installed and add it to your path. See Apache Ant Tutorial for this. Afterwards switch into your newly created directory “de.vogella.android.commandline” and type the following to create a development release

ant debug

You can also build a real release, this requires that you setup the “key.store” and “key.alias” properties in build.properties.

ant release

To install it into an running device, e.g. the emulator, use

ant install

You find now the activity “TestActivity” on your virtual device under programs and you can test it.

I hope this help. Enjoy your Android Development.

Android – Hacking layouts

Monday, March 14th, 2011

One common mis-understanding seem to be that Android starters seem to think that a layout can only be defined via a XML resource. While this is the most common way of defining a layout in most cases you can also define a complete layout via programming code.

For example create a project “de.vogella.android.codelayout” with the activity “CodeLayout” and the following coding.

package de.vogella.android.codelayout;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class CodeLayout extends Activity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		LayoutParams params1 = new LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.WRAP_CONTENT);

		TextView text = new TextView(this);
		text.setText("Hello");
		text.setLayoutParams(params1);
		EditText edit = new EditText(this);
		edit.setHint("This is your input...");
		edit.setLayoutParams(params1);
		Button button = new Button(this);
		button.setText("Press me");
		button.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Toast makeText = Toast.makeText(v.getContext(), "Pressed", 200);
				makeText.show();
			}
		});
		LinearLayout layout = new LinearLayout(this);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(10, 10, 10, 10);
		layout.addView(text);
		layout.addView(edit);
		layout.addView(button);
		setContentView(layout);
	}
}

As you can see the layout is completely created via programming code.

Why is it better to define the layout of an application via XML? See Android Layout Overview.

But even if you define your layout via XML then this layout will be inflated in Java objects by the class “LayoutInflator” which will parse the XML, creates elements for the ViewGroups and Views and calls the setter for the attributes defined in the XML.

Hope this helps.


Switch to our mobile site