On the Android platform, one application cannot directly access (read/write) other application's data. All persistent data of an app is private to that app. Every application has its own id data directory and own protected memory area. This means that an app cannot query or manipulate the data of another app. However, if you want to enable an app to query or manipulate the data of another app, you need to use the concept of content providers.
Content Provider:
Content provider is a set of data wrapped up in a custom API to read and write. It acts as an interface that allows you to store and retrieve data from a data source. And also allows you to share an app’s data with other apps. Content providers decouple the app layer from the data layer by abstracting the underlying data source, thereby making apps data-source independent. They allow full permission control by monitoring which app components or users should have access to the data making data sharing easy. As a result, any app with appropriate permissions can add, remove, update, and retrieve data of another app including the data in some native Android databases.
There are 2 types of Content Providers :
- Custom content providers: These are created by the developer to suit the requirements of an app.
- Native content providers: These provide access to built-in databases, such as contact manager, media player, and other native databases. You need to grant the required permissions to your app before using native content providers.
Eg : The WhatsApp app sharing mobile contacts data.
Media store-Allows other applications to access, store media files.
Above diagram shows how content provider works. Application 2 stores its data in its own database and provides a provider. Application 1 communicates with the provider to access Application 2's data.
Content Provider uses a special URI starting with content:// will be assigned to each content providers and that will be recognized across applications.
Creating a Content Provider :
To create a content provider we need to
- Create sub class for ContentProvider.
- Define content URI
- Implement all the unimplemented methods. insert(), update(), query(), delete(), getType().
- Declare the content provider in AndroidManifest.xml
Specifying the URI of a Content Provide
Content provider URI consists of four parts.
content://authority/path/id
content://authority/path/id
Each content provider exposes a URI that uniquely identifies the content provider’s data set. If a content provider controls multiple datasets, a separate URI needs to be specified for each dataset. The URI of a content provider begins with the string, content://.
content:// - All the content provider URIs should start with this value
authority - A Java namespace of the content provider implementation. (fully qualified Java package name)
path - A virtual directory within the provider that identifies the kind of data being requested.
Id - Its optional part that specifies the primary key of a record being requested. We can omit this part to request all records.
Registering the provider in AndroidManifest.xml
As with any other major parts of Android application, we have to register the content providers too in the AndroidManifest.xml. <provider> element is used to register the content providers. It should be declared under <application>.
<provider
android:name=".MyProvider"
android:authorities="com.example.contentproviderexample.MyProvider"
android:exported="true"
android:multiprocess="true" >
</provider>
Here authorities is the URI authority to access the content provider. Typically this will be the fully qualified name of the content provider class.Creating provider application:
This application will create a content provider and share its data. This uses SQLite database 'sharedDb'. It has a table called 'names'. The table names have two columns id, name.
The URI of this content provider is content://com.example.contentproviderexample.MyProvider/cte
We have layout to insert new records to the database table.
We have layout to insert new records to the database table.
Step 1 : Create a new project by going to File ⇒ New Android Application Project. Fill all the details and name your activity as MainActivity. (eclipse)
Step 2 : Design the activity_main.xml layout for MainActivity under layout folder as shown below for capturing data.
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"
tools:context = "${relativePackage}.${activityClass}" >
<TextView
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = "Enter Name :"
android:textAppearance = "?android:attr/textAppearanceSmall"/>
<EditText
android:id = "@+id/txtName"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"/>
<Button
android:id = "@+id/btnAdd"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:onClick = "onClickAddName"
android:text = "Add Name"/>
</LinearLayout >
Step 3 : Creating a Custom Content Provider
To create your own content provider, you need to create a class that extends the abstract ContentProvider class and overrides its methods.
MyProvider.java
public class MyProvider extends ContentProvider
{
static final String PROVIDER_NAME = "com.example.contentproviderexample.MyProvider";
static final String URL = "content://" + PROVIDER_NAME + "/cte";
Step 5 : Create a new project by going to File ⇒ New Android Application Project. Name it as 'RequestApp' Fill all the details and name your activity as MainActivity. (eclipse)
static final Uri CONTENT_URI = Uri.parse(URL);
static final String id = "id";
static final String name = "name";
static final String uriCode = 1;
static final String UriMatcher uriMatcher;
private static HashMap<String,String> values;
static
{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME ,"cte", uriCode);
uriMatcher.addURI(PROVIDER_NAME ,"cte/*", uriCode);
}
static final String id = "id";
static final String name = "name";
static final String uriCode = 1;
static final String UriMatcher uriMatcher;
private static HashMap<String,String> values;
static
{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME ,"cte", uriCode);
uriMatcher.addURI(PROVIDER_NAME ,"cte/*", uriCode);
}
private SQLiteDatabase db;
static final String DATABASE_NAME = "sharedDb";
static final String TABLE_NAME = "names";
static final int DATABASE_VERSION = 1;
static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);";
static final String DATABASE_NAME = "sharedDb";
static final String TABLE_NAME = "names";
static final int DATABASE_VERSION = 1;
static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);";
@Override
public boolean onCreate()
{
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
if (db != null) {
return true;
}
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
{
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(TABLE_NAME);
switch (uriMatcher.match(uri)) {
case uriCode:
qb.setProjectionMap(values);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (sortOrder == null || sortOrder == "") {
sortOrder = name;
}
Cursor c = qb.query(db, projection, selection, selectionArgs, null,
null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public String getType(Uri uri)
{
switch (uriMatcher.match(uri)) {
case uriCode :
return "vnd.android.cursor.dir/cte";
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values)
{
long rowID = db.insert(TABLE_NAME, "", values);
if (rowID > 0) {
Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(_uri, null);
return _uri;
}
throw new SQLException("Failed to add a record into " + uri);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode :
count = db.delete(TABLE_NAME, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
{
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode :
count = db.update(TABLE_NAME, values, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(CREATE_DB_TABLE);
}
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 " + TABLE_NAME);
onCreate(db);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
}
Step 4 : Now open up the MainActivity from src/package. Add the following code.
Note : onClickAddName() is the onClick attribute declared inside layout.
public void onClickAddName(View view)
{
ContentValues values = new ContentValues();
values.put(MyProvider.name, ((EditText) findViewById(R.id.txtName))
.getText().toString());
Uri uri = getContentResolver().insert(MyProvider.CONTENT_URI, values);
((EditText) findViewById(R.id.txtName)).setText("");
Toast.makeText(getBaseContext(), "New record inserted", Toast.LENGTH_LONG)
.show();
ContentValues values = new ContentValues();
values.put(MyProvider.name, ((EditText) findViewById(R.id.txtName))
.getText().toString());
Uri uri = getContentResolver().insert(MyProvider.CONTENT_URI, values);
((EditText) findViewById(R.id.txtName)).setText("");
Toast.makeText(getBaseContext(), "New record inserted", Toast.LENGTH_LONG)
.show();
}
Creating request application:
This application is very simple, it will use the query() method to access the data stored in the Provider application. This application is having a layout to display the data.
Step 6 : Design the activity_main.xml layout for MainActivity under layout folder as shown below for displaying data.
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"
tools:context = "${relativePackage}.${activityClass}" >
<Button
android:id = "@+id/btnRetrieve"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:onClick = "onClickDisplayNames"
android:text = "Display Names"/>
<TextView
android:layout_width = "wrap_content"
android:id = "@+id/res"
android:layout_height = "wrap_content"
android:textAppearance = "?android:attr/textAppearanceMedium"/>
</LinearLayout >
Step 7 : Now open up the MainActivity from src/package. Add the following code.We have used CusrsorLoader to load the data.
MainActivity.java
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.CursorLoader;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.CursorLoader;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity implements LoaderManager.LoaderCallbacks<Cursor>
{
TextView resultView = null;
CursorLoader cursorLoader;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resultView= (TextView) findViewById(R.id.res);
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1)
{
cursorLoader = new CursorLoader(this, Uri.parse("content://com.example.contentproviderexample.MyProvider/cte"), null, null, null, null);
return cursorLoader;
}
public void onClickDisplayNames(View view)
{
getSupportLoaderManager().initLoader(1, null, this);
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor)
{
if (cursor != null)
{
cursor.moveToFirst();
StringBuilder res = new StringBuilder();
while (!cursor.isAfterLast()) {
res.append("\n"+cursor.getString(cursor.getColumnIndex("id"))+ "-"+ cursor.getString(cursor.getColumnIndex("name")));
cursor.moveToNext();
}
resultView.setText(res);
}
else
{
Toast.makeText(getBaseContext(), "No records", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onLoaderReset(Loader<Cursor> arg0)
{
}
CursorLoader cursorLoader;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resultView= (TextView) findViewById(R.id.res);
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1)
{
cursorLoader = new CursorLoader(this, Uri.parse("content://com.example.contentproviderexample.MyProvider/cte"), null, null, null, null);
return cursorLoader;
}
public void onClickDisplayNames(View view)
{
getSupportLoaderManager().initLoader(1, null, this);
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor)
{
if (cursor != null)
{
cursor.moveToFirst();
StringBuilder res = new StringBuilder();
while (!cursor.isAfterLast()) {
res.append("\n"+cursor.getString(cursor.getColumnIndex("id"))+ "-"+ cursor.getString(cursor.getColumnIndex("name")));
cursor.moveToNext();
}
resultView.setText(res);
}
else
{
Toast.makeText(getBaseContext(), "No records", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onLoaderReset(Loader<Cursor> arg0)
{
}
}
Source code : Click here to download.
Source code : Click here to download.
Thanks a lot for reading...
Don't forget to share this post if you found it interesting!
If you find something to add to this post? or any other quick thoughts/hints that you think people will find useful? Share it in the comments & feedback's are most welcome.
Attached code is deleted. Please add it again.
ReplyDeleteGreat post. Thank you
Thanks for sharing the useful blog about Solutions to share data between apps using Content Provider in Android with Example.
ReplyDeleteAndroid App Development in Coimbatore
Caused by: java.lang.IllegalArgumentException: Unknown URI content://com.ril.gcmbroadcastreciver.MyProvider/cte
ReplyDeleteWonderful!.Thank you so much for this.
ReplyDeleteIt is working wonderfully.Thank you for this.
ReplyDeleteBut there are two small mistakes --
1) In MyProvider class, uriCode will be of type int, not String.
2) Just next to uriCode, there is UriMatcher, where "String" would not come...
Rest the code is perfect..!
Tq for sharing valuable information with us about study bible
ReplyDeleteTo recover lost files click on: android data recovery
android data recovery apk without root
android data recovery software
android data recovery app
android data recovery free
android recovery
diskdigger for android
Excelente!! Funciona perfecto, gracias!
ReplyDeleteYeah, by utilizing ways after reading this article i have transferred data to another application.
ReplyDeleteThe Android users are increasing daily and I hope this recovery tool may help the smartphone users which are suffering from data loss and media files deletion from them.
I would like to recommend you the android data lost users to use Android Data Recovery Software to get easily and in just a few steps they will get back their all lost data from LeMax, Realme, Samsung, Blu Dash, Xiaomi, Huawei, ZTE, Lenovo, Motorola, Oppo, OnePlus, and much more mobile phones also.
Most wonderfull Article, Thanks for sharing!
ReplyDeleteCreating Viral Content In 10 Unforgettable Ways
Thanks for sharing great post. I really like this post.
ReplyDeleteCLICK HERE;
Android App Development
Mobile App DevelopmentiOS App Development
On working with your code and generating the app for android 9+ gives error for overriding and on resolving it show another error, please help.
ReplyDeleteAndroid app online
ReplyDeleteAndroid App Online - Learn more about how to create android app online from Magento 2, We are the best online android app maker that provide the best service for android app, contact us.
to get more - https://www.ibcappmaker.com/en/platforms/magento2-android-ios-app-builder
Thank you for writing such an amazing articles and you have been covered every important points with example.
ReplyDeleteHow to use insert() method from other application for adding data.
ReplyDeleteActually quite pleasant blog. A debt of gratitude is in order for sharing stunning tips. For more data about Mobile app development company in texas visit us at W2S Solutions.
ReplyDeleteThanks for your information is so helpful, and your personal comments are so easy to follow.
ReplyDeleteSAAS Application Development in chennai
Application integration development in Chennai
custom software application development chennai
Custom software application development chennai
Web application development company in Chennai
mobile app developers in chennai
This article is very nice, please inform to more information You are doing a very good job.
ReplyDeletephotoshoot in Andaman
photographers in andaman
photoshoot at andaman
andaman photoshoot
pre wedding shoot in andaman
photoshoot in havelock Andaman
I think this is a real great blog. Really looking forward to read more. Great.
ReplyDeletebest home stay in yercaud
couple friendly hotels in yercaud
yercaud residency
hotel in yercaud tamil nadu
hotels in yercaud for family
hotels in yercaud near lake
yercaud hotels low price
hotel at yercaud tamil nadu
Thank you for taking the time to write such an informative post. Your blog is not only informative, but it is also very creative.
ReplyDeleteprogressive native app
android development company</a
ReplyDeleteCommunication with the audience through blog is one of the core functions of dynamic work culture. Speak highly of by your peers to enhance the ability for building good relationships with your readers. Houses for Sale by Owner
ReplyDeleteI can only express a word of thanks! Nothing else, because your topic is nice, you can add knowledge. Thank you very much for sharing this information.
ReplyDeleteandroid consulting
Your blog is incredibly informative and the way you present your ideas is truly impressive. The effort you put into creating such valuable content is commendable. Thank you for this post, and please continue sharing more insightful articles like this—it’s genuinely helpful for readers like me!
ReplyDeleteBhubaneswar Travels Tour Packages