Building a Mobile Employee Directory – Step 5: Create a ContentProvider to access the database.

| July 21, 2013 | 1 Comment

Continuing with the mobile employee directory example, I’ve added a ContentProvider to access the database.

MainActivity.java

package com.himebaugh.employeedirectory;

import java.util.List;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.Menu;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;

//	GOAL: Build a native android Mobile Employee Directory 

//	** The result is similar to the sample with Flex and Flash Builder 
//	see http://www.adobe.com/devnet/flex/articles/employee-directory-android-flex.html

//	PURPOSE: Learning how to build an Android App.

//	Step 5: Create a ContentProvider to access the database.
//			1) Create EmployeeProvider 
//			2) Modify LoadEmployeesTask To implement the new ContentProvider (MainActivity)
//			3) Remove getAllEmployeesCursor() method from EmployeeDatabase

public class MainActivity extends ListActivity  {

	public List<Employee> employees = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

        // Parse xml data in a non-ui thread
        new LoadEmployeesTask().execute();
	}

	private class LoadEmployeesTask extends AsyncTask<String, Void, Cursor> {

		@Override
		protected Cursor doInBackground(String... args) {

			// EmployeeDatabase employeeDatabase = new EmployeeDatabase(getApplicationContext());
			// Cursor cursor = employeeDatabase.getAllEmployeesCursor();

			// To implement the ContentProvider
			// Replace the 2 lines above with the lines below 
			// .... and remember to modify AndroidManifest.xml
			Uri uri = EmployeeProvider.CONTENT_URI;
			String[] projection = { EmployeeDatabase.COLUMN_ID, EmployeeDatabase.COLUMN_FIRSTNAME, EmployeeDatabase.COLUMN_LASTNAME, EmployeeDatabase.COLUMN_TITLE, EmployeeDatabase.COLUMN_DEPARTMENT,
					EmployeeDatabase.COLUMN_CITY, EmployeeDatabase.COLUMN_OFFICE_PHONE, EmployeeDatabase.COLUMN_MOBILE_PHONE, EmployeeDatabase.COLUMN_EMAIL, EmployeeDatabase.COLUMN_PICTURE };
			String selection = null;
			String[] selectionArgs = null;
			String sortOrder = EmployeeDatabase.COLUMN_LASTNAME + " COLLATE LOCALIZED ASC";

			Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);						

			return cursor;
		}

		@Override
		protected void onPostExecute(Cursor cursor) {

			String[] dataColumns = { 
					EmployeeDatabase.COLUMN_FIRSTNAME, 
					EmployeeDatabase.COLUMN_TITLE, 
					EmployeeDatabase.COLUMN_DEPARTMENT, 
					EmployeeDatabase.COLUMN_CITY, 
					EmployeeDatabase.COLUMN_OFFICE_PHONE, 
					EmployeeDatabase.COLUMN_MOBILE_PHONE, 
					EmployeeDatabase.COLUMN_EMAIL, 
					EmployeeDatabase.COLUMN_PICTURE
					};
			int[] viewIDs = { 
					R.id.list_item_name, 
					R.id.list_item_title, 
					R.id.list_item_department, 
					R.id.list_item_city, 
					R.id.list_item_office_phone, 
					R.id.list_item_mobile_phone, 
					R.id.list_item_email, 
					R.id.list_item_picture 
					};

			SimpleCursorAdapter records = new SimpleCursorAdapter(getBaseContext(), R.layout.list_item, cursor, dataColumns, viewIDs, 0);
			setListAdapter(records);
		}

	}

	@Override
	protected void onListItemClick(ListView l, View view, int position, long id) {

		// get values from selected ListItem
		String empID = ((TextView) view.findViewById(R.id.list_item_emp_id)).getText().toString();
		String name = ((TextView) view.findViewById(R.id.list_item_name)).getText().toString();
		String title = ((TextView) view.findViewById(R.id.list_item_title)).getText().toString();
		String department = ((TextView) view.findViewById(R.id.list_item_department)).getText().toString();
		String city = ((TextView) view.findViewById(R.id.list_item_city)).getText().toString();
		String officePhone = ((TextView) view.findViewById(R.id.list_item_office_phone)).getText().toString();
		String mobilePhone = ((TextView) view.findViewById(R.id.list_item_mobile_phone)).getText().toString();
		String email = ((TextView) view.findViewById(R.id.list_item_email)).getText().toString();
		String picture = ((TextView) view.findViewById(R.id.list_item_picture)).getText().toString();

		// Start new intent
		Intent intent = new Intent(getApplicationContext(), DetailActivity.class);
		intent.putExtra("empID", empID);
		intent.putExtra("name", name);
		intent.putExtra("title", title);
		intent.putExtra("department", department);
		intent.putExtra("city", city);
		intent.putExtra("officePhone", officePhone);
		intent.putExtra("mobilePhone", mobilePhone);
		intent.putExtra("email", email);
		intent.putExtra("picture", picture);
		startActivity(intent);

//		Uri details = Uri.withAppendedPath(EmployeeProvider.CONTENT_URI, "" + id);
//		Intent detailsIntent = new Intent(Intent.ACTION_VIEW, details);
//		startActivity(detailsIntent);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

EmployeeProvider.java

package com.himebaugh.employeedirectory;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;

public class EmployeeProvider extends ContentProvider {

	private EmployeeDatabase mEmployeeDatabase;

	// Uri matcher to decode incoming URIs.
	private final UriMatcher mUriMatcher;

	private static final String AUTHORITY = "com.himebaugh.employeedirectory.EmployeeProvider";

	// content mime types
	public static final String BASE_DATA_NAME = "employees";
	public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.himebaugh.search." + BASE_DATA_NAME;
	public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.himebaugh.search." + BASE_DATA_NAME;

	// common URIs
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_DATA_NAME);

	// matcher
	private static final int EMPLOYEES = 1; // The incoming URI matches the main table URI pattern
	private static final int EMPLOYEE_ID = 2; // The incoming URI matches the main table row ID URI pattern

	public EmployeeProvider() {
		// Create and initialize URI matcher.
		mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		mUriMatcher.addURI(AUTHORITY, EmployeeDatabase.TABLE_EMPLOYEES, EMPLOYEES);
		mUriMatcher.addURI(AUTHORITY, EmployeeDatabase.TABLE_EMPLOYEES + "/#", EMPLOYEE_ID);
	}

	@Override
	public boolean onCreate() {
		mEmployeeDatabase = new EmployeeDatabase(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		queryBuilder.setTables(EmployeeDatabase.TABLE_EMPLOYEES);

		switch (mUriMatcher.match(uri)) {
		case EMPLOYEES:
			// no filter
			break;
		case EMPLOYEE_ID:
			queryBuilder.appendWhere(EmployeeDatabase.COLUMN_ID + "=" + uri.getLastPathSegment());
			break;
		default:
			throw new IllegalArgumentException("Unknown URI");
		}

		Cursor cursor = queryBuilder.query(mEmployeeDatabase.getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder);
		cursor.setNotificationUri(getContext().getContentResolver(), uri);
		return cursor;
	}

	@Override
	public String getType(Uri uri) {
		switch (mUriMatcher.match(uri)) {
		case EMPLOYEES:
			return CONTENT_TYPE;
		case EMPLOYEE_ID:
			return CONTENT_ITEM_TYPE;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		return null;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		return 0;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
		return 0;
	}

}

EmployeeDatabase.java

package com.himebaugh.employeedirectory;

import java.util.ArrayList;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class EmployeeDatabase extends SQLiteOpenHelper {

	private Context context;
	ArrayList<Employee> employeeList = new ArrayList<Employee>();

	private static final int DATABASE_VERSION = 1;
	private static final String DATABASE_NAME = "employee_directory";
	public static final String TABLE_EMPLOYEES = "employees";
	public static final String COLUMN_ID = "_id";
	public static final String COLUMN_FIRSTNAME = "first_name";
	public static final String COLUMN_LASTNAME = "last_name";
	public static final String COLUMN_TITLE = "title";
	public static final String COLUMN_DEPARTMENT = "department";
	public static final String COLUMN_CITY = "city";
	public static final String COLUMN_OFFICE_PHONE = "office_phone";
	public static final String COLUMN_MOBILE_PHONE = "mobile_phone";
	public static final String COLUMN_EMAIL = "email";
	public static final String COLUMN_PICTURE = "picture";

	private static final String CREATE_TABLE_EMPLOYEES = "CREATE TABLE " + TABLE_EMPLOYEES + " (" 
		+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
		+ COLUMN_FIRSTNAME + " TEXT NOT NULL, "
		+ COLUMN_LASTNAME + " TEXT NOT NULL, " 
		+ COLUMN_TITLE + " TEXT NOT NULL, " 
		+ COLUMN_DEPARTMENT + " TEXT NOT NULL, " 
		+ COLUMN_CITY + " TEXT NOT NULL, " 
		+ COLUMN_OFFICE_PHONE + " TEXT NOT NULL, " 
		+ COLUMN_MOBILE_PHONE + " TEXT NOT NULL, " 
		+ COLUMN_EMAIL + " TEXT NOT NULL, " 
		+ COLUMN_PICTURE + " TEXT NOT NULL);";

	public EmployeeDatabase(Context context) {
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
		this.context = context;  // DO I NEED THIS???
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// Called when the database is created for the first time. 
		// This is where the creation of tables and the initial population of the tables happens.
		db.execSQL(CREATE_TABLE_EMPLOYEES);
		seedData(db);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		db.execSQL("DROP TABLE IF EXISTS " + TABLE_EMPLOYEES);
		onCreate(db);
	}

	private void seedData(SQLiteDatabase db) {

		// CALL XMLPULLPARSER & RETURN AN ArrayList OF EMPLOYEES
		EmployeeXmlParser parser = new EmployeeXmlParser();
		employeeList = parser.parse(context);

		// INSERT EACH EMPLOYEE TO THE DATABASE
		for (Employee employee : employeeList) {
			db.execSQL("INSERT INTO employees (" 
					+ COLUMN_FIRSTNAME + ", " 
					+ COLUMN_LASTNAME + ", " 
					+ COLUMN_TITLE + ", " 
					+ COLUMN_DEPARTMENT + ", " 
					+ COLUMN_CITY + ", " 
					+ COLUMN_OFFICE_PHONE + ", "
					+ COLUMN_MOBILE_PHONE + ", " 
					+ COLUMN_EMAIL + ", " 
					+ COLUMN_PICTURE + ")" 
					+ " values (\"" 
					+ String.valueOf(employee._firstName) 
					+ "\", \"" 
					+ String.valueOf(employee._lastName)
					+ "\", \"" 
					+ String.valueOf(employee._title) 
					+ "\", \"" 
					+ String.valueOf(employee._department) 
					+ "\", \"" 
					+ String.valueOf(employee._city) 
					+ "\", \""
					+ String.valueOf(employee._officePhone) 
					+ "\", \"" 
					+ String.valueOf(employee._mobilePhone) 
					+ "\", \"" 
					+ String.valueOf(employee._email) 
					+ "\", \""
					+ String.valueOf(employee._picture) + "\");");
		}

	}

}

Other files unchanged see Step 3

Screenshots of the application

App-EmployeeDirectory-01

 

App-EmployeeDirectory-01

 

Tags: ,

Category: Android Application Development

Comments (1)

Trackback URL | Comments RSS Feed

  1. Langdon Himebaugh says:

    The code has been place on GitHub. Download at https://github.com/langhimebaugh/EmployeeDirectory-Step-05

Leave a Reply

Your email address will not be published. Required fields are marked *