2012-12-30 67 views
0

我仍然在學習編程,而且我正在寫一個程序的問題,這給我一個奇怪的錯誤。內容提供商的錯誤

我的應用程序在數據庫中存儲3個字符串,並存儲1個BLOB(圖片)。

屏幕低於:

鏈接到的圖像是在這裏:http://i.stack.imgur.com/RPxDO.png

我遇到的問題是,你必須採取的照片首次進入任何其他數據之前(即無聊的項目,人名),否則程序將崩潰。如果您先拍照,那麼填寫剩下的照片就沒有問題。

對於下面的代碼是:

public class AddItem extends Activity implements View.OnClickListener { 

    // GUI 
    private EditText itemName; 
    private AutoCompleteTextView personName; 
    private Button setFinish, setDate, camera; 
    private TextView getDate; 
    private ImageView window; 

    // URI 
    private Uri addUri; 

    // Date 
    private int yr, month, day; 

    // DatePicker ID 
    static final int DATE_DIALOG_ID = 1; 

    // For Camera 
    final static int cameraData = 0; 
    private Bitmap bmp; 

    // ---------------------------------------------------- 

    public ArrayList<String> contactNameA = new ArrayList<String>(); 
    public ArrayList<String> contactNumberA = new ArrayList<String>(); 
    String[] nameStringArray = null; 
    String[] phoneStringArray = null; 

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.add_item); 

     // Method Calls ----------------------------------------------------- 
     // ------------------------------------------------------------------ 

     init(); // initialize the parameters 

     tabSetter(); // Create the tabs 

     calenderSet(); 

     autoCompleteBox(); 

     // Listeners -------------------------------------------------------- 

     setFinish.setOnClickListener(this); 

     camera.setOnClickListener(this); 

     setDate.setOnClickListener(this); 

     // ------------------------------------------------------------------ 

     // For pictures --------- 
     InputStream is = getResources().openRawResource(R.drawable.take_camera); 
     bmp = BitmapFactory.decodeStream(is); 
     window.setImageBitmap(bmp); 

     Bundle extras = getIntent().getExtras(); 


     addUri = (savedInstanceState == null) ? null : (Uri) savedInstanceState 
       .getParcelable(BorrowMeContentProvider.CONTENT_ITEM_TYPE); 

     if (extras != null) { 
      addUri = extras 
        .getParcelable(BorrowMeContentProvider.CONTENT_ITEM_TYPE); 

      fillData(addUri); 
     } 



    } 

     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    private void autoCompleteBox() { 

     ContentResolver cr = getContentResolver(); 

     Uri contacts = Uri.parse("content://contacts/people"); 

     Cursor mCursor = cr.query(contacts, null, null, null, null); 

     if (mCursor.moveToFirst()) { 

      String nameOfContact; 
      String phoneNumberContact; 

      int nColumn = mCursor.getColumnIndex("name"); 
      int pColumn = mCursor.getColumnIndex("number"); 
      Log.d("START", "Entering method"); 
      Log.d("int Name", Integer.toString(nColumn)); 
      Log.d("int Number", Integer.toString(pColumn)); 

      do { 

       nameOfContact = mCursor.getString(nColumn); 
       phoneNumberContact = mCursor.getString(pColumn); 
       if ((nameOfContact != " " || nameOfContact != null) 
         && (phoneNumberContact != " " || phoneNumberContact != null)) { 

        contactNameA.add(nameOfContact); 
        contactNumberA.add(phoneNumberContact); 


       } 

      } while (mCursor.moveToNext()); 

     } 

     nameStringArray = (String[]) contactNameA.toArray(new String[contactNameA.size()]); 
     phoneStringArray = (String[]) contactNumberA.toArray(new String[contactNameA.size()]); 

     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
       android.R.layout.simple_dropdown_item_1line, nameStringArray); 


     personName.setAdapter(adapter); 

    } 

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    private void init() { 

     personName = (AutoCompleteTextView) findViewById(R.id.nameOfPerson); 
     itemName = (EditText) findViewById(R.id.borrowItemFeild); 

     setFinish = (Button) findViewById(R.id.finishThis); 

     camera = (Button) findViewById(R.id.cameraButton); 
     window = (ImageView) findViewById(R.id.imageWindow); 

     setDate = (Button) findViewById(R.id.dateChange); 
     getDate = (TextView) findViewById(R.id.textDate); 

    } 

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    @Override 
    public void finish() { 

     super.finish(); 
    } 

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    @Override 
    protected Dialog onCreateDialog(int id) { 
     switch (id) { 
     case DATE_DIALOG_ID: 
      return new DatePickerDialog(this, mDateSetListener, yr, month, day); 

     } 
     return null; 
    } 

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() { 
     public void onDateSet(DatePicker view, int year, int monthOfYear, 
       int dayOfMonth) { 

      yr = year; 
      month = monthOfYear; 
      day = dayOfMonth; 

      getDate.setText((month + 1) + "/" + day + "/" 
        + year); 

      /* 
      * Toast.makeText(getBaseContext(), "Date Selected: " + (month + 1) 
      * + "/" + day + "/" + year, Toast.LENGTH_SHORT).show(); 
      */ 
     } 
    }; 

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    private void calenderSet() { 
     // Call calendar object to get date 
     Calendar today = Calendar.getInstance(); 

     // Set the parameters to the current date, so the user doesn't have to 
     // scroll from the default date 
     yr = today.get(Calendar.YEAR); 
     month = today.get(Calendar.MONTH); 
     day = today.get(Calendar.DAY_OF_MONTH); 
    } 


    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    // Handles the clicks for all the various views 
    @Override 
    public void onClick(View v) { 
     // TODO Auto-generated method stub 

     //TabHost th = (TabHost) findViewById(R.id.tabhost); 

     switch (v.getId()) { 

     case (R.id.finishThis): 

      if (personName.getText().toString().equals("")) { 
       Toast.makeText(this, "Name can't be blank", Toast.LENGTH_SHORT) 
         .show(); 
      } else if (itemName.getText().toString().equals("")) { 
       Toast.makeText(this, "Borrowed item can't be blank", 
         Toast.LENGTH_SHORT).show(); 

       // Sets back to tab 0 to ensure user fills out info 
       //th.setCurrentTab(0); 

      } else if (getDate.getText().toString().equals("Select Date")) { 
       Toast.makeText(this, "Please select a date", Toast.LENGTH_SHORT) 
         .show(); 
       // Sets back to tab 0 to ensure user fills out info 
       //th.setCurrentTab(0); 

      } else { 
       finish(); 
      } 

      break; 

     case (R.id.cameraButton): 

      Intent i = new Intent(
        android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
      startActivityForResult(i, cameraData); 

      break; 

     case (R.id.dateChange): 

      showDialog(DATE_DIALOG_ID); 

      break; 

     } 

    } 

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    private void fillData(Uri uri) { 
     String[] projection = { BorrowMeTable.COLUMN_NAME, 
       BorrowMeTable.COLUMN_DATE, BorrowMeTable.COLUMN_ITEM, BorrowMeTable.COLUMN_IMAGE}; 
     Cursor databaseCursor = getContentResolver().query(uri, projection, null, null, 
       null); 
     if (databaseCursor != null) { 
      databaseCursor.moveToFirst(); 


      personName.setText(databaseCursor.getString(databaseCursor 
        .getColumnIndexOrThrow(BorrowMeTable.COLUMN_NAME))); 
      itemName.setText(databaseCursor.getString(databaseCursor 
        .getColumnIndexOrThrow(BorrowMeTable.COLUMN_ITEM))); 

      getDate.setText(databaseCursor.getString(databaseCursor 
        .getColumnIndexOrThrow(BorrowMeTable.COLUMN_DATE))); 

      try { 
       byte[] imageByteArray = databaseCursor.getBlob(databaseCursor.getColumnIndex(BorrowMeTable.COLUMN_IMAGE)); 
       ByteArrayInputStream imageStream = new ByteArrayInputStream(imageByteArray); 
       bmp = BitmapFactory.decodeStream(imageStream); 
       window.setImageBitmap(bmp); 
      } catch (Exception e) { 


      } 
      databaseCursor.close(); 
     } 
    } 

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

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

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

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

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

    private void saveState() { 
     ContentValues values = new ContentValues(); 
     String date = getDate.getText().toString(); 
     String item = itemName.getText().toString(); 
     String name = personName.getText().toString(); 

     // Only save if either item or person name 
     // is available 

     if (item.length() == 0 && name.length() == 0) { 
      return; 
     } 

     if (bmp == null) { 

      values.put(BorrowMeTable.COLUMN_ITEM, item); 
      values.put(BorrowMeTable.COLUMN_NAME, name); 
      values.put(BorrowMeTable.COLUMN_DATE, date);   

     } else { 
      ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
      bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); 
      byte[] byteArray = stream.toByteArray(); 
      values.put(BorrowMeTable.COLUMN_ITEM, item); 
      values.put(BorrowMeTable.COLUMN_NAME, name); 
      values.put(BorrowMeTable.COLUMN_DATE, date); 
      values.put(BorrowMeTable.COLUMN_IMAGE, byteArray); 

     } 

     // The resolver statement goes here - moved it into the IF above to see if error is corrected. 
     if (addUri == null) { 
      // New Entry 
      addUri = getContentResolver().insert(
        BorrowMeContentProvider.CONTENT_URI, values); 
     } else { 
      // Update Entry 
        getContentResolver().update(addUri, values, null, null); 

     } 


    } 

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 


    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

     // TODO Auto-generated method stub 
     super.onActivityResult(requestCode, resultCode, data); 
     if (resultCode == RESULT_OK) { 
      Bundle extras = data.getExtras(); 
      bmp = (Bitmap) extras.get("data"); 
      window.setImageBitmap(bmp); 
     } 
    } 
} 

這裏是我的內容提供商:

public class BorrowMeContentProvider extends ContentProvider { 


    private BorrowMeDatabaseHelper database; 


    private static final int BORROWME = 10; 
    private static final int BORROWME_ID = 20; 

    private static final String AUTHORITY = "com.fthatnoise.borrow.me.contentprovider"; 

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

    public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE 
      + "/BORROWME"; 
    public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE 
      + "/BORROWMETYPE"; 

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

    // ------------------------------------------------------------- 

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

    // ------------------------------------------------------------- 

    @Override 
    public Cursor query(Uri uri, String[] projection, String selection, 
      String[] selectionArgs, String sortOrder) { 


     SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); 

     checkColumns(projection); 

     queryBuilder.setTables(BorrowMeTable.DATABASE_TABLE); 

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

      queryBuilder.appendWhere(BorrowMeTable.COLUMN_ID + "=" 
        + uri.getLastPathSegment()); 
      break; 
     default: 
      throw new IllegalArgumentException("Error in URI: " + uri); 
     } 

     SQLiteDatabase db = database.getWritableDatabase(); 
     Cursor cursor = queryBuilder.query(db, projection, selection, 
       selectionArgs, null, null, sortOrder); 

     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 BORROWME: 
      id = sqlDB.insert(BorrowMeTable.DATABASE_TABLE, null, values); 
      break; 
     default: 
      throw new IllegalArgumentException("Error in 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 BORROWME: 
      rowsDeleted = sqlDB.delete(BorrowMeTable.DATABASE_TABLE, selection, 
        selectionArgs); 
      break; 
     case BORROWME_ID: 
      String id = uri.getLastPathSegment(); 
      if (TextUtils.isEmpty(selection)) { 
       rowsDeleted = sqlDB.delete(BorrowMeTable.DATABASE_TABLE, 
         BorrowMeTable.COLUMN_ID + "=" + id, null); 
      } else { 
       rowsDeleted = sqlDB.delete(BorrowMeTable.DATABASE_TABLE, 
         BorrowMeTable.COLUMN_ID + "=" + id + " and " + selection, 
         selectionArgs); 
      } 
      break; 
     default: 
      throw new IllegalArgumentException("Error in 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 BORROWME: 
      rowsUpdated = sqlDB.update(BorrowMeTable.DATABASE_TABLE, values, selection, 
        selectionArgs); 
      break; 
     case BORROWME_ID: 
      String id = uri.getLastPathSegment(); 
      if (TextUtils.isEmpty(selection)) { 
       rowsUpdated = sqlDB.update(BorrowMeTable.DATABASE_TABLE, values, 
         BorrowMeTable.COLUMN_ID + "=" + id, null); 
      } else { 
       rowsUpdated = sqlDB.update(BorrowMeTable.DATABASE_TABLE, values, 
         BorrowMeTable.COLUMN_ID + "=" + id + " and " + selection, 
         selectionArgs); 
      } 
      break; 
     default: 
      throw new IllegalArgumentException("Error in URI: " + uri); 
     } 
     getContext().getContentResolver().notifyChange(uri, null); 
     return rowsUpdated; 
    } 

    // ------------------------------------------------------------- 

    private void checkColumns(String[] projection) { 
     String[] available = { BorrowMeTable.COLUMN_ITEM, 
       BorrowMeTable.COLUMN_NAME, BorrowMeTable.COLUMN_DATE, 
       BorrowMeTable.COLUMN_ID, BorrowMeTable.COLUMN_IMAGE }; 
     if (projection != null) { 
      HashSet<String> requestedColumns = new HashSet<String>(
        Arrays.asList(projection)); 
      HashSet<String> availableColumns = new HashSet<String>(
        Arrays.asList(available)); 

      if (!availableColumns.containsAll(requestedColumns)) { 
       throw new IllegalArgumentException(
         "Unknown columns in projection"); 
      } 
     } 
    } 

} 

最後,錯誤消息,如果我不先拍照,我得到和嘗試在輸入任何文本字段中的數據後輸入數據 -

12-30 15:58:21.042: E/AndroidRuntime(22646): FATAL EXCEPTION: main 
12-30 15:58:21.042: E/AndroidRuntime(22646): java.lang.IllegalArgumentException: Unknown URI me/9 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.content.ContentResolver.update(ContentResolver.java:988) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at com.fthatnoise.borrow.me.AddItem.saveState(AddItem.java:400) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at com.fthatnoise.borrow.me.AddItem.onSaveInstanceState(AddItem.java:348) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.app.Activity.performSaveInstanceState(Activity.java:1147) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1216) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3129) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3188) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.app.ActivityThread.access$900(ActivityThread.java:141) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1261) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.os.Handler.dispatchMessage(Handler.java:99) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.os.Looper.loop(Looper.java:137) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at android.app.ActivityThread.main(ActivityThread.java:5039) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at java.lang.reflect.Method.invokeNative(Native Method) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at java.lang.reflect.Method.invoke(Method.java:511) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
12-30 15:58:21.042: E/AndroidRuntime(22646): at dalvik.system.NativeStart.main(Native Method) 

這可能是簡單的,任何幫助會很好。再次感謝。

回答

0
java.lang.IllegalArgumentException: Unknown URI me/9 
    at android.content.ContentResolver.update(ContentResolver.java:988) 

看起來你有一個格式不正確的URI。我不是在ContentProviders最好的,但我相信你想使用這樣的事:

URI uri = ContentUris.withAppendedId(BorrowMeContentProvider.CONTENT_URI, id); 
getContentResolver().update(uri, values, null, null); 

哪裏id是要更新該行的主鍵,在這種情況下9

+0

真棒,謝謝你,你讓我在正確的方向。 – Vince