Copy a file from internal memory to sd-card

der_c

Member
Licensed User
Hi,

I want a file copy from internal device memory, e.g. xxxinternalxx/DCIM/test.jpg to the SD card, e.g. xxexternalxx/TEST/test.jpg (file-type is not specified, can be ".txt", ".jpg", ".wma" or anything else). The original file should be deleted (move the file is also ok). I've already tried it myself, but I can not get it. Somehow that has to go, because a standard android filemanager can indeed .

I offer Euro 100, - (US $ 110, -) for a working code. It should run on Android 4.xx, but at least 5.xx up to the newest. It is only for private use.

Thanks in advance

Stefan
 

Roycefer

Well-Known Member
Licensed User
You should post the code you already tried and the error message you got when you ran it. You should also post details of the devices on which you have run the tests.
 

der_c

Member
Licensed User
Hi,

Great, thanks for the tips, but does not help me, I already needed a snippet of code.

@Roycever
I just tried a bit of, so there is no code that you could take in the hand.

@DonManfred
Super, thanks for the tip, is certainly good to think, I would have to work too deeply, hence my desire for a usable code.

I like to raise to Euro 150, -, if I get a small piece of code, as already written, a file from an internal directory on the SD card copy, specifically main_memory/Download/profil_15.pdf to SD-card/Test/profile_15 .pdf (the targetfolder "Test" does not exist yet).

Thanks in advance
 
Last edited:

DonManfred

Expert
Licensed User
I like to raise to Euro 150, -, if I get a small piece of code
I appreciate the raise ;-)

Basically the example is based on the Example from the Link i posted above.
With a few additions to your needs.

B4X:
Sub btnCopyPDF_Click
    Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    wait for Activity_PermissionResult(Permission As String, Result As Boolean)
    If Result Then
        Log("Permission given. Check content")
        Dim flist As List = File.ListFiles(File.Combine(File.DirRootExternal,"Download/"))
        Log(flist)
        Dim filetocopy As String = "profil_15.pdf"
    End If
   
    ' Get DocumentDir
    Dim docs As JavaObject = GetDocumentdDir(PersistantUri)
   
    ' Check if Destfolder Test already exists.
    Dim chkTest As ExternalFile = Storage.FindFile(Storage.Root,"Test")
    If chkTest.IsInitialized = False Then
        'create the Folder "Test"
        docs.RunMethod("createDirectory",Array("Test"))
    End If
    ' Search the created Folder in the Storage Rootdir (we need to have a reference to it)
    Dim Test As ExternalFile = Storage.FindFile(Storage.Root,"Test")
   
    ' define destfile
    Dim destfile As ExternalFile = Storage.CreateNewFile(Test,filetocopy)
    ' Create an Outputstream to the destfile
    Dim os As OutputStream = Storage.OpenOutputStream(destfile)
    ' Create an Inputstream from the Sourcefile to copy
    Dim inpstr As InputStream  = File.OpenInput(File.Combine(File.DirRootExternal,"Download/"),filetocopy)
    ' Copy file
    File.Copy2(inpstr,os)
    ' Close Outputstream
    os.Close

End Sub
 

Attachments

Last edited:

der_c

Member
Licensed User
Hi DonManfred,

thanks in advance, i will trying it tomorrow, if it works, i will send the money immedetly.

Regards stefan
 

der_c

Member
Licensed User
Hi DonManfred,

i sent the money, because it's fair, after you've done something for it. Unfortunately, i'm only starting to test today. But i get a lot of error messages like these:

B4X:
Logger verbunden mit:  xxxxxxxxx
--------- beginning of main
Copying updated assets files (1)
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
sending message to waiting queue (OnActivityResult)
running waiting messages (1)
content://com.android.externalstorage.documents/tree/primary%3AWhatsApp%2FMedia%2FWhatsApp%20Video
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
sending message to waiting queue (activity_permissionresult)
running waiting messages (1)
Permission given. Check content
(ArrayList) [27.02.19_19.29_Anruf.01705883780.wav, unternehmensprofil_15.pdf, 2014-06-NAL-DE.pdf, Rechnung 1060788990 vom 02.03.2019.pdf, pt1007p.pdf]
Error occurred on line: 59 (Main)
java.lang.reflect.InvocationTargetException
   at java.lang.reflect.Method.invoke(Native Method)
   at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:131)
   at b4a.example3.main._getdocumentddir(main.java:683)
   at b4a.example3.main$ResumableSub_btnCopyPDF_Click.resume(main.java:607)
   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:144)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
   at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
   at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:250)
   at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:137)
   at anywheresoftware.b4a.BA$2.run(BA.java:370)
   at anywheresoftware.b4a.BA.setActivityPaused(BA.java:442)
   at b4a.example3.main$ResumeMessage.run(main.java:306)
   at android.os.Handler.handleCallback(Handler.java:751)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6121)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
Caused by: java.lang.IllegalArgumentException: Invalid URI:
   at android.provider.DocumentsContract.getTreeDocumentId(DocumentsContract.java:927)
   at android.support.v4.provider.DocumentFile.fromTreeUri(DocumentFile.java:138)
   ... 25 more
** Activity (main) Resume **
I think the problem is this line:
(ArrayList) [27.02.19_19.29_Anruf.01705883780.wav, unternehmensprofil_15.pdf, 2014-06-NAL-DE.pdf, Rechnung 1060788990 vom 02.03.2019.pdf

Maybe, it's my mistake, tapped at any other or wrong button?

Stefan
 
Last edited:

DonManfred

Expert
Licensed User
You should create a new thread in the Questionsforum for any Issue you have.
Make sure to post all relevant code you are using. Best is to upload a small project which shows the issue.

Permission given. Check content
(ArrayList) [
27.02.19_19.29_Anruf.01705883780.wav, unternehmensprofil_15.pdf, 2014-06-NAL-DE.pdf, Rechnung 1060788990 vom 02.03.2019.pdf, pt1007p.pdf]
this is the list of the fioles in the folder
The result from this
B4X:
Dim flist As List = File.ListFiles(File.Combine(File.DirRootExternal,"Download/"))
You need to use the file you need from this list. Adapt the example to use one of THESE.

The example is made to use the file
B4X:
Dim filetocopy As String = "profil_15.pdf"
as per your request.

if I get a small piece of code, as already written, a file from an internal directory on the SD card copy, specifically main_memory/Download/profil_15.pdf to SD-card/Test/profile_15 .pdf (the targetfolder "Test" does not exist yet).
 

der_c

Member
Licensed User
..."profil_15.pdf" was only a short, thank's for the info.

I didn't change the code, except the file name. After the second test, I get no more errors, but nothing is copied and no folder is created.

For safety, the project attached.

Stefan
 

Attachments

der_c

Member
Licensed User
..and yes, i will create a new thread, but first, that you can see it, because the example is from you.
 

DonManfred

Expert
Licensed User
After the second test, I get no more errors
the error at the first run is because the example app is reading the stored document root in activity create.
It is an empty result in first run.

You then define the root. The path is stored then.

change the sub to:
B4X:
Sub btnCopyPDF_Click
    Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    wait for Activity_PermissionResult(Permission As String, Result As Boolean)
    If Result Then
        Log("Permission given. Check content")
        Dim flist As List = File.ListFiles(File.Combine(File.DirRootExternal,"Download/"))
        Log(flist)
        Dim filetocopy As String = "unternehmensprofil_15.pdf"
    End If
    If File.Exists(File.DirInternal, FileName) Then
        PersistantUri = File.ReadString(File.DirInternal, FileName)
        Log($"PersistantUri=${PersistantUri}"$)
    End If
    ' Get DocumentDir
    Dim docs As JavaObject = GetDocumentdDir(PersistantUri)
    
    ' Check if Destfolder Test1 already exists.
    Dim chkTest1 As ExternalFile = Storage.FindFile(Storage.Root,"Test1")
    If chkTest1.IsInitialized = False Then
        'create the Folder "Test1"
        docs.RunMethod("createDirectory",Array("Test1"))
    End If
    ' Search the created Folder in the Storage Rootdir (we need to have a reference to it)
    Dim Test1 As ExternalFile = Storage.FindFile(Storage.Root,"Test1")
    
    ' define destfile
    Dim destfile As ExternalFile = Storage.CreateNewFile(Test1,filetocopy)
    ' Create an Outputstream to the destfile
    Dim os As OutputStream = Storage.OpenOutputStream(destfile)
    ' Create an Inputstream from the Sourcefile to copy
    Dim inpstr As InputStream  = File.OpenInput(File.Combine(File.DirRootExternal,"Download/"),filetocopy)
    ' Copy file
    File.Copy2(inpstr,os)
    ' Close Outputstream
    os.Close

End Sub
if added the reading of the persistanturi here to make sure you get it rigth at the first run.

Note that the Code will create a Folder Test1 to copy the file to.
The Code is creating this folder here and the PDF is copied to this folder too

WhatsApp Image 2019-03-10 at 10.54.40.jpeg
Snapshot made in ESExplorer after i pressed the Button.
 

der_c

Member
Licensed User
ok, i see, but the file is not copied into the external storage, but i find it in the internal storage, this is the line of the log.

PersistantUri=content://com.android.externalstorage.documents/tree/primary%3AWhatsApp%2FMedia%2FWhatsApp%20Video

the folder and the file is there "...whatsapp", this is an first success, but i want it on the SD-Card.:(
 

DonManfred

Expert
Licensed User
Did you selected the External SDCard ROOT folder in the first run?
You need to define the root of the external sdcard you want to use.

Do not select the internal sdcard if you want access to the external Card.

Seems like you did select the whatsapp folder you posted as the root.

- Uncheck "Use previously selected" and Click on Pickfolder button again
- Select the External sdcard (do not navigate to any subfolder) and select AUSWÄHLEN button in bottom right.
This way you define the ROOT folder to use. This is stored as persistanturi.

Select it again an post the new persistanturi.
 
Last edited:

DonManfred

Expert
Licensed User
Additional info
PersistantUri=content://com.android.externalstorage.documents/tree/primary%3AWhatsApp%2FMedia%2FWhatsApp%20Video
Based on this tree you selected the Folder "WhatsApp\Media\WhatsApp Video"

Effectively you did define THIS Folder to be the Root of your External SDCArd.

The result is that the code in the btnCopyPDF_Click will create a Folder Test1 here and also copy the pdf.

Check the content of "WhatsApp\Media\WhatsApp Video". Is there a Test1 folder now? Is there a pdf inside this Folder Test1?
 

der_c

Member
Licensed User
Yesterday I understood everything so far, everything works so well.
Still a question, there is no other way to find the exact name of the SD card and folders on the SD card? Except on the cumbersome way use a file manager?

Stefan
 
Last edited:
Top