问题
This is my first time using a content provider but I followed the developer docs but when I run the program it tells me failed to find provider info
here is my manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tyczj.bowling"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="11" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity android:name="Tabs">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="BowlersList"></activity>
</application>
<provider android:name="com.tyczj.bowling.BowlersDB"
android:authorities="com.tyczj.bowling.bowlersdb">
</provider>
</manifest>
and my content provider
public class BowlersDB extends ContentProvider {
private static final String DATABASE_NAME = "Bowlers";
private static final String BOWLERS_TABLE = "bowlers_table";
private static final int DATABASE_VERSION = 1;
public static final Uri CONTENT_URI = Uri.parse("content://com.tyczj.bowling.bowlersdb");
private static final UriMatcher uriMatcher;
static final String NAME = "name";
static final String ID = "_id";
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public Cursor getBowlers(){
return db.query(BOWLERS_TABLE, new String[] {ID,NAME},null,null,null,null,NAME + " ASC");
}
public Cursor getId(String name){
Cursor c = db.query(BOWLERS_TABLE, new String[] {ID,NAME},NAME + "='" + name +"'",null,null,null,null);
if(c != null && c.moveToFirst()){
do{
if(c.getString(c.getColumnIndex(NAME)).equals(name)){
return c;
}
}while(c.moveToNext());
}
return c;
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
createTables(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
Log.w("CalendarDB", "Upgrading database from version " + oldVersion
+ " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS Events_Table");
onCreate(db);
}
private void createTables(SQLiteDatabase db){
db.execSQL("CREATE TABLE " + BOWLERS_TABLE + "(" + ID + " integer primary key autoincrement, " +
NAME + " TEXT);");
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
int num = uriMatcher.match(uri);
if(num == 1){
count = db.delete(BOWLERS_TABLE, selection,selectionArgs);
}else if(num == 2){
String id = uri.getPathSegments().get(1);
count = db.delete(BOWLERS_TABLE, ID + " = " + id + (!TextUtils.isEmpty(selection) ? " AND (" +
selection + ')' : ""),
selectionArgs);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
if(uriMatcher.match(uri) == 1){
return "vnd.android.cursor.dir/vnd.tyczj.bowlersdb ";
}else if(uriMatcher.match(uri) == 2){
return "vdn.android.cursor.item/vnd.tyczj.bowlersdb ";
}else
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowID = db.insert(BOWLERS_TABLE,null, values);
if(rowID > 0){
Uri _uri = ContentUris.withAppendedId(CONTENT_URI,rowID);
getContext().getContentResolver().notifyChange(_uri,null);
return _uri;
}else{
throw new SQLException("Failed to insert row into " + uri);
}
}
@Override
public boolean onCreate() {
Context context = getContext();
DBHelper = new DatabaseHelper(context);
db = DBHelper.getWritableDatabase();
return (db == null)? false:true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
sqlBuilder.setTables(BOWLERS_TABLE);
if(uriMatcher.match(uri) == 1){
sqlBuilder.appendWhere(ID + " = " + uri.getPathSegments().get(1));
}
if(sortOrder == null || sortOrder == "")
sortOrder = NAME;
Cursor c = sqlBuilder.query(db, projection, selection, selectionArgs,null,null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count = 0;
int num = uriMatcher.match(uri);
if(num == 1){
count = db.update(BOWLERS_TABLE, values, selection, selectionArgs);
}else if(num == 2){
count = db.update(BOWLERS_TABLE, values, ID + " = " + uri.getPathSegments().get(1) + (!TextUtils.isEmpty(selection) ? " AND (" +
selection + ')' : ""),
selectionArgs);
}else{
throw new IllegalArgumentException(
"Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("com.tyczj.bowling.bowlersdb","bowlers",1);
uriMatcher.addURI("com.tyczj.bowling.bowlersdb","bowlers/#",2);
}
}
not sure what I did wrong?
回答1:
Provider needs to be in the application tag.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tyczj.bowling"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="11" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity android:name="Tabs">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="BowlersList"></activity>
<provider android:name="com.tyczj.bowling.BowlersDB"
android:authorities="com.tyczj.bowling.bowlersdb">
</provider>
</application>
</manifest>
回答2:
You should not call db = DBHelper.getWritableDatabase(); in the ContentProvider onCreate. This is for the reason given in SQLiteOpenHelper documentation for getReadableDatabase and getWritableDatabase:
Like getWritableDatabase, this method may take a long time to return, so you should not call it from the application main thread, including from ContentProvider.onCreate().
Instead hold a reference to the SQLiteOpenHelper instance and call getWritableDatabase/getReadableDatabase as appropriate in the query/insert/delete/update methods which are called asynchronously if you are using Loaders.
Sorry this is not targeted directly at the question, but it is something I've seen all over the place in code samples.
回答3:
you have got this error because you define your Provider outside of Application tag. so please define your provider inside application.
<application
........
<provider
android:name="com.tyczj.bowling.BowlersDB"
android:authorities="com.tyczj.bowling.bowlersdb">
</provider>
</application>
回答4:
This is a good example of why to use the Android Manifest editor in Eclipse. It puts such items/components in their syntactically correct location so one doesn't need to worry about this question. Another way of looking at it: consider using the Manifest editor in the beginning (& occassionally throughout) just to confirm the correctness of your manifest.
来源:https://stackoverflow.com/questions/8300603/declaring-content-provider