onKeyUp function not calling second time - android

I have been trying to built an app based on GHOST game.
I have written an onKeyUp function which only accepts lowercase alphabets and adds it to a string called wordfragment and then calling the function computerTurn in it. But i had seen after successfully running first time i.e. calling the computerTurn function and getting return statement from computerturn function it(onkeyup) does not works second time.
Here my code to onKeyUp function.
#Override
public boolean onKeyUp(int KeyCode, KeyEvent event) {
char ch = (char)event.getUnicodeChar();
if( !( ch >= 'a' && ch <='z' ) ) {
return super.onKeyUp(KeyCode, event);
}
wordFragment = wordFragment + ch;
label.setText(COMPUTER_TURN);
text.setText(wordFragment);
userTurn = false;
computerTurn();
return true;
}
and my code to computerTurn function is
private boolean computerTurn() {
if(wordFragment.length() >= 4 && dictionary.isWord(wordFragment)){
label.setText("Computer wins");
// challenge.setEnabled(false);
return true;
}
else {
String word = dictionary.getAnyWordStartingWith(wordFragment.toLowerCase());
if(word!=null){
Toast.makeText(GhostActivity.this, "comp word found", Toast.LENGTH_SHORT).show();
wordFragment += word.charAt(wordFragment.length());
}
else{
Toast.makeText(GhostActivity.this, "comp word not found", Toast.LENGTH_SHORT).show();
label.setText("User Wins!!");
//challenge.setEnabled(false);
// wordFragment += (char)(random.nextInt(26) + 61);
}
}
// Do computer turn stuff then make it the user's turn again
userTurn = true;
label.setText(USER_TURN);
text.setText(wordFragment);
Toast.makeText(GhostActivity.this, "return true", Toast.LENGTH_SHORT).show();
return true;
}

Android softkeyboards rarely use key events. The correct way to use an android soft keyboard is via InputConnection. Only hardware keys generally issue key events. Basically you're coding this the right way for Windows or web, but the wrong way for Android.

Related

Codename One - scanning barcodes checking for new line/ENTER character

in Android I can easily detect the ENTER character using the setOnEditorActionListener method so that when a barcode is scanned into a textfield I know when the whole barcode has been read.
[Here is the Android code as requested:]
scanEditText.setOnEditorActionListener(new TextView.OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
if ( (actionId == EditorInfo.IME_ACTION_DONE) || ((event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN )))
{
System.out.println(" *** ENTER!");
return true;
}
else
return false;
}
});
I have been trying to replicate this in Codename One but with no luck. I have tried
setDoneListener
addDataChangedListener
ActionEvent on the text field and text area
overriding the keyPressed and keyReleased methods
but with no joy. If I set a textField with setSingleLineTextArea(false) I can see the barcode characters appear in the box followed by what I am assuming is a
new line character as the next scan appears on a new line. None of the methods listed seem to catch this event. If I change the focus to another box the ActionEvent is triggered but I don't want to have to move the focus each time.
[Here is the Codenameone code]
gui_searchTextField.setSingleLineTextArea(false);
gui_searchTextField.setDoneListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
Dialog.show("KB", "doneListener " +
gui_searchTextField.getText().trim(), "OK", null);
}
});
gui_searchTextField.addDataChangedListener((evt1, evt2) ->
{
System.out.println("DataChanged " + gui_searchTextField.getText());
});
So, how do I catch the end of the barcode like I can easily in the Android SDK?
Text input is very much a special case for us in all OS's so the keys go directly into the native OS text editing and don't "travel" through Codename One API's. However, DataChangeListener should be invoked for every key input so I'm not sure how this is happening exactly.
I did notice you are using System.out instead of Log.p so you might miss the output from the device related to the changes. Also I would recommend overriding the key pressed/released events and not starting the text editing. Then adding the key value to the text field instead of letting the native input handle it e.g.:
class MyForm extends Form {
public void keyReleased(int key) {
if(isCrLf(key)) {
// do this...
} else {
myTextField.setText(myTextField.getText() + ((char)key));
}
}
}

Validation android

I'm new in android programming but I have a validation function after the user inserts some data like:source point,destination point,...etc
I have 2 spinners :source and destinations ,both include same values..and i want to be able to send a pop up if a user is selecting the same source and destination and the function is this one:
spSursa=is the source spinner
spDestinatie=is the destinations spinner
private boolean validare_Date()
{
if(spSursa.getSelectedItem().toString()!=spDestinatie.getSelectedItem().toString() )
{
if(ratb.isChecked()==false && metrorex.isChecked()==false && both.isChecked()==false)
{
Toast.makeText(getApplicationContext(), R.string.ADAUGA_RUTA_EROARE_TRANSPORT, Toast.LENGTH_SHORT).show();
return false;
}
else
{
return true;
}
}
else {
Toast.makeText(getApplicationContext(), R.string.ADAUGA_RUTA_EROARE_SURSA_DEST, Toast.LENGTH_SHORT).show();
return false;
}
}
Try to change
if(spSursa.getSelectedItem().toString()!=spDestinatie.getSelectedItem().toString() )
To
if(!spSursa.getSelectedItem().toString().equals(spDestinatie.getSelectedItem().toString()))

android get barcode scanner input without edittext

I have a physical barcode scanner and I want to get it's input, i.e the barcode, in the app without having a focused EditText.
I tried adding a KeyListener in my Activity. However, none of its implemented methods (onKeyUp, onKeyDown etc) was called.
Then I added the dispatchKeyEvent, which worked, but is never called as many times as the barcode length. Instead, before the barcode is read, some random button in my view gets focus from the barcode scanner.
String barcode = "";
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
char pressedKey = (char) e.getUnicodeChar();
barcode += pressedKey;
if (e.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
Toast.makeText(getApplicationContext(), "barcode--->>>" + barcode, Toast.LENGTH_LONG)
.show();
}
return super.dispatchKeyEvent(e);
}
I've seen a few questions out there in SO but none really gave a concrete answer.
For me, for a barcode scanner (USB, reference STA pcs) works the next code:
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if(e.getAction()==KeyEvent.ACTION_DOWN){
Log.i(TAG,"dispatchKeyEvent: "+e.toString());
char pressedKey = (char) e.getUnicodeChar();
barcode += pressedKey;
}
if (e.getAction()==KeyEvent.ACTION_DOWN && e.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
Toast.makeText(getApplicationContext(),
"barcode--->>>" + barcode, Toast.LENGTH_LONG)
.show();
barcode="";
}
return super.dispatchKeyEvent(e);
}
First, thank you all.
Since my App has to look up the barcode in the DB I had to not add the ENTER_KEY input to the Barcode String, also to prevent any focused button of going off I made the Method return false.
String barcode = "";
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if(e.getAction()==KeyEvent.ACTION_DOWN
&& e.getKeyCode() != KeyEvent.KEYCODE_ENTER){ //Not Adding ENTER_KEY to barcode String
char pressedKey = (char) e.getUnicodeChar();
barcode += pressedKey;
}
if (e.getAction()==KeyEvent.ACTION_DOWN
&& e.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
Log.i(TAG,"Barcode Read: "+barcode);
barcodeLookup(barcode);// or Any method handling the data
barcode="";
}
return false;
}
Using kotlin
private val barcode = StringBuffer()
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
if (event?.action == KeyEvent.ACTION_DOWN) {
val pressedKey = event.unicodeChar.toChar()
barcode.append(pressedKey)
}
if (event?.action == KeyEvent.ACTION_DOWN && event?.keyCode == KeyEvent.KEYCODE_ENTER) {
Toast.makeText(baseContext, barcode.toString(), Toast.LENGTH_SHORT).show()
barcode.delete(0, barcode.length)
}
return super.dispatchKeyEvent(event)
}
e.getCharacters() should give you the complete barcode.
This works for me on a PL-40L device with embedded 2d barcode reader, running Android 5.1
dispatchKeyEvent(KeyEvent e) is triggered once for each read barcode, not for each character in the barcode
Hope this helps
DispatchKeyEvent Hardware key events are always delivered to the View currently in focus. They are dispatched starting from the top of the View hierarchy, and then down, until they reach the appropriate destination. If your View (or a child of your View) currently has focus, then you can see the event travel through the dispatchKeyEvent() method. In short, dispatchKeyEvent() will be only called if TextView/EditText is in focus.
You can do it even without any focused View. You need to subscribe for broadcast intent like this:
const val QR_ACTION: String = "android.intent.ACTION_DECODE_DATA"
const val QR_EXTRA: String = "barcode_string"
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
try {
Timber.d("Get intent ${intent.action}")
if (QR_ACTION == intent.action) {
if (intent.hasExtra(QR_EXTRA)) {
val code = intent.getStringExtra(QR_EXTRA)
Timber.d("New QR code $code")
// now you have qr code here
}
} }
} catch (t: Throwable) {
// handle errors
}
}
}
Please check QR_ACTION and QR_EXTRA in your scanner settings first, it can be different for different brands.

Apply code to a gameObject with EventTrigger

I have a button for which i'd like to signify "attacking". I'm programming for android.
Basically i'd like to run this script, upon the touch of the attack button. Instead of using the F key to stop the code from rapidly repeating, i'm trying to figure out how to run an if statement for "if button is touched & !isAttacking" then go into the method.
if (Input.GetKeyDown(KeyCode.F) && !isAttacking)
{
isAttacking = true;
attackTimer = attackCD;
Debug.Log("F Pressed");
attackTrigger.enabled = true;
}
if (isAttacking)
{
if (attackTimer > 0)
{
attackTimer -= Time.deltaTime;
}
else
{
isAttacking = false;
attackTrigger.enabled = false;
}
}
I'm using Unity 5!

Toggeling Touch by external keyboard

I am building a firmware for visually disabled people. I have to disable touch screen as and when the external key board is connected. And toggle it with Alt + T . For this I have a static volatile flag in View class called misTouchScreenEnabled. Upon plug in of external keyboard I return false from dispatchTouchEvent(). In View Class :
/*
* A register to hold the status of touch screen
*
*{#hide}
*/
public static volatile boolean misTouchScreenEnabled = false;
public boolean dispatchTouchEvent(MotionEvent event) {
if(event == null)
{
return false;
}
Log.d ("CnxsTA","View :: Into dispatchTouchEvent");
// Added by Harsh Vardhan 05102013
Configuration config = getResources().getConfiguration();
if (config.keyboard != Configuration.KEYBOARD_NOKEYS)
{
// And if the device has a hard keyboard, even if it is
// currently hidden, don't pass the touch events to the view
if(!mIsTouchScreenEnabled)
{
Log.d ("CnxsTA","View :: Into dispatchTouchEvent :: Returning False");
return false;
}
}
// Added By Harsh Vardhan
// Some Other Code...
}
In Launcher I catch the ALT + T in dispatchTouchEvent() and toggle the flag using reflection:
case KeyEvent.KEYCODE_T:
{
//Added By Harsh Vardhan 31052013
Log.d ("CnxsTA","Launcher :: onKeyDown :: T pressed");
if ((event.getMetaState() & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON)
{
Object s;
try
{
Log.d ("CnxsTA","Launcher :: In onKeyDown :: In isAltPressed");
s = ToogleTouchScreen(Class.forName("android.view.View"), "mIsTouchScreenEnabled");
if (s instanceof Boolean)
{
boolean v = ((Boolean) s).booleanValue();
//do something
Log.d ("CnxsTA","Launcher :: onKeyDown :: In isAltPressed :: Toggling touchscreen enable flag :: " + v);
if (accessibilityEnabled)
{
if (mTts != null)
{
if (v)
mTts.speak("Touch Screen enabled", TextToSpeech.QUEUE_FLUSH, null);
else
mTts.speak("Touch Screen disabled", TextToSpeech.QUEUE_FLUSH, null);
}
}
}
else if (s == null)
{
//do something
Log.d ("CnxsTA","Launcher :: onKeyDown :: S is Null");
}
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
//return super.dispatchKeyEvent(event);
return true;
//break;
//Added By Harsh Vardhan 31052013
}
This works well for the Launcher and its workspace, ie. the touch gets enabled and disabled when ALT + T is pressed. But the Panel in the bottom containing the back, home, recent apps and notifications remains unresponsive on touch and so is the UI in the application; though in Exploration Mode the Icons names are spoken on touch but the touch is not implemented. And it all retains to normal sate once the external keyboard is removed.
I think the reason behind this could be that the StatusBar Class and Other Classes extending the View which are taking the flag to be false only has cached the whole class or the variables and methods and is not referring to main memory where the flags have been toggled. I am aware that I have made the flag volatile.
I know that my flag gets toggle as I could confirm this from logcat. Please suggest me the direction I could solve this. Thanking in advance.

Categories

Resources