Android Question [SOLVED] External storage. Show a messagebox to user.

max123

Well-Known Member
Licensed User
Longtime User
Hi all,

using External Storage class I know that if root folder no longer exist then the folder picker dialog will appear again, and in SelectDir there is an option to reuse or not the previous folder.

The picker will show, but before I need to show a messagebox that explain user that need to create and select the app folder.
Just a first time if permissions not already granted or if permissions already granted but user removed manually the folder.

Actually my app show a redundant messagebox all the times I start it, then if no permissons granted will show the picker dialog, otherwise just will continue, but I want to avoid show a messagebox if picker dialog wil not appear because permissions already granted.

Is there a way to do it ?

Consider this code:
B4X:
Sub CheckExternalStoragePermission As ResumableSub
    If Not(Storage.HasPermission) Then
        MsgboxAsync("We show you a file manager, please create a new folder to use as Application Folder and select it.","Create 'MaxCNC' folder")
        Wait For MsgBox_Result (Result As Int)
    End If
 
    Storage.SelectDir(True)
    Wait For Storage_ExternalFolderAvailable

    Return (Storage.Root.IsFolder And Storage.Root.Name <> "")
End Sub
I tried to check these conditions but probably I miss something, and do not know how check if folder exist:
B4X:
'Check if permission is already granted.
Public Sub HasPermission As Boolean
    Return File.Exists(File.DirInternal, PreviousUriFileName) And File.ReadString(File.DirInternal, PreviousUriFileName).Length > 0
End Sub

'Public Sub IsStorageFolderSelected As Boolean
'    If PersistantUri.Length > 0 Then
'        Root = DocumentFileToExternalFile(GetPickedDir(PersistantUri))
'        Log("Root.Length=" & Root.Length)
'    End If
'    Return File.Exists(File.DirInternal, PreviousUriFileName) And (Root.Length > 0)
'End Sub

Many thanks
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4X:
Public Sub SelectDir (UsePreviouslySelectedIfAvailable As Boolean)
    If UsePreviouslySelectedIfAvailable And File.Exists(File.DirInternal, PreviousUriFileName) Then
        PersistantUri = File.ReadString(File.DirInternal, PreviousUriFileName)
        Dim list As List = ctxt.RunMethodJO("getContentResolver", Null).RunMethod("getPersistedUriPermissions", Null)
        If list.IsInitialized Then
            For Each uripermission As JavaObject In list
                Dim u As Uri = uripermission.RunMethod("getUri", Null)
                Dim temp As Object = u 
                Dim s As String = temp
                If s = PersistantUri And uripermission.RunMethod("isWritePermission", Null) = True Then
                    Log("Can use persistant uri!")
                    SetPickedDir
                    Return
                End If
            Next
        End If
    End If
    Wait For (xui.MsgboxAsync("Message here", "title")) Msgbox_Result (Result As Int) '<----
    Dim i As Intent
    i.Initialize("android.intent.action.OPEN_DOCUMENT_TREE", "")
    i.PutExtra("android.content.extra.SHOW_ADVANCED", True)
    StartActivityForResult(i)
End Sub
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Thanks, so put a MessageBox directly inside the class is a solution ? :)
I will try it.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
I want make a sub HasPermisson to be used before SelectDir is called. Like my original code here:
B4X:
Sub CheckExternalStoragePermission As ResumableSub
    If Not(Storage.HasPermisson) Then
        MsgboxAsync("We show you a file manager, please create a new folder to use as Application Folder and select it.","Create 'MaxCNC' folder")
        Wait For MsgBox_Result (Result As Int)
    End If
 
    Storage.SelectDir(True)
    Wait For Storage_ExternalFolderAvailable

    Return (Storage.Root.IsFolder And Storage.Root.Name <> "")
End Sub

Without import a class on any project, just mantaining b4xlib as is.

Suppose I need to replicate the SelectDir sub without add an Intent, just check URL and return a Boolean ?

Need even to check if folder exist and user not removed. If user removed, the persistant url exist but the folder do not.

Another option maybe should be pass a string 'message' and string 'title' as arguments in SelectDir sub something like this:
B4X:
Storage.SelectDir(usePrevious As Boolean, Message As String, Title As String)
where messagebox only show if not permissons granted and before the picker folder shows.
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4X:
Public Sub HasPermission As Boolean
    If  File.Exists(File.DirInternal, PreviousUriFileName) Then
        PersistantUri = File.ReadString(File.DirInternal, PreviousUriFileName)
        Dim list As List = ctxt.RunMethodJO("getContentResolver", Null).RunMethod("getPersistedUriPermissions", Null)
        If list.IsInitialized Then
            For Each uripermission As JavaObject In list
                Dim u As Uri = uripermission.RunMethod("getUri", Null)
                Dim temp As Object = u 
                Dim s As String = temp
                If s = PersistantUri And uripermission.RunMethod("isWritePermission", Null) = True Then
                    Return True
                End If
            Next
        End If
    End If
   Return False
End Sub
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
I confirm that this code works well the exact way I need it.
Thanks for great solution, please add it to original ExternalStorage b4xlib.

There's no need to check if folder exists probably Android check itself.

If you create a folder and grant permission, then delete this folder while app is started, if you open it with a file picker no error occours, just it see a void folder.

If you delete a folder then launch the app, a MsgBox will show to create a new folder and by clicking OK the folder picker appear.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Here another option that autocheck for permissions, the messagebox will show only if needed:
B4X:
' As previous Erel post, just changed a bit ...

Storage.SelectDir(True, "Please select a folder and grant a permission.", "ATTENTION")
Wait For Storage_ExternalFolderAvailable

' Message and Title used only if need to show a messagebox.
Public Sub SelectDir (UsePreviouslySelectedIfAvailable As Boolean, Message As String, Title As String)
    If UsePreviouslySelectedIfAvailable And File.Exists(File.DirInternal, PreviousUriFileName) Then
        PersistantUri = File.ReadString(File.DirInternal, PreviousUriFileName)
        Dim list As List = ctxt.RunMethodJO("getContentResolver", Null).RunMethod("getPersistedUriPermissions", Null)
        If list.IsInitialized Then
            For Each uripermission As JavaObject In list
                Dim u As Uri = uripermission.RunMethod("getUri", Null)
                Dim temp As Object = u
                Dim s As String = temp
                If s = PersistantUri And uripermission.RunMethod("isWritePermission", Null) = True Then
                    Log("Can use persistant uri!")
                    SetPickedDir
                    Return
                End If
            Next
        End If
    End If
    Wait For (xui.MsgboxAsync(Message, Title)) Msgbox_Result (Result As Int) '<----
    Dim i As Intent
    i.Initialize("android.intent.action.OPEN_DOCUMENT_TREE", "")
    i.PutExtra("android.content.extra.SHOW_ADVANCED", True)
    StartActivityForResult(i)
End Sub
 
Last edited:
Upvote 0
Top