Grab Virtual Keyboard Events when using EditText? Got stuck!

Put problem concerning Views, Layouts and other XML-Resources (like AndroidManifest) here.

Grab Virtual Keyboard Events when using EditText? Got stuck!

Postby mastix » Mon Jan 18, 2010 6:59 pm

Hi guys,

this might be a pretty simple question, but I've tried several ways - with no luck though! :(

I've set the following properties to the EditText to get the "Smiley" Button which is used by the MessagingApp:

android:inputType="textShortMessage"
android:imeOptions="actionSend|flagNoEnterAction"

This works pretty fine... the button is there and it puts a smiley to the EditText.

BUT: I would like to call my own Smiley Dialog (which is currently triggered by a button), when this key is pressed!

So I've tried the OnKeyListener() on the EditText...

This method catches the backspace key and everything from 0-9. But it refuses to catch any other key, so I am not able to get an event when this "smiley" button is pressed.

Do you guys have any idea, how I could do this?

Thank you very much in advance!!!

Sascha
mastix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Sun Sep 20, 2009 9:57 am

Top

Postby nithin.warier » Tue Jan 19, 2010 1:27 pm

Are you using DigitsKeyListener. It will take only digits.
smartandroidians.blogspot.com
nithin.warier
Experienced Developer
Experienced Developer
 
Posts: 87
Joined: Thu Feb 28, 2008 12:05 pm
Location: Malappuram Kerala India

Postby mastix » Tue Jan 19, 2010 1:50 pm

nithin.warier wrote:Are you using DigitsKeyListener. It will take only digits.


Nope. I'm using the OnKeyListener... that's why I think the behavior is kind of weird as I do not receive any other event (e.g. when I press "a" or "space") but the one I've described above. :(
mastix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Sun Sep 20, 2009 9:57 am

Postby nithin.warier » Tue Jan 19, 2010 2:45 pm

ok, then with this information, its difficult to tell, if you give more information, we will see. Anyway, I feel the problem will be in KeyListener.
smartandroidians.blogspot.com
nithin.warier
Experienced Developer
Experienced Developer
 
Posts: 87
Joined: Thu Feb 28, 2008 12:05 pm
Location: Malappuram Kerala India

Postby mastix » Tue Jan 19, 2010 4:12 pm

To be honest, there's not much more to tell... :)

This is how I set the Listener - as you can see I log out every call of the onKey() method:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. this.txtSMSText.setOnKeyListener(new OnKeyListener() {
  2.  
  3.            
  4.  
  5.             @Override
  6.  
  7.             public boolean onKey(View v, int keyCode, KeyEvent event) {
  8.  
  9.                 Log.d(TAG, "Received keyCode: "+keyCode+" - received event: "+event);
  10.  
  11.                 return false;
  12.  
  13.             }
  14.  
  15.  
  16.  
  17.         });
Parsed in 0.030 seconds, using GeSHi 1.0.8.4


And this is what happens:

See screencast:

http://dl.dropbox.com/u/1676562/VirtualKeyBoardLog.mov

According to video, the onKey() method is only called when hitting 0-9 or backspace, but it is definitely not called when hitting other keys.

So as I've said... there's not much more I could tell you. That's pretty much it... and in my opinion... this should work!

Sascha
mastix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Sun Sep 20, 2009 9:57 am

Postby ruhalmi » Sat Jan 30, 2010 1:51 am

Any progress with it? I just happen to stumbled upon same problem, although it seems to occur only in android 2.0 and above...
ruhalmi
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Nov 09, 2009 8:58 am

Top

Postby mastix » Sat Jan 30, 2010 9:30 am

ruhalmi wrote:Any progress with it? I just happen to stumbled upon same problem, although it seems to occur only in android 2.0 and above...


Hi,

unfortunately, it still doesn't work! I'd appreciate any help!!!

Regards,

Sascha
mastix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Sun Sep 20, 2009 9:57 am

Postby ruhalmi » Sat Jan 30, 2010 1:19 pm

Ok, it seems that I found workaround. Although it doesn't make sense to Virtual Keyboard ignore OnKeyListener, what can we do... Here is my solution:

for EditText you need to addTextChangedListener, which implements TextWatcher. I've created new class, because I reuse one TextWatcher with same functionality for many EditTexts. You can also use anonymous TextWatcher like this:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.                 ((EditText)findViewById(R.id.edittext_id)).addTextChangedListener(new TextWatcher() {
  3.  
  4.                        
  5.  
  6.                         public void onTextChanged(CharSequence s, int start, int before, int count) {
  7.  
  8.                                 // I left empty
  9.  
  10.                         }
  11.  
  12.                        
  13.  
  14.                         public void beforeTextChanged(CharSequence s, int start, int count,
  15.  
  16.                                         int after) {
  17.  
  18.                                 // I left empty
  19.  
  20.                         }
  21.  
  22.                        
  23.  
  24.                         public void afterTextChanged(Editable s) {
  25.  
  26.                                 // here I did my magic <img src="http://www.anddev.org/images/smilies/smile.png" alt=":)" title="Smile" />
  27.  
  28.                         }
  29.  
  30.                 });
  31.  
  32.  
Parsed in 0.032 seconds, using GeSHi 1.0.8.4


I implemented just afterTextChanged() method. One problem I had with it is that in my project I have 2 EditTexts that are dependent on each other (second is inverted value of first and vice-versa). So when I addTextChangedListener() for both of them, they went crazy, changing each others value until finally StackOverFlow occurs. Solution for me was to set up OnTouchListener on each EditText. This OnTouchListener upon touching did addTextChangedListener() for touched EditText and removeTextChangedListener() for other one.

I hope this will help you, ask me if something is unclear.
ruhalmi
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Nov 09, 2009 8:58 am

Postby mastix » Sat Jan 30, 2010 5:42 pm

Hi ruhalmi,

I had the same idea, after stumbling upon this issue. But the problem is that I want to open a dialog, when the "smiley button" is pressed. So my idea was to parse the last three typed letters (in the textWatcher methods) and if these letters had equaled ": - )", I would have opened the dialog. Problem: It would have also opened a dialog if the user had entered the same string, because my TextWatcher would not have been able to distinguish between the pressed button and the manual user input. :( I definitely need to find a way to check if someone pressed the smiley button.

Thx anyway for your idea!!!

Sascha
mastix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Sun Sep 20, 2009 9:57 am

Postby ruhalmi » Sat Jan 30, 2010 6:58 pm

try this one - of course instead of image of smiley in code there must be 4 chars smiley with empty space at the end
Code: Select all
":-) "


I hope this helps ;)

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package sk.halmi.smiley;
  3.  
  4.  
  5.  
  6. import android.app.Activity;
  7.  
  8. import android.app.AlertDialog;
  9.  
  10. import android.content.DialogInterface;
  11.  
  12. import android.os.Bundle;
  13.  
  14. import android.text.Editable;
  15.  
  16. import android.text.TextWatcher;
  17.  
  18. import android.util.Log;
  19.  
  20. import android.widget.EditText;
  21.  
  22.  
  23.  
  24. public class Smiley extends Activity {
  25.  
  26.     /** Called when the activity is first created. */
  27.  
  28.     @Override
  29.  
  30.     public void onCreate(Bundle savedInstanceState) {
  31.  
  32.         super.onCreate(savedInstanceState);
  33.  
  34.         setContentView(R.layout.main);
  35.  
  36.     }
  37.  
  38.  
  39.  
  40.         @Override
  41.  
  42.         protected void onStart() {
  43.  
  44.                 super.onStart();
  45.  
  46.                 ((EditText)findViewById(R.id.e_edit)).addTextChangedListener(new TextWatcher() {
  47.  
  48.                        
  49.  
  50.                         public void onTextChanged(CharSequence s, int start, int before,
  51.  
  52.                                         int count) {
  53.  
  54.                                 String textWritten = s.subSequence(start, start+4).toString();
  55.  
  56.                                 if (count == 4 && ":-) ".equals(textWritten)) {
  57.  
  58.                                         Log.i("Smiley_pressed", "Smiley was pressed");
  59.  
  60.                                         showDialog();
  61.  
  62.                                         //if you wish to erase last smiley - this will however
  63.  
  64.                                         //position cursor to start of EditText
  65.  
  66.                                         ((EditText)findViewById(R.id.e_edit))
  67.  
  68.                                                 .setText(s.subSequence(0, start).toString()
  69.  
  70.                                                         + s.subSequence(start+4, s.length()).toString());
  71.  
  72.                                 }
  73.  
  74.                         }
  75.  
  76.                        
  77.  
  78.                         public void beforeTextChanged(CharSequence s, int start, int count,
  79.  
  80.                                         int after) {
  81.  
  82.                                 //not needed
  83.  
  84.                         }
  85.  
  86.                        
  87.  
  88.                         public void afterTextChanged(Editable s) {
  89.  
  90.                                 //not needed
  91.  
  92.                         }
  93.  
  94.                 });
  95.  
  96.         }
  97.  
  98.        
  99.  
  100.         private void showDialog() {
  101.  
  102.         AlertDialog.Builder b = new AlertDialog.Builder(this)
  103.  
  104.         .setTitle("Smiley pressed")
  105.  
  106.         .setMessage("Hail to the king - smiley was pressed")
  107.  
  108.         .setPositiveButton("OK", new DialogInterface.OnClickListener() {
  109.  
  110.                         public void onClick(DialogInterface dialog, int which) {
  111.  
  112.                                 dialog.dismiss();
  113.  
  114.                         }
  115.  
  116.         });
  117.  
  118.         b.show();
  119.  
  120.         }
  121.  
  122. }
  123.  
  124.  
Parsed in 0.042 seconds, using GeSHi 1.0.8.4
Attachments
smiley.zip
(11.51 KiB) Downloaded 53 times
ruhalmi
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Nov 09, 2009 8:58 am

Postby mastix » Sun Jan 31, 2010 9:43 am

Ah, you're right... I could use the count parameter... Great idea. I will try it right away! But it's still a pity that the Listeners do not work as expected. :(
mastix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Sun Sep 20, 2009 9:57 am

Postby ruhalmi » Sun Jan 31, 2010 10:40 am

damn, above code has bug in it :)
If you press character, it will force close, because of IndexOutOfBounds. This is because originally I had string evaluation after count evaluation, so it should be:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. if (count == 4 && ":-) ".equals(s.subSequence(start, start+4).toString())) {
  3.  
  4.    ...
  5.  
  6. }
  7.  
  8.  
Parsed in 0.035 seconds, using GeSHi 1.0.8.4
ruhalmi
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Nov 09, 2009 8:58 am

Postby mastix » Sun Jan 31, 2010 10:44 am

Hehe... I've already fixed that! :)

You've also mixed up the parameters of the onTextChanged method... :)

It's:
public void onTextChanged(final CharSequence string,
final int start, final int count, final int after)

Not:
public void onTextChanged(CharSequence s, int start, int before,
int count) {

But anyway... your idea was great... Now I only have to set the caret position correctly. Then everything is perfect. :)

Thank you so much! :)

EDIT: Now everything works as expected! Caret is set correctly after changing the text and dialog opens! Thx!!!

Sascha
mastix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Sun Sep 20, 2009 9:57 am

Postby ruhalmi » Sun Jan 31, 2010 11:17 am

It's kind of weird that you have final parameters, do you call TextWatcher's method from separate Thread? My non-final parameters were automatically prefilled by eclipse when I added new TextWatcher to EditText.

Anyway, I'm glad it worked ;)
Just test it in all firmwares, perhaps not all of them represents smiley as ": - ) "
ruhalmi
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Nov 09, 2009 8:58 am

Postby mastix » Sun Jan 31, 2010 11:26 am

ruhalmi wrote:It's kind of weird that you have final parameters, do you call TextWatcher's method from separate Thread? My non-final parameters were automatically prefilled by eclipse when I added new TextWatcher to EditText.


No, I made them final... that's a thing that I do all the time... I'm kind of addicted to that. :)

I've just checked the SDK... you are right... the method signature looks like this:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. CharSequence s, int start, int before, int count
Parsed in 0.038 seconds, using GeSHi 1.0.8.4


When I coded this TextWatcher for a different purpose (in October 2009), it looked like this:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. CharSequence s, int start, int count, int after
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


Anyway... it's working now!

Thanks!

Sascha
mastix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Sun Sep 20, 2009 9:57 am

Top
Next

Return to View, Layout & Resource Problems

Who is online

Users browsing this forum: No registered users and 4 guests