0

我试图弄清楚为什么这个内容提供者不工作。我觉得我拥有一切我应该拥有的东西才能让它工作。由于某种原因,它一直在 insert 方法上崩溃。我认为这与内容提供商的标签有关。如果您有任何帮助,请解释我做错了什么。我在底部也有 logcat。

我的意图是将一些数据插入内容提供程序,但似乎无法找到它。

这是我的内容提供者课程

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;
    }

这是我用来加载内容提供者的清单文件

<?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>

这是假设正在运行的活动

/* 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

原木猫

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
4

1 回答 1

-1

您已创建一个 URI 来访问Course Table但名称错误的课程

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

B'coz 你给的表名是

static final String DATABASE_TABLE = "COURSESINFO";

所以改变你的DATABASE_TABLE名字,即COURSESINFOcourses

或者

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

希望这会对你有所帮助。

于 2013-11-09T01:43:36.777 回答