20353841 Member Licensed User Longtime User May 5, 2024 #1 Hello everyone, I have encountered a problem where when calling the "Storage. SelectDir (True)" function of the ExternalStorage class, the views in the displayed folder selection window cannot use the TV remote control directional keys to move focus, which makes the application unable to continue operating on the TV. How can I solve this problem?
Hello everyone, I have encountered a problem where when calling the "Storage. SelectDir (True)" function of the ExternalStorage class, the views in the displayed folder selection window cannot use the TV remote control directional keys to move focus, which makes the application unable to continue operating on the TV. How can I solve this problem?
JohnC Expert Licensed User Longtime User May 5, 2024 #2 OK, this is an interesting question because I ran into a problem with a third-party app that my tv remote wasn't able to access certain views in it. I solved the issue by using an app called "mouse cursor" that displayed a cursor on the screen and allowed me to use the directional arrows of the TV remote to move the mouse icon to access those hard to reach views. But you are trying to do this in your app, so below is the prompt I used with ChatGPT. This is a complex issue, so ChatGPT's response could be way out of bounds and it's code may not work at all, but it might give you an idea how to solve the issue... My ChatGPT Prompt: My b4a app is calling the Storage. SelectDir (True)" function of the ExternalStorage class to allow the user to select a storage location for a file that my app will save to. However the app is running on an android TV device which does not have a touch screen, so it needs to use the limited buttons on the tv remote to navigate the views of the app. This presents a problem because some of the views of the storage.selectdir method can not receive focus with just the directional keys on the tv remote. So, how can my app programmically bring focus to these touch-only accessible views? ChatGPT's response... To programmatically bring focus to views that cannot be accessed via directional keys on a TV remote in your B4A app, you can try using the RequestFocus method. However, since the Storage.SelectDir method does not provide direct access to its views, you might need to resort to a workaround. One potential workaround is to use the SetOnShowListener method to listen for when the dialog containing the Storage.SelectDir views is shown, and then programmatically traverse through the views to find the one you want to give focus to. Once you find the view, you can call its RequestFocus method. Here's a general outline of how you could implement this workaround: B4X: Sub YourMethodToOpenStorageDialog Dim StorageDialog As Object StorageDialog = ExternalStorage.SelectDir(True) SetStorageDialogListener(StorageDialog) End Sub Sub SetStorageDialogListener(StorageDialog As Object) Dim r As Reflector r.Target = StorageDialog r.SetOnShowListener("StorageDialog_OnShow") End Sub Sub StorageDialog_OnShow Dim r As Reflector r.Target = Sender Dim dlg As Object dlg = r.GetField("dialog") SetFocusToDesiredView(dlg) End Sub Sub SetFocusToDesiredView(dialog As Object) ' Use Reflector to find the desired view and call RequestFocus on it. ' Example: ' Dim r As Reflector ' r.Target = dialog ' Dim desiredView As Object ' desiredView = r.RunMethod2("findViewByName", "nameOfDesiredView", "java.lang.String") ' If desiredView <> Null Then ' desiredView.RequestFocus ' End If End Sub In the SetFocusToDesiredView subroutine, you would use the Reflector object to find the view you want to give focus to. This may require some experimentation and exploration of the view hierarchy using the Reflector methods. Once you've identified the desired view, you can call its RequestFocus method. Please note that this approach may require some trial and error to identify the correct view to give focus to, as it depends on the internal implementation of the Storage.SelectDir method. Additionally, accessing and manipulating views via reflection may be more prone to breaking if the underlying implementation changes in future versions of B4A. Last edited: May 5, 2024 Upvote 0
OK, this is an interesting question because I ran into a problem with a third-party app that my tv remote wasn't able to access certain views in it. I solved the issue by using an app called "mouse cursor" that displayed a cursor on the screen and allowed me to use the directional arrows of the TV remote to move the mouse icon to access those hard to reach views. But you are trying to do this in your app, so below is the prompt I used with ChatGPT. This is a complex issue, so ChatGPT's response could be way out of bounds and it's code may not work at all, but it might give you an idea how to solve the issue... My ChatGPT Prompt: My b4a app is calling the Storage. SelectDir (True)" function of the ExternalStorage class to allow the user to select a storage location for a file that my app will save to. However the app is running on an android TV device which does not have a touch screen, so it needs to use the limited buttons on the tv remote to navigate the views of the app. This presents a problem because some of the views of the storage.selectdir method can not receive focus with just the directional keys on the tv remote. So, how can my app programmically bring focus to these touch-only accessible views? ChatGPT's response... To programmatically bring focus to views that cannot be accessed via directional keys on a TV remote in your B4A app, you can try using the RequestFocus method. However, since the Storage.SelectDir method does not provide direct access to its views, you might need to resort to a workaround. One potential workaround is to use the SetOnShowListener method to listen for when the dialog containing the Storage.SelectDir views is shown, and then programmatically traverse through the views to find the one you want to give focus to. Once you find the view, you can call its RequestFocus method. Here's a general outline of how you could implement this workaround: B4X: Sub YourMethodToOpenStorageDialog Dim StorageDialog As Object StorageDialog = ExternalStorage.SelectDir(True) SetStorageDialogListener(StorageDialog) End Sub Sub SetStorageDialogListener(StorageDialog As Object) Dim r As Reflector r.Target = StorageDialog r.SetOnShowListener("StorageDialog_OnShow") End Sub Sub StorageDialog_OnShow Dim r As Reflector r.Target = Sender Dim dlg As Object dlg = r.GetField("dialog") SetFocusToDesiredView(dlg) End Sub Sub SetFocusToDesiredView(dialog As Object) ' Use Reflector to find the desired view and call RequestFocus on it. ' Example: ' Dim r As Reflector ' r.Target = dialog ' Dim desiredView As Object ' desiredView = r.RunMethod2("findViewByName", "nameOfDesiredView", "java.lang.String") ' If desiredView <> Null Then ' desiredView.RequestFocus ' End If End Sub In the SetFocusToDesiredView subroutine, you would use the Reflector object to find the view you want to give focus to. This may require some experimentation and exploration of the view hierarchy using the Reflector methods. Once you've identified the desired view, you can call its RequestFocus method. Please note that this approach may require some trial and error to identify the correct view to give focus to, as it depends on the internal implementation of the Storage.SelectDir method. Additionally, accessing and manipulating views via reflection may be more prone to breaking if the underlying implementation changes in future versions of B4A.
20353841 Member Licensed User Longtime User May 5, 2024 #3 thx for reply,but i can not found "SetOnShowListener" on Reflector, is Reflector version to low? Maybe we can make a custom folder picker? Upvote 0
thx for reply,but i can not found "SetOnShowListener" on Reflector, is Reflector version to low? Maybe we can make a custom folder picker?
JohnC Expert Licensed User Longtime User May 5, 2024 #4 Another post was trying to use that function, but there was no reply to it.: Java inline: how to import *.R? hello, I read post 'https://www.b4x.com/android/forum/threads/inline-java-code.50141/#content and try to using a java code in project. the java code is copy from tencent ads demo project. when i compile it, An error occurred: src\b4a\example\downloadapkconfirmdialogwebview.java:24: 错误... www.b4x.com Maybe you could try contacting that user to see if they ever found a way to use that function. Upvote 0
Another post was trying to use that function, but there was no reply to it.: Java inline: how to import *.R? hello, I read post 'https://www.b4x.com/android/forum/threads/inline-java-code.50141/#content and try to using a java code in project. the java code is copy from tencent ads demo project. when i compile it, An error occurred: src\b4a\example\downloadapkconfirmdialogwebview.java:24: 错误... www.b4x.com Maybe you could try contacting that user to see if they ever found a way to use that function.
aeric Expert Licensed User Longtime User May 5, 2024 #5 I hate AI hallucination. Maybe this help. B4X: Sub SetFocusButtons Dim jo1 As JavaObject = Button1 Dim e1 As Object = jo1.CreateEvent("android.view.View.OnFocusChangeListener", "Button1", False) jo1.RunMethod("setOnFocusChangeListener", Array As Object(e1)) End Sub Upvote 0
I hate AI hallucination. Maybe this help. B4X: Sub SetFocusButtons Dim jo1 As JavaObject = Button1 Dim e1 As Object = jo1.CreateEvent("android.view.View.OnFocusChangeListener", "Button1", False) jo1.RunMethod("setOnFocusChangeListener", Array As Object(e1)) End Sub
20353841 Member Licensed User Longtime User May 5, 2024 #6 aeric said: I hate AI hallucination. Maybe this help. B4X: Sub SetFocusButtons Dim jo1 As JavaObject = Button1 Dim e1 As Object = jo1.CreateEvent("android.view.View.OnFocusChangeListener", "Button1", False) jo1.RunMethod("setOnFocusChangeListener", Array As Object(e1)) End Sub Click to expand... the dialog from "Storage.SelectDir(false)",so i can't know wich views in dialog. Upvote 0
aeric said: I hate AI hallucination. Maybe this help. B4X: Sub SetFocusButtons Dim jo1 As JavaObject = Button1 Dim e1 As Object = jo1.CreateEvent("android.view.View.OnFocusChangeListener", "Button1", False) jo1.RunMethod("setOnFocusChangeListener", Array As Object(e1)) End Sub Click to expand... the dialog from "Storage.SelectDir(false)",so i can't know wich views in dialog.
aeric Expert Licensed User Longtime User May 5, 2024 #7 20353841 said: the dialog from "Storage.SelectDir(false)",so i can't know wich views in dialog. Click to expand... try to Log in the IDE. Upvote 0
20353841 said: the dialog from "Storage.SelectDir(false)",so i can't know wich views in dialog. Click to expand... try to Log in the IDE.
aeric Expert Licensed User Longtime User May 5, 2024 #8 More searches: https://www.b4x.com/android/forum/pages/results/?query=OnFocusChangeListener&product=b4a Upvote 0
More searches: https://www.b4x.com/android/forum/pages/results/?query=OnFocusChangeListener&product=b4a
20353841 Member Licensed User Longtime User May 5, 2024 #9 aeric said: More searches: https://www.b4x.com/android/forum/pages/results/?query=OnFocusChangeListener&product=b4a Click to expand... My question is: Step 1: I called "Storage.SelectDir(false)",this show a directory select dialog(see the top picture),there is no error or exception. Step 2: Use TV remote,focus can not to move to any view in this dialog. For an example: I try to press TAB,Topleft view has no focus.So i can not to use TV remote to select another folder path. Last edited: May 5, 2024 Upvote 0
aeric said: More searches: https://www.b4x.com/android/forum/pages/results/?query=OnFocusChangeListener&product=b4a Click to expand... My question is: Step 1: I called "Storage.SelectDir(false)",this show a directory select dialog(see the top picture),there is no error or exception. Step 2: Use TV remote,focus can not to move to any view in this dialog. For an example: I try to press TAB,Topleft view has no focus.So i can not to use TV remote to select another folder path.
JohnC Expert Licensed User Longtime User May 5, 2024 #10 I think @aeric is suggesting is to setup logging of the name of views when they get focus. Then run your app on a touch-screen device, and when you then touch a view that you normally can't reach with the remote, the logging will reveal the name of the view that just got focus. Then implement some user interface that will programmically give focus to those views using buttons on the remote. Last edited: May 5, 2024 Upvote 0
I think @aeric is suggesting is to setup logging of the name of views when they get focus. Then run your app on a touch-screen device, and when you then touch a view that you normally can't reach with the remote, the logging will reveal the name of the view that just got focus. Then implement some user interface that will programmically give focus to those views using buttons on the remote.
aeric Expert Licensed User Longtime User May 5, 2024 #12 Stop using a remote control. Use something like this with a touchpad. Upvote 0
20353841 Member Licensed User Longtime User May 5, 2024 #13 aeric said: Stop using a remote control. Use something like this with a touchpad. View attachment 153433 Click to expand... thx aeric,my app used for any device,not a specify device.on dialog is show, i can not get or set focus form views,TV remote just only arrow and menu keys. All these operations ,because I am unable to read files from other folders well, such as MP3 music use file.listfiles. Upvote 0
aeric said: Stop using a remote control. Use something like this with a touchpad. View attachment 153433 Click to expand... thx aeric,my app used for any device,not a specify device.on dialog is show, i can not get or set focus form views,TV remote just only arrow and menu keys. All these operations ,because I am unable to read files from other folders well, such as MP3 music use file.listfiles.
20353841 Member Licensed User Longtime User May 5, 2024 #14 Now I have solved it through another method, skipping the "Storage. SelectDir" method and using "file. listfiles" after adding permissions, I can now read the MP3 file list B4X: AddPermission("android.permission.READ_EXTERNAL_STORAGE") AddPermission("android.permission.WRITE_EXTERNAL_STORAGE") AddPermission("android.permission.MANAGE_EXTERNAL_STORAGE") B4X: B4XPage_Created() Dim RP As RuntimePermissions RP.CheckAndRequest(RP.PERMISSION_READ_EXTERNAL_STORAGE) Dim Sb As StringBuilder Sb.Initialize Dim Lst As List=File.ListFiles(Pth) For I=0 To Lst.Size-1 Sb.Append(Lst.Get(I) & CRLF) Next JJ.Text=Sb.ToString end sub thanks everyone Upvote 0
Now I have solved it through another method, skipping the "Storage. SelectDir" method and using "file. listfiles" after adding permissions, I can now read the MP3 file list B4X: AddPermission("android.permission.READ_EXTERNAL_STORAGE") AddPermission("android.permission.WRITE_EXTERNAL_STORAGE") AddPermission("android.permission.MANAGE_EXTERNAL_STORAGE") B4X: B4XPage_Created() Dim RP As RuntimePermissions RP.CheckAndRequest(RP.PERMISSION_READ_EXTERNAL_STORAGE) Dim Sb As StringBuilder Sb.Initialize Dim Lst As List=File.ListFiles(Pth) For I=0 To Lst.Size-1 Sb.Append(Lst.Get(I) & CRLF) Next JJ.Text=Sb.ToString end sub thanks everyone