iink SDK on Device

Answered

Double-tap detection on Android

I noticed that both taps must be very close in distance to be detected as a double-tap on Android when using the UI Reference Implementation. For example, this can be observed with the sample projects (Demo and GetStarted). 

Is there some way to change that sensitivity? The app "Nebo for Huawei" is much more permissive and will detect 2 taps as a double-tap even if there is more distance between the 2 tap locations.

Thank you.


Best Answer

Dear Nicolas,


thank you for the explanation.


If I understand well, all you need is not call the "editor.convert" using our double tap but using the default Android one?


In that case, we just though of the following way you could proceed:

-You disable the "convert-on-double-tap" ; this is done setting the configuration to false: conf.setBoolean("convert.convert-on-double-tap", false);

-Then, in your onDoubleTap function, you call the editor.convert.


Let us know if this answers your expectations.


Best regards,


Olivier


Thank you for looking into this again.

I don't want to achieve anything fancy. It's just that since we find that the detection of double-taps by iink is too harsh (meaning that too often a double-tap is not detected when we try to do one), we would like to use Android's double-tap detection and call iink's Editor.convert ourselves when we detect it.

We would like to leave the handling of the rest of the touches (single taps, scroll, etc.) to iink since we don't have any problem with its handling of those. However, we want to avoid iink acting on the individual taps of a double-tap as well as handling double-taps twice if both our detector and iink detect it.

Answer

Dear Nicolas,


thank you for the explanation.


If I understand well, all you need is not call the "editor.convert" using our double tap but using the default Android one?


In that case, we just though of the following way you could proceed:

-You disable the "convert-on-double-tap" ; this is done setting the configuration to false: conf.setBoolean("convert.convert-on-double-tap", false);

-Then, in your onDoubleTap function, you call the editor.convert.


Let us know if this answers your expectations.


Best regards,


Olivier

Thank you Olivier.

Your solution is pretty good.

This is still not perfect since there are cases where both a single tap and a double tap are handled for the same event (single-tap handled by the iink detector that did not detect the double tap and double tap handled by our own detector) but I think we can live with that and this is a good enough solution for us.

Thanks again!


Dear Nicolas,


thank you for the update. I am glad this way to proceed better answers your use-case.


Best regards,


Olivier

Dear Nicolas,


thank you for contacting us on your question.


Indeed, our iink SDK uses the default Android double tap detection: https://developer.android.com/reference/android/view/GestureDetector.OnDoubleTapListener#onDoubleTap(android.view.MotionEvent)


If you want to tune it, you shall then implement your own Double tap detection.


Best regards,


Olivier

Thank you Olivier.

Are you sure that version 1.3.1 of iink for Android uses Android's double tap detection?

I tried adding my own GestureDetector.OnDoubleTapListener and it detects double taps that are not recognized by iink when the taps are a bit far apart. By looking at the code in UIReferenceImplementation's InputController.java, the touch events are passed to the Editor which in turn sends them to native functions, so my guess is that double tap detection is done in the native code and not using Android APIs, but I could be wrong.

In any case, I tried handling double taps in my app, but if I avoid sending the event where the double tap is detected to the Editor, the app crashes. And if I both handle the double tap myself and pass the event to the Editor, the double tap would end up being processed twice (as though the user had double tapped 2 times), which is not desirable.

So I'm stuck and not sure how to proceed to handle double taps myself.

Dear Nicolas,


I confirm we are using the Android double tap detection.


Currently, is it possible to learn more about your implementation?


Do you proceed detecting 2 single taps, and when the timer in between both is as you prefer, you consider a "doubleTap?


If so, theen you should be able to find help on forums: https://stackoverflow.com/questions/2217670/android-how-to-detect-double-tap


Best regards,


Olivier

Thanks Olivier.

My problem is that the double-tap detection by the iink library does not work very well on our test devices. What I mean is that there are many instances where I think I double-tapped on a block of text, but no "conversion" is done by the library, so it looks like the double-tap was not detected. It sometimes takes 4 to 5 tries before a double-tap is finally detected and the conversion is applied. Doing these tests I noticed that the distance between the 2 taps (physical distance in pixels on the screen, not the time between the taps) has to be closer than usual for a double-tap to be detected, but I'm not sure it's the only cause for the issue.

I tried adding my own double-tap detector in version 1.3.1 of the module UIReferenceImplementation taken from your repository [MyScript / interactive-ink-examples-android] on Github by doing the following:

In InputController.java:

Add GestureDetector.OnDoubleTapListener to what the class InputController implements.

Add a private Context member called mContext and initialize it with the Context received as parameter in the constructor.

Also in the constructor, add the line

 

gestureDetector.setOnDoubleTapListener(this);

 At the end of the class, implement the DoubleTapListener as follows:


 

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
  return false;
}

@Override
public boolean onDoubleTap(MotionEvent e) {
  Toast.makeText(mContext, "Double tap", Toast.LENGTH_SHORT).show();
  return true;
}

@Override
public boolean onDoubleTapEvent(MotionEvent e) {
  return true;
}

 

 

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
  return false;
}

@Override
public boolean onDoubleTap(MotionEvent e) {
  Toast.makeText(mContext, "Double tap", Toast.LENGTH_SHORT).show();
  return true;
}

@Override
public boolean onDoubleTapEvent(MotionEvent e) {
  return true;
}

 

 

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
  return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
  Toast.makeText(mContext, "Double tap", Toast.LENGTH_SHORT).show();
  return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
  return true;
}

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
  return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
  Toast.makeText(mContext, "Double tap", Toast.LENGTH_SHORT).show();
  return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
  return true;
}

This new double-tap listener will simply show a Toast when it detects a double-tap.

This can be done using either the Demo or GetStarted apps from the examples available in your Github. When doing this, I see that if I tap 2 points with a certain distance (in pixels on the screen) over a block of text, a double-tap is detected by my detector, but there is no reaction from the iink library (it does not do "convert" on the block). However, if both taps are very close together, I will still the toast from my detector and "convert" will also be applied most of the time.

 


Dear Nicolas,


my apologies, as you are indeed right, the iink has its own tap detection, which explains the difference in behavior in between the iink and our Nebo application.


Is it possible to learn more of what you want to achieve, so that we may think of a way to bypass the iink gesture detetion?


Best regards,


Olivier