MainActivity.java 5.5 KB

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