我试图弄清楚为什么这个内容提供者不工作。我觉得我拥有一切我应该拥有的东西才能让它工作。由于某种原因,它一直在 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