Просмотр исходного кода

Initial commit for ContentProviderSQLite project.

Cristian Tanas 11 лет назад
Родитель
Сommit
b97a057886
21 измененных файлов с 909 добавлено и 0 удалено
  1. 36 0
      ContentProviderSQLite/AndroidManifest.xml
  2. BIN
      ContentProviderSQLite/ic_launcher-web.png
  3. BIN
      ContentProviderSQLite/libs/android-support-v4.jar
  4. BIN
      ContentProviderSQLite/res/drawable-hdpi/ic_launcher.png
  5. BIN
      ContentProviderSQLite/res/drawable-mdpi/ic_launcher.png
  6. BIN
      ContentProviderSQLite/res/drawable-xhdpi/ic_launcher.png
  7. BIN
      ContentProviderSQLite/res/drawable-xxhdpi/ic_launcher.png
  8. 182 0
      ContentProviderSQLite/res/layout/activity_main.xml
  9. 21 0
      ContentProviderSQLite/res/layout/courses_list.xml
  10. 8 0
      ContentProviderSQLite/res/layout/list_item.xml
  11. 9 0
      ContentProviderSQLite/res/menu/courses_list_menu.xml
  12. 11 0
      ContentProviderSQLite/res/values-v11/styles.xml
  13. 12 0
      ContentProviderSQLite/res/values-v14/styles.xml
  14. 12 0
      ContentProviderSQLite/res/values/arrays.xml
  15. 25 0
      ContentProviderSQLite/res/values/strings.xml
  16. 20 0
      ContentProviderSQLite/res/values/styles.xml
  17. 101 0
      ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/CoursesListActivity.java
  18. 145 0
      ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/CoursesNewFormActivty.java
  19. 100 0
      ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/CoursesProvider.java
  20. 58 0
      ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/DatabaseOpenHelper.java
  21. 169 0
      ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/SQLiteDataRepository.java

+ 36 - 0
ContentProviderSQLite/AndroidManifest.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.uab.android.contentprovider.sqlite"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="14"
+        android:targetSdkVersion="19" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".CoursesNewFormActivty"
+            android:label="@string/app_name" >
+        </activity>
+        <activity
+            android:name=".CoursesListActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        
+        <provider 
+            android:name=".CoursesProvider"
+            android:authorities="org.uab.android.contentprovider.sqlite.provider"
+            android:exported="true"></provider>
+    </application>
+
+</manifest>

BIN
ContentProviderSQLite/ic_launcher-web.png


BIN
ContentProviderSQLite/libs/android-support-v4.jar


BIN
ContentProviderSQLite/res/drawable-hdpi/ic_launcher.png


BIN
ContentProviderSQLite/res/drawable-mdpi/ic_launcher.png


BIN
ContentProviderSQLite/res/drawable-xhdpi/ic_launcher.png


BIN
ContentProviderSQLite/res/drawable-xxhdpi/ic_launcher.png


+ 182 - 0
ContentProviderSQLite/res/layout/activity_main.xml

@@ -0,0 +1,182 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="${relativePackage}.${activityClass}" >
+    
+    <TextView
+        android:id="@+id/sep1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_marginTop="5dp"
+        android:text="@string/class_sep"
+        style="?android:attr/listSeparatorTextViewStyle" />
+
+    <TextView
+        android:id="@+id/classLabel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/sep1"
+        android:layout_alignParentLeft="true"
+        android:layout_marginTop="15dp"
+        android:layout_marginLeft="10dp"
+        android:text="@string/class_name" />
+
+    <AutoCompleteTextView
+        android:id="@+id/classAutoComplete"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/classLabel"
+        android:layout_alignBottom="@+id/classLabel"
+        android:layout_marginLeft="16dp"
+        android:layout_toRightOf="@+id/classLabel"
+        android:ems="10" >
+        
+        <requestFocus />
+ 	</AutoCompleteTextView>
+
+    <TextView
+        android:id="@+id/creditLabel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignLeft="@+id/classLabel"
+        android:layout_below="@+id/classLabel"
+        android:layout_marginTop="30dp"
+        android:text="@string/credits" />
+
+    <EditText
+        android:id="@+id/creditsEditText"
+        android:layout_width="50dp"
+        android:layout_height="wrap_content"
+        android:layout_alignBottom="@+id/creditLabel"
+        android:layout_toRightOf="@+id/creditLabel"
+        android:layout_marginLeft="16dp"
+        android:ems="10"
+        android:inputType="numberDecimal" >
+    </EditText>
+
+    <TextView
+        android:id="@+id/sep2"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_below="@+id/creditLabel"
+        android:layout_marginTop="25dp"
+        android:text="@string/timetable_sep"
+        style="?android:attr/listSeparatorTextViewStyle" />
+
+    <TextView
+        android:id="@+id/dayOfWeekLabel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignLeft="@+id/classLabel"
+        android:layout_below="@+id/sep2"
+        android:layout_marginTop="15dp"
+        android:text="@string/day_of_week" />
+
+    <CheckBox
+        android:id="@+id/checkBoxMon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_below="@+id/dayOfWeekLabel"
+        android:layout_marginTop="10dp"
+        android:text="@string/monday"
+        android:onClick="onCheckBoxClicked" />
+    
+    <CheckBox
+        android:id="@+id/checkBoxTue"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/checkBoxMon"
+        android:layout_alignBottom="@+id/checkBoxMon"
+        android:layout_toRightOf="@+id/checkBoxMon"
+        android:text="@string/tuesday"
+        android:onClick="onCheckBoxClicked" />
+
+    <CheckBox
+        android:id="@+id/checkBoxWed"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/checkBoxTue"
+        android:layout_alignBottom="@+id/checkBoxTue"
+        android:layout_toRightOf="@+id/checkBoxTue"
+        android:text="@string/wednesday"
+        android:onClick="onCheckBoxClicked" />
+
+    <CheckBox
+        android:id="@+id/checkBoxThu"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/checkBoxWed"
+        android:layout_alignBottom="@+id/checkBoxWed"
+        android:layout_toRightOf="@+id/checkBoxWed"
+        android:text="@string/thursday"
+        android:onClick="onCheckBoxClicked" />
+
+    <CheckBox
+        android:id="@+id/checkBoxFri"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/checkBoxThu"
+        android:layout_alignBottom="@+id/checkBoxThu"
+        android:layout_toRightOf="@+id/checkBoxThu"
+        android:text="@string/friday"
+        android:onClick="onCheckBoxClicked" />
+
+    <TextView
+        android:id="@+id/hourLabel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignLeft="@+id/classLabel"
+        android:layout_below="@+id/checkBoxMon"
+        android:layout_marginTop="20dp"
+        android:text="@string/hour" />
+
+    <TextView
+        android:id="@+id/defaultHourLabel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/hourLabel"
+        android:layout_alignBottom="@+id/hourLabel"
+        android:layout_toRightOf="@+id/hourLabel"
+        android:layout_marginLeft="15dp"
+        android:text="@string/default_hour_label" />
+
+    <Button
+        android:id="@+id/setHourButton"
+        style="?android:attr/buttonStyleSmall"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/defaultHourLabel"
+        android:layout_alignBottom="@+id/defaultHourLabel"
+        android:layout_toRightOf="@+id/defaultHourLabel"
+        android:layout_marginLeft="10dp"
+        android:text="@string/sethour" />
+
+    <Button
+        android:id="@+id/saveButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        android:text="@string/submit" />
+
+    <Button
+        android:id="@+id/clearButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_toRightOf="@+id/saveButton"
+        android:text="@string/clear" />
+
+    <Button
+        android:id="@+id/cancelButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_toRightOf="@+id/clearButton"
+        android:text="@string/cancel" />
+
+</RelativeLayout>

+ 21 - 0
ContentProviderSQLite/res/layout/courses_list.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+    
+    <TextView 
+        android:id="@+id/courseName"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="10dp"
+        android:textSize="24sp"/>
+    
+    <TextView 
+        android:id="@+id/courseCredits"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="10dp"
+        android:textSize="24sp"/>
+
+</LinearLayout>

+ 8 - 0
ContentProviderSQLite/res/layout/list_item.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="5dp" >
+    
+
+</TextView>

+ 9 - 0
ContentProviderSQLite/res/menu/courses_list_menu.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item 
+        android:id="@+id/addNewCourse"
+        android:title="@string/addNewCourseLabel"
+        android:icon="@android:drawable/ic_menu_add"
+        android:showAsAction="ifRoom|withText"/>
+</menu>

+ 11 - 0
ContentProviderSQLite/res/values-v11/styles.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>

+ 12 - 0
ContentProviderSQLite/res/values-v14/styles.xml

@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>

+ 12 - 0
ContentProviderSQLite/res/values/arrays.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    
+    <string-array name="classes">
+        <item>Desarrollo de Apps Móviles</item>
+        <item>Desarrollo de Apps en plataforma Android</item>
+        <item>Desarrollo de Apps en plataforma iOS</item>
+        <item>Desarrollo de Apps en plataforma Windows Phone</item>
+        <item>Desarrollo de Apps Multiplataforma</item>
+    </string-array>
+    
+</resources>

+ 25 - 0
ContentProviderSQLite/res/values/strings.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">ContentProviderSQLite</string>
+    <string name="hello_world">Hello world!</string>
+    <string name="class_name">Nombre asignatura</string>
+    <string name="credits">Créditos</string>
+    <string name="class_sep">Datos asignatura</string>
+    <string name="timetable_sep">Horario</string>
+    <string name="day_of_week">Día de la semana</string>
+    <string name="monday">Lun</string>
+    <string name="tuesday">Mar</string>
+    <string name="wednesday">Mie</string>
+    <string name="thursday">Jue</string>
+    <string name="friday">Vie</string>
+    <string name="hour">Hora:</string>
+    <string name="default_hour_label">00:00</string>
+    <string name="sethour">Establecer</string>
+    <string name="submit">Guardar</string>
+    <string name="clear">Limpiar</string>
+    <string name="cancel">Cancelar</string>
+    <string name="title_activity_courses_list">Lista asignaturas</string>
+    <string name="addNewCourseLabel">Nueva asignatura</string>
+
+</resources>

+ 20 - 0
ContentProviderSQLite/res/values/styles.xml

@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>

+ 101 - 0
ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/CoursesListActivity.java

@@ -0,0 +1,101 @@
+package org.uab.android.contentprovider.sqlite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.ListActivity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.ArrayAdapter;
+
+public class CoursesListActivity extends ListActivity {
+	
+	private static final int		COURSE_NEW_REQUEST_CODE = 1;
+	
+	ArrayAdapter<String> 	adapter;
+	ContentResolver 		contentResolver;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		
+		this.contentResolver = getContentResolver();
+		
+		Cursor coursesListCursor = this.contentResolver.query(
+				CoursesProvider.CONTENT_URI, 
+				new String[] {CoursesProvider.COURSE_NAME}, 
+				null, 
+				null, 
+				null);
+		
+		this.adapter = new ArrayAdapter<String>(
+				this, 
+				android.R.layout.simple_list_item_1, 
+				fromCursor(coursesListCursor));
+		setListAdapter(this.adapter);
+	}
+	
+	private List<String> fromCursor(Cursor cursor) {
+		
+		List<String> courses = new ArrayList<String>();
+		if (cursor.moveToFirst()) {
+			do {
+				
+				courses.add(
+						cursor.getString(
+								cursor.getColumnIndex(CoursesProvider.COURSE_NAME)
+								)
+						);
+				
+			} while (cursor.moveToNext());
+		}
+		
+		return courses;
+	}
+	
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+		
+		MenuInflater inflater = getMenuInflater();
+		inflater.inflate(R.menu.courses_list_menu, menu);
+		return super.onCreateOptionsMenu(menu);
+	}
+	
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item) {
+		
+		switch ( item.getItemId() ) {
+		case R.id.addNewCourse:
+			Intent addNewCourseIntent = new Intent(this, CoursesNewFormActivty.class);
+			startActivityForResult(addNewCourseIntent, COURSE_NEW_REQUEST_CODE);
+			return true;
+
+		default:
+			return super.onOptionsItemSelected(item);
+		}
+		
+	}
+	
+	@Override
+	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+		
+		if ( resultCode == RESULT_OK && requestCode == COURSE_NEW_REQUEST_CODE ) {
+			
+			Cursor courses = this.contentResolver.query(
+					CoursesProvider.CONTENT_URI, 
+					new String[] {CoursesProvider.COURSE_NAME}, 
+					null, 
+					null, 
+					null);
+			
+			adapter.clear();
+			adapter.addAll(fromCursor(courses));
+			adapter.notifyDataSetChanged();
+		}
+	}
+}

+ 145 - 0
ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/CoursesNewFormActivty.java

@@ -0,0 +1,145 @@
+package org.uab.android.contentprovider.sqlite;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import android.app.Activity;
+import android.app.TimePickerDialog;
+import android.app.TimePickerDialog.OnTimeSetListener;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.TimePicker;
+
+public class CoursesNewFormActivty extends Activity {
+	
+	AutoCompleteTextView	classesAutoCompleteTextView;
+	EditText				numberOfCreditsEditText;
+	TextView				defaultHourTextView;
+	Button					setHourButton;
+	
+	Button					saveButton;
+	
+	Map<Integer, Boolean> checkBoxStateMap = new HashMap<>();
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_main);
+		
+		// Get a reference to the UI element
+		classesAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.classAutoComplete);
+		
+		numberOfCreditsEditText = (EditText) findViewById(R.id.creditsEditText);
+		
+		// Set an ArrayAdapter containing pre-define classes names
+		ArrayAdapter<CharSequence> classesAdapter = ArrayAdapter.
+				createFromResource(this, R.array.classes, R.layout.list_item);
+		classesAutoCompleteTextView.setAdapter(classesAdapter);
+		
+		setHourButton = (Button) findViewById(R.id.setHourButton);
+		
+		// Set an OnClickListener for the set hour Button
+		setHourButton.setOnClickListener(new OnClickListener() {
+			
+			@Override
+			public void onClick(View arg0) {
+				
+				// Get an instance of a Calendar to set the current time
+				Calendar c = Calendar.getInstance();
+				int hourOfDay = c.get(Calendar.HOUR_OF_DAY);
+				int minute = c.get(Calendar.MINUTE);
+				
+				// Create a new dialog that displays a TimePicker
+				TimePickerDialog timePickerDialog = new TimePickerDialog(
+						CoursesNewFormActivty.this, 
+						timeSetListener, 
+						hourOfDay, 
+						minute, 
+						true);
+				timePickerDialog.show();
+			}
+		});
+		
+		defaultHourTextView = (TextView) findViewById(R.id.defaultHourLabel);
+		
+		saveButton = (Button) findViewById(R.id.saveButton);
+		saveButton.setOnClickListener(new OnClickListener() {
+			
+			@Override
+			public void onClick(View v) {
+				
+				// Get the values from the form's inputs
+				String courseName = classesAutoCompleteTextView.getText().toString();
+				int numberOfCredits = Integer.parseInt(numberOfCreditsEditText.getText().toString());
+				String checkBoxState = checkBoxStateMap.keySet().toString();
+				String hour = defaultHourTextView.getText().toString();
+				
+				// Open the database for writing
+				ContentResolver contentResolver = getContentResolver();
+				
+				// Create the ContentValues for the data to be saved 
+				ContentValues values = new ContentValues();
+				values.put(CoursesProvider.COURSE_NAME, courseName);
+				values.put(CoursesProvider.COURSE_CREDITS, numberOfCredits);
+				values.put(CoursesProvider.COURSE_DAYS, checkBoxState);
+				values.put(CoursesProvider.COURSE_HOUR, hour);
+				
+				// Save the data through the ContentProvider
+				contentResolver.insert(CoursesProvider.CONTENT_URI, values);
+				
+				// Clear the form's inputs
+				clearForm();
+				
+				// Set the result for the calling Activity
+				setResult(RESULT_OK);
+				finish();
+			}
+		});
+	}
+	
+	// Resets the form's input Views
+	private void clearForm() {
+		
+		classesAutoCompleteTextView.setText("");
+		numberOfCreditsEditText.setText("");
+		
+		for ( int checkBoxId : checkBoxStateMap.keySet() ) {
+			
+			CheckBox cb = (CheckBox) findViewById(checkBoxId);
+			cb.setChecked(false);
+		}
+		
+		defaultHourTextView.setText(R.string.default_hour_label);
+	}
+	
+	// Called when the user clicks on one of the CheckBoxes, changing it's state
+	public void onCheckBoxClicked(View v) {
+		
+		// Save the ID of the CheckBox jointly with it's current state
+		CheckBox cb = (CheckBox) v;
+		checkBoxStateMap.put(cb.getId(), cb.isChecked());
+		
+	}
+	
+	// Implementation of the OnTimeSetListener interface
+	OnTimeSetListener timeSetListener = new OnTimeSetListener() {
+		
+		// This method is called when the user click done on the TimePicker
+		@Override
+		public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
+			
+			// Set the hour and minute on the corresponding TextView
+			defaultHourTextView.setText(hourOfDay + ":" + minute);
+		}
+	};
+}

+ 100 - 0
ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/CoursesProvider.java

@@ -0,0 +1,100 @@
+package org.uab.android.contentprovider.sqlite;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class CoursesProvider extends ContentProvider {
+	
+	/* ========COURSES_PROVIDER CONTRACT===============================================
+	 * Defines
+	 * 		. CONTENT_URI
+	 * 		. COURSES_PROVIDER COLUMNS
+	 */
+	public static final Uri CONTENT_URI = Uri
+			.parse("content://org.uab.android.contentprovider.sqlite.provider/courses");
+	
+	public static final String COURSE_NAME = DatabaseOpenHelper.COURSE_NAME;
+	public static final String COURSE_CREDITS = DatabaseOpenHelper.COURSE_NUM_OF_CREDITS;
+	public static final String COURSE_DAYS = DatabaseOpenHelper.COURSE_DAYS_OF_WEEK;
+	public static final String COURSE_HOUR = DatabaseOpenHelper.COURSE_STARTS_AT;
+	/* ================================================================================= */
+	
+	private static final int ALL_COURSES = 1;
+	private static final int COURSE_BY_CREDITS = 2;
+	
+	private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+	static {
+		uriMatcher.addURI("org.uab.android.contentprovider.sqlite.provider", 
+				"courses", ALL_COURSES);
+		
+		uriMatcher.addURI("org.uab.android.contentprovider.sqlite.provider", 
+				"courses/#", COURSE_BY_CREDITS);
+	}
+	
+	@Override
+	public boolean onCreate() {
+		return true;
+	}
+
+	@Override
+	public Cursor query(Uri uri, String[] projection, String selection, 
+			String[] selectionArgs, String sortOrder) {
+		
+		SQLiteDataRepository coursesDb = new SQLiteDataRepository(getContext());
+		coursesDb.openDatabaseForReadOnly();
+		Cursor result = null;
+		
+		switch ( uriMatcher.match(uri) ) {
+		case ALL_COURSES:
+			result = coursesDb.fetchAllCourses(projection);
+			break;
+			
+		case COURSE_BY_CREDITS:
+			int credits = Integer.parseInt(uri.getLastPathSegment());
+			result = coursesDb.fetchCourseByCredits(projection, credits);
+
+		default:
+			break;
+		}
+		
+		
+		return result;
+	}
+	
+	@Override
+	public Uri insert(Uri uri, ContentValues values) {
+		
+		if ( uriMatcher.match(uri) == ALL_COURSES ) {
+			SQLiteDataRepository coursesDb = new SQLiteDataRepository(getContext());
+			coursesDb.openDatabaseForWrite();
+		
+			long rowId = coursesDb.insert(values);
+			if ( rowId > 0 ) {
+				Uri resultUri = ContentUris.withAppendedId(CONTENT_URI, rowId);
+				return resultUri;
+			}
+		}
+			
+		return uri;
+	}
+
+	@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;
+	}
+	
+	@Override
+	public String getType(Uri uri) {
+		return null;
+	}
+
+}

+ 58 - 0
ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/DatabaseOpenHelper.java

@@ -0,0 +1,58 @@
+package org.uab.android.contentprovider.sqlite;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class DatabaseOpenHelper extends SQLiteOpenHelper {
+	
+	// Variable holding the name of the database to be created
+	private static final String		DATABASE_NAME = "courses";
+	private static final int		DATABASE_VERSION = 1;
+	
+	// Variables holding the name of the table and columns to be created
+	static final String		COURSES_TABLE_NAME = "ASIGNATURAS";
+	static final String		_ID = "_id";
+	static final String		COURSE_NAME = "asignatura";
+	static final String		COURSE_NUM_OF_CREDITS = "creditos";
+	static final String		COURSE_DAYS_OF_WEEK = "dias";
+	static final String		COURSE_STARTS_AT = "hora";
+	
+	// Static variable containing the name of all the table's columns
+	static final String[] COLUMNS = {
+		_ID,
+		COURSE_NAME,
+		COURSE_NUM_OF_CREDITS,
+		COURSE_DAYS_OF_WEEK,
+		COURSE_STARTS_AT
+	};
+	
+	// Variable holding the SQL instruction to create a new table 
+	private static final String CREATE_COURSES_TABLE = 
+			"CREATE TABLE " + COURSES_TABLE_NAME + "( " +
+					_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+					COURSE_NAME + " TEXT NOT NULL, " +
+					COURSE_NUM_OF_CREDITS + " INTEGER NOT NULL, " +
+					COURSE_DAYS_OF_WEEK + " TEXT, " +
+					COURSE_STARTS_AT + " TEXT)";
+	
+	// Public constructor. Delegates the construction to the SQLiteOpenHelper class
+	public DatabaseOpenHelper(Context context) {
+		super(context, DATABASE_NAME, null, DATABASE_VERSION);
+	}
+
+	// Create and initialize the database if not present
+	@Override
+	public void onCreate(SQLiteDatabase db) {
+		
+		db.execSQL(CREATE_COURSES_TABLE);
+	}
+
+	// Update the database if any changes have occurred (changes in the version number)
+	@Override
+	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+		// TODO Auto-generated method stub
+
+	}
+
+}

+ 169 - 0
ContentProviderSQLite/src/org/uab/android/contentprovider/sqlite/SQLiteDataRepository.java

@@ -0,0 +1,169 @@
+package org.uab.android.contentprovider.sqlite;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+public class SQLiteDataRepository {
+
+	// Helper object to obtain a reference to the database
+	private DatabaseOpenHelper databaseOpenHelper;
+
+	// Reference to the SQLiteDatabase to store and retrieve data
+	private SQLiteDatabase				sqliteDatabase;
+
+	// Private constructor for the SQLiteDataRepository class
+	// Creates a new DatabaseOpenHelper object and holds a reference to the actual database
+	public SQLiteDataRepository(Context context) {
+
+		this.databaseOpenHelper = new DatabaseOpenHelper(context);
+	}
+
+	/**
+	 * Opens the database for read-only operations
+	 */
+	public void openDatabaseForReadOnly() {
+
+		this.sqliteDatabase = this.databaseOpenHelper.getReadableDatabase();
+	}
+
+	/**
+	 * Opens the database for read and write operations
+	 */
+	public void openDatabaseForWrite() {
+
+		this.sqliteDatabase = this.databaseOpenHelper.getWritableDatabase();
+	}
+
+	/**
+	 * Saves the information for a particular course.
+	 * 
+	 * @param courseName Name of the course.
+	 * @param numberOfCredits Number of credits of the course.
+	 * @param checkBoxState String identifying the state of the 
+	 * 						days of the week check boxes.
+	 * @param hour Starting hour for the course.
+	 */
+	public void saveCourse(String courseName, int numberOfCredits, 
+			String checkBoxState, String hour) {
+
+		ContentValues values = new ContentValues();
+		values.put(DatabaseOpenHelper.COURSE_NAME, courseName);
+		values.put(DatabaseOpenHelper.COURSE_NUM_OF_CREDITS, numberOfCredits);
+		values.put(DatabaseOpenHelper.COURSE_DAYS_OF_WEEK, checkBoxState);
+		values.put(DatabaseOpenHelper.COURSE_STARTS_AT, hour);
+
+		this.sqliteDatabase.insert(
+				DatabaseOpenHelper.COURSES_TABLE_NAME, 
+				null, 
+				values);
+	}
+	
+	public long insert(ContentValues values) {
+		
+		return this.sqliteDatabase.insert(
+				DatabaseOpenHelper.COURSES_TABLE_NAME, 
+				null, 
+				values);
+	}
+
+	/**
+	 * Returns a specific course based on its ID.
+	 * 
+	 * @param courseId The unique course ID.
+	 * 
+	 * @return An iterator over the obtained registers.
+	 */
+	public Cursor fetchCourseById(int courseId) {
+
+		String selection = DatabaseOpenHelper._ID + " = ?";
+		String[] selectionArgs = new String[] { String.valueOf(courseId) };
+
+		Cursor result = this.sqliteDatabase.query(
+				DatabaseOpenHelper.COURSES_TABLE_NAME, 
+				DatabaseOpenHelper.COLUMNS, 
+				selection, 
+				selectionArgs, 
+				null, 
+				null, 
+				null);
+		return result;
+	}
+
+	/**
+	 * Returns courses based on their credit number.
+	 * 
+	 * @param projection The names of the columns to fetch.
+	 * @param numOfCredits The number of credits the course should be tested against.
+	 * 
+	 * @return An iterator over the obtained registers.
+	 */
+	public Cursor fetchCourseByCredits(String[] projection, int numOfCredits) {
+
+		String selection = DatabaseOpenHelper.COURSE_NUM_OF_CREDITS + " = ?";
+		String[] selectionArgs = new String[] { String.valueOf(numOfCredits) };
+
+		Cursor result = this.databaseOpenHelper.getReadableDatabase()
+				.query(
+						DatabaseOpenHelper.COURSES_TABLE_NAME, 
+						DatabaseOpenHelper.COLUMNS, 
+						selection, 
+						selectionArgs, 
+						null, 
+						null, 
+						null);
+
+		return result;
+	}
+
+	/**
+	 * Returns all saved courses.
+	 * 
+	 * @return An iterator over the list of courses from the database.
+	 */
+	public Cursor fetchAllCourses() {
+
+		Cursor result = this.sqliteDatabase.query(
+				DatabaseOpenHelper.COURSES_TABLE_NAME, 
+				DatabaseOpenHelper.COLUMNS, 
+				null, 
+				null, 
+				null, 
+				null, 
+				null);
+		return result;
+	}
+
+	/**
+	 * Returns all saved courses.
+	 * 
+	 * @param projection The names of the columns to fetch.
+	 * 
+	 * @return An iterator over the list of courses from the database.
+	 */
+	public Cursor fetchAllCourses(String[] projection) {
+
+		Cursor result = this.databaseOpenHelper.getReadableDatabase()
+				.query(
+						DatabaseOpenHelper.COURSES_TABLE_NAME, 
+						projection, 
+						null, 
+						null, 
+						null, 
+						null, 
+						null);
+		return result;
+	}
+
+	/**
+	 * Release the database resources
+	 */
+	public void release() {
+
+		if ( sqliteDatabase != null ) {
+			sqliteDatabase.close();
+			sqliteDatabase = null;
+		}
+	}
+}