B4A Library PublicFile: Saving your files in the public system folders

version 1.0
Introduction

Have you ever wondered how you can save a file in the Documents or the Downloads folder?
After a brainstorming session I had with [B]NJDude[/B] (was actually his idea), the PublicFile class was born and will assist you with this task from now on.

Latest package (library files and samples)
https://www.dropbox.com/s/plxiq0bai4f3y0h/PublicFile.zip

Precompiled sample APK
https://www.dropbox.com/s/mxbz37ks35zap6j/sample.apk


How to use

IMPORTANT: IT DOES NOT WORK IN THE EMULATOR. USE A REAL DEVICE!


Add this to your manifest file:
B4X:
AddPermission("android.permission.WRITE_EXTERNAL_STORAGE")

Now, the only thing you need is the PublicFile.Save method.
Choose the desired location+name, pass an InputStream to it and you are done!
B4X:
Dim MyFile as PublicFile = MyFile.Save(MyFile.DirDownloads, "file.zip", Input)

Where Input is an InputStream containing the data to be saved.

Examples:

Saving a text file:
B4X:
'The text to be written
Dim Text As String = "b4a-rocks!" 'Yeap, it does :D

'Create an InputStream and add the text to it
Dim Input As InputStream
Dim Data() As Byte = Text.GetBytes("UTF8")
Input.InitializeFromBytesArray(Data, 0, Data.Length)

'Create a PublicFile and pass the InputStream
Dim MyFile As PublicFile
MyFile.Save(MyFile.DirDocuments, "publicfile.txt", Input)

Saving an image file:
B4X:
'Open the picture stream
Dim Input As InputStream
Input = File.OpenInput(File.DirAssets, "image.jpg")

'Create a PublicFile and pass the picture stream
Dim MyFile As PublicFile
MyFile.Save(MyFile.DirPictures, "publicfile.jpg", Input)

Available PublicFile.Dir(...) constants:
  • DirMovies
  • DirPictures
  • DirDocuments
  • DirDCIM
  • DirAlarms
  • DirMusic
  • DirNotifications
  • DirDownloads
  • DirPodcasts
  • DirRingtones

Don't panic tips:
  1. In some devices, some folder locations may not be available.
  2. The Gallery, is a virtual folder that is updated whenever the system has indexed your file. That means that your saved picture will appear few moments later.


Version history:

1.0
  • Initial version

--

That's all for now folks! :D
 
Last edited:

susu

Well-Known Member
Licensed User
Longtime User
The sample app crash when I click on the buttons.
 

jackythj

New Member
Licensed User
Longtime User
I update the sample app and execute.
MyFile.Save(MyFile.DirNotifications, "publicfile.txt", Input)

But I can not find the publicfile.txt in the Notifications folder from pc while the device connect to pc

=> I restart my device and connect to pc , it's find the publicfile.txt in the Notifications folder
 
Last edited:

ibra939

Active Member
Licensed User
Longtime User
thanks
 

ibra939

Active Member
Licensed User
Longtime User
Problem is missing PublicFile?
 

fishwolf

Well-Known Member
Licensed User
Longtime User
the example code go to in crash

B4X:
main_btncreatefiletext_click (B4A line: 49)

Dim MyFile As PublicFile
java.lang.ExceptionInInitializerError

   at com.datasteam.b4a.system.file.publicfile.sample.main._btncreatefiletext_click(main.java:418)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:163)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:159)
   at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:66)
   at android.view.View.performClick(View.java:4084)
   at android.view.View$PerformClick.run(View.java:16966)
   at android.os.Handler.handleCallback(Handler.java:615)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:4745)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
   at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NoSuchFieldError: android.os.Environment.DIRECTORY_DOCUMENTS
   at com.datasteam.b4a.system.file.PublicFile.<clinit>(PublicFile.java:22)
   ... 18 more
 

fishwolf

Well-Known Member
Licensed User
Longtime User
android.os.Environment.DIRECTORY_DOCUMENTS is only available in Android 4.4+.
i need save a image downloaded from b4a app into image gallery.

is it possible with previous android version ?

how ?
 

DLL

New Member
Licensed User
Longtime User
Thanks for the library and the sample.

I'm trying to get it to work with the beginners guides '17.15 Taking a screenshot programaticaly'. Being new to this I was hoping that someone had already done this, but I can't seem to find a code.

My idea is to either combine the Screenshot Code with the Public File Code or to first run the Screenshot Code, store the shot in Dir.InternalCache and then load it as input into the Public File Code. I have added the permission to the manifest. Something like this:
B4X:
Sub btnScrShot_LongClick
[INDENT]' Screenshot Code
Dim Obj1, Obj2 As Reflector
Dim bmp As Bitmap
Dim c As Canvas
Dim now, i As Long
Dim dt As String
DateTime.DateFormat = "yyMMddHHmmss"
now = DateTime.now
dt = DateTime.Date(now) ' e.g.: "110812150355" is Aug.12, 2011, 3:03:55 p.m.
Obj1.Target = Obj1.GetActivityBA
Obj1.Target = Obj1.GetField("vg")
bmp.InitializeMutable(Activity.Width, Activity.Height)
c.Initialize2(bmp)
Dim args(1) As Object
Dim types(1) As String
Obj2.Target = c
Obj2.Target = Obj2.GetField("canvas")
args(0) = Obj2.Target
types(0) = "android.graphics.Canvas"
Obj1.RunMethod4("draw", args, types)
Dim Out As OutputStream
Out = File.OpenOutput(File.DirInternalCache, "screenshot.png", False)
bmp.WriteToStream(Out, 100, "PNG")
Out.Close

' Public File Code
Dim Input As InputStream
Input = File.OpenInput(File.DirInternalCache, "screenshot.png")
Dim MyFile As PublicFile
MyFile.Save(MyFile.DirPictures, dt & ".png", Input)   
[/INDENT]
End Sub

(In the preview it as some [INTENT] which is not part of the code).

This code makes the app stop running when activated.

Is something like this possible? And can anyone help me make/find a code that does this?
 

schemer

Active Member
Licensed User
Longtime User
So some of the below dirs are not available on all devices:
Available PublicFile.Dir(...) constants:
  • DirMovies
  • DirPictures
  • DirDocuments
  • DirDCIM
  • DirAlarms
  • DirMusic
  • DirNotifications
  • DirDownloads
  • DirPodcasts
  • DirRingtones
android.os.Environment.DIRECTORY_DOCUMENTS is only available in Android 4.4+.

Question: Which one is available on all devices? Would dirDownloads be a safe place to save files?

Thanks,
schemer
 
Top