Jul 20, 2021 Replies: 35 This is a B4i and B4A example, which demonstrates various external files related tasks. The behavior is not exactly the same as the platforms capabilities and behavior are different. B4A Load external files, including online files, using ContentChooser. Save to an external target, using SaveAs: https://www.b4x.com/android/forum/t...list-of-other-related-methods.129897/#content Allow other apps to view text files using this app : Receiving shared images from other apps Extract information from the passed uri. Note that no permission is needed. The minimum version was set to 7 (API 24), though it will probably work in older versions as well. Don't miss the manifest editor additions and ime in the main module. B4i Load external files, including online files, using DocumentPickerViewController: https://www.b4x.com/android/forum/t...ments-with-documentpickerviewcontroller.99365 Share the text with ActivityViewController: https://www.b4x.com/android/forum/t...pp-with-activityviewcontroller.73159/#content This also allows saving the text with the Files app. Allow other apps to view text files using this app: https://www.b4x.com/android/forum/threads/open-external-files-with-your-app.50525/#content Don't miss the main module PListExtra attributes and OpenUrl event. A bit related B4J example: https://www.b4x.com/android/forum/threads/class-recent-files-manager.104633/post-822842 Updates: - 9/2023 - Fixed an issue in B4A where overwriting existing files didn't trim file. Thanks @noeleon for reporting! Attachments TextEditor.zip TextEditor.zip 184.2 KB · Views: 3,160 Last edited: Sep 10, 2023 Click to expand...
This is a B4i and B4A example, which demonstrates various external files related tasks. The behavior is not exactly the same as the platforms capabilities and behavior are different. B4A Load external files, including online files, using ContentChooser. Save to an external target, using SaveAs: https://www.b4x.com/android/forum/t...list-of-other-related-methods.129897/#content Allow other apps to view text files using this app : Receiving shared images from other apps Extract information from the passed uri. Note that no permission is needed. The minimum version was set to 7 (API 24), though it will probably work in older versions as well. Don't miss the manifest editor additions and ime in the main module. B4i Load external files, including online files, using DocumentPickerViewController: https://www.b4x.com/android/forum/t...ments-with-documentpickerviewcontroller.99365 Share the text with ActivityViewController: https://www.b4x.com/android/forum/t...pp-with-activityviewcontroller.73159/#content This also allows saving the text with the Files app. Allow other apps to view text files using this app: https://www.b4x.com/android/forum/threads/open-external-files-with-your-app.50525/#content Don't miss the main module PListExtra attributes and OpenUrl event. A bit related B4J example: https://www.b4x.com/android/forum/threads/class-recent-files-manager.104633/post-822842 Updates: - 9/2023 - Fixed an issue in B4A where overwriting existing files didn't trim file. Thanks @noeleon for reporting!
DonManfred Expert Licensed User Longtime User Feb 28, 2023 #21 LucaMs said: Done (now); it crashes. Click to expand... Where is the code used and the full stacktrace? I don´t think anyone can help without.
LucaMs said: Done (now); it crashes. Click to expand... Where is the code used and the full stacktrace? I don´t think anyone can help without.
LucaMs Expert Licensed User Longtime User Feb 28, 2023 #22 DonManfred said: Where is the code used and the full stacktrace? I don´t think anyone can help without. Click to expand... The source code is in my post; also, it uses the FileHandler class which is part of the Erel's example project. You can see the data of the selected file (log). The only code that is missing is the one about the MediaPlayer: B4X: Copy mMediaPlayer.Load(Result.FileName, Result.RealName) mMediaPlayer.Play I also tried: B4X: Copy mMediaPlayer.Load(Result.Dir, Result.RealName) mMediaPlayer.Play although it seems to me that neither could have worked and indeed it is. Spoiler: Log & error msg DIR: ContentDir FN : content://com.android.providers.media.documents/document/audio%3A2247 RN : Dream_It_Possible.flac Error occurred on line: 85 (B4XMainPage) java.io.IOException: Prepare failed.: status=0x1 at android.media.MediaPlayer._prepare(Native Method) at android.media.MediaPlayer.prepare(MediaPlayer.java:1313) at anywheresoftware.b4a.objects.MediaPlayerWrapper.loadAfterReset(MediaPlayerWrapper.java:101) at anywheresoftware.b4a.objects.MediaPlayerWrapper.Load(MediaPlayerWrapper.java:66) at b4a.example.b4xmainpage$ResumableSub_pnlKey_LongClick.resume(b4xmainpage.java:274) at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732) at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348) at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157) at anywheresoftware.b4a.BA.raiseEvent(BA.java:201) at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43) at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:150) at anywheresoftware.b4a.BA.raiseEvent(BA.java:201) at anywheresoftware.b4a.keywords.Common$15.run(Common.java:1804) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:101) at android.os.Looper.loop(Looper.java:166) at android.app.ActivityThread.main(ActivityThread.java:7529) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) Last edited: Feb 28, 2023
DonManfred said: Where is the code used and the full stacktrace? I don´t think anyone can help without. Click to expand... The source code is in my post; also, it uses the FileHandler class which is part of the Erel's example project. You can see the data of the selected file (log). The only code that is missing is the one about the MediaPlayer: B4X: Copy mMediaPlayer.Load(Result.FileName, Result.RealName) mMediaPlayer.Play I also tried: B4X: Copy mMediaPlayer.Load(Result.Dir, Result.RealName) mMediaPlayer.Play although it seems to me that neither could have worked and indeed it is. Spoiler: Log & error msg DIR: ContentDir FN : content://com.android.providers.media.documents/document/audio%3A2247 RN : Dream_It_Possible.flac Error occurred on line: 85 (B4XMainPage) java.io.IOException: Prepare failed.: status=0x1 at android.media.MediaPlayer._prepare(Native Method) at android.media.MediaPlayer.prepare(MediaPlayer.java:1313) at anywheresoftware.b4a.objects.MediaPlayerWrapper.loadAfterReset(MediaPlayerWrapper.java:101) at anywheresoftware.b4a.objects.MediaPlayerWrapper.Load(MediaPlayerWrapper.java:66) at b4a.example.b4xmainpage$ResumableSub_pnlKey_LongClick.resume(b4xmainpage.java:274) at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732) at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348) at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157) at anywheresoftware.b4a.BA.raiseEvent(BA.java:201) at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43) at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:150) at anywheresoftware.b4a.BA.raiseEvent(BA.java:201) at anywheresoftware.b4a.keywords.Common$15.run(Common.java:1804) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:101) at android.os.Looper.loop(Looper.java:166) at android.app.ActivityThread.main(ActivityThread.java:7529) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
DonManfred Expert Licensed User Longtime User Feb 28, 2023 #23 LucaMs said: mMediaPlayer.Load(Result.FileName, Result.RealName) Click to expand... looks wrong If should be Result.Dir and Result.FileName Path= ContentDir filename: content://com.android.providers.media.documents/document/audio%3A2247
LucaMs said: mMediaPlayer.Load(Result.FileName, Result.RealName) Click to expand... looks wrong If should be Result.Dir and Result.FileName Path= ContentDir filename: content://com.android.providers.media.documents/document/audio%3A2247
LucaMs Expert Licensed User Longtime User Feb 28, 2023 #24 DonManfred said: looks wrong If should be Result.Dir and Result.FileName Path= ContentDir filename: content://com.android.providers.media.documents/document/audio%3A2247 Click to expand... Thanks, @DonManfred, so it works [BTW Nice song, i didn't know i had ? ]
DonManfred said: looks wrong If should be Result.Dir and Result.FileName Path= ContentDir filename: content://com.android.providers.media.documents/document/audio%3A2247 Click to expand... Thanks, @DonManfred, so it works [BTW Nice song, i didn't know i had ? ]
Erel B4X founder Staff member Licensed User Longtime User Sep 10, 2023 #25 - 9/2023 - Fixed an issue in B4A where overwriting existing files didn't trim file. Thanks @noeleon for reporting! The change is in FileHandler.SaveAs: Code: Copy Dim ContentResolver As JavaObject = ctxt.InitializeContext.RunMethodJO("getContentResolver", Null) Dim out As OutputStream = ContentResolver.RunMethod("openOutputStream", Array(jo.RunMethod("getData", Null), "wt")) 'wt = Write+Trim
- 9/2023 - Fixed an issue in B4A where overwriting existing files didn't trim file. Thanks @noeleon for reporting! The change is in FileHandler.SaveAs: Code: Copy Dim ContentResolver As JavaObject = ctxt.InitializeContext.RunMethodJO("getContentResolver", Null) Dim out As OutputStream = ContentResolver.RunMethod("openOutputStream", Array(jo.RunMethod("getData", Null), "wt")) 'wt = Write+Trim
J Juan Vargas (Bioagro) Member Licensed User Longtime User Dec 15, 2023 #26 If I could have a sample where I could save and restore a complete folder using this method, will be appreciated.
If I could have a sample where I could save and restore a complete folder using this method, will be appreciated.
Erel B4X founder Staff member Licensed User Longtime User Dec 20, 2023 #27 The user should have an option to overwrite an existing file. This is something that is controlled by the third party app that handles the "create document" intent.
The user should have an option to overwrite an existing file. This is something that is controlled by the third party app that handles the "create document" intent.
P papajds Member Feb 3, 2024 #28 Good morning, what is the maximum size of a file that can be edited THANKS
Erel B4X founder Staff member Licensed User Longtime User Feb 4, 2024 #29 The focus of this example is the various ways to access external files/resources. The text editor itself is a regular multiline EditText. It will try to load the complete file into the text field. If you want to edit large files then a more sophisticated approach is needed.
The focus of this example is the various ways to access external files/resources. The text editor itself is a regular multiline EditText. It will try to load the complete file into the text field. If you want to edit large files then a more sophisticated approach is needed.
ivan.tellez Active Member Licensed User Longtime User Aug 30, 2025 #31 Tunning the example as is, it works if a file is selected directly in the Android chooser but if you select the "file from other apps", (for example a file explorer app like Solid explorer, My Files, Drive, etc) the app cant load the file. This is shown in the Log: Sub ExtractInformationFromURI Code: Copy error extracting information from file provider Code: Copy Error occurred on line: 63 (FileHandler) java.lang.RuntimeException: Object should first be initialized (Cursor). at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:67) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732) at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348) at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157) at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262) at b4a.example.filehandler._extractinformationfromuri(filehandler.java:413) at b4a.example.filehandler$ResumableSub_Load.resume(filehandler.java:203) at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732) at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351) at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157) at anywheresoftware.b4a.BA.raiseEvent(BA.java:201) at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43) at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:150) at anywheresoftware.b4a.BA.raiseEvent(BA.java:201) at anywheresoftware.b4a.phone.Phone$ContentChooser$1.ResultArrived(Phone.java:906) at anywheresoftware.b4a.BA$4.run(BA.java:593) at anywheresoftware.b4a.BA.setActivityPaused(BA.java:467) at b4a.example.main$ResumeMessage.run(main.java:313) at android.os.Handler.handleCallback(Handler.java:959) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loopOnce(Looper.java:257) at android.os.Looper.loop(Looper.java:342) at android.app.ActivityThread.main(ActivityThread.java:9634) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) Any Idea on how to improve the example?
Tunning the example as is, it works if a file is selected directly in the Android chooser but if you select the "file from other apps", (for example a file explorer app like Solid explorer, My Files, Drive, etc) the app cant load the file. This is shown in the Log: Sub ExtractInformationFromURI Code: Copy error extracting information from file provider Code: Copy Error occurred on line: 63 (FileHandler) java.lang.RuntimeException: Object should first be initialized (Cursor). at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:67) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732) at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348) at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157) at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262) at b4a.example.filehandler._extractinformationfromuri(filehandler.java:413) at b4a.example.filehandler$ResumableSub_Load.resume(filehandler.java:203) at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732) at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351) at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157) at anywheresoftware.b4a.BA.raiseEvent(BA.java:201) at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43) at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:150) at anywheresoftware.b4a.BA.raiseEvent(BA.java:201) at anywheresoftware.b4a.phone.Phone$ContentChooser$1.ResultArrived(Phone.java:906) at anywheresoftware.b4a.BA$4.run(BA.java:593) at anywheresoftware.b4a.BA.setActivityPaused(BA.java:467) at b4a.example.main$ResumeMessage.run(main.java:313) at android.os.Handler.handleCallback(Handler.java:959) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loopOnce(Looper.java:257) at android.os.Looper.loop(Looper.java:342) at android.app.ActivityThread.main(ActivityThread.java:9634) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) Any Idea on how to improve the example?
Erel B4X founder Staff member Licensed User Longtime User Aug 31, 2025 #32 Does it actually crash or this error is caught in the Catch block? It is expected that ExtractInformationFromURI will not work in all cases.
Does it actually crash or this error is caught in the Catch block? It is expected that ExtractInformationFromURI will not work in all cases.
ivan.tellez Active Member Licensed User Longtime User Sep 1, 2025 #33 Erel said: Does it actually crash or this error is caught in the Catch block? Click to expand... Right, it is caught in the Catch block. Doing tests on other examples, looks like it needs the READ_EXTERNAL_STORAGE permission to open the file choosed using another app. I tried to implement CheckAndRequest but the dialog doesnt show and Result is allways false. Can you update the example to use READ_EXTERNAL_STORAGE ?
Erel said: Does it actually crash or this error is caught in the Catch block? Click to expand... Right, it is caught in the Catch block. Doing tests on other examples, looks like it needs the READ_EXTERNAL_STORAGE permission to open the file choosed using another app. I tried to implement CheckAndRequest but the dialog doesnt show and Result is allways false. Can you update the example to use READ_EXTERNAL_STORAGE ?
Erel B4X founder Staff member Licensed User Longtime User Sep 1, 2025 #34 No such thing. READ_EXTERNAL_STORAGE is no longer accepted by Android.
ivan.tellez Active Member Licensed User Longtime User Sep 1, 2025 #35 Erel said: No such thing. Click to expand... Right. I saw the "AudioChooseAndPlay" example but didnt notice it has a targetSdkVersion="28"... In the "AudioChooseAndPlay" I saw this behavior. File is openned (either the audio or an xml) if choosed directly in the filechooser. But using another app as the source, the file will not open with the error described on #31. however, if the READ_EXTERNAL_STORAGE is used in that example, the file works... In this text editor example we have the same behavior except that READ_EXTERNAL_STORAGE cant be used. So the question is, what is the equivalent to READ_EXTERNAL_STORAGE in targetSdkVersion="35" for openning a file returned from a provider app in the chooser?
Erel said: No such thing. Click to expand... Right. I saw the "AudioChooseAndPlay" example but didnt notice it has a targetSdkVersion="28"... In the "AudioChooseAndPlay" I saw this behavior. File is openned (either the audio or an xml) if choosed directly in the filechooser. But using another app as the source, the file will not open with the error described on #31. however, if the READ_EXTERNAL_STORAGE is used in that example, the file works... In this text editor example we have the same behavior except that READ_EXTERNAL_STORAGE cant be used. So the question is, what is the equivalent to READ_EXTERNAL_STORAGE in targetSdkVersion="35" for openning a file returned from a provider app in the chooser?
Erel B4X founder Staff member Licensed User Longtime User Sep 2, 2025 #36 The alternative is demonstrated in this example - ContentChooser. For further discussion please start a new thread.
The alternative is demonstrated in this example - ContentChooser. For further discussion please start a new thread.