简体   繁体   中英

Parsing user input in edittext field of the type date and check for correct date format

I am working on an Android app and processing user input from an edittext field. I want to check if the user entered a correct date format; however, for reasons that I don´t understand, I need to convert the type of the edittext type date to a string and then convert it back to a float number, to check against a regular expression and that is not working correctly.

The editactivity.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="1">

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_normal_text"
        android:hint="Enter the title of your selfie"
        android:inputType="text"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_name"
        android:hint="Enter the title of your selfie"
        android:inputType="text"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/name"
        android:hint="Enter the title of your selfie"
        android:inputType="text"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_location"
        android:hint="Enter the title of your selfie"
        android:inputType="text"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_email_address"
        android:textStyle="bold"
        android:inputType="textEmailAddress"
        android:hint="Enter Email Address"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/ed_date"
        android:hint="Enter Date"
        android:inputType="date"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/location"
        android:hint="Enter Location"
        android:inputType="textAutoComplete"
        android:textStyle="bold"/>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Submit"
        android:id="@+id/btn_submit" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="match_parent"
        android:layout_height="106dp"
        android:padding="1dp"
        android:layout_weight="0.98"></ImageView>

    <Button
        android:id="@+id/btnCapture"
        android:layout_width="135dp"
        android:layout_height="wrap_content"
        android:text="Take picture" />

    <Button
        android:id="@+id/save"
        android:layout_width="135dp"
        android:layout_height="wrap_content"
        android:text="Save" />

    <Button
        android:id="@+id/cancel"
        android:layout_width="135dp"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="Cancel" />

    <Button
        android:id="@+id/image"
        android:layout_width="135dp"
        android:layout_height="wrap_content"
        android:text="See Image" />

</LinearLayout>

The EditActivity:

package gmbh.packagename.myselfieme;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.icu.util.Calendar;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import static gmbh.packagename.myselfieme.R.drawable.marker;
import static gmbh.packagename.myselfieme.R.id.date;
import static gmbh.packagename.myselfieme.R.id.time;
import static gmbh.packagename.myselfieme.R.string.snippet;


public class EditActivity extends Activity {


    public static int count = 0;
    static final int REQUEST_TAKE_PHOTO = 1;
    private static final String KEY_MARKER_ID = "id";
    private static final String KEY_MARKER_TITLE = "title";
    private static final String KEY_MARKER_DATE = "date";
    private static final String KEY_MARKER_LOC = "location";
    private static final String KEY_MARKER_LAT = "latlng";
    private static final String KEY_MARKER_NAME = "name";
    private static final String KEY_MARKER_PIC = "picture";
    private static final int CAMERA_REQUEST = 1888;

    private EditText etNormalText;
    private EditText etName;
    private EditText etLocation;
    private EditText etEmailAddrss;
    private EditText etDate;
    private Button btnSubmit;
    private ImageView imageView;
    Bitmap photo;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.editactivity);
        PostsDatabaseHelper helper = PostsDatabaseHelper.getInstance(this);
        helper.getReadableDatabase();
        registerViews();
        this.imageView = (ImageView) this.findViewById(R.id.imageView1);
        Button photoButton = (Button) this.findViewById(R.id.btnCapture);
        photoButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(cameraIntent, CAMERA_REQUEST);
            }
        });
    }
    private void registerViews() {
        etNormalText = (EditText) findViewById(R.id.et_normal_text);
        etName = (EditText) findViewById(R.id.et_name);
        etLocation = (EditText) findViewById(R.id.et_location);
        // TextWatcher would let us check validation error on the fly
        etNormalText.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                Validation.hasText(etNormalText);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });
        etName.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                Validation.hasText(etName);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });
        etLocation.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                Validation.hasText(etLocation);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });
        etEmailAddrss = (EditText) findViewById(R.id.et_email_address);
        etEmailAddrss.addTextChangedListener(new TextWatcher() {
            // after every change has been made to this editText, we would like to check validity
            public void afterTextChanged(Editable s) {
                Validation.isEmailAddress(etEmailAddrss, true);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });

        etDate = (EditText) findViewById(R.id.ed_date);
        etDate.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                Validation.isDate(etDate, false);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });

        btnSubmit = (Button) findViewById(R.id.btn_submit);
        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Log.w("EditActivity", "clicking on btn_submit");
                /*
                Validation class will check the error and display the error on respective fields
                but it won't resist the form submission, so we need to check again before submit
                 */
                if ( checkValidation () )
                    submitForm();
                else
                    Toast.makeText(EditActivity.this, "Form contains error", Toast.LENGTH_LONG).show();
            }
        });

        final LatLng latlng = getIntent().getParcelableExtra("location");
        final EditText title = (EditText) findViewById(R.id.title);
        final EditText date = (EditText) findViewById(R.id.ed_date);
        final EditText location = (EditText) findViewById(R.id.location);
        final EditText name = (EditText) findViewById(R.id.name);
        Button button = (Button) findViewById(R.id.save);
        Button cancelbutton = (Button) findViewById(R.id.cancel);
        Button imagebutton = (Button) findViewById(R.id.image);


        imagebutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent myIntent = new Intent(EditActivity.this, ImageActivity.class);
                myIntent.putExtra("marker", marker);
                myIntent.putExtra("BitmapImage", photo);
                EditActivity.this.startActivity(myIntent);
                setResult(Activity.RESULT_OK, myIntent);
            }
        });

        date.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(date.getText().length()<1){
                    // Display toast
                    Toast.makeText(getApplicationContext(), "Please enter something !",Toast.LENGTH_LONG).show();
                }

            }

        });

        date.addTextChangedListener(new TextWatcher(){

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {
                if(date.getText().length()<1){
                    // Display toast
                    Toast.makeText(getApplicationContext(), "Please enter something !",Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                                      int count) {

            }
            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
                //String ss = date.getText().toString();
                int o = 0;

                //String regEx ="^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\\d{2}$";

                /*
                                if ((ss.charAt(2) == '/') && (ss.charAt(4) == '/')) {

                                }*/
                int ss = date.getInputType();

                if (ss == (InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_DATE))
                {
                    int dateInput = Integer.parseInt(date.getText().toString());

                    //(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)

                    Toast.makeText(EditActivity.this, "Format Is right", Toast.LENGTH_LONG).show();
                }

               /* if (ss.matches("\\d{4}-\\d{2}-\\d{2}")) {
                    Toast.makeText(EditActivity.this, "Format Is right", Toast.LENGTH_LONG).show();
                }*/
                /*if(date.getText().length()<4){
                    // Display toast
                    Toast.makeText(getApplicationContext(), "Please enter something !",Toast.LENGTH_LONG).show();
                }*/
                else {
                    date.setTextColor(Color.RED);
                    date.setText("Invalid Format");
                }
                //ss = "";
            }
        });


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View view) {
                Bitmap resized = Bitmap.createScaledBitmap(photo, (int) (photo.getWidth() * 0.5), (int) (photo.getHeight() * 0.5), true);

                //Bitmap.Config conf = Bitmap.Config.ARGB_8888;
                //Bitmap bmp = Bitmap.createBitmap(150, 150, conf);
                Canvas canvas1 = new Canvas();
                Rect rectangle = new Rect(0,0,100,100);
                canvas1.drawBitmap(resized, new Rect(0,0,100,100), rectangle, null);
                resized = addBorderToBitmap(resized, 10, Color.WHITE);
                // Add a border around the bitmap as shadow
                resized = addBorderToBitmap(resized, 3, Color.LTGRAY);
                MarkerOptions marker = new MarkerOptions().position(latlng)
                        .icon(BitmapDescriptorFactory.fromBitmap(resized))
                        .draggable(true);
                if (title.getText() != null) {

                    marker.title(title.getText().toString());
                }
                if( date.getText().toString().length() == 0 )
                    date.setError( "date is required!" );
                marker.snippet(date.getText().toString());
                if (name.getText() !=null) {
                    marker.snippet(name.getText().toString());
                }
                if (location.getText() !=null) {
                    marker.snippet(location.getText().toString());
                }
                Intent resultIntent = new Intent();
                resultIntent.putExtra("marker", marker);
                resultIntent.putExtra("BitmapImage", photo); // passing the bitmap to the next activity . and retrieve it to the next activity
                setResult(Activity.RESULT_OK, resultIntent);
                finish();
            }

        });}

    public static Bitmap overlay(Bitmap bmp, Bitmap resized) {
        Bitmap bmOverlay = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
        Canvas canvas = new Canvas(bmOverlay);
        canvas.drawBitmap(bmp, new Matrix(), null);
        canvas.drawBitmap(resized, 0, 0, null);
        return bmOverlay;
    }

    private void submitForm() {
        // Submit your form here. your form is valid
        Toast.makeText(this, "Submitting form...", Toast.LENGTH_LONG).show();
        Log.w("EditActivity", "submitForm");
    }

    private boolean checkValidation() {
        Log.w("EditActivity", "checkValidation");
        boolean ret = true;

        if (!Validation.hasText(etNormalText)) ret = false;
        if (!Validation.isEmailAddress(etEmailAddrss, true)) ret = false;
        if (!Validation.isDate(etDate, false)) ret = false;
        return ret;

    }


    public void onClick(View v) {
        // TODO:
        // Launch Activity Two
        // Hint: use Context's startActivity() method
        // Create an intent stating which Activity you would like to start
        Intent myIntent = new Intent(EditActivity.this, MapsActivity.class);

        // Launch the Activity using the intent
        EditActivity.this.startActivity(myIntent);
    }

    protected Bitmap addBorderToBitmap(Bitmap resized, int borderWidth, int borderColor) {
        // Initialize a new Bitmap to make it bordered bitmap
        Bitmap dstBitmap = Bitmap.createBitmap(
                resized.getWidth() + borderWidth * 2, // Width
                resized.getHeight() + borderWidth * 2, // Height
                Bitmap.Config.ARGB_8888 // Config
        );

        /*
            Canvas
                The Canvas class holds the "draw" calls. To draw something, you need 4 basic
                components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing
                into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint
                (to describe the colors and styles for the drawing).
        */
        // Initialize a new Canvas instance
        Canvas canvas = new Canvas(dstBitmap);

        // Initialize a new Paint instance to draw border
        Paint paint = new Paint();
        paint.setColor(borderColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(borderWidth);
        paint.setAntiAlias(true);
        Rect rect = new Rect(
                borderWidth / 2,
                borderWidth / 2,
                canvas.getWidth() - borderWidth / 2,
                canvas.getHeight() - borderWidth / 2
        );

          // Draw a rectangle as a border/shadow on canvas
        canvas.drawRect(rect, paint);

        // Draw source bitmap to canvas
        canvas.drawBitmap(resized, borderWidth, borderWidth, null);
            resized.recycle();
            // Return the bordered circular bitmap
            return dstBitmap;
   }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
            photo = (Bitmap) data.getExtras().get("data");
            this.imageView.setImageBitmap(photo);
        }
    }

}

The problem is in this snippet of code here:

@Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
                //String ss = date.getText().toString();
                int o = 0;

                //String regEx ="^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\\d{2}$";

                /*
                                if ((ss.charAt(2) == '/') && (ss.charAt(4) == '/')) {

                                }*/
                int ss = date.getInputType();

                if (ss == (InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_DATE))
                {
                    int dateInput = Integer.parseInt(date.getText().toString());

                    //(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)

                    Toast.makeText(EditActivity.this, "Format Is right", Toast.LENGTH_LONG).show();
                }

               /* if (ss.matches("\\d{4}-\\d{2}-\\d{2}")) {
                    Toast.makeText(EditActivity.this, "Format Is right", Toast.LENGTH_LONG).show();
                }*/
                /*if(date.getText().length()<4){
                    // Display toast
                    Toast.makeText(getApplicationContext(), "Please enter something !",Toast.LENGTH_LONG).show();
                }*/
                else {
                    date.setTextColor(Color.RED);
                    date.setText("Invalid Format");
                }
                //ss = "";
            }
        });

This is the validation.java:

package gmbh.package.myselfieme;

import android.widget.EditText;
import java.util.regex.Pattern;

public class Validation {

    // Regular Expression
    // you can change the expression based on your need
    private static final String EMAIL_REGEX = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
    private static final String DATE_REGEX = "^\\d{4}-\\d{2}-\\d{2}$";

    // Error Messages
    private static final String REQUIRED_MSG = "required";
    private static final String EMAIL_MSG = "invalid email";
    private static final String DATE_MSG = "###-#######";

    // call this method when you need to check email validation
    public static boolean isEmailAddress(EditText editText, boolean required) {
        return isValid(editText, EMAIL_REGEX, EMAIL_MSG, required);
    }

    // call this method when you need to check phone number validation
    public static boolean isDate(EditText editText, boolean required) {
        return isValid(editText, DATE_REGEX, DATE_MSG, required);
    }

    // return true if the input field is valid, based on the parameter passed
    public static boolean isValid(EditText editText, String regex, String errMsg, boolean required) {

        String text = editText.getText().toString().trim();
        // clearing the error, if it was previously set by some other values
        editText.setError(null);

        // text required and editText is blank, so return false
        if ( required && !hasText(editText) ) return false;

        // pattern doesn't match so returning false
        if (required && !Pattern.matches(regex, text)) {
            editText.setError(errMsg);
            return false;
        };

        return true;
    }

    // check the input field has any text or not
    // return true if it contains text otherwise false
    public static boolean hasText(EditText editText) {

        String text = editText.getText().toString().trim();
        editText.setError(null);

        // length 0 means there is no text
        if (text.length() == 0) {
            editText.setError(REQUIRED_MSG);
            return false;
        }

        return true;
    }
}

This is the error message:

  Process: gmbh.packagename.myselfieme, PID: 17795
                                                                            java.lang.NumberFormatException: Invalid int: "2505250525"
                                                                                at java.lang.Integer.invalidInt(Integer.java:138)
                                                                                at java.lang.Integer.parse(Integer.java:413)
                                                                                at java.lang.Integer.parseInt(Integer.java:367)
                                                                                at java.lang.Integer.parseInt(Integer.java:334)
                                                                                at gmbh.packagename.myselfieme.EditActivity$10.afterTextChanged(EditActivity.java:203)

Actually, why do I need to read the input in an input type of date, cast it to an integer and check if this integer value has the right format? Isn`t there any other, better way? I just want to check that the users does not enter more than 6 digits and that these digits have the right format.

Any hints or help would be appreciated, thanks!

First, Tim Biegeleisen's comment that you should use a date picker rather than an EditText is probably well worth considering.

Anyway, if you get your date as a string, the recommended way of validating it is to try to parse it into a date and see if you succeed — not through a regular expression. And you certainly shouldn't try to parse it as an integer, that is bound to fail. My code would go something like:

    String ss = date.getText().toString();
    if (ss.isEmpty()) {
        // tell the user to enter something
    } else {
        try {
            LocalDate.parse(ss);
            // tell the user the format is right
        } catch (DateTimeParseException dtpe) {
            // tell the user that this is not a valid date
        }
    }

I am assuming that your date should be in the format yyyy-MM-dd. This is the default parse format for LocalDate , so it's rather straightforward if you know about exceptions and try / catch constructs. If you require a different format, you will need to specify it through a DateTimeFormatter .

The advantage over the regex approach is it gives you much better validation. ^\\\\d{4}-\\\\d{2}-\\\\d{2}$ will accept 2017-29-11 and 2017-11-92 as dates, where the parsing approach will catch if the month is not 1 through 12 or the day-of-month is not within the number of days in that month.

Now you are at it, if you need to keep your date (likely since you asked the user to enter it), keep it as a LocalDate object rather than a string. This will prepare your app for doing all sorts of operations on the date. Whenever you need a string, just use LocalDate.toString() . Or use a DateTimeFormatter if you want the string as for example “Sunday November 19, 2017” or even in German or some other language.

I am using java.time , the modern Java date and time API also known as JSR-310. Unfortunately this doesn't come with most Android devices yet. The solution is the ThreeTenABP , the backport of JSR-310 to Android. I encourage you to get this and start coding.

I just want to check that the users does not enter more than 6 digits and that these digits have the right format.

Lets say, required format is dd-mm-yy

Use regex - \\d{2}-\\d{2}-\\d{2}

For example,

if (inputSTR.matches("\\d{2}-\\d{2}-\\d{2}")) {
    // input matches to required pattern
} else {
    // Show error msg
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM