我还在学习编程,我有一个关于我正在编写的程序的问题,它给了我一个奇怪的错误。
我的应用程序在数据库中存储 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)
这可能很简单,任何帮助都会很棒。再次感谢。