11package com .gazlaws .codeboard ;
22
3+ import android .Manifest ;
4+ import android .annotation .SuppressLint ;
35import android .app .NotificationChannel ;
46import android .app .NotificationManager ;
57import android .app .PendingIntent ;
810import android .content .Context ;
911import android .content .Intent ;
1012import android .content .IntentFilter ;
13+ import android .content .pm .PackageManager ;
1114import android .content .res .Configuration ;
1215import android .graphics .Color ;
1316import android .inputmethodservice .InputMethodService ;
1619import android .os .Handler ;
1720import android .os .IBinder ;
1821import android .os .Looper ;
22+ import android .os .ResultReceiver ;
1923import android .os .Vibrator ;
2024import android .util .Log ;
2125import android .view .KeyEvent ;
2630import android .view .inputmethod .InputMethodManager ;
2731import android .media .MediaPlayer ; // for keypress sound
2832
33+ import androidx .core .app .ActivityCompat ;
2934import androidx .core .app .NotificationCompat ;
3035import androidx .core .app .NotificationManagerCompat ;
36+ import androidx .core .app .RemoteInput ;
3137import androidx .core .graphics .ColorUtils ;
3238
3339import com .gazlaws .codeboard .layout .Box ;
4652import java .util .TimerTask ;
4753
4854import static android .content .ClipDescription .MIMETYPE_TEXT_PLAIN ;
55+ import static android .view .inputmethod .InputMethodManager .HIDE_IMPLICIT_ONLY ;
56+ import static android .view .inputmethod .InputMethodManager .HIDE_NOT_ALWAYS ;
4957
5058/*Created by Ruby(aka gazlaws) on 13/02/2016.
5159 */
@@ -73,7 +81,7 @@ public void onKey(int primaryCode, int[] KeyCodes) {
7381 //NOTE: Long press goes second, this is onDown
7482 InputConnection ic = getCurrentInputConnection ();
7583 char code = (char ) primaryCode ;
76- Log .i (getClass ().getSimpleName (), "onKey: " + primaryCode );
84+ Log .d (getClass ().getSimpleName (), "onKey: " + primaryCode );
7785
7886 switch (primaryCode ) {
7987 //First handle cases that don't use shift/ctrl meta modifiers
@@ -274,7 +282,7 @@ public void onKey(int primaryCode, int[] KeyCodes) {
274282 }
275283 if (ke != 0 ) {
276284
277- Log .i (getClass ().getSimpleName (), "onKey: keyEvent " + ke );
285+ Log .d (getClass ().getSimpleName (), "onKey: keyEvent " + ke );
278286
279287 /*
280288 * The if statement was added in order to prevent the space button
@@ -284,7 +292,9 @@ public void onKey(int primaryCode, int[] KeyCodes) {
284292 * and afterwards produce the right output to the screen.
285293 * TODO: Investigate whether KeyEvent.ACTION_UP is still required.
286294 */
287- if (primaryCode != 32 ) { ic .sendKeyEvent (new KeyEvent (0 , 0 , KeyEvent .ACTION_DOWN , ke , 0 , meta )); }
295+ if (primaryCode != 32 ) {
296+ ic .sendKeyEvent (new KeyEvent (0 , 0 , KeyEvent .ACTION_DOWN , ke , 0 , meta ));
297+ }
288298
289299 ic .sendKeyEvent (new KeyEvent (0 , 0 , KeyEvent .ACTION_UP , ke , 0 , meta ));
290300 } else {
@@ -341,6 +351,19 @@ public void run() {
341351 }, ViewConfiguration .getLongPressTimeout ());
342352 }
343353
354+ @ Override
355+ public void onExtractingInputChanged (EditorInfo ei ){
356+ Log .d (getClass ().getSimpleName (), "onExtractingInputChanged: " );
357+ }
358+ @ Override
359+ public void requestHideSelf (int flags ){
360+ int new_flag = HIDE_IMPLICIT_ONLY ;
361+ new_flag = flags ;
362+ Log .d (getClass ().getSimpleName (), "requestHideSelf: " +new_flag + "," + flags );
363+ // do nothing
364+ super .requestHideSelf (new_flag );
365+ }
366+
344367 @ Override
345368 public void onWindowHidden () {
346369 super .onWindowHidden ();
@@ -361,10 +384,10 @@ public void onRelease(int primaryCode) {
361384 * If it was, we don't do anything,
362385 * but If it wasn't, we print a "space" to the screen.
363386 */
364- if ((primaryCode == 32 ) && (! longPressedSpaceButton )) {
387+ if ((primaryCode == 32 ) && (!longPressedSpaceButton )) {
365388
366- InputConnection ic = getCurrentInputConnection ();
367- ic .commitText (String .valueOf ((char ) primaryCode ), 1 );
389+ InputConnection ic = getCurrentInputConnection ();
390+ ic .commitText (String .valueOf ((char ) primaryCode ), 1 );
368391 }
369392
370393 longPressedSpaceButton = false ;
@@ -671,6 +694,7 @@ private void createNotificationChannel() {
671694 private static final int NOTIFICATION_ONGOING_ID = 1001 ;
672695
673696 //Code from Hacker keyboard's source
697+ @ SuppressLint ("MissingPermission" )
674698 private void setNotification (boolean visible ) {
675699 NotificationManager mNotificationManager =
676700 (NotificationManager ) getSystemService (Context .NOTIFICATION_SERVICE );
@@ -682,19 +706,55 @@ private void setNotification(boolean visible) {
682706 createNotificationChannel ();
683707 mNotificationReceiver = new NotificationReceiver (this );
684708 final IntentFilter pFilter = new IntentFilter (NotificationReceiver .ACTION_SHOW );
685- pFilter .addAction (NotificationReceiver .ACTION_SETTINGS );
686- registerReceiver (mNotificationReceiver , pFilter );
687709
688- Intent notificationIntent = new Intent (NotificationReceiver .ACTION_SHOW );
689- PendingIntent contentIntent =
690- PendingIntent .getBroadcast (getApplicationContext (), 1 , notificationIntent , 0 );
710+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
711+ registerReceiver (mNotificationReceiver , pFilter , Context .RECEIVER_NOT_EXPORTED );
712+ } else {
713+ registerReceiver (mNotificationReceiver , pFilter );
714+ }
715+
716+
717+ Intent imeIntent = new Intent (NotificationReceiver .ACTION_SHOW );
718+ PendingIntent imePendingIntent =
719+ PendingIntent .getBroadcast (getApplicationContext (),
720+ 1 , imeIntent , PendingIntent .FLAG_IMMUTABLE );
691721
692- Intent configIntent = new Intent (NotificationReceiver .ACTION_SETTINGS );
693- PendingIntent configPendingIntent =
694- PendingIntent .getBroadcast (getApplicationContext (), 2 , configIntent , 0 );
722+ // BUG: IM closes when notification drawer is closed
723+ // try making a input field here?
724+ // Key for the string that's delivered in the action's intent.
725+ String KEY_TEXT_REPLY = "key_text_reply" ;
695726
727+ RemoteInput remoteInput = new RemoteInput .Builder (KEY_TEXT_REPLY )
728+ .setLabel ("Now click first icon" )
729+ .build ();
730+
731+
732+ // Build a PendingIntent for the keyboard action to trigger first
733+ int flags = PendingIntent .FLAG_MUTABLE ;
734+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .UPSIDE_DOWN_CAKE ) {
735+ flags = PendingIntent .FLAG_MUTABLE | PendingIntent .FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT ;
736+ }
737+ PendingIntent replyPendingIntent =
738+ PendingIntent .getBroadcast (getApplicationContext (),
739+ 2 ,
740+ imeIntent ,
741+ flags );
742+
743+
744+ // Create the reply action and add the remote input.
745+ NotificationCompat .Action action =
746+ new NotificationCompat .Action .Builder (R .drawable .icon_large ,
747+ getString (R .string .notification_action_open_keyboard_workaround ), replyPendingIntent )
748+ .addRemoteInput (remoteInput )
749+ .build ();
750+
751+ Intent settingsIntent = new Intent (this , MainActivity .class );
752+ settingsIntent .setFlags (Intent .FLAG_ACTIVITY_NEW_TASK | Intent .FLAG_ACTIVITY_CLEAR_TASK );
753+ PendingIntent settingsPendingIntent =
754+ PendingIntent .getActivity (this ,0
755+ , settingsIntent , PendingIntent .FLAG_IMMUTABLE );
696756 String title = "Show Codeboard Keyboard" ;
697- String body = "Select this to open the keyboard. Disable in settings." ;
757+ String body = "Select this to open the keyboard. Disable in settings. You may have to fix open the fix as a workaround for newer Android versions " ;
698758
699759 NotificationCompat .Builder mBuilder =
700760 new NotificationCompat .Builder (this , NOTIFICATION_CHANNEL_ID )
@@ -704,17 +764,17 @@ private void setNotification(boolean visible) {
704764 .setTicker (text )
705765 .setContentTitle (title )
706766 .setContentText (body )
707- .setContentIntent (contentIntent )
767+ .setContentIntent (imePendingIntent )
708768 .setOngoing (true )
709769 .addAction (R .drawable .icon_large , getString (R .string .notification_action_open_keyboard ),
710- contentIntent )
770+ imePendingIntent )
711771 .addAction (R .drawable .icon_large , getString (R .string .notification_action_settings ),
712- configPendingIntent )
772+ settingsPendingIntent )
773+ .addAction (action )
713774 .setPriority (NotificationCompat .PRIORITY_DEFAULT );
714775
715776 NotificationManagerCompat notificationManager = NotificationManagerCompat .from (this );
716777
717- // notificationId is a unique int for each notification that you must define
718778 notificationManager .notify (NOTIFICATION_ONGOING_ID , mBuilder .build ());
719779
720780 } else if (!visible && mNotificationReceiver != null ) {
0 commit comments