2014-01-20 111 views
10

我按照下面的教程http://www.vogella.de/articles/AndroidSQLite/article.htm如何解決在android內容提供者中找不到的內容提供者url?

但是,讓這個異常後點擊 「確認」 按鈕

01-20 10:18:14.585: E/AndroidRuntime(2006): Caused by: java.lang.IllegalArgumentException: Unknown URL content://com.example.todos.contentprovider/todos 
01-20 10:18:14.585: E/AndroidRuntime(2006):  at android.content.ContentResolver.insert(ContentResolver.java:910) 
01-20 10:18:14.585: E/AndroidRuntime(2006):  at com.example.todos.TodoDetailActivity.saveState(TodoDetailActivity.java:122) 
01-20 10:18:14.585: E/AndroidRuntime(2006):  at com.example.todos.TodoDetailActivity.onPause(TodoDetailActivity.java:100) 

TodoDetailActivity

public class TodoDetailActivity extends Activity { 

    private Spinner mCategory; 
    private EditText mTitleText; 
    private EditText mBodyText; 

    private Uri todoUri; 

    @Override 
    protected void onCreate(Bundle bundle) { 
     super.onCreate(bundle); 
     setContentView(R.layout.todo_edit); 

     mCategory = (Spinner) findViewById(R.id.category); 
     mTitleText = (EditText) findViewById(R.id.todo_edit_summary); 
     mBodyText = (EditText) findViewById(R.id.todo_edit_description); 
     Button confirmButton = (Button) findViewById(R.id.todo_edit_button); 

     Bundle extras = getIntent().getExtras(); 

     // check from the saved Instance 
     todoUri = (bundle == null) ? null : (Uri) bundle 
       .getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE); 

     // Or passed from the other activity 
     if (extras != null) { 
      todoUri = extras 
        .getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE); 

      fillData(todoUri); 
     } 

     confirmButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View view) { 
       if (TextUtils.isEmpty(mTitleText.getText().toString())) { 
        makeToast(); 
       } else { 
        setResult(RESULT_OK); 
        finish(); 
       } 
      } 

     }); 
    } 

    private void fillData(Uri uri) { 
     String[] projection = { TodoTable.COLUMN_SUMMARY, 
       TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY }; 
     Cursor cursor = getContentResolver().query(uri, projection, null, null, 
       null); 
     if (cursor != null) { 
      cursor.moveToFirst(); 
      String category = cursor.getString(cursor 
        .getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY)); 

      for (int i = 0; i < mCategory.getCount(); i++) { 

       String s = (String) mCategory.getItemAtPosition(i); 
       if (s.equalsIgnoreCase(category)) { 
        mCategory.setSelection(i); 
       } 
      } 

      mTitleText.setText(cursor.getString(cursor 
        .getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY))); 
      mBodyText.setText(cursor.getString(cursor 
        .getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION))); 

      // always close the cursor 
      cursor.close(); 
     } 
    } 

    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     saveState(); 
     outState.putParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     saveState(); 
    } 

    private void saveState() { 
     String category = (String) mCategory.getSelectedItem(); 
     String summary = mTitleText.getText().toString(); 
     String description = mBodyText.getText().toString(); 

     // only save if either summary or description 
     // is available 

     if (description.length() == 0 && summary.length() == 0) { 
      return; 
     } 

     ContentValues values = new ContentValues(); 
     values.put(TodoTable.COLUMN_CATEGORY, category); 
     values.put(TodoTable.COLUMN_SUMMARY, summary); 
     values.put(TodoTable.COLUMN_DESCRIPTION, description); 

     if (todoUri == null) { 
      // New todo 
      todoUri = getContentResolver().insert(
        MyTodoContentProvider.CONTENT_URI, values); 
     } else { 
      // Update todo 
      getContentResolver().update(todoUri, values, null, null); 
     } 
    } 

    private void makeToast() { 
     Toast.makeText(TodoDetailActivity.this, "Please maintain a summary", 
       Toast.LENGTH_LONG).show(); 
    } 
} 

MyTodoContentProvider

public class MyTodoContentProvider extends ContentProvider{ 

    //database 
    private TodoDatabaseHelper database; 

    //Used for the uriMatcher 
    private static final int TODOS = 10; 
    private static final int TODO_ID = 20; 


    private static final String AUTHORITY = "com.example.todos.contentprovider"; 
    private static final String BASE_PATH = "todos"; 
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY+ "/" + BASE_PATH); 

    public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +"/todos"; 

    public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/todo"; 

    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
    static { 
     sURIMatcher.addURI(AUTHORITY, BASE_PATH, TODOS); 
     sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", TODO_ID); 
    } 

    @Override 
    public boolean onCreate() 
    { 
     database = new TodoDatabaseHelper(getContext()); 
     return false; 
    } 

    @Override 
    public Cursor query(Uri uri,String[] projection, String selection, 
       String[] selectionArgs, String sortOrder) 
    { 
     // Uisng SQLiteQueryBuilder instead of query() method 
     SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); 

     // check if the caller has requested a column which does not exists 
     checkColumns(projection); 

     //set the table 
     queryBuilder.setTables(TodoTable.TABLE_TODO); 

     int uriType = sURIMatcher.match(uri); 
     switch (uriType) { 
     case TODOS: 
      break; 

     case TODO_ID: 
      // adding the ID to the original query 
      queryBuilder.appendWhere(TodoTable.COLUMN_ID + "=" 
         + uri.getLastPathSegment()); 
      break; 

     default: 
      throw new IllegalArgumentException("Unknown URI: " + uri); 
     } 
     SQLiteDatabase db = database.getWritableDatabase(); 
     Cursor cursor = queryBuilder.query(db, projection, selection, 
       selectionArgs, null, null, sortOrder); 

    // make sure that potential listeners are getting notified 
     cursor.setNotificationUri(getContext().getContentResolver(), uri); 

     return cursor; 

    } 

    @Override 
     public String getType(Uri uri) { 
     return null; 
     } 

    @Override 
     public Uri insert(Uri uri, ContentValues values) 
    { 
     int uriType = sURIMatcher.match(uri); 
     SQLiteDatabase sqlDB = database.getWritableDatabase(); 
     long id = 0; 
     switch (uriType) { 
     case TODOS: 
      id = sqlDB.insert(TodoTable.TABLE_TODO, null, values); 
      break; 
     default: 
      throw new IllegalArgumentException("Unknown URI: " + uri); 
     } 
     getContext().getContentResolver().notifyChange(uri, null); 
      return Uri.parse(BASE_PATH + "/" + id); 
    } 

    @Override 
    public int delete(Uri uri, String selection,String[] selectionArgs) 
    { 
     int uriType = sURIMatcher.match(uri); 
     SQLiteDatabase sqlDB = database.getWritableDatabase(); 
     int rowsDeleted = 0; 
     switch (uriType) { 

     case TODOS: 
      rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,selection, selectionArgs); 
      break; 

     case TODO_ID: 
      String id = uri.getLastPathSegment(); 
      if(TextUtils.isEmpty(selection)) 
      { 
       rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,TodoTable.COLUMN_ID + "=" + id,null); 
      } 
      else 
      { 
       rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,TodoTable.COLUMN_ID + "=" + id + "and" + selection ,selectionArgs); 
      } 

     default: 
      throw new IllegalArgumentException("Unknown URI: " + uri); 
     } 
     getContext().getContentResolver().notifyChange(uri, null); 
     return rowsDeleted; 
    } 

    @Override 
    public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs) 
    { 
     int uriType = sURIMatcher.match(uri); 
     SQLiteDatabase sqlDb = database.getWritableDatabase(); 
     int rowsUpdated = 0; 
     switch (uriType) { 
     case TODOS: 
      rowsUpdated = sqlDb.update(TodoTable.TABLE_TODO, values, selection, selectionArgs); 
      break; 
     case TODO_ID: 
      String id = uri.getLastPathSegment(); 
      if(TextUtils.isEmpty(selection)) 
      { 
       rowsUpdated = sqlDb.update(TodoTable.TABLE_TODO, values, TodoTable.COLUMN_ID + "=" + id, null); 
      } 
      else 
      { 
       rowsUpdated = sqlDb.update(TodoTable.TABLE_TODO, values, TodoTable.COLUMN_ID + "=" + id + "and" + selection, selectionArgs); 
      } 
      break; 
     default: 
      throw new IllegalArgumentException("Unknown URI: " + uri); 
     } 
     getContext().getContentResolver().notifyChange(uri, null); 
     return rowsUpdated; 
    } 


    private void checkColumns(String[] projection) 
    { 
     String[] available = {TodoTable.COLUMN_CATEGORY,TodoTable.COLUMN_SUMMARY,TodoTable.COLUMN_DESCRIPTION,TodoTable.COLUMN_ID}; 
     HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection)); 
     HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available)); 
     if(projection != null) 
     { 
      if (!availableColumns.containsAll(requestedColumns)) { 
       throw new IllegalArgumentException("Unknown columns in projection"); 
       } 
     } 

    } 
} 

TodoDatabaseHelper

public class TodoDatabaseHelper extends SQLiteOpenHelper{ 

    private static final String DATABASE_NAME = "todotable.db"; 
    private static final int DATABASE_VERSION = 1; 


    public TodoDatabaseHelper(Context context) 
    { 
     super(context,DATABASE_NAME,null,DATABASE_VERSION); 
    } 

    //Method is called during creation of database 
    @Override 
    public void onCreate(SQLiteDatabase database) 
    { 
     TodoTable.onCreate(database); 
    } 

    // Method is called during an upgrade of the database, 
     // e.g. if you increase the database version 
     @Override 
     public void onUpgrade(SQLiteDatabase database, int oldVersion, 
      int newVersion) { 
     TodoTable.onUpgrade(database, oldVersion, newVersion); 
     } 


} 
+1

你試圖打開的URL沒有找到com.example.todos.contentprovider/todos。一旦改變了這個 –

回答

31

您正在使用

private static final String AUTHORITY = "com.example.todos.contentprovider"; 
// It should same as you defined in manifest 

所以這

Caused by: java.lang.IllegalArgumentException: Unknown URL content://com.example.todos.contentprovider/todos 

因此,請確保您定義ContentProvider具有相同authoritymanifest.xml

<provider 
     android:authorities="com.example.todos.contentprovider" 
     android:name=".YOUR_ContentProvider" > 
</provider> 

希望這會對你有用。

+2

在AUTHORITY中寫入整個包名解決了我的情況 – josuadas

3

還要確保在manifest.xml中給出android:exported =「true」,同時確保它們放在</application>之內,而不在</activity>之內。

<provider 
     android:name="com.example.todos.contentprovider" 
     android:authorities="com.example.todos.contentprovider.MyTodoContentProvider" 
     android:exported="true"> 
    </provider> 
+0

如果我不想導出我的內容提供商 – ocross

+0

謝謝,你救了我的日子:) – SonDang

+0

在這裏,他們建議將它設置爲false: https: //stackoverflow.com/a/2917602 – Halfacht