2011-05-18 44 views
1

我想第一次創建自己的內容提供者,並且無法弄清楚我做錯了什麼。當我在底部運行測試代碼時,我得到一個未知的URI異常,並且在我的生活中,我無法弄清楚什麼是錯誤的。任何幫助將不勝感激。我的ContentProvider出什麼問題

CodesContentProvider.java

public class CodesContentProvider extends ContentProvider { 

private static final String TAG = "CodesContentProvider"; 

private static String DATABASE_NAME; 

private static final int DATABASE_VERSION = 1; 

private static final String CODES_TABLE_NAME = "codes"; 

private static final String TITLES_TABLE_NAME = "titles"; 

public static final String AUTHORITY = "com.xxx.capenal.providers.CodesContentProvider"; 

private static UriMatcher sUriMatcher; 

private static final int CODES = 1; 

private static final int TITLES = 2; 

private static SQLiteDatabase mDatabase = null; 

private static HashMap<String, String> codesProjectionMap; 

private static HashMap<String, String> titlesProjectionMap; 




private static class DatabaseHelper extends SQLiteOpenHelper { 

    DatabaseHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 

     File path; 
     final File DataDirectory; 
     path = Environment.getExternalStorageDirectory(); 
     DataDirectory = new File(path,context.getString(R.string.DATABASE_DIRECTORY)); 
     DATABASE_NAME = new File(DataDirectory, context.getString(R.string.DATABASE_FILE_NAME)).toString(); 


    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     //TODO: Add titles to this statement 
     db.execSQL("CREATE TABLE " + CODES_TABLE_NAME + " (" + Codes.CODE_ID 
       + " INTEGER PRIMARY KEY AUTOINCREMENT," + Codes.PARENT_ID + " VARCHAR(255)," + Codes.CODE 
       + " LONGTEXT" + ");"); 
    } 

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

    @Override 
    public synchronized SQLiteDatabase getReadableDatabase() { 

     try { 
      return getWritableDatabase(); 
     } catch (SQLiteException e) { 
       //Log.e("", "Couldn't open " + DATABASE_NAME + " for writing (will try read-only):", e); 
     } 

     SQLiteDatabase db = null; 

     try { 
      //mIsInitializing = true; 
      db = SQLiteDatabase.openDatabase(DATABASE_NAME, null, SQLiteDatabase.OPEN_READONLY); 
      if (db.getVersion() != DATABASE_VERSION) { 
       throw new SQLiteException("Can't upgrade read-only database from version " + db.getVersion() + " to " 
        + DATABASE_VERSION + ": " + DATABASE_NAME); 
     } 
      onOpen(db); 
      mDatabase = db; 
      return mDatabase; 
     } finally { 
      //mIsInitializing = false; 
      if (db != null && db != mDatabase) 
       db.close(); 
     } 
    } 

    @Override 
    public synchronized SQLiteDatabase getWritableDatabase() { 
     boolean success = false; 
     SQLiteDatabase db = null; 
     // if (mDatabase != null) mDatabase.lock(); //can't call the locks for 
     // some reason. beginTransaction does lock it though 
     try { 
      //mIsInitializing = true; 
      db = SQLiteDatabase.openOrCreateDatabase(DATABASE_NAME, null); 
      int version = db.getVersion(); 
      if (version != DATABASE_VERSION) { 
       db.beginTransaction(); 
       try { 
        if (version == 0) { 
          onCreate(db); 
        } else { 
          onUpgrade(db, version, DATABASE_VERSION); 
        } 
        db.setVersion(DATABASE_VERSION); 
        db.setTransactionSuccessful(); 
       } finally { 
        db.endTransaction(); 
       } 
      } 
      onOpen(db); 
      success = true; 
      return db; 
     } finally { 
      // mIsInitializing = false; 
      if (success) { 
       if (mDatabase != null) { 
        try { 
         mDatabase.close(); 
        } catch (Exception e) { 
        } 
        // mDatabase.unlock(); 
       } 
       mDatabase = db; 
      } else { 
       // if (mDatabase != null) mDatabase.unlock(); 
       if (db != null) 
        db.close(); 
      } 
     } 
    } 
} 

private DatabaseHelper dbHelper; 

@Override 
public int delete(Uri uri, String where, String[] whereArgs) { 
    SQLiteDatabase db = dbHelper.getWritableDatabase(); 
    int count; 
    switch (sUriMatcher.match(uri)) { 
     case CODES: 
      count = db.delete(CODES_TABLE_NAME, where, whereArgs); 
      break; 

     case TITLES: 
      count = db.delete(TITLES_TABLE_NAME, where, whereArgs); 
      break; 

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

    getContext().getContentResolver().notifyChange(uri, null); 
    return count; 
} 

@Override 
public String getType(Uri uri) { 
    switch (sUriMatcher.match(uri)) { 
     case CODES: 
      return Codes.CONTENT_TYPE; 

     case TITLES: 
      return Titles.CONTENT_TYPE; 

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

@Override 
public Uri insert(Uri uri, ContentValues initialValues) { 
    if (sUriMatcher.match(uri) != CODES) { throw new IllegalArgumentException("Unknown URI " + uri); } 

    ContentValues values; 
    if (initialValues != null) { 
     values = new ContentValues(initialValues); 
    } else { 
     values = new ContentValues(); 
    } 

    SQLiteDatabase db = dbHelper.getWritableDatabase(); 
    long rowId = db.insert(CODES_TABLE_NAME, Codes.DEFINITION, values); 
    if (rowId > 0) { 
     Uri CodeUri = ContentUris.withAppendedId(Codes.CONTENT_URI, rowId); 
     getContext().getContentResolver().notifyChange(CodeUri, null); 
     return CodeUri; 
    } 

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

@Override 
public boolean onCreate() { 
    dbHelper = new DatabaseHelper(getContext()); 
    return true; 
} 

@Override 
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 

    switch (sUriMatcher.match(uri)) { 
     case CODES: 
      qb.setTables(CODES_TABLE_NAME); 
      qb.setProjectionMap(codesProjectionMap); 
      break; 

     case TITLES: 
      qb.setTables(TITLES_TABLE_NAME); 
      qb.setProjectionMap(titlesProjectionMap); 
      break; 

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

    SQLiteDatabase db = dbHelper.getReadableDatabase(); 
    Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); 

    c.setNotificationUri(getContext().getContentResolver(), uri); 
    return c; 
} 

@Override 
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { 
    SQLiteDatabase db = dbHelper.getWritableDatabase(); 
    int count; 
    switch (sUriMatcher.match(uri)) { 
     case CODES: 
      count = db.update(CODES_TABLE_NAME, values, where, whereArgs); 
      break; 

     case TITLES: 
      count = db.update(TITLES_TABLE_NAME, values, where, whereArgs); 
      break; 

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

    getContext().getContentResolver().notifyChange(uri, null); 
    return count; 
} 

static { 
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
    sUriMatcher.addURI(AUTHORITY, CODES_TABLE_NAME, CODES); 

    codesProjectionMap = new HashMap<String, String>(); 
    codesProjectionMap.put(Codes.CODE_ID, Codes.CODE_ID); 
    codesProjectionMap.put(Codes.PARENT_ID, Codes.PARENT_ID); 
    codesProjectionMap.put(Codes.CODE, Codes.CODE); 
    codesProjectionMap.put(Codes.DEFINITION, Codes.DEFINITION); 
    codesProjectionMap.put(Codes.EXCERPT, Codes.EXCERPT); 

} 

static { 
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
    sUriMatcher.addURI(AUTHORITY, TITLES_TABLE_NAME, TITLES); 

    titlesProjectionMap = new HashMap<String, String>(); 
    titlesProjectionMap.put(Titles.TYPE, Titles.TYPE); 
    titlesProjectionMap.put(Titles.SECTION, Titles.SECTION); 
    titlesProjectionMap.put(Titles.FULL_TITLE, Titles.FULL_TITLE); 
    titlesProjectionMap.put(Titles.TITLE, Titles.TITLE); 
    titlesProjectionMap.put(Titles.TITLE_ID, Titles.TITLE_ID); 
    titlesProjectionMap.put(Titles.PARENT_ID, Titles.PARENT_ID); 
    titlesProjectionMap.put(Titles.CODE_RANGE, Titles.CODE_RANGE); 

} 

}

public class Code { 

public Code() { 
} 

public static final class Codes implements BaseColumns { 
    private Codes() { 
    } 

    public static final Uri CONTENT_URI = Uri.parse("content://" 
      + CodesContentProvider.AUTHORITY + "/codes"); 

    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.xxx.codes"; 

    public static final String CODE_ID = "_id"; 
    public static final String PARENT_ID = "parent_id"; 
    public static final String CODE = "code"; 
    public static final String DEFINITION = "definition"; 
    public static final String EXCERPT = "excerpt"; 
} 

}

 <provider android:name="com.xxx.capenal.providers.CodesContentProvider" 
    android:authorities="com.xxx.capenal.providers.CodesContentProvider" /> 

測試代碼:

// Form an array specifying which columns to return. 
    String[] projection = new String[] { 
           Codes._ID, 
           Codes.CODE_ID, 
           Codes.PARENT_ID, 
           Codes.EXCERPT 
           }; 

    // Get the base URI for the People table in the Contacts content provider. 
    Uri codes = Codes.CONTENT_URI; 

    // Make the query. 
    Cursor managedCursor = managedQuery(codes, 
          projection, // Which columns to return 
          null,  // Which rows to return (all rows) 
          null,  // Selection arguments (none) 
          // Put the results in ascending order by name 
          Codes.CODE_ID + " ASC"); 

堆棧跟蹤:

05-17 17:49:48.959: ERROR/AndroidRuntime(22769): FATAL EXCEPTION: main 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769): java.lang.RuntimeException: Unable to pause activity {com.xxx.capenal/com.xxx.capenal.main}: java.lang.RuntimeException: Unable to pause activity {com.xxx.capenal/com.xxx.capenal.parent}: java.lang.IllegalArgumentException: Unknown URI content://com.xxx.capenal.providers.CodesContentProvider/codes/23 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2487) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2444) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2422) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread.access$1700(ActivityThread.java:122) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1009) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.os.Handler.dispatchMessage(Handler.java:99) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.os.Looper.loop(Looper.java:132) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread.main(ActivityThread.java:4025) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at java.lang.reflect.Method.invokeNative(Native Method) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at java.lang.reflect.Method.invoke(Method.java:491) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at dalvik.system.NativeStart.main(Native Method) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769): Caused by: java.lang.RuntimeException: Unable to pause activity {com.xxx.capenal/com.xxx.capenal.parent}: java.lang.IllegalArgumentException: Unknown URI content://com.xxx.capenal.providers.CodesContentProvider/codes/23 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2487) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2444) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.LocalActivityManager.performPause(LocalActivityManager.java:203) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:187) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.LocalActivityManager.dispatchPause(LocalActivityManager.java:547) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityGroup.onPause(ActivityGroup.java:73) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.Activity.performPause(Activity.java:4452) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1194) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2474) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  ... 12 more 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769): Caused by: java.lang.IllegalArgumentException: Unknown URI content://com.xxx.capenal.providers.CodesContentProvider/codes/23 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at com.xxx.capenal.providers.CodesContentProvider.query(CodesContentProvider.java:241) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.content.ContentProvider$Transport.query(ContentProvider.java:192) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.content.ContentResolver.query(ContentResolver.java:302) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.Activity.managedQuery(Activity.java:1670) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at com.xxx.capenal.parent.onPause(parent.java:160) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.Activity.performPause(Activity.java:4452) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1194) 
05-17 17:49:48.959: ERROR/AndroidRuntime(22769):  at android.app.ActivityThread.performPauseActivity(ActivityThread.jav 

一:2474) 05-17 17:49:48.959:ERROR/AndroidRuntime(22769):...... 20多個

+0

對我來說,似乎是在'CodesContentProvider'類的末尾的兩個靜態初始化塊中爲'sUriMatcher'分配兩次。 – 2011-05-18 03:05:24

+0

你是完全正確的。我不知道我以爲這會起作用。你介意讓這個答案,所以我可以給你信用? – 2011-05-18 04:13:00

+0

當然,謝謝。 (15個字符) – 2011-05-18 05:32:05

回答

1

看來你要分配兩次在CodesContentProvider類的末尾的兩個靜態初始化塊中。