Sunday, June 6, 2010

My first App is now available on the Android market, free.


Aspect Ratio Calculator is a simple tool that makes it easy to calculate the dimensions to resize an image.

Great for graphic designers, or anyone resizing images for blogging, it's available in Spanish, Russian, Portuguese, Chinese & Italian.

.. And of course, English ;)

Sunday, April 25, 2010

Book Review: Professional Android 2 Application Development

Professional Android 2 Application Development (Wrox Programmer to Programmer)

Written by an Android authority, this up-to-date resource shows you how to leverage the features of Android 2 to enhance existing products or create innovative new ones.

Serving as a hands-on guide to building mobile apps using Android, the book walks you through a series of sample projects that introduces you to Android's new features and techniques.

It is perhaps one of the most in-depth Android books available, and is also very regularly updated, currently covering Android SDK 2.1 r1.


The Book's author, Reto Meier is a software developer who has been involved in Android since the initial release in 2007. He is an Android Developer Advocate at Google.

Monday, April 19, 2010

Writing Real-Time Games for Android - Google I/O 2009



Do vertex arrays keep you up at night? Do you have nightmares involving frame rates and event loops? If so, this session might have the cure for your condition.

Chris Pruett will discuss the game engine that he developed, using it as a case study to explain the common pitfalls and best practices for building graphics-intensive applications. You'll learn how to properly pipeline game and rendering code, manage drawing surfaces, and incorporate 2D and 3D graphics cleanly.

Tuesday, April 13, 2010

Some notes about Android Context



Context is an interface to global information about an application environment. It's an abstract class whose implementation is provided by the Android system.

Context allows access to application-specific resources and classes, as well as calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

All the widgets receive a Context parameter in their constructor. In a regular Android application, you usually have two kinds of Context, Activity and Application. It's usually an Activity Context that the developer passes to classes and methods that need a Context.

Basically the Application context is associated with the Application and will always be the same throughout the life cycle of your app, where as the Activity context is associated with the activity and could possible be destroyed many times as the activity is destroyed during screen orientation changes and such.

In particular you should be careful when dealing with anything that deals with the GUI that requires a Context. For example, if you pass the application Context into the LayoutInflator you will get an Exception. It's good practice to use an Activity's Context within that Activity, and the Application Context when passing a context beyond the scope of an Activity to avoid memory leaks.

Here's a quick snippet showing how you can find both the Activity Context and the Application Context:


public class MyActivity extends Activity {
public void aMethod() {
Context actContext = this; /*returns the Activity Context since Activity extends Context.*/

Context appContext = getApplicationContext(); /*returns the context of the single, global Application object of the current process. */

Button btnGoToFirstAct = (Button) findViewById(R.id.btnGoToAct1);
Context vwContext = btnGoToFirstAct.getContext(); /*returns the context of the View. */



When run in the debugger, you can see the results of this:


 Notice that the vwContext in this case also returns the Activity Context.



Hope that helps answer some questions. Drop me a message in the comments if you have anything to add.

Sunday, April 11, 2010

Learn what it takes to make a good Android app great.



Jason, John, and David, mobile industry veterans from Hands-On Mobile, present a technical overview of ways to improve your Android applications stickiness, boost adoption, engage users, and increase monetization and ROI.

This event was hosted by The San Francisco Android User Group at CBS Interactive in San Francisco on August 27th, 2009. The event was sponsored by Hands-On Mobile and organized by Marakana Inc.

Learn how to develop for Android, Beyond HelloWorld



This is a nice, long (2hrs) video, demonstrating many aspects of creating a simple Android application from scratch. Definitely worth checking out if you've got the time.

Sunday, April 4, 2010

How to Make your Android UI Fast and Efficient - video from Google I/O 2009 with Romain Guy


Here a video from Google I/O 2009 with Romain Guy from Google.

"Learn practical tips, techniques and tricks for making your Android applications fast and responsive. This session focussed on optimizations recommended by the Android framework team to make the best use of the UI toolkit."

.. Very interesting stuff. I would really encourage everyone to watch this.
Covers: Adapters, View & Layouts, Backgrounds & images, memory allocation and Drawing & invalidating.

Tuesday, March 16, 2010

Default text for an EditText? Here's a Hint



Sometimes it can be a nice idea to put default values in an EditText to let your users know what sort of information you're wanting them to enter.

What I had been doing previously was setting the .text value of the EditText to some default value, then clearing it onClick, after checking if the value was still the default, like this:

etName.setOnClickListener(new OnClickListener() {


String name = etName.getText().toString();
String origVal = getResources().getText(R.string.NameDefault).toString();

@Override
public void onClick(View v) {
if(name.equals(origVal));
{
etName.setText("");

}

}
});


Here's my String resource, stored in res/strings.xml as used above:

<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="NameDefault">Enter your name</string>
</resources>


But there is another, easier way, and it's called a Hint.

Simply by adding the below, bold attribute into my xml layout, my EditText by default contains a default string, which only exists when the EditText is empty.

It's all done for me!

.. here is my layout xml, note the android:hint line:

<EditText android:id="@+id/etName"
android:hint="@string/NameDefault"
android:minWidth="100dip"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</EditText>



Saturday, March 6, 2010

Handling Button clicks in a ListView Row


Lets say you have a spinner widget, like the one we created in our 'colours' example, and you wanted to put a button on each row of your spinner for your users to click (everyone loves clicking buttons, right?).

You might have a layout a bit like this simple one below:

<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">

 <TextView android:text="this is a row"
     android:id="@+id/tvViewRow"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content">
 </TextView>
 <Button android:text="Click me!"
     android:id="@+id/BtnToClick"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:onClick="myClickHandler">
 </Button>

</LinearLayout>

.. Containing just a textView and a Button View.

A listView with textual, non-clickable views in it responds to Click events via the OnItemClickListener event.

But once you put a button in the ListView, this event no longer fires.

So how do you capture the button's click event, and find what row in your ListView a clicked button is located in?

You may have noticed this android:onClick="myClickHandler"> in our layout above..
What this does is tie every click of every instance of that button, in every row of our ListView to one single handler, located in the code of our ListActivity class below:

    public void myClickHandler(View v) 
    {
          
        //reset all the listView items background colours 
        //before we set the clicked one..

        ListView lvItems = getListView();
        for (int i=0; i < lvItems.getChildCount(); i++) 
        {
            lvItems.getChildAt(i).setBackgroundColor(Color.BLUE);        
        }
        
        
        //get the row the clicked button is in
        LinearLayout vwParentRow = (LinearLayout)v.getParent();
         
        TextView child = (TextView)vwParentRow.getChildAt(0);
        Button btnChild = (Button)vwParentRow.getChildAt(1);
        btnChild.setText(child.getText());
        btnChild.setText("I've been clicked!");
        
        int c = Color.CYAN;
        
        vwParentRow.setBackgroundColor(c); 
        vwParentRow.refreshDrawableState();       
    }


In this case, the View v being passed in as a parameter is our button.
We get the parent of our button, being careful to cast it as a LinearLayout (have another look at the xml if you're not sure why), and then simply set the background colour of our Layout Row.

Don't forget to call .refreshDrawableState(); on your vwParentRow or it will never redraw and you won't see your nice colour change.

.. Tada!




Update: Hi everyone, thanks for all the interest, here's a link to the full project zipped.
Updated Update: Here's another link, and another, and another.

I've also updated the above myClickHandler to loop through the other items in the ListView and reset them to a default colour, in this case blue, to make it a bit more obvious what's going on. Hope that helps.

Thursday, February 18, 2010

How to create Status Bar Notifications


A status bar notification is used to notify the user of a system event, like an sms being received or a new device being detected, without interrupting the user from whatever other task they might be doing with their phone.

The status bar area is located at the top of the screen and the user can pull this area to expand it, and show a history of notifications.





If a Notification has been setup to include an enclosed Intent, selecting that particular notification in this expanded view can fire the Intent, taking the user to an Activity screen of the related application, or do any of the many other things that Intents can do.

You can also configure the notification to alert the user with a sound, a vibration, and flashing lights on the device.

A background Service should never launch an Activity on its own in order to receive user interaction. The Service should instead create a status bar notification that will launch the Activity when selected by the user.

A status bar notification should be used for any case in which a background Service needs to alert the user about an event.


Here is a simple method that creates and displays a notification when passed a string msg :


public void displayNotification(String msg)
{
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon, msg, System.currentTimeMillis());

// The PendingIntent will launch activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, REQUEST_CODE, new Intent(this, ExpandNotification.class), 0);

notification.setLatestEventInfo(this, "Title here", ".. And here's some more details..", contentIntent);

manager.notify(NOTIFICATION_ID, notification);

}


.. Which you can call simply like this:


displayNotification("Hi, I'm a Statusbar Notification..");



.. Easy, isn't it?

Sunday, February 14, 2010

Want to display a quick message to your users? Use some Toast!



A toast is a notification view that contains a quick little message for the user. All it does is display the message, it's not interactive at all.

The toast class helps you create and show those.

When this view is shown to the user, it appears to float over the application. It will never receive focus as the user may be in the middle of typing something else. The idea is to be as unobtrusive as possible, while still showing the user the information you want them to see. Two possible examples are a volume control, and a brief message saying that your settings have been saved.

The easiest way to use this class is to call one of the static methods that constructs everything you need and returns a new Toast object.

A piece of toast is typically a simple text message, an image, or a combination of text and image.
You don't have control on the toast duration. There are only two states LENGTH_LONG and LENGTH_SHORT.

For this example we have added an image to one of the drawable folders under 'res' in our project, we refer to it simply like this:

view.setImageResource(R.drawable.flash);

Our image is actually called flash.png, note that we don't need to include the 'png' extension in our Android code, it already knows what we're talking about ;)

Here are 3 methods, demonstrating the above.

First, just show an image:

private void imageToast()
{
Toast toast = new Toast(getApplicationContext());
ImageView view = new ImageView(getApplicationContext());
view.setImageResource(R.drawable.flash);
toast.setView(view);
toast.show();
}


This method just displays a text toast:

public void textToast(String textToDisplay) {
Context context = getApplicationContext();
CharSequence text = textToDisplay;
int duration = Toast.LENGTH_SHORT;

Toast toast = Toast.makeText(context, text, duration);
toast.setGravity(Gravity.TOP|Gravity.LEFT, 50, 50);
toast.show();
}


.. And this method displays a Toast that contains both an image and text:

public void textAndImageToast(String textToDisplay)
{
Toast toast = Toast.makeText(getApplicationContext(), textToDisplay, Toast.LENGTH_LONG);
View textView = toast.getView();
LinearLayout lay = new LinearLayout(getApplicationContext());
lay.setOrientation(LinearLayout.HORIZONTAL);
ImageView view = new ImageView(getApplicationContext());
view.setImageResource(R.drawable.flash);
lay.addView(view);
lay.addView(textView);
toast.setView(lay);
toast.show();
}

You can call each of these like this:

textToast("This is a text toast");
        imageToast();

textAndImageToast("This is a text and image toast");


And here are the results:

A text Toast



A text & image Toast


this is an image Toast


Here is the same image Toast with default Gravity for better demonstration purposes


Hope that makes sense.
.. Till next time, happy coding :)


Monday, February 1, 2010

How to populate a Spinner widget from a database


Yesterday we saw how to populate a Spinner widget from an Array, and today, as promised, I'll show you how to populate a Spinner widget from a database.

This tutorial assumes that you're using the same code we used previously (link above), essentially the only differences are that we're using a different type of Adapter (a SimpleCursorAdapter this time) and populating it with the results of a query from a database table, and we're using a separate layout item to put our colour names


Here is our new layout, called db_view_row.xml:

<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">

<TextView android:text=""
android:id="@+id/tvDBViewRow"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>


put this file in your res/layout directory in your project.


Let's assume for this example that you've already populated your database table with the same list of colours that we used previously.

Here's the statement to create our table structure:


CREATE TABLE "colours" (
"_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"colourName" TEXT NOT NULL
)




In our database adapter class we have a method called fetchAllColours(), which has the responsibility (probably no surprises here) of fetching all our colours ;).


At the top of our class we declare some static variables we're going to use :


public class TestDBAdapter {

public static final String KEY_TITLE = "colourName";
public static final String KEY_ROWID = "_id";

//..rest of class continues from here..



Here is this method also from our TestDBAdapter class:

public Cursor fetchAllColours()
{
if (mDb == null)
{
this.open();
}


/* here we check if our db exists as the connection might have been closed unexpectedly... and open it if it doesn't already exist*/


String tableName = "colours";

return mDb.query(tableName, new String[] { KEY_ROWID, KEY_TITLE}, null, null, null, null, null);

}



... which returns a database Cursor to our method below..


private void fillData() {
Cursor coloursCursor;
Spinner colourSpinner = (Spinner) findViewById(R.id.my_colour_spinner);
coloursCursor = thisTestDBAdapter.fetchAllColours();

startManagingCursor(
coloursCursor);
/*Create an array to specify the fields we want to display in the list (only the 'colourName' column in this case) */

String[] from = new String[]{TestDBAdapter.KEY_TITLE};

/* and an array of the fields we want to bind those fields to (in this case just the textView 'tvDBViewRow' from our new
db_view_row.xml layout above) */

int[] to = new int[]{R.id.tvDBViewRow};

/*
Now create a simple cursor adapter.. */

SimpleCursorAdapter colourAdapter =
new SimpleCursorAdapter(this, R.layout.db_view_row,
coloursCursor, from, to);

/* and assign it to our Spinner widget */

colourSpinner.setAdapter(colourAdapter);
}





Update: Due to popular demand, here is a project that demonstrates this concept:
Spinner from Database example.


.. Let me know if you're having any access issues, it's just hosted publicly from my google docs.


I've learnt my lesson, I'm going to be including an example project with all future posts :)

Thanks for your support

This site has only been in existence for 6 weeks, I just wanted to say thankyou for visiting, wherever you are!

:)

Please feel free to post comments on anything you see, and if you have any suggestions for articles, just let me know.

Sunday, January 31, 2010

How to populate a Spinner widget from an Array

Lets say we have an Array of colours, defined in a xml file in our res folder in our Eclipse project, like below.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, droidTest1!</string>
<string name="app_name">droidTest1</string>

<string-array name="colours">
<item>Red</item>
<item>Blue</item>
<item>White</item>
<item>Yellow</item>
<item>Black</item>
<item>Green</item>
<item>Purple</item>
<item>Orange</item>
<item>Grey</item>
</string-array>
</resources>

Spinners are Android's implementation of a dropdown menu, of sorts.
How do we insert these values into a spinner widget?

First, we need to create a layout for our Spinner widget, so it has a user interface.
We could do this is code, but the more accepted method is to define our layouts for Android applications in XML files, located in our res/layout folder in our project.

<Spinner

android:id="@+id/my_colour_spinner"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:drawSelectorOnTop="true”

/>




Then we create an instance of the Spinner class,

Spinner colourSpinner = (Spinner) findViewById(R.id.my_colour_spinner);



Next we create an ArrayAdapter to wrap our xml array (Array of colours) and we put some pre-defined styles.



ArrayAdapter adapter = ArrayAdapter.createFromResource( this, R.array.colors, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);


And we set the ArrayAdapter to our instance of the Spinner class:
colourSpinner.setAdapter(adapter);


And when we run our application:

The closed Spinner Widget



.. When selected shows us out colour options.





Aaah.. Sweet Androidy Success!


Next..

Saturday, January 30, 2010

Android Adapters: an introduction


An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.

An AdapterView is a view whose children are determined by an Adapter.

Some examples of AdapterViews are ListView, GridView, Spinner and Gallery.


There are several types or sub-classes of Adapter:

ListAdapter: Extended Adapter that is the bridge between a ListView and the data that backs the list. Frequently that data comes from a Cursor, but that is not required. The ListView can display any data provided that it is wrapped in a ListAdapter.


ArrayAdapter: A ListAdapter that manages a ListView backed by an array of arbitrary objects. By default this class expects that the provided resource id references a single TextView.


CursorAdapter: Adapter that exposes data from a Cursor to a ListView widget. The Cursor must include a column named "_id" or this class will not work.


HeaderViewListAdapter: ListAdapter used when a ListView has header views. This ListAdapter wraps another one and also keeps track of the header views and their associated data objects.
This is intended as a base class; you will probably not need to use this class directly in your own code.


ResourceCursorAdapter: An easy adapter that creates views defined in an XML file. You can specify the XML file that defines the appearance of the views.


SimpleAdapter: An easy adapter to map static data to views defined in an XML file. You can specify the data backing the list as an ArrayList of Maps. Each entry in the ArrayList corresponds to one row in the list.


SimpleCursorAdapter: An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file. You can specify which columns you want, which views you want to display the columns, and the XML file that defines the appearance of these views.


SpinnerAdapter: Extended Adapter that is the bridge between a Spinner and its data. A spinner adapter allows to define two different views: one that shows the data in the spinner itself and one that shows the data in the drop down list when the spinner is pressed.


WrapperListAdapter: List adapter that wraps another list adapter. The wrapped adapter can be retrieved by calling getWrappedAdapter().

Android applications: Components and Structure


Android extends the standard views/data model, providing a new model that is suitable for equipment activated at all times.

The structure of an Android application is defined as follows:



The file AndroidManifest.xml

This defines the components of the application and their relationships. It gives the permissions to application as to what it can do with users. It can also give permission to components of the application.



The views (Class android.view.View)

The interface of a program for Android is a tree of views.



Activity (android.app.Activity class)
This is something that the user can do, translated into program. It corresponds to a screen, but can have multiple views.



Intent (android.content.Intent class)
Describes an action which must be performed.



Service (android.app.Service )
Program that operates in background.



Content Provider (android.content.ContentProvider class)
Encapsulates data and provides them commonly to several programs.



Notification (android.app.NotificationManager and android.app.Notification classes)
Class which informs the user about what is happening.

Besides components, there are also resources that can be XML files, image files as jpeg, etc. These use the android.content.Resources interface and are stored in the res directory.





Components of an Android application

Each component is included in a list stored in the manifest file AndroidManifest.xml of each application.



Activity

An activity corresponds to a screen. If an application is composed of several screens, it has an activity for each screen. Each activity is a class that extends the base class Activity. It has a graphical user interface made of views, and it responds to events. When you change screen, a new activity is launched.
It can return a value. For example, if an activity can choose something, text, image, it returns what is chosen.

The graphical interface of an activity is described by a Layout:
- Full screen.
- Float: dialogue or alert.
- None. In this case it works in background and is invisible. It is maked visible by giving it a layout.

Note that the graphical user interface is described in XML as XUL and XAML.



Intent

The intents are the goals of applications and are made effective by a new screen. An intent is made up of an action and data that are URI.

Examples of actions: MAIN, VIEW, EDIT, PICK.
If one wants to see a card about a person, an intent is defined. The action is VIEW and the data is the URI which enables access to this card.

IntentFilters describes how the action should apply.

IntentReceiver is an object that responds to external events. It can operate in the application or it can start an application.

Example of intent, view a webpage: VIEW for action and for data http://www.linkToStuff.org.



Service

A service is designed to operate independently of the screen, thus of activities. The best example is the music player that can works while moving from one screen to another.



Content Provider

Data stored by a computer program, in the form of files or SQLite databases are private and may not be used by other applications.
But Content Provider may be used to share data among several applications. The interface ContentResolver is the interface that provides data to other objects.



Notification

The class android.app.Notification defines how an event must be notified to user: displaying an icon, changing state of a led, vibration, or others. While the class android.app.NotificationManager sends the message in the form so defined.

Thursday, January 28, 2010

Inspiration: 50 Android games in one video..



*

- homerunbattle 3d
- speed forge 3d
- radiant
- flight director
- Zen Table Tennis
- tank ace 1944
- sky force
- Shoot U!
- Armageddon Squadron
- Light Racer 3D
- gang wars
- Wave Blazer
- death ride
- head to head racing
- avatar
- Farm Frenzy
- light racer
- Family Guy Uncensored
- super boom boom
- toonwarz
- air hockey
- meteor
- what the doodle!?
- Raging Thunder
- the settlers
- lightup
- the game of life
- military madness
- bebbled
- jump santa jump
- diner dash
- brain challenge
- assassins creed
- space physics
- million dollar poker
- derek jeter 2009
- armored strike
- robo defense
- guitar hero
- air attack
- wpt texas hold'em
- de Blob
- papastacker
- spades
- spore
- tennis slam
- Iron Sight
- TETRIS
- tower bloxx
- mechanics touch
- TightRope Hero
- flying aces

Game Developers Conference 2010 organizers have announced that they are working together with Google "to celebrate and inspire the mobile and independent game development communities" by offering free Nexus One and Verizon Droid by Motorola phones to select attendees.

The newly announced offer, part of Google's outreach into the mobile phone space as it expands use of its Android operating system, is open to qualifying developers who register to attend GDC 2010 by February 4th, 2010.

The Game Developers Conference, as the world’s largest professional-only game developer event, has been at the center of the industry’s discussions on these topics.

It serves as home to major Summits such as the GDC Mobile/Handheld Summit and the Independent Games Summit, as well as the IGF Mobile competition to award handheld game innovation.

In recent years, the smartphone has become one of the most widespread and widely-used game platforms, and has proven particularly suited to independent developers experimenting with new and unusual gameplay.

As an official statement on the tie-in notes: "This makes conference attendees great potential developers of new content for phones using the Android operating system." Alongside the announcement, Google's Eric Chu has posted about Android's GDC 2010 presence on the official Android Developers weblog.

"At the GDC, we are constantly looking for ways to help the game development community learn and thrive. The mobile and independent game spaces having been providing so many of those opportunities for years now," said Meggan Scavio, event director of the Game Developers Conference. "We are so appreciative that we can better reach those goals by actually putting a new opportunity – Android-powered devices – into the hands of our attendees."

Early Bird rates for GDC 2010 end February 4. For more information about the 2010 Game Developers Conference, including the eight summits and the Android phone promotion, please visit the official Game Developers Conference website.

Sunday, January 24, 2010

Creating multiple sqlite database tables in Android



Most of the Android database examples you will find on the web will usually contain only one table to demonstrate the basic database concepts.

That's great, the only problem with this is that most non-trivial database implementations will contain more than one table.


The standard database creation string for a single table will probably look a lot like the below:


private static final String CREATE_TABLE_1 =
" create table " + table1 +
" (_id integer primary key autoincrement," +
" title text not null, body text not null);";



Which is called in your DB Adapter class like this:


@Override
public void onCreate(SQLiteDatabase db) {

db.execSQL(CREATE_TABLE_1);
}


So what to do if you want to create more than one table?
You may do the below.. but will it work?
Note that this is one big string containing three separate create statements...


private static final String DATABASE_CREATE_MULTIPLE_TABLES =
" create table " + ITEMS_TABLE +
" (_id integer primary key autoincrement," +
" title text not null)" +

" create table " + TAGS_TABLE +
" (_id integer primary key autoincrement," +
" tagName text not null)" +

" create table " + LOCATIONS_TABLE +
" (_id integer primary key autoincrement," +
" locationName text not null, gpsCoOrds text);"
;


And then you try calling them in your DB Adapter class like so:


@Override
public void onCreate(SQLiteDatabase db) {

db.execSQL(DATABASE_CREATE_MULTIPLE_TABLES);
}


So you're trying to create the three tables in one call to db.execSQL.


This appears to compile and run successfully, you can even read and write to the FIRST table that is created, but..
..when you try to read or write to any other table you will see the dreaded

'Sorry! The application Kdkddfblah (process test.Kdkddfblah) has stopped unexpectedly. Please try again'

..error message.


Uh-oh.

If you debug your application, you might see references to syntax errors 'near create', and possible a reference that the table doesn't exist.

Hmm... What went wrong?

The answer is that sqlite, and therefore the db.exec method, only lets you execute one sql command at a time. We were trying to run three sql statements in one go in db.execSQL(DATABASE_CREATE_MULTIPLE_TABLES);.

So what you need to do to fix this is move each of the above table create statements into their own strings, like this (Note that this now creates three seperate strings, unlike above):


private static final String CREATE_TABLE_1 =
" create table " + table1 +
" (_id integer primary key autoincrement," +
" title text not null, body text not null);";

private static final String CREATE_TABLE_2 =
" create table " + TAGS_TABLE +
" (_id integer primary key autoincrement," +
" tagName text not null)";

private static final String CREATE_TABLE_3 =
" create table " + LOCATIONS_TABLE +
" (_id integer primary key autoincrement," +
" locationName text not null, gpsCoOrds text);";


.. and then use these strings in your onCreate method like below, this then works.


@Override
public void onCreate(SQLiteDatabase db) {

db.execSQL(CREATE_TABLE_1);
db.execSQL(CREATE_TABLE_2);
db.execSQL(CREATE_TABLE_3);
}


If you find this doesn't work for you, try dropping all the tables in your database and try again, or give the database a different name, or different version number. The SQLiteOpenHelper seems to have some troubles registering that the database is to be changed. It finds a db with the same name and version number, goes 'meh' and doesn't look to see if the structure is different at all.

You can also pull the sqlite db file right off your device (or emulator) by going into the DDMS perspective in Eclipse (Window menu\ Open perspective \ Other \ DDMS), navigating to the database file which will probably be at \data\data\*Your Application Name*\databases.

There's a 'pull file' button on the top left as seen highlighted below:



.. You can then open the DB in your favourite sqlite manager (I like Sqliteman) and play around. Can can also of course, push the file back to the device if you wish.




Monday, January 18, 2010

Psst..Remember that your layout files must have lowercase names..

Remember that your layout files must have lowercase names, or they won't show up in your autoComplete list of options after 'R.layout' in Eclipse when you try this :

setContentView(R.layout.test_db);


The file won't actually show up as having any errors in your package explorer (on the right by default in the IDE), but if you look down in the console (by default down the bottom), you'll see this:

Invalid file name: must contain only [a-z0-9_.]


You might see an error on your project name, but with all the folders and files it can be hard to track down the cause.

When you try to run your application you will see:

'Your project contains error(s) please fix them before running your application'


.. and it won't be happy until you delete the offending file, even if you're not actively referencing it in your code.



Hope that helps.. Happy coding!

Sunday, January 17, 2010

Errors trying to run ADB (Android Debug Bridge)?




The Android Debug Bridge (adb) is a tool lets you manage the state of an emulator instance or Android-powered device.

I was trying to run it for the first time on my ubuntu 9.10 box and I kept getting this error:


desktop:~/dev/Android/android-sdk-linux/tools$ adb
No command 'adb' found, did you mean:
Command 'cdb' from package 'tinycdb' (main)
Command 'gdb' from package 'gdb' (main)
Command 'aub' from package 'aub' (universe)
Command 'dab' from package 'bsdgames' (universe)
Command 'mdb' from package 'mono-debugger' (universe)
Command 'arb' from package 'arb' (multiverse)
Command 'tdb' from package 'tads2-dev' (multiverse)
Command 'pdb' from package 'python' (main)
Command 'jdb' from package 'openjdk-6-jdk' (main)
Command 'jdb' from package 'sun-java6-jdk' (multiverse)
Command 'ab' from package 'apache2-utils' (main)
adb: command not found


What was I doing wrong?

A quick google search shows me the error of my ways.. I haven't added my Android SDK tools directory to my system path!


It should go something like this...

open a terminal window and type:

$ echo $PATH
---(should return the directories associated with $PATH)

$ export PATH=$PATH:/home/YOUR-USERNAME/sdk/tools
---(replace with path to your tools directory, you may need to add 'sudo' to the beginning of this cmd)
Update: later versions of the SDK have ADB moved to the platform-tools directory, so adjust the above accordingly.


$ echo $PATH
---(you should now see your tools directory added to the end of the $PATH variable)

$ adb devices
---(now adb should do something, if nothing else at least error, no devices)


And now I get:

List of devices attached
emulator-5554 device


Sweet Success!

p.s. Adding to the system path in Windows is along the lines of :
  1. right-click '(My) Computer'
  2. Select 'Properties'
  3. Go to 'Advanced' or whatever tab you find 'Environment Variables'
  4. Select 'Path' then 'Edit' and add your new path in.
Update: if you are using 64-bit linux you may need to also install the ia32-libs package like so:

sudo apt-get install ia32-libs