LUHN credit-card validation fails on a valid card number - android

In my application i want to check whether the user have entered valid card number for that i have used LUHN algorithm.I have created it as method and called in the mainactivity. But even if i give valid card number it shows invalid.While entering card number i have given spaces in between i didn't know because of that its not validating properly. Please help me in finding the mistake.
CreditcardValidation.java
public class CreditcardValidation {
String creditcard_validation,msg;
//String mobilepattern;
public static boolean isValid(long number) {
int total = sumOfDoubleEvenPlace(number) + sumOfOddPlace(number);
if ((total % 10 == 0) && (prefixMatched(number, 1) == true) && (getSize(number)>=16 ) && (getSize(number)<=19 )) {
return true;
} else {
return false;
}
}
public static int getDigit(int number) {
if (number <= 9) {
return number;
} else {
int firstDigit = number % 10;
int secondDigit = (int) (number / 10);
return firstDigit + secondDigit;
}
}
public static int sumOfOddPlace(long number) {
int result = 0;
while (number > 0) {
result += (int) (number % 10);
number = number / 100;
}
return result;
}
public static int sumOfDoubleEvenPlace(long number) {
int result = 0;
long temp = 0;
while (number > 0) {
temp = number % 100;
result += getDigit((int) (temp / 10) * 2);
number = number / 100;
}
return result;
}
public static boolean prefixMatched(long number, int d) {
if ((getPrefix(number, d) == 5)
|| (getPrefix(number, d) == 4)
|| (getPrefix(number, d) == 3)) {
if (getPrefix(number, d) == 4) {
System.out.println("\nVisa Card ");
} else if (getPrefix(number, d) == 5) {
System.out.println("\nMaster Card ");
} else if (getPrefix(number, d) == 3) {
System.out.println("\nAmerican Express Card ");
}
return true;
} else {
return false;
}
}
public static int getSize(long d) {
int count = 0;
while (d > 0) {
d = d / 10;
count++;
}
return count;
}
public static long getPrefix(long number, int k) {
if (getSize(number) < k) {
return number;
} else {
int size = (int) getSize(number);
for (int i = 0; i < (size - k); i++) {
number = number / 10;
}
return number;
}
}
public String creditcardvalidation(String creditcard)
{
Scanner sc = new Scanner(System.in);
this.creditcard_validation= creditcard;
long input = 0;
input = sc.nextLong();
//long input = sc.nextLong();
if (isValid(input) == true) {
Log.d("Please fill all the column","valid");
msg="Valid card number";
}
else{
Log.d("Please fill all the column","invalid");
msg="Please enter the valid card number";
}
return msg;
}
}
MainActivity.java
addcard.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
if(v.getId()==R.id.btn_add)
{
creditcard= card_number.getText().toString();
cv = new CreditcardValidation();
String mob = cv.creditcardvalidation(creditcard);
Toast.makeText(getActivity(), mob, 1000).show();``

refer code below
EditText cardNumber=(EditText)findViewById(R.id.cardNumber);
String CreditCardType = "Unknown";
/// Remove all spaces and dashes from the passed string
String CardNo ="9292304336";///////cardNumber.getText().toString();
CardNo = CardNo.replace(" ", "");//removing empty space
CardNo = CardNo.replace("-", "");//removing '-'
twoDigit=Integer.parseInt(CardNo.substring(0, 2));
System.out.println("----------twoDigit--"+twoDigit);
fourDigit=Integer.parseInt(CardNo.substring(0, 4));
System.out.println("----------fourDigit--"+fourDigit);
oneDigit=Integer.parseInt(Character.toString(CardNo.charAt(0)));
System.out.println("----------oneDigit--"+oneDigit);
boolean cardValidation=false;
// 'Check that the minimum length of the string isn't <14 characters and -is- numeric
if(CardNo.length()>=14)
{
cardValidation=cardValidationMethod(CardNo);
}
boolean cardValidationMethod(String CardNo)
{
//'Check the first two digits first,for AmericanExpress
if(CardNo.length()==15 && (twoDigit==34 || twoDigit==37))
return true;
else
//'Check the first two digits first,for MasterCard
if(CardNo.length()==16 && twoDigit>=51 && twoDigit<=55)
return true;
else
//'None of the above - so check the 'first four digits collectively
if(CardNo.length()==16 && fourDigit==6011)//for DiscoverCard
return true;
else
if(CardNo.length()==16 || CardNo.length()==13 && oneDigit==4)//for VISA
return true;
else
return false;
}
also u can refer this demo project

Scanner.nextLong() will stop reading as spaces (or other non-digit characters) are encountered.
For instance, if the input is 1234 567 .. then nextLong() will only read 1234.
However, while spaces in the credit-card will [likely] cause it to fail LUHN validation with the above code, I make no guarantee that removing the spaces would make it pass - I'd use a more robust (and well-tested) implementation from the start. There is no need to rewrite such code.

Related

Comparison of app version

How to compare app version in android
I got latest version code and current version code , but the problem is
current version is 1.0
and latest version is 1.0.0
so how to compare that float value in android
I have written a small Android library for comparing version numbers: https://github.com/G00fY2/version-compare
What it basically does is this:
public int compareVersions(String versionA, String versionB) {
String[] versionTokensA = versionA.split("\\.");
String[] versionTokensB = versionB.split("\\.");
List<Integer> versionNumbersA = new ArrayList<>();
List<Integer> versionNumbersB = new ArrayList<>();
for (String versionToken : versionTokensA) {
versionNumbersA.add(Integer.parseInt(versionToken));
}
for (String versionToken : versionTokensB) {
versionNumbersB.add(Integer.parseInt(versionToken));
}
final int versionASize = versionNumbersA.size();
final int versionBSize = versionNumbersB.size();
int maxSize = Math.max(versionASize, versionBSize);
for (int i = 0; i < maxSize; i++) {
if ((i < versionASize ? versionNumbersA.get(i) : 0) > (i < versionBSize ? versionNumbersB.get(i) : 0)) {
return 1;
} else if ((i < versionASize ? versionNumbersA.get(i) : 0) < (i < versionBSize ? versionNumbersB.get(i) : 0)) {
return -1;
}
}
return 0;
}
This snippet doesn't offer any error checks or handling. Beside that my library also supports suffixes like "1.2-rc" > "1.2-beta".
I am a bit late to the party but I have a great solution for all of you!
1. Use this class:
public class VersionComparator implements Comparator {
public boolean equals(Object o1, Object o2) {
return compare(o1, o2) == 0;
}
public int compare(Object o1, Object o2) {
String version1 = (String) o1;
String version2 = (String) o2;
VersionTokenizer tokenizer1 = new VersionTokenizer(version1);
VersionTokenizer tokenizer2 = new VersionTokenizer(version2);
int number1, number2;
String suffix1, suffix2;
while (tokenizer1.MoveNext()) {
if (!tokenizer2.MoveNext()) {
do {
number1 = tokenizer1.getNumber();
suffix1 = tokenizer1.getSuffix();
if (number1 != 0 || suffix1.length() != 0) {
// Version one is longer than number two, and non-zero
return 1;
}
}
while (tokenizer1.MoveNext());
// Version one is longer than version two, but zero
return 0;
}
number1 = tokenizer1.getNumber();
suffix1 = tokenizer1.getSuffix();
number2 = tokenizer2.getNumber();
suffix2 = tokenizer2.getSuffix();
if (number1 < number2) {
// Number one is less than number two
return -1;
}
if (number1 > number2) {
// Number one is greater than number two
return 1;
}
boolean empty1 = suffix1.length() == 0;
boolean empty2 = suffix2.length() == 0;
if (empty1 && empty2) continue; // No suffixes
if (empty1) return 1; // First suffix is empty (1.2 > 1.2b)
if (empty2) return -1; // Second suffix is empty (1.2a < 1.2)
// Lexical comparison of suffixes
int result = suffix1.compareTo(suffix2);
if (result != 0) return result;
}
if (tokenizer2.MoveNext()) {
do {
number2 = tokenizer2.getNumber();
suffix2 = tokenizer2.getSuffix();
if (number2 != 0 || suffix2.length() != 0) {
// Version one is longer than version two, and non-zero
return -1;
}
}
while (tokenizer2.MoveNext());
// Version two is longer than version one, but zero
return 0;
}
return 0;
}
// VersionTokenizer.java
public static class VersionTokenizer {
private final String _versionString;
private final int _length;
private int _position;
private int _number;
private String _suffix;
private boolean _hasValue;
VersionTokenizer(String versionString) {
if (versionString == null)
throw new IllegalArgumentException("versionString is null");
_versionString = versionString;
_length = versionString.length();
}
public int getNumber() {
return _number;
}
String getSuffix() {
return _suffix;
}
public boolean hasValue() {
return _hasValue;
}
boolean MoveNext() {
_number = 0;
_suffix = "";
_hasValue = false;
// No more characters
if (_position >= _length)
return false;
_hasValue = true;
while (_position < _length) {
char c = _versionString.charAt(_position);
if (c < '0' || c > '9') break;
_number = _number * 10 + (c - '0');
_position++;
}
int suffixStart = _position;
while (_position < _length) {
char c = _versionString.charAt(_position);
if (c == '.') break;
_position++;
}
_suffix = _versionString.substring(suffixStart, _position);
if (_position < _length) _position++;
return true;
}
}
}
2. create this function
private fun isNewVersionAvailable(currentVersion: String, latestVersion: String): Boolean {
val versionComparator = VersionComparator()
val result: Int = versionComparator.compare(currentVersion, latestVersion)
var op = "=="
if (result < 0) op = "<"
if (result > 0) op = ">"
System.out.printf("%s %s %s\n", currentVersion, op, latestVersion)
return if (op == ">" || op == "==") {
false
} else op == "<"
}
3. and just call it by
e.g. isNewVersionAvailable("1.2.8","1.2.9") where 1.2.8 is your current version here and 1.2.9 is the latest version, which returns true!
Why overcomplicate this so much?
Just scale the major, minor, patch version and you have it covered:
fun getAppVersionFromString(version: String): Int { // "2.3.5"
val versions = version.split(".") // [2, 3, 5]
val major = versions[0].toIntOrDefault(0) * 10000 // 20000
val minor = versions[1].toIntOrDefault(0) * 1000 // 3000
val patch = versions[2].toIntOrDefault(0) * 100 // 500
return major + minor + patch // 2350
}
That way when you compare e.g 9.10.10 with 10.0.0 the second one is greater.
Use the following method to compare the versions number:
Convert float to String first.
public static int versionCompare(String str1, String str2) {
String[] vals1 = str1.split("\\.");
String[] vals2 = str2.split("\\.");
int i = 0;
// set index to first non-equal ordinal or length of shortest version string
while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) {
i++;
}
// compare first non-equal ordinal number
if (i < vals1.length && i < vals2.length) {
int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i]));
return Integer.signum(diff);
}
// the strings are equal or one string is a substring of the other
// e.g. "1.2.3" = "1.2.3" or "1.2.3" < "1.2.3.4"
return Integer.signum(vals1.length - vals2.length);
}
Refer the following SO question : Efficient way to compare version strings in Java

Android Password Strength checker with seekbar

How to Create Password Strength checker with seekbar in android ?
You can use https://github.com/VenomVendor/Password-Strength-Checker for your requirement
or use TextWatcher for checking EditText length .Like this way
public void afterTextChanged(Editable s)
{
if(s.length()==0)
textViewPasswordStrengthIndiactor.setText("Not Entered");
else if(s.length()<6)
textViewPasswordStrengthIndiactor.setText("EASY");
else if(s.length()<10)
textViewPasswordStrengthIndiactor.setText("MEDIUM");
else if(s.length()<15)
textViewPasswordStrengthIndiactor.setText("STRONG");
else
textViewPasswordStrengthIndiactor.setText("STRONGEST");
if(s.length()==20)
textViewPasswordStrengthIndiactor.setText("Password Max Length Reached");
}
};
Demo Help .
afterTextChanged (Editable s) - This method is called when the text
has been changed. Because any changes you make will cause this method
to be called again recursively, you have to be watchful about
performing operations here, otherwise it might lead to infinite loop.
create a rule engine for password strength, may be a simple function which returns strength when you pass a string to it.
use a TextWatcher on your password edit text and pass any string entered through your rules.
Use returned strength value from your rule engine to set progress value and progress color of your progress bar.
https://github.com/yesterselga/password-strength-checker-android
is a really good example. I changed the code not to use string values. Instead of it I am using values from 0-4. here is the code
public enum PasswordStrength
{
WEAK(0, Color.RED), MEDIUM(1, Color.argb(255, 220, 185, 0)), STRONG(2, Color.GREEN), VERY_STRONG(3, Color.BLUE);
//--------REQUIREMENTS--------
static int REQUIRED_LENGTH = 6;
static int MAXIMUM_LENGTH = 6;
static boolean REQUIRE_SPECIAL_CHARACTERS = true;
static boolean REQUIRE_DIGITS = true;
static boolean REQUIRE_LOWER_CASE = true;
static boolean REQUIRE_UPPER_CASE = true;
int resId;
int color;
PasswordStrength(int resId, int color)
{
this.resId = resId;
this.color = color;
}
public int getValue()
{
return resId;
}
public int getColor()
{
return color;
}
public static PasswordStrength calculateStrength(String password)
{
int currentScore = 0;
boolean sawUpper = false;
boolean sawLower = false;
boolean sawDigit = false;
boolean sawSpecial = false;
for (int i = 0; i < password.length(); i++)
{
char c = password.charAt(i);
if (!sawSpecial && !Character.isLetterOrDigit(c))
{
currentScore += 1;
sawSpecial = true;
}
else
{
if (!sawDigit && Character.isDigit(c))
{
currentScore += 1;
sawDigit = true;
}
else
{
if (!sawUpper || !sawLower)
{
if (Character.isUpperCase(c))
sawUpper = true;
else
sawLower = true;
if (sawUpper && sawLower)
currentScore += 1;
}
}
}
}
if (password.length() > REQUIRED_LENGTH)
{
if ((REQUIRE_SPECIAL_CHARACTERS && !sawSpecial) || (REQUIRE_UPPER_CASE && !sawUpper) || (REQUIRE_LOWER_CASE && !sawLower) || (REQUIRE_DIGITS && !sawDigit))
{
currentScore = 1;
}
else
{
currentScore = 2;
if (password.length() > MAXIMUM_LENGTH)
{
currentScore = 3;
}
}
}
else
{
currentScore = 0;
}
switch (currentScore)
{
case 0:
return WEAK;
case 1:
return MEDIUM;
case 2:
return STRONG;
case 3:
return VERY_STRONG;
default:
}
return VERY_STRONG;
}
}
and how to use it:
if(PasswordStrength.calculateStrength(mViewData.mRegisterData.password). getValue() < PasswordStrength.STRONG.getValue())
{
message = "Password should contain min of 6 characters and at least 1 lowercase, 1 uppercase and 1 numeric value";
return null;
}
you may use PasswordStrength.VERY_STRONG.getValue() as alternative. or MEDIUM

Get Index Of The Shuffled Item After collections.shuffle

I am trying to do a jigsaw puzzle app in android. In this, I have split a Bitmap into many small chunks. These chunks are then displayed in a GridViewNow I need to shuffle them. Then, I need to know each image chunk's actualPosition(where the piece was supposed to be, its actual location in the image) and its currentPosition(where the piece is currently located). actualPosition and currentPosition are 2 integer arrays. So is there a way that I can get each image chunk's currentPosition and actualPosition after the shuffling so that after every move that the user make I can check wether every image chunk's actualPosition equals its currentPosition. If so the user wins the game. Can anyone please help me out.
Below is the number puzzle game in pure Java that works. Can be run from command line.
It re-prints the whole matrix after every move (not pretty). It demos the basic game.
I hope most of the code is self explanatory. This shows the basic 2-dim mapping of the game, position tracking, validating based on numbers. Have fun.
package madhav.turangi.basic.game;
import java.util.Random;
import java.util.Scanner;
public class NumberPuzzle {
int size;
int[][] arr;
int spaceRow;
int spaceCol;
int turnsTook;
public NumberPuzzle(int size) {
this.size = size;
arr = new int[size][size];
}
void init()
{
for(int r=0; r<size; r++)
{
for(int c=0; c<arr[r].length; c++)
{
arr[r][c] = r*size + c + 1; // row-column of cell to its value equation
}
}
spaceRow = spaceCol = size - 1; // bottom-right cell index
}
int readUserInput()
{
int value = -1;
boolean valid = false;
do {
System.out.printf("To move space [0 - Up, 1 - Down, 2 - Left, 3 - Right] : ? ");
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
try
{
value = Integer.parseInt(line);
valid = (value>=0 && value<=3);
}
catch(NumberFormatException ne)
{
}
if(! valid) System.out.println("== Invalid ==");
} while (! valid);
return value;
}
void swap(int aRow, int aCol, int withRow, int withCol)
{
int temp = arr[aRow][aCol];
arr[aRow][aCol] = arr[withRow][withCol];
arr[withRow][withCol] = temp;
}
boolean moveUp()
{
if(spaceRow != 0)
{
int newSpaceRow = spaceRow - 1;
swap(spaceRow, spaceCol, newSpaceRow, spaceCol);
spaceRow--;
return true;
}
else
{
return false;
}
}
boolean moveDown()
{
if(spaceRow != size-1)
{
int newSpaceRow = spaceRow + 1;
swap(spaceRow, spaceCol, newSpaceRow, spaceCol);
spaceRow++;
return true;
}
else
{
return false;
}
}
boolean moveRight()
{
if(spaceCol != size-1)
{
int newSpaceCol = spaceCol + 1;
swap(spaceRow, spaceCol, spaceRow, newSpaceCol);
spaceCol++;
return true;
}
else
{
return false;
}
}
boolean moveLeft()
{
if(spaceCol != 0)
{
int newSpaceCol = spaceCol - 1;
swap(spaceRow, spaceCol, spaceRow, newSpaceCol);
spaceCol--;
return true;
}
else
{
return false;
}
}
void shuffle()
{
Random rnd = new Random(System.currentTimeMillis());
boolean moved = false;
int attemptCount = 1;
int maxMoves = 20;
for(int moveCount=0; moveCount<maxMoves; moveCount++, attemptCount++)
{
int randomMoveDir = rnd.nextInt(4);
moved = move(randomMoveDir);
if(! moved) moveCount--; //ensure maxMoves number of moves
}
System.out.printf("Shuffle attempts %d\n",attemptCount);
}
boolean move(int dir)
{
boolean moved = false;
switch(dir)
{
case 0 : // up
moved = moveUp();
break;
case 1 : // down
moved = moveDown();
break;
case 2 : // left
moved = moveLeft();
break;
case 3 : // right
moved = moveRight();
break;
}
return moved;
}
void prnArray()
{
System.out.println("-- -- -- -- --");
for(int[] row : arr)
{
for(int cellValue : row)
{
String v = (cellValue == 16 ? "" : String.valueOf(cellValue));
System.out.printf("%4s", v);
}
System.out.println();
}
System.out.println("-- -- -- -- --");
}
boolean validate()
{
for(int r=0; r<size; r++)
{
for(int c=0; c<arr[r].length; c++)
{
if(arr[r][c] != (r*size + c + 1))
{
return false;
}
}
}
return true;
}
boolean oneTurn()
{
int dir = readUserInput();
boolean moved = move(dir);
boolean won = false;
if(moved)
{
turnsTook++;
prnArray();
won = validate();
}
else
{
System.out.println("= Invalid =");
}
return won;
}
void play()
{
init();
System.out.println("Before shuffle");
prnArray();
shuffle();
prnArray();
boolean won = false;
while(! won)
{
won = oneTurn();
}
System.out.printf("Won in %d\n", turnsTook);
}
public static void main(String[] args)
{
NumberPuzzle puzzle = new NumberPuzzle(4);
puzzle.play();
}
}

Limiting a user to enter 1 decimal value in Edit Text

The requirement is to limit user from not entering more than 1 decimal value in a numeric/decimal edit text field. That said, I also need to limit the number entry to 6 Max digits. eg. 999999.9
If a user enters numeric alone - then I should be able to limit the user to 6 digits Max, but should allow "." and decimal number(if entered by the user).
I am not sure, how to do this. Any help and reference will be of great help.
Maybe some implementation similar to this? I'm pretty sure it can be optimized a lot!
EditText et;
.....
// force number input type on edittext
et.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
et.addTextChangedListener(new CustomTextWatcher(et));
where:
class CustomTextWatcher implements TextWatcher {
private NumberFormat nf = NumberFormat.getNumberInstance();
private EditText et;
private String tmp = "";
private int moveCaretTo;
private static final int INTEGER_CONSTRAINT = 6;
private static final int FRACTION_CONSTRAINT = 1;
private static final int MAX_LENGTH = INTEGER_CONSTRAINT + FRACTION_CONSTRAINT + 1;
public CustomTextWatcher(EditText et) {
this.et = et;
nf.setMaximumIntegerDigits(INTEGER_CONSTRAINT);
nf.setMaximumFractionDigits(FRACTION_CONSTRAINT);
nf.setGroupingUsed(false);
}
public int countOccurrences(String str, char c) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == c) {
count++;
}
}
return count;
}
#Override
public void afterTextChanged(Editable s) {
et.removeTextChangedListener(this); // remove to prevent stackoverflow
String ss = s.toString();
int len = ss.length();
int dots = countOccurrences(ss, '.');
boolean shouldParse = dots <= 1 && (dots == 0 ? len != (INTEGER_CONSTRAINT + 1) : len < (MAX_LENGTH + 1));
if (shouldParse) {
if (len > 1 && ss.lastIndexOf(".") != len - 1) {
try {
Double d = Double.parseDouble(ss);
if (d != null) {
et.setText(nf.format(d));
}
} catch (NumberFormatException e) {
}
}
} else {
et.setText(tmp);
}
et.addTextChangedListener(this); // reset listener
//tried to fix caret positioning after key type:
if (et.getText().toString().length() > 0) {
if (dots == 0 && len >= INTEGER_CONSTRAINT && moveCaretTo > INTEGER_CONSTRAINT) {
moveCaretTo = INTEGER_CONSTRAINT;
} else if (dots > 0 && len >= (MAX_LENGTH) && moveCaretTo > (MAX_LENGTH)) {
moveCaretTo = MAX_LENGTH;
}
try {
et.setSelection(et.getText().toString().length());
// et.setSelection(moveCaretTo); <- almost had it :))
} catch (Exception e) {
}
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
moveCaretTo = et.getSelectionEnd();
tmp = s.toString();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int length = et.getText().toString().length();
if (length > 0) {
moveCaretTo = start + count - before;
}
}
}
Not 100% but you can use as a base and build on top of it ;)
EDIT: tried to polishing setting the caret position after text changed but it was more difficult than I estimated and reverted to setting the caret at the end after each char input. I left the code I started on for the caret maybe you can improve it?
There is a small mistake in above answer
I edited that one use the below code.
import java.math.RoundingMode;
import java.text.NumberFormat;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
public class DecimalTextWatcher implements TextWatcher {
private NumberFormat numberFormat = NumberFormat.getNumberInstance();
private EditText editText;
private String temp = "";
private int moveCaretTo;
private int integerConstraint;
private int fractionConstraint;
private int maxLength;
/**
* Add a text watcher to Edit text for decimal formats
*
* #param editText
* EditText to add DecimalTextWatcher
* #param before
* digits before decimal point
* #param after
* digits after decimal point
*/
public DecimalTextWatcher(EditText editText, int before, int after) {
this.editText = editText;
this.integerConstraint = before;
this.fractionConstraint = after;
this.maxLength = before + after + 1;
numberFormat.setMaximumIntegerDigits(integerConstraint);
numberFormat.setMaximumFractionDigits(fractionConstraint);
numberFormat.setRoundingMode(RoundingMode.DOWN);
numberFormat.setGroupingUsed(false);
}
private int countOccurrences(String str, char c) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == c) {
count++;
}
}
return count;
}
#Override
public void afterTextChanged(Editable s) {
// remove to prevent StackOverFlowException
editText.removeTextChangedListener(this);
String ss = s.toString();
int len = ss.length();
int dots = countOccurrences(ss, '.');
boolean shouldParse = dots <= 1 && (dots == 0 ? len != (integerConstraint + 1) : len < (maxLength + 1));
boolean x = false;
if (dots == 1) {
int indexOf = ss.indexOf('.');
try {
if (ss.charAt(indexOf + 1) == '0') {
shouldParse = false;
x = true;
if (ss.substring(indexOf).length() > 2) {
shouldParse = true;
x = false;
}
}
} catch (Exception ex) {
}
}
if (shouldParse) {
if (len > 1 && ss.lastIndexOf(".") != len - 1) {
try {
Double d = Double.parseDouble(ss);
if (d != null) {
editText.setText(numberFormat.format(d));
}
} catch (NumberFormatException e) {
}
}
} else {
if (x) {
editText.setText(ss);
} else {
editText.setText(temp);
}
}
editText.addTextChangedListener(this); // reset listener
// tried to fix caret positioning after key type:
if (editText.getText().toString().length() > 0) {
if (dots == 0 && len >= integerConstraint && moveCaretTo > integerConstraint) {
moveCaretTo = integerConstraint;
} else if (dots > 0 && len >= (maxLength) && moveCaretTo > (maxLength)) {
moveCaretTo = maxLength;
}
try {
editText.setSelection(editText.getText().toString().length());
// et.setSelection(moveCaretTo); <- almost had it :))
} catch (Exception e) {
}
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
moveCaretTo = editText.getSelectionEnd();
temp = s.toString();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int length = editText.getText().toString().length();
if (length > 0) {
moveCaretTo = start + count - before;
}
}
}
use it as below..
itemCostEditText.addTextChangedListener(new DecimalTextWatcher(itemCostEditText, 6, 2));
You can make use of TextWatcher's afterTextChanged/onTextChanged methods to get notified for text changes and DecimalFormat to format input text
http://developer.android.com/reference/java/text/DecimalFormat.html
http://developer.android.com/reference/android/text/TextWatcher.html

Application randomly stops responding.

I am new to programming and I'm making a very simple blackjack game with only basic functions. When I run the program on the emulator it runs maybe for one hand, two, sometimes 5 or more but it always stops responding at some stage when i click on one of the three butons. There is a splash screen that runs for three seconds and the there is a thread comming from that activity that starts this menu activity. Could anyone maybe tell why this is happening? It usually happens when I clcik on one of the buttons even though there is no much comput
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btDeal = (Button) findViewById(R.id.deal);
playerCards1 = (TextView) findViewById(R.id.playerCards);
playerPoints = (TextView) findViewById(R.id.playerPoints);
dealerCards1 = (TextView) findViewById(R.id.dealerCard);
mpBusted= MediaPlayer.create(this, R.raw.busted);
mpWin = MediaPlayer.create(this, R.raw.win);
mpShuffling = MediaPlayer.create(this, R.raw.shuffling);
mpEven = MediaPlayer.create(this, R.raw.even);
mpHit= MediaPlayer.create(this, R.raw.hit);
btDeal.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
deal ();
}
}); //getTotalDealerCards()
//getTotalPlayerCards()
btHit = (Button) findViewById(R.id.hit);
btHit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Boolean busted = isBusted();
if(!busted){
hitPlayer();
playerCards1.setText(getPlayerCardsToString());
if (isBusted()){
mpBusted.start();
}else{
playerCards1.setText(getPlayerCardsToString());
playerPoints.setText(Integer.toString(getTotalPlayerPoints()));
}
}
}
});
btStand = (Button) findViewById(R.id.stand);
btStand.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
checkWinner();
}// testValue(getTotalPlayerCards())
});
}
/*********** Function declarations starts here **********/
//Sum and return the total points for the dealer cards
public int getTotalDealerPoints(){
int points = 0;
int aceFlag = 0; //flag to deal with Aces
int counter;
for (counter = 0; counter <= getTotalDealerCards(); counter++){
if (dealerCards [counter].getCard() + 1 == 1){
points += 11;
aceFlag++;
}
else if (dealerCards [counter].getCard() + 1 > 10)
points += 10;
else
points += dealerCards [counter].getCard() + 1;
}
do {
if (points > 21 && aceFlag > 0){
points -= 10;
aceFlag--;
}
} while (aceFlag>0);
return points;
}
//Get the total player points deal
public int getTotalPlayerPoints(){
int points = 0;
int aceFlag = 0; //flag to deal with Aces
int counter;
for (counter = 0; counter <= getTotalPlayerCards(); counter++){
if (playerCards [counter].getCard() + 1 == 1){
points += 11;
aceFlag++;
}
else if (playerCards [counter].getCard() + 1 > 10)
points += 10;
else
points += playerCards [counter].getCard() + 1;
}
do {
if (points > 21 && aceFlag > 0){
points -= 10;
aceFlag--;
}
} while (aceFlag>0);
return points;
}
//Deal function to start hand
public void deal (){
// If deal is pressed reset all and start over.
mpShuffling.start();
totalDealerPoints = 0;
totalPlayerPoints = 0;
totalCreatedCards = 0;
for (int i = 0; i < TOTAL_CARDS; i++){
dealerCards [i] = null;
playerCards [i] = null;
createdCards [i] = null;
}
// create dealer & player cards and save them to dealer, player and total arrays.
for (int dealcounter = 0; dealcounter <=1 ; dealcounter++){
dealerCards[dealcounter]= createCard();
addCardToCreatedCards(dealerCards[dealcounter]);
playerCards[dealcounter] = createCard();
addCardToCreatedCards(playerCards[dealcounter]);
}
String theCards = getPlayerCardsToString();
String dealerCard = dealerCards[0].toString();
String playerpoints= Integer.toString(getTotalPlayerPoints());
playerCards1.setText(theCards);
dealerCards1.setText(dealerCard);
playerPoints.setText(playerpoints);//getTotalPlayerPoints()
while (getTotalDealerPoints() < 16){
hitDealer();
}
}
// Create card and validate against existing before returning object.
public Card createCard(){
int counter2 = 0;
int flag = 0;
int value;
int suit;
do {
flag = 0;
suit = randomer.nextInt(4);
value = randomer.nextInt(13);
// validate against permitted values before creating cards
while (counter2 <= getTotalPlayerCards()) {
if (createdCards[counter2].getSuit() == suit && createdCards[counter2].getCard() == value || suit > 3 || suit < 0 || value > 12 || value < 0){
flag = -1;
}
counter2++;
}
} while (flag != 0);
Card theCard = new Card (suit, value);
return theCard;
}
// Add card to the records of created cards
public void addCardToCreatedCards(Card aCard){
createdCards [totalCreatedCards] = aCard;
totalCreatedCards++;
}
// Add a card to dealers cards
public void hitPlayer(){
//If the hand was started add card, else deal to start hand.
if (getTotalPlayerCards()+1 != 0){
mpHit.start();
playerCards [getTotalPlayerCards()+1] = createCard();
addCardToCreatedCards(playerCards [getTotalPlayerCards()]);
}
else
deal();
}
// Create a new card for the dealer
public void hitDealer(){
dealerCards [getTotalDealerCards()+1] = createCard();
addCardToCreatedCards(dealerCards [getTotalDealerCards()]);
}
public String getPlayerCardsToString(){
String cards = "";
int total = getTotalPlayerCards();
if (getTotalPlayerPoints() <=21){
int counter = 0;
while (counter <= total){
cards += playerCards[counter].toString() + " ";
counter++;
}
return cards;
}else {
int counter=0;
while (counter <= total){
cards += playerCards[counter].toString() + " ";
counter++;
}
return cards;
}
}
public int getTotalPlayerCards(){
int initialCount = 0;
while (playerCards[initialCount] != null){
initialCount++;
}
return initialCount-1;
}
public int getTotalDealerCards(){
int initialCount = 0;
while (dealerCards[initialCount] != null){
initialCount++;
}
return initialCount-1;
}
public int getTotalCreatedCards(){
int initialCount = 0;
while (createdCards[initialCount] != null){
initialCount++;
}
return initialCount-1;
}
public Boolean isBusted(){
Boolean busted = false;
if (getTotalPlayerPoints()>21){
busted=true;
totalDealerPoints = 0;
totalPlayerPoints = 0;
mpBusted.start();
playerPoints.setText("You were busted!!");
for (int i = 0; i < TOTAL_CARDS; i++){
dealerCards [i] = null;
playerCards [i] = null;
createdCards [i] = null;
}
}
return busted;
}
//Check for winner
public void checkWinner(){
if (getTotalDealerPoints() <= 21 || getTotalPlayerPoints() <= 21 && !isBusted()){
if (getTotalDealerPoints() > 21 || getTotalDealerPoints() < getTotalPlayerPoints()){
playerPoints.setText("You won!!");
mpWin.start();
}
else if(getTotalDealerPoints() > getTotalPlayerPoints()){
mpBusted.start();
playerPoints.setText("You were busted!!");
for (int i = 0; i < TOTAL_CARDS; i++){
dealerCards [i] = null;
playerCards [i] = null;
createdCards [i] = null;
}
}
else{
mpEven.start();
playerCards1.setText("We have same points!");
}
}
else {
deal ();
}
}
}
Use the debugger in eclipse to find out where it gets frozen.
Also the android emulator is very slow even with a fast PC.
Try using the low resolution simulators.
open DDMS from the android-sdk\tools and check which method or thread is taking more time to execute.
Use AsyncTask or Handler when there is a functional(Computational) things running.

Categories

Resources