MainActivity.java 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //% IMPORTS
  2. import android.view.ViewGroup;
  3. import android.text.Editable;
  4. import android.text.Spannable;
  5. import android.text.SpanWatcher;
  6. import android.text.Spanned;
  7. import android.text.TextWatcher;
  8. import android.widget.EditText;
  9. import android.widget.TextView;
  10. import android.view.inputmethod.BaseInputConnection;
  11. import java.util.HashMap;
  12. import autosuggest.InvisibleInputView;
  13. import autosuggest.CustomInputConnection;
  14. //% END
  15. //% MAIN_ACTIVITY_BODY
  16. private ViewGroup rootView;
  17. private HashMap<Integer, InvisibleInputView> editors;
  18. native static void onInitEdit(int id);
  19. public void createComposer(final int id) {
  20. Log.d("darkfi", "createComposer() -> " + id);
  21. final InvisibleInputView iv = new InvisibleInputView(this, id);
  22. editors.put(id, iv);
  23. runOnUiThread(new Runnable() {
  24. @Override
  25. public void run() {
  26. rootView.addView(iv);
  27. iv.clearFocus();
  28. onInitEdit(id);
  29. }
  30. });
  31. }
  32. private InputMethodManager getIMM() {
  33. return (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
  34. }
  35. public boolean focus(final int id) {
  36. final InvisibleInputView iv = editors.get(id);
  37. if (iv == null) {
  38. return false;
  39. }
  40. runOnUiThread(new Runnable() {
  41. @Override
  42. public void run() {
  43. boolean isFocused = iv.requestFocus();
  44. // Just Android things ;)
  45. if (!isFocused) {
  46. Log.w("darkfi", "error requesting focus for id=" + id + ": " + iv);
  47. }
  48. getIMM().showSoftInput(iv, InputMethodManager.SHOW_IMPLICIT);
  49. }
  50. });
  51. return true;
  52. }
  53. public boolean unfocus(final int id) {
  54. final InvisibleInputView iv = editors.get(id);
  55. if (iv == null) {
  56. return false;
  57. }
  58. runOnUiThread(new Runnable() {
  59. @Override
  60. public void run() {
  61. iv.clearFocus();
  62. getIMM().hideSoftInputFromWindow(iv.getWindowToken(), 0);
  63. }
  64. });
  65. return true;
  66. }
  67. /*
  68. public CustomInputConnection getInputConnect(int id) {
  69. InvisibleInputView iv = editors.get(id);
  70. if (iv == null) {
  71. return null;
  72. }
  73. return iv.inputConnection;
  74. }
  75. */
  76. public InvisibleInputView getInputView(int id) {
  77. return editors.get(id);
  78. }
  79. public boolean setText(int id, String txt) {
  80. //Log.d("darkfi", "setText(" + id + ", " + txt + ")");
  81. InvisibleInputView iv = editors.get(id);
  82. if (iv == null) {
  83. return false;
  84. }
  85. // If inputConnection is not yet ready, then setup the editable directly.
  86. if (iv.inputConnection == null) {
  87. iv.setEditableText(txt);
  88. return true;
  89. }
  90. // Maybe do this on the UI thread?
  91. iv.inputConnection.setEditableText(txt, txt.length(), txt.length(), 0, 0);
  92. return true;
  93. }
  94. public boolean setSelection(int id, int start, int end) {
  95. InvisibleInputView iv = editors.get(id);
  96. if (iv == null) {
  97. return false;
  98. }
  99. // If inputConnection is not yet ready, then setup the sel directly.
  100. if (iv.inputConnection == null) {
  101. iv.setSelection(start, end);
  102. return true;
  103. }
  104. iv.inputConnection.beginBatchEdit();
  105. // Not sure if this is needed
  106. //if (start != end)
  107. // iv.inputConnection.finishComposingText();
  108. iv.inputConnection.setSelection(start, end);
  109. iv.inputConnection.endBatchEdit();
  110. return true;
  111. }
  112. public boolean commitText(int id, String txt) {
  113. //Log.d("darkfi", "setText(" + id + ", " + txt + ")");
  114. InvisibleInputView iv = editors.get(id);
  115. if (iv == null) {
  116. return false;
  117. }
  118. if (iv.inputConnection == null) {
  119. return false;
  120. }
  121. iv.inputConnection.beginBatchEdit();
  122. iv.inputConnection.finishComposingText();
  123. iv.inputConnection.commitText(txt, 1);
  124. iv.inputConnection.endBatchEdit();
  125. return true;
  126. }
  127. /*
  128. // Editable string with the spans displayed inline
  129. public String getDebugEditableStr() {
  130. String edit = view.inputConnection.debugEditableStr();
  131. Log.d("darkfi", "getDebugEditableStr() -> " + edit);
  132. return edit;
  133. }
  134. */
  135. public String getAppDataPath() {
  136. return getApplicationContext().getDataDir().getAbsolutePath();
  137. }
  138. public String getExternalStoragePath() {
  139. return getApplicationContext().getExternalFilesDir(null).getAbsolutePath();
  140. }
  141. public int getKeyboardHeight() {
  142. WindowInsets windowInsets = view.getRootWindowInsets();
  143. if (windowInsets == null) {
  144. return 0;
  145. }
  146. Insets imeInsets = windowInsets.getInsets(WindowInsets.Type.ime());
  147. Insets navInsets = windowInsets.getInsets(WindowInsets.Type.navigationBars());
  148. return Math.max(0, imeInsets.bottom - navInsets.bottom);
  149. }
  150. public float getScreenDensity() {
  151. return getResources().getDisplayMetrics().density;
  152. }
  153. //% END
  154. //% MAIN_ACTIVITY_ON_CREATE
  155. rootView = layout;
  156. editors = new HashMap<>();
  157. view.setFocusable(false);
  158. view.setFocusableInTouchMode(false);
  159. view.clearFocus();
  160. // Start a foreground service so the app stays awake
  161. Intent serviceIntent = new Intent(this, ForegroundService.class);
  162. startForegroundService(serviceIntent);
  163. //% END