Browse Source

Initial commit for ContentProviderSQLite project.

Cristian Tanas 11 năm trước cách đây
mục cha
commit
b97a057886
21 tập tin đã thay đổi với 909 bổ sung0 xóa
  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;
+		}
+	}
+}