I can pause and resume in text to speech by using below code but onRangeStart() values are discarded, i am highlighting text also while tts is speaking however when i resume, then onRangeStart() values fall back to 0th index.
HOW can i save onRangeStart() values?
int index;
int start;
int end;
String text;
String alltext;
public void getReady() {
alltext = main_input.getText().toString() ;
alltextlen = alltext.length();
list.clear();
int i;
int i2 = 0;
while(true) {
i = alltextlen;
if(i2 >= i - 1) {
break;
}
String s = Character.toString().alltext.charAt(i2);
if(s.equals(".") {
list.add(i2);
i2++;
}
list.add(i - 1);
start = maininput.getSelectionStart();
while(i3 < list.size()) {
if(list.get(i3) >= start) {
index = i3;
break;
}
speak();
}
private void speak() {
if(index < list.size()) {
end = list.get(index) + 1;
text = allText.substring(start, end);
start = end;
texttospeech.speak(text, 0, null, "tts");
}
}
Related
I have an activity where credit/debit card details is added. Currently my code allows to add date and month in MM/YY format. But i need year in 4 digits format MM/YYYY. Adding the '/' divider is set after 2nd digit. So if i increase my total digits count, i get the divider after every 2nd digit. How to fix this?
Carddetails.java:
public class CardDetailsActivity extends AppCompatActivity implements TextWatcher {
private static final int CARD_NUMBER_TOTAL_SYMBOLS = 19; // size of pattern 0000-0000-0000-0000
private static final int CARD_NUMBER_TOTAL_DIGITS = 16; // max numbers of digits in pattern: 0000 x walknew2
private static final int CARD_NUMBER_DIVIDER_MODULO = 5; // means divider position is every 5th symbol beginning with walknew4
private static final int CARD_NUMBER_DIVIDER_POSITION = CARD_NUMBER_DIVIDER_MODULO - 1; // means divider position is every 4th symbol beginning with 0
private static final char CARD_NUMBER_DIVIDER = '-';
#BindView(R.id.cardno)
EditText cardno;
#BindView(R.id.cardDateEditText)
EditText cardDateEditText;
#BindView(R.id.cardCVCEditText)
EditText cardCVCEditText;
SharedPreferences pref;
SharedPreferences.Editor editor;
private static final int CARD_DATE_TOTAL_SYMBOLS = 7; // size of pattern MM/YY
private static final int CARD_DATE_TOTAL_DIGITS = 6; // max numbers of digits in pattern: MM + YY
private static final int CARD_DATE_DIVIDER_MODULO = 3; // means divider position is every 3rd symbol beginning with walknew4
private static final int CARD_DATE_DIVIDER_POSITION = CARD_DATE_DIVIDER_MODULO - 1; // means divider position is every 2nd symbol beginning with 0
private static final char CARD_DATE_DIVIDER = '/';
private static final int CARD_CVC_TOTAL_SYMBOLS = 3;
String card_date, card_year, card_month, card_cvv, card_num, user_id, card_type = "debitcard";
#BindView(R.id.btn_add_card)
Button btn_add_card;
#BindView(R.id.btn_back)
Button btn_back;
Context context;
ProgressDialog progressDialog;
ApiService apiService;
String driverid, id, usertype, c_id, booking_id;
EditText card_numm, card_yearm, card_cvvm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_details);
ButterKnife.bind(this);
context = CardDetailsActivity.this;
Log.e("TAG", "Inside Card Details Activity:");
apiService = RetrofitSingleton.getApiService();
usertype = PrefConnect.readString(CardDetailsActivity.this, PrefConnect.USERTYPE, "");
pref = getApplicationContext().getSharedPreferences("MyPref", 0);
editor = pref.edit();
id = pref.getString("driver_id", "");
Log.e("driver_id", id);
try {
if (getIntent() != null) {
driverid = getIntent().getStringExtra("Driverid");
booking_id = getIntent().getStringExtra("bookingid");
}
} catch (Exception e) {
e.printStackTrace();
Log.e("paymentact", e.getMessage());
}
cardno.getText().toString().trim();
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
cardno.addTextChangedListener(this);
cardDateEditText.addTextChangedListener(this);
card_numm = (EditText) findViewById(R.id.cardno);
card_yearm = (EditText) findViewById(R.id.cardDateEditText);
card_cvvm = (EditText) findViewById(R.id.cardCVCEditText);
}
#OnClick({R.id.btn_add_card, R.id.btn_back})
public void OnClick(View view) {
switch (view.getId()) {
case R.id.btn_back:
finish();
break;
case R.id.btn_add_card:
View view1 = getCurrentFocus();
Log.e("TAG", "Inside Card Details Activity Button Add Card ");
Validation();
break;
}
}
private boolean isInputCorrect(Editable s, int size, int dividerPosition, char divider) {
boolean isCorrect = s.length() <= size;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && (i + 1) % dividerPosition == 0) {
isCorrect &= divider == s.charAt(i);
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
private String concatString(char[] digits, int dividerPosition, char divider) {
final StringBuilder formatted = new StringBuilder();
for (int i = 0; i < digits.length; i++) {
if (digits[i] != 0) {
formatted.append(digits[i]);
if ((i > 0) && (i < (digits.length - 1)) && (((i + 1) % dividerPosition) == 0)) {
formatted.append(divider);
}
}
}
return formatted.toString();
}
private char[] getDigitArray(final Editable s, final int size) {
char[] digits = new char[size];
int index = 0;
for (int i = 0; i < s.length() && index < size; i++) {
char current = s.charAt(i);
if (Character.isDigit(current)) {
digits[index] = current;
index++;
}
}
return digits;
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable s) {
card_num = String.valueOf(s);
Log.i("TAG", "Card Date:" + s);
Log.i("TAG", "Card Date :" + cardDateEditText.getEditableText());
if (s == cardno.getEditableText()) {
if (!isInputCorrect(s, CARD_NUMBER_TOTAL_SYMBOLS, CARD_NUMBER_DIVIDER_MODULO, CARD_NUMBER_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_NUMBER_TOTAL_DIGITS), CARD_NUMBER_DIVIDER_POSITION, CARD_NUMBER_DIVIDER));
}
// DO STH
} else if (s == cardDateEditText.getEditableText()) {
if (!isInputCorrect(s, CARD_DATE_TOTAL_SYMBOLS, CARD_DATE_DIVIDER_MODULO, CARD_DATE_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_DATE_TOTAL_DIGITS), CARD_DATE_DIVIDER_POSITION, CARD_DATE_DIVIDER));
} else if (s == cardCVCEditText.getEditableText()) {
if (s.length() > CARD_CVC_TOTAL_SYMBOLS) {
s.delete(CARD_CVC_TOTAL_SYMBOLS, s.length());
}
}
}
}
}
As by my understanding, your date divider must always be at position 2
private static final int CARD_DATE_DIVIDER_POSITION = CARD_DATE_DIVIDER_MODULO - 1; // means divider position is every 2nd symbol beginning with 0
with the above declaration, before appending the date divider, I should test this way ( you can change your isInputCorrect method this way):
private boolean isInputCorrect(Editable s, int size, int dividerPosition, char divider) {
boolean isCorrect = s.length() <= size;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && (i + 1) % dividerPosition == 0) {
if (divider=='/') {
if (i==2) {
isCorrect &= divider == s.charAt(i);
}
}
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
And then after the text has changed can be modified a bit to become:
#Override
public void afterTextChanged(Editable s) {
card_num = String.valueOf(s);
String ss=cardDateEditText.getText().toString();
Log.i("TAG", "Card Date:" + s);
Log.i("TAG", "Card Date :" + ss);
if (s == cardno.getEditableText()) {
if (!isInputCorrect(s, CARD_NUMBER_TOTAL_SYMBOLS, CARD_NUMBER_DIVIDER_MODULO, CARD_NUMBER_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_NUMBER_TOTAL_DIGITS), CARD_NUMBER_DIVIDER_POSITION, CARD_NUMBER_DIVIDER));
}
} else if (s == cardDateEditText.getEditableText()) {
if (s.length()<=CARD_DATE_TOTAL_SYMBOLS)
{
if (!isInputCorrect(s, CARD_DATE_TOTAL_SYMBOLS, CARD_DATE_DIVIDER_MODULO, CARD_DATE_DIVIDER)) {
Log.e("TAG",s+"");
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_DATE_TOTAL_DIGITS), CARD_DATE_DIVIDER_POSITION, CARD_DATE_DIVIDER));
}
}else
{
s.delete(CARD_DATE_TOTAL_SYMBOLS,s.length());
}
} else if (s == cardCVCEditText.getEditableText()) {
if (s.length() > CARD_CVC_TOTAL_SYMBOLS) {
s.delete(CARD_CVC_TOTAL_SYMBOLS, s.length());
}
}
}
So you test also the length of the editable text.
The date divider must be included only once and just after the month represented by two first characters. That means the last digit must be at 2nd position index 1, at that instant i==1. So no other divider will be appended. I should have to test if the divider set is for date, to know I'm dealing with the date and then test if the index is not greater or equals to 2.
That's how I could handle that. I hope this will help.
I want to Justify text inside Android TextView. With copy and share function and can accept spannable string. Can someone help me. It's so important for me. Thank you in advance
I have a solution for the text-justify in Android.
I have created a Custom Textview class, with this you can solve the justification issue in Android.
<com.trailcreator.util.JustifyCustomTextView
android:id="#+id/yourTextViewID"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Here is the class
public class JustifyCustomTextView extends android.support.v7.widget.AppCompatTextView {
//Object that helps us to measure the words and characters like spaces.
private Paint mPaint;
//Thin space (Hair Space actually) character that will fill the spaces
private String mThinSpace = "\u200A";
//String that will storage the text with the inserted spaces
private String mJustifiedText = "";
//Float that represents the actual width of a sentence
private float mSentenceWidth = 0;
//Integer that counts the spaces needed to fill the line being processed
private int mWhiteSpacesNeeded = 0;
//Integer that counts the actual amount of words in the sentence
private int mWordsInThisSentence = 0;
//ArrayList of Strings that will contain the words of the sentence being processed
private ArrayList<String> mTemporalLine = new ArrayList<String>();
//StringBuilder that will hold the temporal chunk of the string to calculate word index.
private StringBuilder mStringBuilderCSequence = new StringBuilder();
//List of SpanHolder class that will hold the spans within the giving string.
private List<SpanHolder> mSpanHolderList = new ArrayList<>();
//StringBuilder that will store temp data for joining sentence.
private StringBuilder sentence = new StringBuilder();
private int mViewWidth;
private float mThinSpaceWidth;
private float mWhiteSpaceWidth;
//Default Constructors!
public JustifyCustomTextView(Context context) {
super(context);
}
public JustifyCustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public JustifyCustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mJustifiedText.replace(" ", "")
.replace("", mThinSpace)
.equals(this.getText().toString().replace(" ", "").replace("", mThinSpace))) {
return;
}
ViewGroup.LayoutParams params = this.getLayoutParams();
CharSequence charSequence = this.getText();
mSpanHolderList.clear();
String[] words = this.getText().toString().split(" ");
//Get spans within the string and adds the instance references into the
//SpanHolderList to be applied once the justify process has been performed.
SpannableString s = SpannableString.valueOf(charSequence);
if ((charSequence instanceof SpannedString)) {
for (int i = 0; i < this.getText().length() - 1; i++) {
CharacterStyle[] spans =
((SpannedString) charSequence).getSpans(i, i + 1, CharacterStyle.class);
if (spans != null && spans.length > 0) {
for (CharacterStyle span : spans) {
int spaces =
charSequence.toString().substring(0, i).split(" ").length + charSequence.toString()
.substring(0, i)
.split(mThinSpace).length;
SpanHolder spanHolder =
SpanHolder.getNewInstance(spans, s.getSpanStart(span), s.getSpanEnd(span), spaces);
mStringBuilderCSequence.setLength(0);
for (int j = 0; j <= words.length - 1; j++) {
mStringBuilderCSequence.append(words[j]);
mStringBuilderCSequence.append(" ");
if (mStringBuilderCSequence.length() > i) {
if (words[j].trim().replace(mThinSpace, "").length() == 1) {
spanHolder.setWordHolderIndex(j);
} else {
spanHolder.setWordHolderIndex(j);
spanHolder.setTextChunkPadded(true);
}
break;
}
}
mSpanHolderList.add(spanHolder);
}
}
}
}
mPaint = this.getPaint();
mViewWidth = this.getMeasuredWidth() - (getPaddingLeft() + getPaddingRight());
//This class won't justify the text if the TextView has wrap_content as width
//And won't repeat the process of justify text if it's already done.
//AND! won't justify the text if the view width is 0
if (params.width != ViewGroup.LayoutParams.WRAP_CONTENT
&& mViewWidth > 0
&& words.length > 0
&& mJustifiedText.isEmpty()) {
mThinSpaceWidth = mPaint.measureText(mThinSpace);
mWhiteSpaceWidth = mPaint.measureText(" ");
for (int i = 0; i <= words.length - 1; i++) {
boolean containsNewLine = (words[i].contains("\n") || words[i].contains("\r"));
if (containsNewLine) {
String[] splitted = words[i].split("(?<=\\n)");
for (String splitWord : splitted) {
processWord(splitWord, splitWord.contains("\n"));
}
} else {
processWord(words[i], false);
}
}
mJustifiedText += joinWords(mTemporalLine);
}
//Apply the extra spaces to the items of the SpanList that were added due
//the justifying process.
SpannableString spannableString = SpannableString.valueOf(mJustifiedText);
for (SpanHolder sH : mSpanHolderList) {
int spaceCount = 0, wordCount = 0;
boolean isCountingWord = false;
int j = 0;
while (wordCount < (sH.getWordHolderIndex() + 1)) {
if (mJustifiedText.charAt(j) == ' ' || mJustifiedText.charAt(j) == ' ') {
spaceCount++;
if (isCountingWord) {
wordCount++;
}
isCountingWord = false;
} else {
isCountingWord = true;
}
j++;
}
sH.setStart(
sH.getStart() + spaceCount - sH.getCurrentSpaces() + (sH.isTextChunkPadded() ? 1 : 0));
sH.setEnd(
sH.getEnd() + spaceCount - sH.getCurrentSpaces() + (sH.isTextChunkPadded() ? 1 : 0));
}
//Applies spans on Justified String.
for (SpanHolder sH : mSpanHolderList) {
for (CharacterStyle cS : sH.getSpans())
spannableString.setSpan(cS, sH.getStart(), sH.getEnd(), 0);
}
if (!mJustifiedText.isEmpty()) this.setText(spannableString);
}
private void processWord(String word, boolean containsNewLine) {
if ((mSentenceWidth + mPaint.measureText(word)) < mViewWidth) {
mTemporalLine.add(word);
mWordsInThisSentence++;
mTemporalLine.add(containsNewLine ? "" : " ");
mSentenceWidth += mPaint.measureText(word) + mWhiteSpaceWidth;
if (containsNewLine) {
mJustifiedText += joinWords(mTemporalLine);
resetLineValues();
}
} else {
while (mSentenceWidth < mViewWidth) {
mSentenceWidth += mThinSpaceWidth;
if (mSentenceWidth < mViewWidth) mWhiteSpacesNeeded++;
}
if (mWordsInThisSentence > 1) {
insertWhiteSpaces(mWhiteSpacesNeeded, mWordsInThisSentence, mTemporalLine);
}
mJustifiedText += joinWords(mTemporalLine);
resetLineValues();
if (containsNewLine) {
mJustifiedText += word;
mWordsInThisSentence = 0;
return;
}
mTemporalLine.add(word);
mWordsInThisSentence = 1;
mTemporalLine.add(" ");
mSentenceWidth += mPaint.measureText(word) + mWhiteSpaceWidth;
}
}
//Method that resets the values of the actual line being processed
private void resetLineValues() {
mTemporalLine.clear();
mSentenceWidth = 0;
mWhiteSpacesNeeded = 0;
mWordsInThisSentence = 0;
}
//Function that joins the words of the ArrayList
private String joinWords(ArrayList<String> words) {
sentence.setLength(0);
for (String word : words) {
sentence.append(word);
}
return sentence.toString();
}
//Method that inserts spaces into the words to make them fix perfectly in the width of the view. I know I'm a genius naming stuff :)
private void insertWhiteSpaces(int whiteSpacesNeeded, int wordsInThisSentence,
ArrayList<String> sentence) {
if (whiteSpacesNeeded == 0) return;
if (whiteSpacesNeeded == wordsInThisSentence) {
for (int i = 1; i < sentence.size(); i += 2) {
sentence.set(i, sentence.get(i) + mThinSpace);
}
} else if (whiteSpacesNeeded < wordsInThisSentence) {
for (int i = 0; i < whiteSpacesNeeded; i++) {
int randomPosition = getRandomEvenNumber(sentence.size() - 1);
sentence.set(randomPosition, sentence.get(randomPosition) + mThinSpace);
}
} else if (whiteSpacesNeeded > wordsInThisSentence) {
//I was using recursion to achieve this... but when you tried to watch the preview,
//Android Studio couldn't show any preview because a StackOverflow happened.
//So... it ended like this, with a wild while xD.
while (whiteSpacesNeeded > wordsInThisSentence) {
for (int i = 1; i < sentence.size() - 1; i += 2) {
sentence.set(i, sentence.get(i) + mThinSpace);
}
whiteSpacesNeeded -= (wordsInThisSentence - 1);
}
if (whiteSpacesNeeded == 0) return;
if (whiteSpacesNeeded == wordsInThisSentence) {
for (int i = 1; i < sentence.size(); i += 2) {
sentence.set(i, sentence.get(i) + mThinSpace);
}
} else if (whiteSpacesNeeded < wordsInThisSentence) {
for (int i = 0; i < whiteSpacesNeeded; i++) {
int randomPosition = getRandomEvenNumber(sentence.size() - 1);
sentence.set(randomPosition, sentence.get(randomPosition) + mThinSpace);
}
}
}
}
//Gets a random number, it's part of the algorithm... don't blame me.
private int getRandomEvenNumber(int max) {
Random rand = new Random();
// nextInt is normally exclusive of the top value,
return rand.nextInt((max)) & ~1;
}
}
public class SpanHolder {
private CharacterStyle[] spans;
private int start;
private int end;
private boolean textChunkPadded =false;
private int wordHolderIndex;
private int currentSpaces;
public SpanHolder(CharacterStyle[] spans, int start, int end, int spaces){
this.setSpans(spans);
this.setStart(start);
this.setEnd(end);
this.setCurrentSpaces(spaces);
}
public static SpanHolder getNewInstance(CharacterStyle[] spans, int start, int end, int spaces){
return new SpanHolder(spans,start,end,spaces);
}
public boolean isTextChunkPadded() {
return textChunkPadded;
}
public void setTextChunkPadded(boolean textChunkPadded) {
this.textChunkPadded = textChunkPadded;
}
public int getWordHolderIndex() {
return wordHolderIndex;
}
public void setWordHolderIndex(int wordHolderIndex) {
this.wordHolderIndex = wordHolderIndex;
}
public CharacterStyle[] getSpans() {
return spans;
}
public void setSpans(CharacterStyle[] spans) {
this.spans = spans;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public int getCurrentSpaces() {
return currentSpaces;
}
public void setCurrentSpaces(int currentSpaces) {
this.currentSpaces = currentSpaces;
}
}
GOOD LUCK! (Y)
I want to show the number in this xx-xxx-xxx-xxx-x format on EditText.
Eg (01-140-176-515-4)
I tried modifying the below code which displays the number in credit card number format
(xxxx-xxxx-xxxx-xxxx)
et_cardnumber.addTextChangedListener(new TextWatcher() {
private static final int TOTAL_SYMBOLS = 19; // size of pattern 0000-0000-0000-0000
private static final int TOTAL_DIGITS = 16; // max numbers of digits in pattern: 0000 x 4
private static final int DIVIDER_MODULO = 5; // means divider position is every 5th symbol beginning with 1
private static final int DIVIDER_POSITION = DIVIDER_MODULO - 1; // means divider position is every 4th symbol beginning with 0
private static final char DIVIDER = '-';
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// noop
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
iv_cardtype.setImageResource(getCreditCardTypeForImageView(et_cardnumber.getText().toString()));
}
#Override
public void afterTextChanged(Editable s) {
if (!isInputCorrect(s, TOTAL_SYMBOLS, DIVIDER_MODULO, DIVIDER)) {
s.replace(0, s.length(), buildCorrecntString(getDigitArray(s, TOTAL_DIGITS), DIVIDER_POSITION, DIVIDER));
}
}
private boolean isInputCorrect(Editable s, int totalSymbols, int dividerModulo, char divider) {
boolean isCorrect = s.length() <= totalSymbols; // check size of entered string
for (int i = 0; i < s.length(); i++) { // chech that every element is right
if (i > 0 && (i + 1) % dividerModulo == 0) {
isCorrect &= divider == s.charAt(i);
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
private String buildCorrecntString(char[] digits, int dividerPosition, char divider) {
final StringBuilder formatted = new StringBuilder();
for (int i = 0; i < digits.length; i++) {
if (digits[i] != 0) {
formatted.append(digits[i]);
if ((i > 0) && (i < (digits.length - 1)) && (((i + 1) % dividerPosition) == 0)) {
formatted.append(divider);
}
}
}
return formatted.toString();
}
private char[] getDigitArray(final Editable s, final int size) {
char[] digits = new char[size];
int index = 0;
for (int i = 0; i < s.length() && index < size; i++) {
char current = s.charAt(i);
if (Character.isDigit(current)) {
digits[index] = current;
index++;
}
}
return digits;
}
});
I couldn't get it right when i make changes to get the format which i want.
Can anyone help me to get the number in xx-xxx-xxx-xxx-x format?
i dont know much in Android , but try to build something like this .
str Yourstring = "";
for (int i = 0; i < digits.length; i++) {
if (i == 2 || i == 5 || i == 8 || i == 11) {
Yourstring = Yourstring + "-" +digits[i];
}
else
{
Yourstring = Yourstring +digits[i];
}
}
I answered this already in this link , please change the logic according to your format
Use this library.
it will allow according yo your formate
EditText Pattern lib
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();
}
}
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.