Subject: P15A2AAD - Android Application Development
Topic of Study: Modifying Content Providers Data
Grade/Level: Master of Computer Applications
Objective: To Modifying Content Providers Data using built-in content provider
Time Allotment: 55 Minutes
- Modifying Content Providers Data
- Whenever you want to use another content provider you first have to access a ContentResolver object.
- The ContentResolver decides which provider to use based on the authority part of the URI.
- You can get the ContentResolver object by calling getContentResolver() on the Context object.
- The Context object should always be available since the Activity and Service classes inherit from Context and the other components also provide easy access to it.
- Exa.
- Modifying Content Providers Data:
- Your application must have the appropriate permissions (i.e WRITE_CONTACTS as opposed to READ_CONTACTS) to perform some of these actions.
- Exa.
- Example of Content Providers Data
Step - 01: Create an Android application and name it as My Application under a package com.example.MyApplication, with blank Activity.
Step - 02: Design the main activity at res/layout/activity_main.xml file.
Component Tree
Design
XML Code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Content Provider"
android:textAlignment="center"
android:textColor="#009688"
android:textSize="30sp"
android:textStyle="bold" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sarthak Edu"
android:textAlignment="center"
android:textSize="20sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Roll No:"
android:textSize="30sp"
android:textStyle="bold" />
<EditText
android:id="@+id/etRollno"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="number"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Name :"
android:textSize="30sp"
android:textStyle="bold" />
<EditText
android:id="@+id/etName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName"
android:textSize="20sp" />
</LinearLayout>
<Button
android:id="@+id/btnAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add Student"
android:textSize="30sp"
android:textStyle="bold" />
<Button
android:id="@+id/btnFind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Find Student"
android:textSize="30sp"
android:textStyle="bold" />
</LinearLayout>
Step - 03: Create a new java file called StudentsProvider.java under the package com.example.MyApplication to define your actual provider and associated methods.
Step A: Right click on app and Select New > Other > Content Provider, write URI authorities and Click on Finish
This step registered your provider in AndroidManifest.xml and it looks like this.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="in.ac.ampics.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<provider
android:name=".StudentsProvider"
android:authorities="in.ac.ampics.myapplication.provider"
android:enabled="true"
android:exported="true"></provider>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
In addition, it also give you ready made skeleton for your provider with different methods and it looks like this.
package in.ac.ampics.myapplication;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
public class StudentsProvider extends ContentProvider {
public StudentsProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO: Implement this to handle requests to insert a new row.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public boolean onCreate() {
// TODO: Implement this to initialize your content provider on startup.
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
}
Step 04: Change in StudentsProvider.java file as per following code.
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import java.util.HashMap;
public class StudentsProvider extends ContentProvider {
static final String _ID = "_id"; //assume roll no
static final String NAME = "name";
private SQLiteDatabase db;
static final String DATABASE_NAME = "College";
static final String STUDENTS_TABLE_NAME = "students";
static final int DATABASE_VERSION = 1;
static final String CREATE_DB_TABLE =
" CREATE TABLE " + STUDENTS_TABLE_NAME +
" (_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
" name TEXT NOT NULL);";
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DB_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + STUDENTS_TABLE_NAME);
onCreate(db);
}
}
private static HashMap<String, String> STUDENTS_PROJECTION_MAP;
//copy android:authorities from AndroidManifest.xml
static final String PROVIDER_NAME = "in.ac.ampics.myapplication.provider";
static final String URL = "content://" + PROVIDER_NAME + "/students";
static final Uri CONTENT_URI = Uri.parse(URL);
static final int STUDENTS = 1;
static final int STUDENT_ID = 2;
static final UriMatcher uriMatcher;
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME, "students", STUDENTS);
uriMatcher.addURI(PROVIDER_NAME, "students/#", STUDENT_ID);
}
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowID = db.insert(STUDENTS_TABLE_NAME, "", values);
if (rowID > 0) {
Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(_uri, null);
return _uri;
}
throw new UnsupportedOperationException("Failed to add a record into " + uri);
}
@Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
return (db == null)? false:true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(STUDENTS_TABLE_NAME);
switch (uriMatcher.match(uri)) {
case STUDENTS:
qb.setProjectionMap(STUDENTS_PROJECTION_MAP);
break;
case STUDENT_ID:
qb.appendWhere( _ID + "=" + uri.getPathSegments().get(1));
break;
default:
}
Cursor c = qb.query(db, projection, selection,
selectionArgs,null, null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
}
Step - 05: Modify main activity file MainActivity.java to add two new methods AddStudent() and FindStudent().
public void AddStudent(View view) {
// Add a new student record
ContentValues values = new ContentValues();
values.put(StudentsProvider.NAME,((EditText)findViewById(R.id.etName)).getText().toString());
Uri uri = getContentResolver().insert(StudentsProvider.CONTENT_URI, values);
Toast.makeText(getBaseContext(), uri.toString(), Toast.LENGTH_LONG).show();
}
public void FindStudent(View view) {
// Retrieve all student records
String URL = "content://in.ac.ampics.myapplication.provider";
Uri students = Uri.parse(URL);
Cursor c = getContentResolver().query(students, null, null, null, "_id");
if (c.moveToFirst()) {
do {
Toast.makeText(this,
c.getString(c.getColumnIndex(StudentsProvider._ID)) +
", " + c.getString(c.getColumnIndex(StudentsProvider.NAME)),
Toast.LENGTH_SHORT).show();
} while (c.moveToNext());
}