简体   繁体   中英

Android Content Provider not working

I am trying to figure out why this content provider isn't working. I feel like i have everything that i should have inorder to get it to work. for some reason it keeps crashing on the insert method. I think it's got something to do with the labelling of the content provider. If you have any help please explain what i am doing wrong. I also have the logcat at the bottom.

My intention is to insert some data into the content provider but doesn't seem to be able to find it.

this is my class for the content provider

package net.learn2develop.ContentProviders;

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.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

public class CourseProvider extends ContentProvider
{
    /* define constants for the content provider */

    // authority
    static final String PROVIDER_NAME =
                           "seneca.ict.provider.Courses";

    // content URI: authority + data path
    // - access modifier: public!
    public static final Uri CONTENT_URI =
                         Uri.parse("content://"+ PROVIDER_NAME + "/courses");

    // column names for the content provider
    // - access modifiers: public!
    public static final String _ID = "_id";
    public static final String TITLE = "desc";
    public static final String ISBN = "code";

    static final int BOOKS = 1;
    static final int BOOK_ID = 2;

    // UriMatcher: utility class used for matching URIs
    private static final UriMatcher uriMatcher;
    static{
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(PROVIDER_NAME, "courses", BOOKS);
        uriMatcher.addURI(PROVIDER_NAME, "courses/#", BOOK_ID);
    }

    /* define constants for the database */
    //---for database use---
    SQLiteDatabase booksDB;

    static final String DATABASE_NAME = "ICTCOURSES";
    static final String DATABASE_TABLE = "COURSESINFO";
    static final int    DATABASE_VERSION = 1;

    static final String DATABASE_CREATE =
                        "create table " + DATABASE_TABLE +
                        " (_id integer primary key autoincrement, "
                        + "desc text not null, code text not null,room 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(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion,
                int newVersion) {
            Log.w("Content provider database",
                    "Upgrading database from version " +
                            oldVersion + " to " + newVersion +
                    ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS titles");
            onCreate(db);
        }
    } // end DatabaseHelper

    /* implemenation of the CRUD principle */
    @Override
    public int delete(Uri arg0, String arg1, String[] arg2) {
        // arg0 = uri 
        // arg1 = selection
        // arg2 = selectionArgs
        int count=0;
        switch (uriMatcher.match(arg0)){
        case BOOKS:
            count = booksDB.delete(
                    DATABASE_TABLE,
                    arg1,
                    arg2);
            break;
        case BOOK_ID:
            String id = arg0.getPathSegments().get(1);
            count = booksDB.delete(
                    DATABASE_TABLE,
                    _ID + " = " + id +
                    (!TextUtils.isEmpty(arg1) ? " AND (" +
                            arg1 + ')' : ""),
                            arg2);
            break;
        default: throw new IllegalArgumentException("Unknown URI " + arg0);
        }

        // notify listeners for data changes (caused by delete) in the content provider
        getContext().getContentResolver().notifyChange(arg0, null);

        return count;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)){

        //---get all books---
        case BOOKS:
            return "vnd.android.cursor.dir/vnd.learn2develop.courses ";

        //---get a particular book---
        case BOOK_ID:
            return "vnd.android.cursor.item/vnd.learn2develop.courses ";

        default:
            throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        //---add a new book---

        long rowID = booksDB.insert(
                        DATABASE_TABLE,
                        "",
                        values);

        //---if added successfully---
        if (rowID>0)
        {
            Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);

            // notify listeners for data changes (caused by insert) in the content provider
            getContext().getContentResolver().notifyChange(_uri, null);

            return _uri;
        }
        throw new SQLException("Failed to insert row into " + uri);
    }

    @Override
    public boolean onCreate() {
        Context context = getContext();

        DatabaseHelper dbHelper = new DatabaseHelper(context);

        booksDB = dbHelper.getWritableDatabase();

        return (booksDB == null)? false:true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {

        SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();

        sqlBuilder.setTables(DATABASE_TABLE);

        if (uriMatcher.match(uri) == BOOK_ID)

            //---if getting a particular book---
            sqlBuilder.appendWhere(
                    _ID + " = " + uri.getPathSegments().get(1));

        if (sortOrder==null || sortOrder=="")
            sortOrder = TITLE;

        Cursor c = sqlBuilder.query(
                      booksDB,
                      projection,
                      selection,
                      selectionArgs,
                      null,
                      null,
                      sortOrder);

        //---register to watch a content URI for changes---
        // - the given URI will be notified when there'a a data change in the Cursor object
        c.setNotificationUri(getContext().getContentResolver(), uri);

        return c;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {

        int count = 0;

        switch (uriMatcher.match(uri)){

        case BOOKS:
             count = booksDB.update(
                        DATABASE_TABLE,
                        values,
                        selection,
                        selectionArgs );
            break;
        case BOOK_ID:
             count = booksDB.update(
                        DATABASE_TABLE,
                        values,
                        _ID + " = " + uri.getPathSegments().get(1) +
                        (!TextUtils.isEmpty(selection) ? " AND (" +
                             selection + ')' : ""), 
                        selectionArgs );
            break;
        default: throw new IllegalArgumentException("Unknown URI " + uri);
        }

        // notify listeners for data changes (caused by update) in the content provider
        getContext().getContentResolver().notifyChange(uri, null);

        return count;
    }

and this is the manifest file that i used to load the content provider

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.learn2develop.ContentProviders"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="14" 
              android:targetSdkVersion="18"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".ContentProvidersActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider android:name="CourseProvider"
            android:authorities="net.learn2develop.provider.Courses"
            android:exported="true">            
        </provider>            
    </application>

</manifest>

this is the activity that is suppose to be running

/* Source: Wei-Ming Lee's website
 * http://www.wrox.com/WileyCDA/WroxTitle/Beginning-Android-4-Application-Development.productCd-1118199545.html
 * Modified and Commented by Peter Liu (10/01/2013) 
 */
package net.learn2develop.ContentProviders;

import android.app.Activity;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
/* The activity is used to create (and test) the content provider */

public class ContentProvidersActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void onClickAddTitle(View view) {

        //---add a book---
        ContentValues values = new ContentValues();

        // use the class BooksProvider (within the same package)!
        values.put( CourseProvider.TITLE, 
                    ((EditText)
                         findViewById(R.id.txtTitle)).getText().toString());

        values.put( CourseProvider.ISBN, 
                    ((EditText)
                         findViewById(R.id.txtISBN)).getText().toString());


        Uri uri = getContentResolver().insert(
                      CourseProvider.CONTENT_URI, 
                      values);

       /*
        ContentValues values = new ContentValues();

        values.put( "title", 
                    ((EditText) findViewById(R.id.txtTitle)).getText().toString() );

        values.put( "isbn", 
                    ((EditText) findViewById(R.id.txtISBN)).getText().toString());

        Uri uri = getContentResolver().insert(
                     Uri.parse("content://net.learn2develop.provider.Books/books"),
                     values );
        */

        Toast.makeText( getBaseContext(),
                        uri.toString(),
                        Toast.LENGTH_LONG).show();

//      Toast.makeText( getBaseContext(),
//              "hello",
//              Toast.LENGTH_LONG).show();
    }

    public void onClickRetrieveTitles(View view) {

        //---retrieve the titles---
        Uri allTitles = Uri.parse("content://seneca.ict.provider.Courses/courses");

        Cursor c; 

        if (android.os.Build.VERSION.SDK_INT <11) {
            //---before Honeycomb---
            c = managedQuery(allTitles, null, null, null,
                    "title desc");
        } else {

            //---Honeycomb and later---
            CursorLoader cursorLoader = new CursorLoader(
                    this, 
                    allTitles, // URI
                    null, 
                    null, 
                    null,
                    "title desc" );

            c = cursorLoader.loadInBackground();   // a separate thread         
        }

        // use the class BooksProvider (within the same package)!
        if (c.moveToFirst()) {
            do{
                Toast.makeText(this, 
                        c.getString(c.getColumnIndex(
                                    CourseProvider._ID)) + ", " +

                        c.getString(c.getColumnIndex(
                                    CourseProvider.TITLE)) + ", " +

                        c.getString(c.getColumnIndex(
                                    CourseProvider.ISBN)),

                        Toast.LENGTH_SHORT).show();

            } while (c.moveToNext());
        }
    }

    public void updateTitle() {
        ContentValues editedValues = new ContentValues();

        editedValues.put(CourseProvider.TITLE, "Android Tips and Tricks");

        getContentResolver().update(

                Uri.parse("content://seneca.ict.provider.Courses/courses/2"),

                editedValues,
                null,
                null );
    }

    public void deleteTitle() {

        //---delete a title---
        getContentResolver().delete(

                Uri.parse("content://seneca.ict.provider.Courses/courses/2"),
                null, 
                null );


        //---delete all titles---
        getContentResolver().delete(

                Uri.parse("content://seneca.ict.provider.Courses/courses"),
                null, 
                null );
    }
} // end class

the log cat

11-08 19:26:15.536: E/ActivityThread(2022): Failed to find provider info for seneca.ict.provider.Courses
11-08 19:26:15.547: D/AndroidRuntime(2022): Shutting down VM
11-08 19:26:15.547: W/dalvikvm(2022): threadid=1: thread exiting with uncaught exception (group=0x41465700)
11-08 19:26:15.636: E/AndroidRuntime(2022): FATAL EXCEPTION: main
11-08 19:26:15.636: E/AndroidRuntime(2022): java.lang.IllegalStateException: Could not execute method of the activity
11-08 19:26:15.636: E/AndroidRuntime(2022):     at android.view.View$1.onClick(View.java:3633)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at android.view.View.performClick(View.java:4240)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at android.view.View$PerformClick.run(View.java:17721)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at android.os.Handler.handleCallback(Handler.java:730)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at android.os.Handler.dispatchMessage(Handler.java:92)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at android.os.Looper.loop(Looper.java:137)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at android.app.ActivityThread.main(ActivityThread.java:5103)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at java.lang.reflect.Method.invokeNative(Native Method)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at java.lang.reflect.Method.invoke(Method.java:525)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at dalvik.system.NativeStart.main(Native Method)
11-08 19:26:15.636: E/AndroidRuntime(2022): Caused by: java.lang.reflect.InvocationTargetException
11-08 19:26:15.636: E/AndroidRuntime(2022):     at java.lang.reflect.Method.invokeNative(Native Method)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at java.lang.reflect.Method.invoke(Method.java:525)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at android.view.View$1.onClick(View.java:3628)
11-08 19:26:15.636: E/AndroidRuntime(2022):     ... 11 more
11-08 19:26:15.636: E/AndroidRuntime(2022): Caused by: java.lang.IllegalArgumentException: Unknown URL content://seneca.ict.provider.Courses/courses
11-08 19:26:15.636: E/AndroidRuntime(2022):     at android.content.ContentResolver.insert(ContentResolver.java:910)
11-08 19:26:15.636: E/AndroidRuntime(2022):     at net.learn2develop.ContentProviders.ContentProvidersActivity.onClickAddTitle(ContentProvidersActivity.java:41)
11-08 19:26:15.636: E/AndroidRuntime(2022):     ... 14 more

You have create a URI to access the Course Table but given wrong name courses

public static final Uri CONTENT_URI =
                         Uri.parse("content://"+ PROVIDER_NAME + "/courses");//Wrong

B'coz you given Table name is

static final String DATABASE_TABLE = "COURSESINFO";

So change your DATABASE_TABLE name ie COURSESINFO to courses

or

public static final Uri CONTENT_URI =
                         Uri.parse("content://"+ PROVIDER_NAME + "/COURSESINFO");

Hope this would help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM