Android content provider example
May 17, 2011 11:13:17 Last update: May 17, 2011 11:13:17
This is an odd-ball content provider in that it doesn't provide database records, but provides a resource as a stream. It can be used to provide media files or XML resources.
- Start the project with:
tools/android create project --package com.android.cptest \ --activity Dummy --target 2 --path ContentProvider
- Create
assetsdirectory and add an XML file (assets/demo.xml):<? xml version="1.0" encoding="UTF-8"?> <people> <person id="1"> <first-name>Jack</first-name> <last-name>Smith</last-name> </person> <person id="2"> <first-name>Steve</first-name> <last-name>Jones</last-name> </person> </people>
- Edit the layout (
res/layout/main.xml):<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/content" /> </LinearLayout>
- Edit
src/com/android/cptest/Dummy.java:package com.android.cptest; import java.io.*; import android.app.Activity; import android.content.ContentResolver; import android.os.Bundle; import android.net.Uri; import android.util.Log; import android.widget.TextView; public class Dummy extends Activity { private static final String TAG = "Dummy"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { ContentResolver r = getContentResolver(); InputStream in = r.openInputStream(Uri.parse("content://com.android.cptest.XmlResource")); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int n = in.read(buffer); while (n >= 0) { out.write(buffer, 0, n); n = in.read(buffer); } in.close(); TextView content = (TextView) findViewById(R.id.content); content.setText(out.toString()); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "ERROR: " + e); } } }
- Add content provider (
src/com/android/cptest/XmlResource.java):package com.android.cptest; import java.io.*; import android.content.ContentProvider; import android.content.ContentValues; import android.content.res.AssetFileDescriptor; import android.database.Cursor; import android.net.Uri; import android.util.Log; public class XmlResource extends ContentProvider { private static final String TAG = "XmlResource"; @Override public boolean onCreate() { return true; } @Override public String getType(Uri uri) { return null; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int delete(Uri uri, String selection, String[] aelectionArgs) { return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } @Override public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { Log.d(TAG, "Uri: " + uri); Log.d(TAG, "mode: " + mode); try { return getContext().getAssets().openFd("demo.xml"); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "ERROR: " + e); throw new FileNotFoundException(e.getMessage()); } } }
- Update
AndroidManifest.xml:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.cptest" android:versionCode="1" android:versionName="1.0"> <application android:label="@string/app_name" android:icon="@drawable/icon"> <activity android:name="Dummy" 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="XmlResource" android:authorities="com.android.cptest.XmlResource"/> </application> </manifest>
- Add this section to the end of
build.xml:<target name="-package-resources"> <echo>Packaging resources!!!</echo> <aapt executable="${aapt}" command="package" versioncode="${version.code}" debug="${build.packaging.debug}" manifest="AndroidManifest.xml" assets="${asset.absolute.dir}" androidjar="${android.jar}" apkfolder="${out.absolute.dir}" resourcefilename="${resource.package.file.name}" resourcefilter="${aapt.resource.filter}"> <res path="${resource.absolute.dir}" /> <nocompress extension="xml" /> </aapt> </target>
- Build and install:
ant install
- Screenshot:
- Remove the
Dummyactivity (AndroidManifest.xml):<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.cptest" android:versionCode="1" android:versionName="1.0"> <application android:label="@string/app_name" android:icon="@drawable/icon"> <provider android:name="XmlResource" android:authorities="com.android.cptest.XmlResource"/> </application> </manifest>
- Create a new project for the content consumer:
tools/android create project --package com.android.cctest \ --activity ContentConsumer --target 2 --path ContentConsumer
- Copy the layout from the previous project:
cp ../ContentProvider/res/layout/main.xml res/layout/main.xml
- Copy the
Activitycode from the previous project (src/com/android/cctest/ContentConsumer.java):package com.android.cctest; import java.io.*; import android.app.Activity; import android.content.ContentResolver; import android.os.Bundle; import android.net.Uri; import android.util.Log; import android.widget.TextView; public class ContentConsumer extends Activity { private static final String TAG = "ContentConsumer"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { ContentResolver r = getContentResolver(); InputStream in = r.openInputStream(Uri.parse("content://com.android.cptest.XmlResource")); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int n = in.read(buffer); while (n >= 0) { out.write(buffer, 0, n); n = in.read(buffer); } in.close(); TextView content = (TextView) findViewById(R.id.content); content.setText(out.toString()); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "ERROR: " + e); } } }
- Install
ContentConsumer:ant install
- Now we have a content consumer in a separate APK from the content provider.