Content Provider出错

时间:2012-12-30 21:41:53

标签: java android database

我还在学习编程,我对我正在编写的程序有疑问,这给我一个奇怪的错误。

我的应用程序在数据库中存储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)

这可能很简单,任何帮助都会很棒。再次感谢。

1 个答案:

答案 0 :(得分: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