#Region Project Attributes
#ApplicationLabel: B4A Example External Storage Service
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: portrait
#CanInstallToExternalStorage: False
#End Region
#Region Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region
#AdditionalJar: com.android.support:support-core-utils
Sub Process_Globals
Private Storage As ExternalStorage
Private FoldersStack As List
Private UpItem As ExternalFile
End Sub
Sub Globals
'Private chkUsePreviouslySelected As CheckBox
Private Previous As Boolean
Private ListView1 As ListView ' Change this to a list
Private ImageView1 As ImageView
Private lblPath As Label
'>>>>>>>>>>>>>>>>>>>>> Below is from Module
Private ion As Object
Private PersistantUri As String
Private const FileName As String = "PersistantUri"
Private ctxt As JavaObject
Private mCallback As Object
Private mEventName As String
Public Root As ExternalFile
Type ExternalFile (Name As String, Length As Long, LastModified As Long, IsFolder As Boolean, Native As JavaObject)
'>>>>>>>>>>>>>>>>>>>>> Above is from Module
End Sub
Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
Storage.Initialize("Storage")
FoldersStack.Initialize
UpItem.Initialize
End If
'Activity.LoadLayout("1")
'chkUsePreviouslySelected.Checked = True
Previous = True
Storage.SelectDir(Previous)
Wait For Storage_ExternalFolderAvailable
FoldersStack.Clear
EnterFolder(Storage.Root)
End Sub
'>>>>>>>>>>>>>>>>>>>>> Below is from Module
Public Sub Initialize (Callback As Object, EventName As String)
mCallback = Callback
mEventName = EventName
ctxt.InitializeContext
End Sub
'>>>>>>>>>>>>>>>>>>>>> Above is from Module
Private Sub EnterFolder (folder As ExternalFile)
FoldersStack.Add(folder)
Dim sb As StringBuilder
sb.Initialize
For Each f As ExternalFile In FoldersStack
If f = Storage.Root Then
sb.Append("Root")
Else
sb.Append(" / ").Append(f.Name)
End If
Next
lblPath.Text = sb.ToString
ListView1.Clear ' Change this to a list
If FoldersStack.Size > 1 Then
ListView1.AddSingleLine2("..", UpItem) ' Change this to a list
End If
For Each f As ExternalFile In Storage.ListFiles(folder)
If f.IsFolder Then
ListView1.AddSingleLine2($"[${f.Name}]"$, f) ' Change this to a list
Else If IsImageFile(f.Name) Then
Dim cs As CSBuilder
cs.Initialize.Append(f.Name).Append(" ").Color(0xFF00EEFF).Append("(click)").PopAll
ListView1.AddSingleLine2(cs, f) ' Change this to a list
Else
ListView1.AddSingleLine2(f.Name, f) ' Change this to a list
End If
Next
End Sub
Private Sub ListView1_ItemClick (Position As Int, Value As Object)
Dim f As ExternalFile = Value
If f = UpItem Then
'remove the current folder
FoldersStack.RemoveAt(FoldersStack.Size - 1)
'get the parent folder which is now the topmost folder
Dim folder As ExternalFile = GetCurrentFolder
'remove it and enter it again
FoldersStack.RemoveAt(FoldersStack.Size - 1)
EnterFolder(folder)
Else
'The ExternalFile returned from ListFiles cannot be used directly.
'We need to first call FindFile.
f = Storage.FindFile(GetCurrentFolder, f.Name)
If f.IsFolder Then
EnterFolder(f)
Else If IsImageFile(f.Name) Then
Dim in As InputStream = Storage.OpenInputStream(f)
'We can open the image directly with Bitmap.Initialize2 however it will not allow us to use LoadBitmapResize
'so instead we copy it to a temporary file.
Dim out As OutputStream = File.OpenOutput(File.DirInternal, "temp", False)
File.Copy2(in, out)
out.Close
ImageView1.SetBackgroundImage(LoadBitmapResize(File.DirInternal, "temp", ImageView1.Width, ImageView1.Height, True))
End If
End If
End Sub
Private Sub GetCurrentFolder As ExternalFile
Return FoldersStack.Get(FoldersStack.Size - 1) 'get the last item
End Sub
Private Sub IsImageFile (Name As String) As Boolean
Dim n As String = Name.ToLowerCase
For Each extension As String In Array(".jpg", ".png", ".gif", ".bmp")
If n.EndsWith(extension) Then Return True
Next
Return False
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
'>>>>>>>>>>>>>>>>>>>>> Below is from Module
'Lets the user pick a folder.
'Optionally using the previous selected folder.
Public Sub SelectDir (UsePreviouslySelectedIfAvaiable As Boolean)
If UsePreviouslySelectedIfAvaiable And File.Exists(File.DirInternal, FileName) Then
PersistantUri = File.ReadString(File.DirInternal, FileName)
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
Dim i As Intent
i.Initialize("android.intent.action.OPEN_DOCUMENT_TREE", "")
i.PutExtra("android.content.extra.SHOW_ADVANCED", True)
StartActivityForResult(i)
End Sub
'List all files in the given folder.
Public Sub ListFiles (Folder As ExternalFile) As List
Dim files() As Object = Folder.Native.RunMethod("listFiles", Null)
Dim res As List
res.Initialize
For Each o As Object In files
Dim f As JavaObject = o
res.Add(DocumentFileToExternalFile(f))
Next
Return res
End Sub
'Finds the file with the given name.
'Returns an uninitialized ExternalFile if not found.
Public Sub FindFile (Parent As ExternalFile, Name As String) As ExternalFile
Dim f As JavaObject = Parent.Native.RunMethod("findFile", Array(Name))
Return DocumentFileToExternalFile(f)
End Sub
'Creates a new file.
Public Sub CreateNewFile (Parent As ExternalFile, Name As String) As ExternalFile
Return DocumentFileToExternalFile(Parent.Native.RunMethod("createFile", Array("", Name)))
End Sub
'Deletes the file.
Public Sub DeleteFile (EF As ExternalFile) As Boolean
If EF.IsInitialized = False Then Return False
Return EF.Native.RunMethod("delete", Null)
End Sub
'Open an output stream that writes to the file.
Public Sub OpenOutputStream(EF As ExternalFile) As OutputStream
Return ctxt.RunMethodJO("getContentResolver", Null).RunMethod("openOutputStream", Array(EF.Native.RunMethod("getUri", Null)))
End Sub
'Open an input stream that reads from the file.
Public Sub OpenInputStream(EF As ExternalFile) As InputStream
Return ctxt.RunMethodJO("getContentResolver", Null).RunMethod("openInputStream", Array(EF.Native.RunMethod("getUri", Null)))
End Sub
'Finds the file with the given name. If not found creates a new file.
Public Sub FindFileOrCreate (Parent As ExternalFile, Name As String) As ExternalFile
Dim f As ExternalFile = FindFile(Parent, Name)
If f.IsInitialized = False Then
Return CreateNewFile(Parent, Name)
Else
Return f
End If
End Sub
Private Sub DocumentFileToExternalFile (DocumentFile As JavaObject) As ExternalFile
Dim ef As ExternalFile
If DocumentFile.IsInitialized = False Then
Return ef
End If
ef.Initialize
ef.Name = DocumentFile.RunMethod("getName", Null)
ef.Length = DocumentFile.RunMethod("length", Null)
ef.IsFolder = DocumentFile.RunMethod("isDirectory", Null)
ef.Native = DocumentFile
ef.LastModified = DocumentFile.RunMethod("lastModified", Null)
Return ef
End Sub
Private Sub SetPickedDir
Root = DocumentFileToExternalFile(GetPickedDir(PersistantUri))
CallSubDelayed(mCallback, mEventName & "_ExternalFolderAvailable")
End Sub
Private Sub ion_Event (MethodName As String, Args() As Object) As Object
If Args(0) = -1 Then 'resultCode = RESULT_OK
Dim i As Intent = Args(1)
Dim jo As JavaObject = i
Dim treeUri As Uri = jo.RunMethod("getData", Null)
Dim takeFlags As Int = Bit.And(i.Flags, 3)
ctxt.RunMethodJO("getContentResolver", Null).RunMethod("takePersistableUriPermission", Array(treeUri, takeFlags))
Dim temp As Object = treeUri
PersistantUri = temp
File.WriteString(File.DirInternal, FileName, PersistantUri)
Log(PersistantUri)
SetPickedDir
End If
Return Null
End Sub
Private Sub GetPickedDir (uri As String) As JavaObject
Dim DocumentFileStatic As JavaObject
Dim treeUri As Uri
treeUri.Parse(uri)
Dim PickedDir As JavaObject = DocumentFileStatic.InitializeStatic("android.support.v4.provider.DocumentFile").RunMethod("fromTreeUri", Array(ctxt, treeUri))
Return PickedDir
End Sub
Private Sub StartActivityForResult(i As Intent)
Dim jo As JavaObject = GetBA
ion = jo.CreateEvent("anywheresoftware.b4a.IOnActivityResult", "ion", Null)
jo.RunMethod("startActivityForResult", Array As Object(ion, i))
End Sub
Private Sub GetBA As Object
Dim jo As JavaObject = Me
Return jo.RunMethod("getBA", Null)
End Sub
'>>>>>>>>>>>>>>>>>>>>> Above is from Module