Android How to - Create Content Provider to read from Asset folder








The following code shows how to Create Content Provider to read from Asset folder.

Example

Register content provider in manifest xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.java2s.myapplication3.app" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="java2s.com"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.java2s.myapplication3.app.MainActivity"
            android:label="java2s.com" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider android:name=".MyProvider"
        android:authorities="com.java2s.myapplication3.app.imageprovider">
    </provider>

    </application>

</manifest>

Layout xml file

<?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:id="@+id/name"
    android:layout_width="wrap_content" 
    android:layout_height="20dip"
    android:layout_gravity="center_horizontal"
  />
  <ImageView
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="50dip"
    android:layout_gravity="center_horizontal"
  />
  <ListView
    android:id="@+id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
  />
</LinearLayout>

Main activity Java code

/* ww w  .  java 2s. c o m*/
package com.java2s.myapplication3.app;

import java.io.FileNotFoundException;
import java.io.InputStream;

import android.app.Activity;
import android.app.LoaderManager;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

public class MainActivity extends Activity implements
        LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener {
    private static final int LOADER_LIST = 100;
    SimpleCursorAdapter mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1,
                null, new String[]{MyProvider.COLUMN_NAME}, new int[]{android.R.id.text1}, 0);

        ListView list = (ListView)findViewById(R.id.list);
        list.setOnItemClickListener(this);
        list.setAdapter(mAdapter);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        //Seek the cursor to the selection
        Cursor c = mAdapter.getCursor();
        c.moveToPosition(position);

        //Load the name column into the TextView
        TextView tv = (TextView)findViewById(R.id.name);
        tv.setText(c.getString(1));

        ImageView iv = (ImageView)findViewById(R.id.image);
        try {
            //Load the content from the image column into the ImageView
            InputStream in = getContentResolver().openInputStream(Uri.parse(c.getString(2)));
            Bitmap image = BitmapFactory.decodeStream(in);
            iv.setImageBitmap(image);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        String[] projection = new String[]{"_id",
                MyProvider.COLUMN_NAME,
                MyProvider.COLUMN_IMAGE};
        return new CursorLoader(this, MyProvider.CONTENT_URI,
                projection, null, null, null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        mAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }
}

Java code for image content provider

package com.java2s.myapplication3.app;
//from  ww w  .j a  va 2 s .  com
import java.io.FileNotFoundException;
import java.io.IOException;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;

public class MyProvider extends ContentProvider {

    public static final Uri CONTENT_URI = Uri.parse("content://com.examples.share.imageprovider");

    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_NAME = "nameString";
    public static final String COLUMN_IMAGE = "imageUri";
    /* Default projection if none provided */
    private static final String[] DEFAULT_PROJECTION = {
            COLUMN_ID, COLUMN_NAME, COLUMN_IMAGE
    };

    private String[] mNames, mFilenames;

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("This ContentProvider is read-only");
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        throw new UnsupportedOperationException("This ContentProvider is read-only");
    }

    @Override
    public boolean onCreate() {
        mNames = new String[] {"John Doe", "Jane Doe", "Jill Doe"};
        mFilenames = new String[] {"logo1.png", "logo2.png", "logo3.png"};
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        //Return all columns if no projection given
        if (projection == null) {
            projection = DEFAULT_PROJECTION;
        }
        MatrixCursor cursor = new MatrixCursor(projection);

        for(int i = 0; i < mNames.length; i++) {
            //Insert only the columns they requested
            MatrixCursor.RowBuilder builder = cursor.newRow();
            for(String column : projection) {
                if(COLUMN_ID.equals(column)) {
                    //Use the array index as a unique id
                    builder.add(i);
                }
                if(COLUMN_NAME.equals(column)) {
                    builder.add(mNames[i]);
                }
                if(COLUMN_IMAGE.equals(column)) {
                    builder.add(Uri.withAppendedPath(CONTENT_URI, String.valueOf(i)));
                }
            }
        }
        return cursor;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("This ContentProvider is read-only");
    }

    @Override
    public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
        int requested = Integer.parseInt(uri.getLastPathSegment());
        AssetFileDescriptor afd;
        AssetManager manager = getContext().getAssets();
        //Return the appropriate asset for the requested item
        try {
            switch(requested) {
                case 0:
                case 1:
                case 2:
                    afd = manager.openFd(mFilenames[requested]);
                    break;
                default:
                    afd = manager.openFd(mFilenames[0]);
                    break;
            }
            return afd;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}