Ch3 Listings
satya - Sunday, April 12, 2009 10:53:59 AM
Listing3-1.xml: Simple String Resources
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">hello</string>
<string name="app_name">hello appname</string>
</resources>
satya - Sunday, April 12, 2009 10:57:03 AM
Listing3-2: A simple 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"
>
<TextView android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button android:id="@+id/b1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@+string/hello"
/>
</LinearLayout>
satya - Sunday, April 12, 2009 10:58:47 AM
Listing3-3: Defining color resources
<resources>
<color name="red">#f00</color>
<color name="blue">#0000ff</color>
<color name="green">#f0f0</color>
<color name="main_back_ground_color">#ffffff00</color>
</resources>
satya - Sunday, April 12, 2009 11:02:21 AM
Listing3-4: Color Resources in Java code
int mainBackGroundColor
= activity.getResources.getColor(R.color.main_back_ground_color);
satya - Sunday, April 12, 2009 11:03:26 AM
Listing3-5: Using colors in view definitions
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@color/ red"
android:text="Sample Text to Show Red Color"/>
satya - Sunday, April 12, 2009 11:05:32 AM
Listing 3-6. XML Syntax for Defining String Resources
<resources>
<string name="simple_string">simple string</string>
<string name="quoted_string">"quoted'string"</string>
<string name="double_quoted_string">\"double quotes\"</string>
<string name="java_format_string">
hello %2$s java format string. %1$s again
</string>
<string name="tagged_string">
Hello <b><i>Slanted Android</i></b>, You are bold.
</string>
</resources>
satya - Sunday, April 12, 2009 11:15:31 AM
Listing 3-7. Using String Resources in Java Code
//Read a simple string and set it in a text view
String simpleString = activity.getString(R.string.simple_string);
textView.setText(simpleString);
//Read a quoted string and set it in a text view
String quotedString = activity.getString(R.string.quoted_string);
textView.setText(quotedString);
//Read a double quoted string and set it in a text view
String doubleQuotedString = activity.getString(R.string.double_quoted_string);
textView.setText(doubleQuotedString);
//Read a Java format string
String javaFormatString = activity.getString(R.string.java_format_string);
//Convert the formatted string by passing in arguments
String substitutedString = String.format(javaFormatString, "Hello" , "Android");
//set the output in a text view
textView.setText(substitutedString);
//Read an html string from the resource and set it in a text view
String htmlTaggedString = activity.getString(R.string.tagged_string);
//Convert it to a text span so that it can be set in a text view
//android.text.Html class allows painting of "html" strings
//This is strictly an Android class and does not support all html tags
Spanned textSpan = android.text.Html.fromHtml(htmlTaggedString);
//Set it in a text view
textView.setText(textSpan);
satya - Sunday, April 12, 2009 11:16:26 AM
Listing 3-8. Using String Resources in XML
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAlign="center"
android:text="@string/tagged_string"/>
satya - Sunday, April 12, 2009 11:17:11 AM
Listing 3-9. XML Syntax for Defining Dimension Resources
<resources>
<dimen name="mysize_in_pixels">1px</dimen>
<dimen name="mysize_in_dp">5dp</dimen>
<dimen name="medium_size">100sp</dimen>
</resources>
satya - Sunday, April 12, 2009 11:18:01 AM
Listing 3-10. Using Dimension Resources in Java Code
float dimen =
activity.getResources().getDimension(R.dimen.mysize_in_pixels);
satya - Sunday, April 12, 2009 11:18:54 AM
Listing 3-11. Using Dimension Resources in XML
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/medium_size"/>
satya - Sunday, April 12, 2009 11:19:46 AM
Listing 3-12. Using Image Resources in XML
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Dial"
android:background="@drawable/sample_image"
/>
satya - Sunday, April 12, 2009 11:21:47 AM
Listing 3-13. Using Image Resources in Java
//Call getDrawable to get the image
BitmapDrawable d =
activity.getResources().getDrawable(R.drawable.sample_image);
//You can use the drawable then to set the background
button.setBackgroundDrawable(d);
//or you can set the background directly from the Resource Id
button.setBackgroundResource(R.drawable.icon);
satya - Sunday, April 12, 2009 11:23:07 AM
Listing 3-14. XML Syntax for Defining Color-Drawable Resources
<resources>
<drawable name="red_rectangle">#f00</drawable>
<drawable name="blue_rectangle">#0000ff</drawable>
<drawable name="green_rectangle">#f0f0</drawable>
</resources>
satya - Sunday, April 12, 2009 11:25:19 AM
Listing 3-15. Using Color-Drawable Resources in Java Code
// Get a drawable
ColorDrawble redDrawable =
(ColorDrawable)
activity.getResources().getDrawable(R.drawable.red_rectnagle);
//Set it as a background to a text view
textView.setBackground(redDrawable);
satya - Sunday, April 12, 2009 11:27:35 AM
Listing 3-16. Using Color-Drawable Resources in XML Code
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAlign="center"
android:background="@drawable/red_rectangle"/>
satya - Sunday, April 12, 2009 11:30:04 AM
Listing 3-17. Defining a Rounded Rectangle
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f0600000"/>
<stroke android:width="3dp" color="#ffff8080"/>
<corners android:radius="13dp" />
<padding android:left="10dp" android:top="10dp"
android:right="10dp" android:bottom="10dp" />
</shape>
satya - Sunday, April 12, 2009 11:54:56 AM
Listing 3-18. Using XmlPullParser
private String getEventsFromAnXMLFile(Activity activity)
throws XmlPullParserException, IOException
{
StringBuffer sb = new StringBuffer();
Resources res = activity.getResources();
XmlResourceParser xpp = res.getXml(R.xml.test);
xpp.next();
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT)
{
if(eventType == XmlPullParser.START_DOCUMENT)
{
sb.append("******Start document");
}
else if(eventType == XmlPullParser.START_TAG)
{
sb.append("\nStart tag "+xpp.getName());
}
else if(eventType == XmlPullParser.END_TAG)
{
sb.append("\nEnd tag "+xpp.getName());
}
else if(eventType == XmlPullParser.TEXT)
{
sb.append("\nText "+xpp.getText());
}
eventType = xpp.next();
}//eof-while
sb.append("\n******End document");
return sb.toString();
}//eof-function
satya - Sunday, April 12, 2009 11:57:06 AM
Listing 3-19. Reading a Raw Resource
String getStringFromRawFile(Activity activity)
{
Resources r = activity.getResources();
InputStream is = r.openRawResource(R.raw.test);
String myText = convertStreamToString(is);
is.close();
return myText;
}
String convertStreamToString(InputStream is)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = is.read();
while (i != -1)
{
baos.write(i);
i = baos.read();
}
return baos.toString();
}
satya - Sunday, April 12, 2009 12:00:34 PM
Listing 3-20. Retrieving a Cursor from a Content Provider
// An array specifying which columns to return.
string[] projection = new string[] {
People._ID,
People.NAME,
People.NUMBER,
};
// Get the base URI for People table in Contacts Content Provider.
// ie. content://contacts/people/
Uri mContactsUri = People.CONTENT_URI;
// Best way to retrieve a query; returns a managed query.
Cursor managedCursor = managedQuery( mContactsUri,
projection, //Which columns to return.
null, // WHERE clause
People.NAME + " ASC"); // Order-by clause.
satya - Sunday, April 12, 2009 12:02:05 PM
Listing 3-21. Navigating Through a Cursor Using a while Loop
if (cur.moveToFirst() == false)
{
//no rows empty cursor
return;
}
//The cursor is already pointing to the first row
//let's access a few columns
int nameColumnIndex = cur.getColumnIndex(People.NAME);
String name = cur.getString(nameColumnIndex);
//let's now see how we can loop through a cursor
while(cur.moveToNext())
{
//cursor moved successfully
//access fields
}
satya - Sunday, April 12, 2009 12:08:12 PM
Listing 3-22. Navigating Through a Cursor Using a for Loop
for(cur.moveToFirst();!cur.isAfterLast();cur.moveToNext())
{
int nameColumn = cur.getColumnIndex(People.NAME);
int phoneColumn = cur.getColumnIndex(People.NUMBER);
String name = cur.getString(nameColumn);
String phoneNumber = cur.getString(phoneColumn);
}
satya - Sunday, April 12, 2009 12:09:51 PM
Listing 3-23. Passing SQL WHERE Clauses Through the URI
Activity someActivity;
//..initialize someActivity
String noteUri = "content://com.google.provider.NotePad/notes/23";
Cursor managedCursor = someActivity.managedQuery( noteUri,
projection, //Which columns to return.
null, // WHERE clause
null); // Order-by clause.
satya - Sunday, April 12, 2009 12:13:07 PM
Listing 3-24. Defining Metadata for Your Database: The BookProviderMetaData Class
public class BookProviderMetaData
{
public static final String AUTHORITY = "com.androidbook.provider.BookProvider";
public static final String DATABASE_NAME = "book.db";
public static final int DATABASE_VERSION = 1;
public static final String BOOKS_TABLE_NAME = "books";
private BookProviderMetaData() {}
//inner class describing BookTable
public static final class BookTableMetaData implements BaseColumns
{
private BookTableMetaData() {}
public static final String TABLE_NAME = "books";
//uri and MIME type definitions
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/books");
public static final String CONTENT_TYPE =
"vnd.android.cursor.dir/vnd.androidbook.book";
public static final String CONTENT_ITEM_TYPE =
"vnd.android.cursor.item/vnd.androidbook.book";
public static final String DEFAULT_SORT_ORDER = "modified DESC";
//Additional Columns start here.
//string type
public static final String BOOK_NAME = "name";
//string type
public static final String BOOK_ISBN = "isbn";
//string type
public static final String BOOK_AUTHOR = "author";
//Integer from System.currentTimeMillis()
public static final String CREATED_DATE = "created";
//Integer from System.currentTimeMillis()
public static final String MODIFIED_DATE = "modified";
}
}
satya - Sunday, April 12, 2009 12:19:33 PM
Listing 3-25. Implementing the BookProvider Content Provider
public class BookProvider extends ContentProvider
{
//Create a Projection Map for Columns
//Projection maps are similar to "as" construct in an sql
//statement whereby you can rename the
//columns.
private static HashMap<String, String> sBooksProjectionMap;
static
{
sBooksProjectionMap = new HashMap<String, String>();
sBooksProjectionMap.put(BookTableMetaData._ID, BookTableMetaData._ID);
//name, isbn, author
sBooksProjectionMap.put(BookTableMetaData.BOOK_NAME
, BookTableMetaData.BOOK_NAME);
sBooksProjectionMap.put(BookTableMetaData.BOOK_ISBN
, BookTableMetaData.BOOK_ISBN);
sBooksProjectionMap.put(BookTableMetaData.BOOK_AUTHOR
, BookTableMetaData.BOOK_AUTHOR);
//created date, modified date
sBooksProjectionMap.put(BookTableMetaData.CREATED_DATE
, BookTableMetaData.CREATED_DATE);
sBooksProjectionMap.put(BookTableMetaData.MODIFIED_DATE
, BookTableMetaData.MODIFIED_DATE);
}
//Provide a mechanism to identify all the incoming uri patterns.
private static final UriMatcher sUriMatcher;
private static final int INCOMING_BOOK_COLLECTION_URI_INDICATOR = 1;
private static final int INCOMING_SINGLE_BOOK_URI_INDICATOR = 2;
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(BookProviderMetaData.AUTHORITY
, "books"
, INCOMING_BOOK_COLLECTION_URI_INDICATOR);
sUriMatcher.addURI(BookProviderMetaData.AUTHORITY
, "books/#",
INCOMING_SINGLE_BOOK_URI_INDICATOR);
}
// Deal with OnCreate call back
private DatabaseHelper mOpenHelper;
@Override
public boolean onCreate() {
mOpenHelper = new DatabaseHelper(getContext());
return true;
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, BookProviderMetaData.DATABASE_NAME, null
, BookProviderMetaData.DATABASE_VERSION);
}
//Create the database
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE " + BookTableMetaData.TABLE_NAME + " ("
+ BookProviderMetaData.BookTableMetaData._ID
+ " INTEGER PRIMARY KEY,"
+ BookTableMetaData.BOOK_NAME + " TEXT,"
+ BookTableMetaData.BOOK_ISBN + " TEXT,"
+ BookTableMetaData.BOOK_AUTHOR + " TEXT,"
+ BookTableMetaData.CREATED_DATE + " INTEGER,"
+ BookTableMetaData.MODIFIED_DATE + " INTEGER"
+ ");");
}
//Deal with version changes
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + BookTableMetaData.TABLE_NAME);
onCreate(db);
}
}
....other code
satya - Sunday, April 12, 2009 12:21:21 PM
Listing 3-26. The getType() Method Implementation
@Override
public String getType(Uri uri)
{
switch (sUriMatcher.match(uri))
{
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
return BookTableMetaData.CONTENT_TYPE;
case INCOMING_SINGLE_BOOK_URI_INDICATOR:
return BookTableMetaData.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
satya - Sunday, April 12, 2009 12:26:45 PM
Listing 3-27. The query() Method Implementation
@Override
public Cursor query(Uri uri, String[] projection, String selection
, String[] selectionArgs, String sortOrder)
{
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
switch (sUriMatcher.match(uri))
{
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
qb.setTables(BookTableMetaData.TABLE_NAME);
qb.setProjectionMap(sBooksProjectionMap);
break;
case INCOMING_SINGLE_BOOK_URI_INDICATOR:
qb.setTables(BookTableMetaData.TABLE_NAME);
qb.setProjectionMap(sBooksProjectionMap);
qb.appendWhere(BookTableMetaData._ID + "="
+ uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
// If no sort order is specified use the default
String orderBy;
if (TextUtils.isEmpty(sortOrder)) {
orderBy = BookTableMetaData.DEFAULT_SORT_ORDER;
} else {
orderBy = sortOrder;
}
// Get the database and run the query
SQLiteDatabase db =
mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection,
selectionArgs, null, null, orderBy);
int i = c.getCount();
// Tell the cursor what uri to watch,
// so it knows when its source data changes
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
satya - Sunday, April 12, 2009 12:29:04 PM
Listing 3-28. The insert() Method Implementation
@Override
public Uri insert(Uri uri, ContentValues values)
{
// Validate the requested uri
if (sUriMatcher.match(uri) != INCOMING_BOOK_COLLECTION_URI_INDICATOR) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
Long now = Long.valueOf(System.currentTimeMillis());
//validate input fields
// Make sure that the fields are all set
if (values.containsKey(BookTableMetaData.CREATED_DATE) == false) {
values.put(BookTableMetaData.CREATED_DATE, now);
}
if (values.containsKey(BookTableMetaData.MODIFIED_DATE) == false) {
values.put(BookTableMetaData.MODIFIED_DATE, now);
}
if (values.containsKey(BookTableMetaData.BOOK_NAME) == false) {
throw new SQLException(
"Failed to insert row because Book Name is needed " + uri);
}
if (values.containsKey(BookTableMetaData.BOOK_ISBN) == false) {
values.put(BookTableMetaData.BOOK_ISBN, "Unknown ISBN");
}
if (values.containsKey(BookTableMetaData.BOOK_AUTHOR) == false) {
values.put(BookTableMetaData.BOOK_ISBN, "Unknown Author");
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long rowId = db.insert(BookTableMetaData.TABLE_NAME
, BookTableMetaData.BOOK_NAME, values);
if (rowId > 0) {
Uri insertedBookUri = ContentUris.withAppendedId(
BookTableMetaData.CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(insertedBookUri, null);
return insertedBookUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
satya - Wednesday, April 15, 2009 9:20:26 PM
Listing 3-29. The update() Method Implementation
@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs)
{
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri))
{
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
count = db.update(BookTableMetaData.TABLE_NAME,
values, where, whereArgs);
break;
case INCOMING_SINGLE_BOOK_URI_INDICATOR:
String rowId = uri.getPathSegments().get(1);
count = db.update(BookTableMetaData.TABLE_NAME
, values
, BookTableMetaData._ID + "=" + rowId
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : "")
, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
satya - Wednesday, April 15, 2009 9:24:35 PM
Listing 3-30. The delete() Method Implementation
@Override
public int delete(Uri uri, String where, String[] whereArgs)
{
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri))
{
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
count = db.delete(BookTableMetaData.TABLE_NAME, where, whereArgs);
break;
case INCOMING_SINGLE_BOOK_URI_INDICATOR:
String rowId = uri.getPathSegments().get(1);
count = db.delete(BookTableMetaData.TABLE_NAME
, BookTableMetaData._ID + "=" + rowId
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : "")
, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
satya - Wednesday, April 15, 2009 9:27:01 PM
Listing 3-31. Registering URI Patterns with UriMatcher
private static final UriMatcher sUriMatcher;
//define ids for each uri type
private static final int INCOMING_BOOK_COLLECTION_URI_INDICATOR = 1;
private static final int INCOMING_SINGLE_BOOK_URI_INDICATOR = 2;
static
{
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//Register pattern for the books
sUriMatcher.addURI(BookProviderMetaData.AUTHORITY
, "books"
, INCOMING_BOOK_COLLECTION_URI_INDICATOR);
//Register pattern for a single book
sUriMatcher.addURI(BookProviderMetaData.AUTHORITY
, "books/#",
INCOMING_SINGLE_BOOK_URI_INDICATOR);
}
satya - Wednesday, April 15, 2009 9:30:21 PM
Listing 3-32. Exercising Android?s Prefabricated Applications
public class IntentsUtils
{
public static void invokeWebBrowser(Activity activity)
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));
activity.startActivity(intent);
}
public static void invokeWebSearch(Activity activity)
{
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.setData(Uri.parse("http://www.google.com"));
activity.startActivity(intent);
}
public static void dial(Activity activity)
{
Intent intent = new Intent(Intent.ACTION_DIAL);
activity.startActivity(intent);
}
public static void call(Activity activity)
{
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:555-555-5555"));
activity.startActivity(intent);
}
public static void showMapAtLatLong(Activity activity)
{
Intent intent = new Intent(Intent.ACTION_VIEW);
//geo:lat,long?z=zoomlevel&q=question-string
intent.setData(Uri.parse("geo:0,0?z=4&q=business+near+city"));
activity.startActivity(intent);
}
public static void tryOneOfThese(Activity activity)
{
IntentsUtils.call(activity);
}
}
satya - Wednesday, April 15, 2009 9:33:57 PM
Listing 3-33. A Test Harness to Create a Simple Menu
public class HelloWorld extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Hello, Android. Say hello");
setContentView(tv);
registerMenu(this.getTextView());
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
int base=Menu.FIRST; // value is 1
MenuItem item1 = menu.add(base,base,base,"Test");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == 1)
{
IntentUtils.tryOneOfThese(this);
}
else
{
return super.onOptionsItemSelected(item);
}
return true;
}
}
satya - Wednesday, April 15, 2009 9:42:44 PM
Listing 3-34. Returning Data After Invoking an Action
public static void invokePick(Activity activity)
{
Intent pickIntent = new Intent(Intent.ACTION_PICK);
int requestCode = 1;
pickIntent.setData(Uri.parse(
"content://com.google.provider.NotePad/notes"));
activity.startActivityForResult(pickIntent, requestCode);
}
protected void onActivityResult(int requestCode
,int resultCode
,Intent outputIntent)
{
super.onActivityResult(requestCode, resultCode, outputIntent);
parseResult(this, requestCode, resultCode, outputIntent);
}
public static void parseResult(Activity activity
, int requestCode
, int resultCode
, Intent outputIntent)
{
if (requestCode != 1)
{
Log.d("Test", "Some one else called this. not us");
return;
}
if (resultCode != Activity.RESULT_OK)
{
Log.d("Result code is not ok:" + resultCode);
return;
}
Log.d("Test", "Result code is ok:" + resultCode);
Uri selectedUri = outputIntent.getData();
Log.d("Test", "The output uri:" + selectedUri.toString());
//Proceed to display the note
outputIntent.setAction(Intent.VIEW);
startActivity(outputIntent);
}