MainActivity.java 5.3 KB

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