Content providers in Android provide access to data that is shared between different apps.
1. First App: The producer application is designed to construct the SQLite database and the data entry screen.
2. Second App: The consumer application is designed to view the data stored by the first app (as list) the data can be edited also.
2. Background
Content providers in Android provide access to data that is shared between different apps. The
contentprovideristhe ownerof the data,but providesaninterfacetoallow activitiesfromother
applications in Android to access the data.
The intention istoadd; You can populate the contentwithdataaboutEuropeanUnion
countries,orGulf CooperationCouncil countries,AfricanUnion,etc.For eachcountry you
shouldstore itscapital city,population,areainsquare kilometres,anditsofficial language or
languages,andanyotherdata you like..
The Solution:
1. FirstApp:The producerapplicationisdesignedtoconstructthe SQLite database and
the data entryscreen.
2. SecondApp:The consumerapplicationisdesignedtoview the datastoredbythe
firstapp (aslist) the data can be editedalso.
The followingscreensandJavaclasses includedinthe ProducerApplication:
1. Classeswithin com.example.contentproviderproducerpackage
MainActivity
CountryProvider
2. ClasseswithinDBSQLin com.example.contentproviderproducer package
DBCountry
CountryDatabaseHelper
3. Activities
activity_main.xml
Introduction
The ApplicationUserExperience.
Simple userinterfacetoenterthe followingrequireddata,
Selectthe " union", " capital ", " population","area", " language" and" other”
7. The Code for First Application(Producer)
1. The manifestfile
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.contentproviderproducer" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
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:authorities="com.example.contentproviderproducer.countrycrovider"
android:name=".CountryProvider"
android:exported="true"></provider>
</application>
</manifest>
2. Main Activity
3. package com.example.contentproviderproducer;
import android.app.Activity;
import android.content.ContentValues;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import com.example.contentproviderproducer.DBSQL.DBCountry;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// declare new instance of the database and open the connection
final DBCountry db = new DBCountry(this);
db.open();
final EditText name = (EditText)findViewById(R.id.name);
8. final EditText population =
(EditText)findViewById(R.id.population);
final EditText area = (EditText)findViewById(R.id.area);
final EditText capital = (EditText)findViewById(R.id.capital);
final EditText language = (EditText)findViewById(R.id.language);
final EditText other = (EditText)findViewById(R.id.other);
final Spinner union = (Spinner)findViewById(R.id.union);
Button buttonsave=(Button)findViewById(R.id.insert);
// add items values taken from the input screen to contentValues;
buttonsave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put("name", ""+name.getText().toString());
values.put("capital", ""+capital.getText().toString());
values.put("population",
""+population.getText().toString());
values.put("area", ""+area.getText().toString());
values.put("language", ""+language.getText().toString());
values.put("count_union",
""+union.getSelectedItem().toString());
values.put("other", ""+other.getText().toString());
// insert the loaded values into database using the DB helper
insert procedure
db.insert("Country", values);
// preview a toast message to user confirming the new entry
Toast.makeText(MainActivity.this, "New Country Added!",
Toast.LENGTH_SHORT).show();
}
});
}
}
4. CountryProvider
package com.example.contentproviderproducer;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import com.example.contentproviderproducer.DBSQL.DBCountry;
/**
* class CountryProvider as Content Provide and uri.
*/
public class CountryProvider extends ContentProvider{
public static final String AUTHORITY =
"com.example.contentproviderproducer.countrycrovider";
9. public static final String STUDENT_TABLE = "Country";
public static final int CHOICE_TABLE = 1;
public static final int CHOICE_TABLE_ROW = 2;
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
DBCountry db;
@Override
public boolean onCreate() {
uriMatcher.addURI(AUTHORITY,STUDENT_TABLE,CHOICE_TABLE);
uriMatcher.addURI(AUTHORITY,STUDENT_TABLE+"/#",CHOICE_TABLE_ROW);
db = new DBCountry(getContext());
db.open();
return (db==null)? false:true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int choice = uriMatcher.match(uri);
Cursor c = null;
if(choice == CHOICE_TABLE){
c =
db.query(STUDENT_TABLE,projection,selection,selectionArgs,sortOrder);
getContext().getContentResolver().notifyChange(uri,null);
}
return c;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int choice = uriMatcher.match(uri);
long id = -1;
if(choice == CHOICE_TABLE){
id = db.insert(STUDENT_TABLE,values);
getContext().getContentResolver().notifyChange(uri,null);
}
return Uri.parse("content://"+AUTHORITY+"/"+STUDENT_TABLE+"/"+id);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int choice = uriMatcher.match(uri);
int count = -1;
if(choice == CHOICE_TABLE){
count = db.delete(STUDENT_TABLE,selection,selectionArgs);
}
return count;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[]
selectionArgs) {
int choice = uriMatcher.match(uri);
int rowsAffected = -1;
if(choice == CHOICE_TABLE){
rowsAffected =
db.update(STUDENT_TABLE,values,selection,selectionArgs);
}
10. return rowsAffected;
}
@Override
public String getType(Uri uri) {
return null;
}
}
5. DBSQL. DBCountry
6. package com.example.contentproviderproducer.DBSQL;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
/**
* Define the databse helper to perform CRUD actions on the deatabase.
* I used insert prcedure in this app
*/
public class DBCountry {
CountryDatabaseHelper countryDatabaseHelper;
SQLiteDatabase db;
Context context;
public DBCountry(Context context) {
this.context = context;
countryDatabaseHelper = new CountryDatabaseHelper(context,
"dbCountry", null, 1);
}
public void open() {
db = countryDatabaseHelper.getWritableDatabase();
}
public void close() {
countryDatabaseHelper.close();
}
public void beginTransaction() {
db.beginTransaction();
}
public void endTransaction() {
db.endTransaction();
}
public void setTransactionSuccessful() {
db.setTransactionSuccessful();
}
public long insert(String tableName, ContentValues values) {
return db.insert(tableName, null, values);
}
public Cursor query(String tableName, String[] projection, String
selection, String[] selectionArgs, String sortOrder) {
11. return db.query(tableName, projection, selection, selectionArgs,
null, null, sortOrder);
}
public int delete(String tableName , String whereClause , String[]
args){
return db.delete(tableName, whereClause, args);
}
public int update(String tableName ,ContentValues values, String
whereClause , String[] args){
return db.update(tableName, values, whereClause, args);
}
public void insertWithPerformance(String query,String... values){
SQLiteStatement stmt = db.compileStatement(query);
beginTransaction();
stmt.bindString(1,values[0]);
stmt.bindString(2,values[1]);
stmt.execute();
stmt.clearBindings();
setTransactionSuccessful();
endTransaction();
}
}
7. DBSQL. CountryDatabaseHelper
package com.example.contentproviderproducer.DBSQL;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Create the database table required to store the app data - Country.
* using SQLite
*/
public class CountryDatabaseHelper extends SQLiteOpenHelper{
public CountryDatabaseHelper(Context context, String name,
SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("Create Table Country(_id INTEGER PRIMARY KEY AUTOINCREMENT
," +
" name TEXT NOT NULL ," +
" capital TEXT ," +
" population TEXT ," +
" area TEXT ," +
" language TEXT ," +
" count_union TEXT ," +
" other TEXT )");
}
12. // in case of updating the app, the table will be recreated
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE Country IF EXIST");
onCreate(db);
}
}
8. Activity_main.xml
<LinearLayout 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"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:orientation="vertical"
>
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Union"
android:ems="10"
android:id="@+id/union"
android:entries="@array/unionArray" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="name"
android:ems="10"
android:id="@+id/name" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="capital"
android:ems="10"
android:id="@+id/capital" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="population"
android:ems="10"
android:id="@+id/population" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="area"
android:ems="10"
android:id="@+id/area" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
17. }
});
}
});
}
@Override
public void onLoaderReset(Loader loader) {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem item = menu.findItem(R.id.add);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
int id = item.getItemId();
if (id == R.id.add) {
btnAddClick();
try {
flipper.showNext();
} catch (Exception w) {
flipper.showPrevious();
}
return true;
} else {
try {
flipper.showPrevious();
} catch (Exception w) {
flipper.showNext();
}
return true;
}
}
}
4. CountryCursorAdapter
package com.example.contentproviderconsumer;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
18. import android.widget.RelativeLayout;
import android.widget.TextView;
public class CountryCursorAdapter extends CursorAdapter {
public CountryCursorAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, 0);
}
CutdorListLisiner cutdorListLisiner;
public void setCutdorListLisiner(CutdorListLisiner cutdorListLisiner) {
this.cutdorListLisiner = cutdorListLisiner;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.row_country,
parent, false);
}
// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
@Override
public void bindView(View view, final Context context, Cursor cursor) {
// Find fields to populate in inflated template
final TextView name = (TextView)view.findViewById(R.id.name);
final TextView population =
(TextView)view.findViewById(R.id.population);
final TextView area = (TextView)view.findViewById(R.id.area);
final TextView capital = (TextView)view.findViewById(R.id.capital);
final TextView language = (TextView)view.findViewById(R.id.language);
final TextView union = (TextView)view.findViewById(R.id.union);
final RelativeLayout rel_item =
(RelativeLayout)view.findViewById(R.id.rel_item);
final String _id =
cursor.getString(cursor.getColumnIndexOrThrow("_id"));
final String s_name =
cursor.getString(cursor.getColumnIndexOrThrow("name"));
final String s_population =
cursor.getString(cursor.getColumnIndexOrThrow("population"));
final String s_area =
cursor.getString(cursor.getColumnIndexOrThrow("area"));
final String s_capital =
cursor.getString(cursor.getColumnIndexOrThrow("capital"));
final String s_language =
cursor.getString(cursor.getColumnIndexOrThrow("language"));
final String s_union =
cursor.getString(cursor.getColumnIndexOrThrow("count_union"));
rel_item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cutdorListLisiner.OnClickCountryListener(context,_id,s_name,s_population,s_a
rea,s_capital,s_language);
}
});
// Populate fields with extracted properties
name.setText(s_name);
population.setText(s_population);
area.setText(s_area);
capital.setText("("+s_capital+")");
language.setText(s_language);