-
Notifications
You must be signed in to change notification settings - Fork 717
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,6 +105,17 @@ public static final class PetEntry implements BaseColumns { | |
public static final int GENDER_UNKNOWN = 0; | ||
public static final int GENDER_MALE = 1; | ||
public static final int GENDER_FEMALE = 2; | ||
|
||
/** | ||
* Returns whether or not the given gender is {@link #GENDER_UNKNOWN}, {@link #GENDER_MALE}, | ||
* or {@link #GENDER_FEMALE}. | ||
*/ | ||
public static boolean isValidGender(int gender) { | ||
if (gender == GENDER_UNKNOWN || gender == GENDER_MALE || gender == GENDER_FEMALE) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
ayush251196
|
||
} | ||
|
||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -140,6 +140,26 @@ public Uri insert(Uri uri, ContentValues contentValues) { | |
* for that specific row in the database. | ||
*/ | ||
private Uri insertPet(Uri uri, ContentValues values) { | ||
// Check that the name is not null | ||
String name = values.getAsString(PetEntry.COLUMN_PET_NAME); | ||
if (name == null) { | ||
This comment has been minimized.
Sorry, something went wrong.
pooriant
|
||
throw new IllegalArgumentException("Pet requires a name"); | ||
} | ||
|
||
// Check that the gender is valid | ||
Integer gender = values.getAsInteger(PetEntry.COLUMN_PET_GENDER); | ||
if (gender == null || !PetEntry.isValidGender(gender)) { | ||
This comment has been minimized.
Sorry, something went wrong.
trobbierob
|
||
throw new IllegalArgumentException("Pet requires valid gender"); | ||
} | ||
|
||
// If the weight is provided, check that it's greater than or equal to 0 kg | ||
Integer weight = values.getAsInteger(PetEntry.COLUMN_PET_WEIGHT); | ||
if (weight != null && weight < 0) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
oluwasegunmaths
|
||
throw new IllegalArgumentException("Pet requires valid weight"); | ||
} | ||
|
||
This comment has been minimized.
Sorry, something went wrong.
rydarg
|
||
// No need to check the breed, any value is valid (including null). | ||
|
||
// Get writeable database | ||
SQLiteDatabase database = mDbHelper.getWritableDatabase(); | ||
|
||
|
26 comments
on commit 6861be5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesnt work for me. I still can add a pet without name, and breed. Leaving weight empty i crashing my app with "java.lang.NumberFormatException: For input string: "" " communicate. I just dont get it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MarekFish93 I had the same issue where it works without name but I realized that the Editext has initially an empty String "" (length = 0) so it is always different from null, I modified the condition like this if (name == null || name.length()==0) {...}
and it works now.
Also, for the exception you get when the weight is empty, I think it is because somewhere you are parsing the weight from String to int like this
int weight =Integer.parseInt(mWeightEditText.getText().toString().trim());
which excepts a valid String representing a number but finds "" .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The app crashes on this line of code:
throw new IllegalArgumentException("Pet requires a name");
Error:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.android.pets, PID: 8539
java.lang.IllegalArgumentException: Pet requires a name
Please help! Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cl5rt Did you input a name?
If no, this is the expected behavior as you are throwing a IllegalArgumentException when the name is empty so the app crashes.
I think for new learners, Udacity should use visual feedback like Toast to know if the input validation is correct instead of exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brewsfab
Ooohhh I got it!!!! Thank you!
I must have not been listening too hard on the lesson.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MarekFish93 On the EditorsActivity. java you can find this lines of code:
String weightString = mWeightEditText.getText().toString().trim();
int weight = Integer.parseInt(weightString);
This is okay on a ideal world where the user doesn't make mistakes, but what if you try to parse to an integer value when the weightString value is empty, which means "" (No user input). This throws an NumberFormatException because we are trying to convert a empty string to an integer.
my solution:
String weightString = mWeightEditText.getText().toString().trim();
int weight ;
try {
weight = Integer.parseInt(weightString);
}catch (NumberFormatException e){
weight=0; // I set the weight to 0 because this is the default value in the database so..
}
Regards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My app doesnt crash even if I put in a black pet name.
I had to check for the "" and " " conditions as well to make it crash.
if (petName == null||petName.equals("")||petName.equals(" ")) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karkinissan
try to edit the if statement for petName into:
if(petName.isEmpty)
i think this is better to check if a String is null or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is not working for me. my app crashes and error is:
Process: com.example.android.pets, PID: 30835
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.pets
/com.example.android.pets.CatalogActivity}: java.lang.NumberFormatException: Invalid long: "pets"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ahmadjawidmuhammadi Go to PetProvider.java and double check your sUriMatcher.addUri() method. I forgot to put in "/#" after using the PetContract.PATH_PETS.
This was my original way:
sUriMatcher.addURI(PetContract.CONTENT_AUTHORITY, PetContract.PATH_PETS, PetProvider.PET_ID);
So if you look at what i had originally the output would look like: content://com.example.android.pets/pets(then Pet_ID).
If you look below to the correct method call, it would look like this when output: content://com.example.android.pets/pets/5. As you can see i was missing the extra slash and the wildcard that would be replaced by an Integer of pet id. Thus causing the number format exception as it can't find the location to insert the id.
This is the correct way:
sUriMatcher.addURI(PetContract.CONTENT_AUTHORITY, PetContract.PATH_PETS + "/#", PetProvider.PET_ID);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My app has just crashed before I could insert anything. It was beacuse of
"CatalogActivity}: java.lang.IllegalArgumentException: Cannot query unknown URI content://com.example.android.pets/pets"
It is stupid because most of time I was copying everything and i have no idea, where I could do mistake 😢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now when I've opened master version of this app I see that when I don't insert name, or breed, or weight, nothing happens. I thought that we want to see some messages. at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Katherine, make sure the URI is correct by check the PetProvider.java file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am getting errors with both " weight == null" and "gender ==null" sections. Android Studio says "Operator == cannot be applied to 'int' 'null'"
However, I do feel like that by just checking for negative numbers in weight, we are covering it all; since the default is 0 if there is nothing entered, and if the input is negative then it throws an exception.
Also for the Gender, this is un-necessary check since our input is a spinner which has the only three acceptable options, and the user cannot enter anything else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was getting NullPointer errors when I set the weight to 0 and I couldn't figure out how to solve it other than adding code in the EditorActivity to convert an empty user input to int 0:
String WeightString = WeightField.getText().toString();
int petWeight;
if (WeightString.isEmpty()) {
petWeight = 0;
} else {
petWeight = Integer.parseInt(WeightString);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@khash021 - Did you receive weight as "Integer weight = values.getAsInteger(...); or int weight = values.getAsInteger(...); ??"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Apurba000Biswas It was a while ago, I can't remember what I had. Since it was giving me errors, I changed it and got it to work. But now that you mentioned it, I probably used int that's why I was getting an error. == would work with Integer only I assume.
Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can anyone help me here? isValidGender is never used in my code so the program is not working?
Code here:
/**
* Returns whether or not the given gender is {@link #GENDER_UNKNOWN}, {@link #GENDER_MALE},
* or {@link #GENDER_FEMALE}.
*/
public static boolean isValidGender(int gender) {
if (gender == GENDER_UNKNOWN || gender == GENDER_MALE || gender == GENDER_FEMALE) {
return true;
}
return false;
}
/**
* Insert a pet into the database with the given content values. Return the new content URI
* for that specific row in the database.
*/
private Uri insertPet(Uri uri, ContentValues values) {
// Check that the name is not null
String name = values.getAsString(PetEntry.COLUMN_PET_NAME);
if (name == null) {
throw new IllegalArgumentException("Pet requires a name");
}
// Check that the gender is valid
Integer gender = values.getAsInteger(PetEntry.COLUMN_PET_GENDER);
if (gender == null || !PetEntry.isValidGender(gender)) {
throw new IllegalArgumentException("Pet requires valid gender");
}
// If the weight is provided, check that it's greater than or equal to 0 kg
Integer weight = values.getAsInteger(PetEntry.COLUMN_PET_WEIGHT);
if (weight != null && weight < 0) {
throw new IllegalArgumentException("Pet requires valid weight");
}
// No need to check the breed, any value is valid (including null).
// Get writeable database
SQLiteDatabase database = mDbHelper.getWritableDatabase();
// Insert the new pet with the given values
long id = database.insert(PetEntry.TABLE_NAME, null, values);
// If the ID is -1, then the insertion failed. Log an error and return null.
if (id == -1) {
Log.e(LOG_TAG, "Failed to insert row for " + uri);
return null;
}
// Return the new URI with the ID (of the newly inserted row) appended at the end
return ContentUris.withAppendedId(uri, id);
}
Error: error: cannot find symbol method isValidGender(Integer)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a lot of information and but it is beautiful work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Kurosakicoder you need to implement the method isValidGender in PetContract.java inside PetEntry class
public static boolean isValidGender(int gender) { if (gender == GENDER_UNKNOWN || gender == GENDER_MALE || gender == GENDER_FEMALE) { return true; } return false; }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should validate on insertion and not allow the user to proceed if its wrong input. 😃
Keep Calm and Carry On
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first I made weight and gender as int but then I realized that by doing it I cannot check if they are null.
Good work!!
@joaosouzadev Why making an entire method for a simple if statement ??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Prompt the user to confirm that they want to delete all pets.
*/
private void showDeleteConfirmationDialog() {
// Create an AlertDialog.Builder and set the message, and click listeners
// for the positive and negative buttons on the dialog.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.delete_all_pets);
builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User clicked the "Delete" button, so delete the pet.
deleteAllPets();
Toast.makeText(getApplicationContext(), R.string.del_pets_success,
Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User clicked the "Cancel" button, so dismiss the dialog
// and continue editing the pet.
if (dialog != null) {
dialog.dismiss();
}
}
});
// Create and show the AlertDialog
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
/**
* Helper method to delete all pets in the database.
*/
private void deleteAllPets() {
int rowsDeleted = getContentResolver().delete(PetEntry.CONTENT_URI, null, null);
Log.v("CatalogActivity", rowsDeleted + "rows deleted from pets database");
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
guy I'm struggling with CatalogActivity. app is stopping. and Logcat says its NPE but as a beginner i dont understand which part to change. here is the code.
`package com.example.android.pets;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.example.android.pets.data.PetContract.PetEntry;
/**
-
Displays list of pets that were entered and stored in the app.
*/
public class CatalogActivity extends AppCompatActivity {@OverRide
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_catalog);// Setup FAB to open EditorActivity FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(CatalogActivity.this, EditorActivity.class); startActivity(intent); } });
}
@OverRide
protected void onStart() {
super.onStart();
displayDatabaseInfo();
}/**
-
Temporary helper method to display information in the onscreen TextView about the state of
-
the pets database.
*/
private void displayDatabaseInfo() {
// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
PetEntry._ID,
PetEntry.COLUMN_PET_NAME,
PetEntry.COLUMN_PET_BREED,
PetEntry.COLUMN_PET_GENDER,
PetEntry.COLUMN_PET_WEIGHT };// Perform a query on the provider using the ContentResolver.
// Use the {@link PetEntry#CONTENT_URI} to access the pet data.
Cursor cursor = getContentResolver().query(
PetEntry.CONTENT_URI, // The content URI of the words table
projection, // The columns to return for each row
null, // Selection criteria
null, // Selection criteria
null); // The sort order for the returned rowsTextView displayView = (TextView) findViewById(R.id.text_view_pet);
try {
// Create a header in the Text View that looks like this:
//
// The pets table contains pets.
// _id - name - breed - gender - weight
//
// In the while loop below, iterate through the rows of the cursor and display
// the information from each column in this order.
displayView.setText("The pets table contains " + cursor.getCount() + " pets.\n\n");
displayView.append(PetEntry._ID + " - " +
PetEntry.COLUMN_PET_NAME + " - " +
PetEntry.COLUMN_PET_BREED + " - " +
PetEntry.COLUMN_PET_GENDER + " - " +
PetEntry.COLUMN_PET_WEIGHT + "\n");// Figure out the index of each column int idColumnIndex = cursor.getColumnIndex(PetEntry._ID); int nameColumnIndex = cursor.getColumnIndex(PetEntry.COLUMN_PET_NAME); int breedColumnIndex = cursor.getColumnIndex(PetEntry.COLUMN_PET_BREED); int genderColumnIndex = cursor.getColumnIndex(PetEntry.COLUMN_PET_GENDER); int weightColumnIndex = cursor.getColumnIndex(PetEntry.COLUMN_PET_WEIGHT); // Iterate through all the returned rows in the cursor while (cursor.moveToNext()) { // Use that index to extract the String or Int value of the word // at the current row the cursor is on. int currentID = cursor.getInt(idColumnIndex); String currentName = cursor.getString(nameColumnIndex); String currentBreed = cursor.getString(breedColumnIndex); int currentGender = cursor.getInt(genderColumnIndex); int currentWeight = cursor.getInt(weightColumnIndex); // Display the values from each column of the current row in the cursor in the TextView displayView.append("\n" + currentID + " - " + currentName + " - " + currentBreed + " - " + currentGender + " - " + currentWeight); }
} finally {
// Always close the cursor when you're done reading from it. This releases all its
// resources and makes it invalid.
if (cursor != null) {
cursor.close();
}
}
}
/**
-
Helper method to insert hardcoded pet data into the database. For debugging purposes only.
*/
private void insertPet() {
// Create a ContentValues object where column names are the keys,
// and Toto's pet attributes are the values.
ContentValues values = new ContentValues();
values.put(PetEntry.COLUMN_PET_NAME, "Toto");
values.put(PetEntry.COLUMN_PET_BREED, "Terrier");
values.put(PetEntry.COLUMN_PET_GENDER, PetEntry.GENDER_MALE);
values.put(PetEntry.COLUMN_PET_WEIGHT, 7);// Insert a new row for Toto into the provider using the ContentResolver.
// Use the {@link PetEntry#CONTENT_URI} to indicate that we want to insert
// into the pets database table.
// Receive the new content URI that will allow us to access Toto's data in the future.
Uri newUri = getContentResolver().insert(PetEntry.CONTENT_URI, values);
}
@OverRide
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu options from the res/menu/menu_catalog.xml file.
// This adds menu items to the app bar.
getMenuInflater().inflate(R.menu.menu_catalog, menu);
return true;
}@OverRide
public boolean onOptionsItemSelected(MenuItem item) {
// User clicked on a menu option in the app bar overflow menu
switch (item.getItemId()) {
// Respond to a click on the "Insert dummy data" menu option
case R.id.action_insert_dummy_data:
insertPet();
displayDatabaseInfo();
return true;
// Respond to a click on the "Delete all entries" menu option
case R.id.action_delete_all_entries:
// Do nothing for now
return true;
}
return super.onOptionsItemSelected(item);
}
}`
here is the Logcat
-
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abdullah-shamali I tried using your code but I am not getting any NullPointerExceptions. Not sure what to tell you. Looking at the lines Logcat is pointing at (if I counted correctly) those are comment lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cl5rt Did you input a name?
If no, this is the expected behavior as you are throwing a IllegalArgumentException when the name is empty so the app crashes.
I think for new learners, Udacity should use visual feedback like Toast to know if the input validation is correct instead of exceptions.
Here is my fix:
6861be5#commitcomment-33260481
Could be simply:
return gender == GENDER_UNKNOWN || gender == GENDER_MALE || gender == GENDER_FEMALE;