Italian Non riesco a scrivere su un file txt

3394509365

Active Member
Licensed User
Longtime User
Sto facendo un app che carica un file di testo dalla memoria del telefono che contiene una lista di numeri

carico file:
Sub cc_Result (Success As Boolean, Dir As String, FileName As String)
    Directory=""
    NomeFile=""
 
    If Success = True  Then
        Directory=Dir
        NomeFile=FileName

        Log("Directory= " & Dir)
        Log("NomeFile= " & FileName)

        ' Leggiamo i numeridal file
       
        currentNumberIndex = 0
        
        numbersList.Initialize
'        Dim in As InputStream
        'in = File.OpenInput(File.DirInternal, "numbers.txt")
        in = File.OpenInput(Directory, NomeFile)
        Dim reader As TextReader
        reader.Initialize(in)
        Do While reader.Ready
            Dim number As String = reader.ReadLine.Trim
            If number <> ""  And  number.EndsWith("#") = False Then
                numbersList.Add(number)
            End If
        Loop
        reader.Close
        in.Close
        
        
        currentNumberIndex = 0
        smsSent = False


dopo di che, periodicamente leggoun numero dalla lista e poi quel numero che in teoria è sempre quello con index =0, e lo vorrei eliminare dal file da cui lo avevo letto.
alla fine il file dovrebbe essere vuoto.

Ho messo i permessi

permessi manifest:
AddManifestText(
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="29"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
CreateResourceFromFile(Macro, Themes.LightTheme)
'End of default text.
AddManifestText(
<uses-permission
  android:name="android.permission.WRITE_EXTERNAL_STORAGE" />)

e tutto funziona, infatti all' inizio mi chiede di dare il permesso

poi elimino il numero che ho appena usato

B4X:
    numbersList.RemoveAt(index)
'


e cerco di riscrivere la nuova lista senza il numero camcellato
B4X:
    Dim out As OutputStream = File.OpenOutput(Directory, NomeFile ,False)

    Dim writer As TextWriter

    writer.Initialize(out)

    For Each item As String In numbersList

        writer.WriteLine(item)

    Next

    writer.Close

    out.Close

questa riga mi genera un errorem credo di permessi

Dim out As OutputStream = File.OpenOutput(Directory, NomeFile ,False)

Directory e Nome File li ottengo dalla sub Sub cc_Result (Success As Boolean, Dir As String, FileName As String) vedi sopra.

il mio file si chiama numbers.txt edanche se sostituisco NomeFile con "numbers.txt" ho lo stesso errore



questo è l' errore:
B4X:
java.io.FileNotFoundException: ContentDir/content:/com.android.providers.media.documents/document/document%3A1000009746: open failed: ENOENT (No such file or directory)

Dove sta il problema ?
 

Star-Dust

Expert
Licensed User
Longtime User
 

3394509365

Active Member
Licensed User
Longtime User

nel frattempo ho fatto questo per accertarmi che sono dentro la memoria giusta e che il file esista:
adesso pasaa dentro senza errore ma non cancella

B4X:
If File.Exists(File.DirInternal,"numbers.txt") = True Then

        Log("File exist")
        
        Dim out As OutputStream = File.OpenOutput(File.DirInternal,"numbers.txt" ,False)
        Dim writer As TextWriter
        writer.Initialize(out)
        For Each item As String In numbersList
            writer.WriteLine(item)
        Next
        writer.Close
        out.Close
    
    End If
 

3394509365

Active Member
Licensed User
Longtime User
questo lo avevo visto ma non risolve il mio problema
 

3394509365

Active Member
Licensed User
Longtime User
provate aad aiutare me, visto che nelforum italiano c' è poco da fare,

qualcuno mi può spiegare perchè prendo la directory ed il nome del file così:
B4X:
Sub cc_Result (Success As Boolean, Dir As String, FileName As String)
    'Directory=""
    'NomeFile=""
    'Sub cc_Result (Success As Boolean, Dir As String, FileName As String, FileType As String)

    If Success = True  Then
        Directory=Dir
        NomeFile=FileName
        Log("Directory= " & Dir)
        Log("NomeFile= " & FileName)
        ' Leggiamo i numeri di telefono dal file
        'numbersList = LoadNumbersFromFile
        currentNumberIndex = 0
       
        numbersList.Initialize
'        Dim in As InputStream
        'in = File.OpenInput(File.DirInternal, "numbers.txt")
        in = File.OpenInput(Directory, NomeFile)
        Dim reader As TextReader
        reader.Initialize(in)
        Do While reader.Ready
            Dim number As String = reader.ReadLine.Trim
            If number <> ""  And  number.EndsWith("#") = False Then
                numbersList.Add(number)
            End If
        Loop
        reader.Close
        in.Close

questo è uno stralcio-

come si vede do alla variabile Directory =Dir e Nomefile = Filename

poi qui li utilizzo e va tutto bene
B4X:
in = File.OpenInput(Directory, NomeFile)

però in realtà il nome della directory è sempre "Contentdir" anche se io il file lo carico da diverse parti della memorie o dentro altre cartelle Come mai?
infatti più avanti voglio utilizzare la stessa variabile per lavorare ancora su quel file, ma non mi funziona più perchè non è un percorso valido.

La stessa cosa mi succede con il nome del file, quando lo seleziono per importarlo si chia,a "numbers.txt" ed invece la variabile ha come nome NomeFile= content://media/external/file/1000009800

cosa non so che voi sicuramente sapete ?
 

LucaMs

Expert
Licensed User
Longtime User
Due domandine:

1 - come "apri" il ContentChooser? Show("text/*"...) ?
2 - quel file di testo... ti arriva da Internet e lo salvi in qualche cartella? Perché se tu lo avessi già, potresti metterlo nel Tab Files, copiarlo nella DirInternal e lavorare in quella (tra l'altro, ti suggerirei di usare KeyValueStore2, molto più comodo di un file di testo, anche perché puoi cambiare direttamente la singola voce-numero, senza dover riscrivere tutto il file. Nota che c'è anche il metodo File.WriteList, comunque).
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
questo lo avevo visto ma non risolve il mio problema
L'esempio è per spiegarti come fare. Dopo aver aperto con ContentChooser, modifichi la lista e ancora una volta con ContentChooser lo salvi.
ContentChooser ti autorizza solo un accesso alla volta, quindi devi usarlo 2 volte una per la lettura e la seconda volta per scriverlo.

Poi se vuoi l'accesso continuo, e non devi pubblicare sul PLAYSTORE, allora usa questo
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Dim out As OutputStream = File.OpenOutput(File.DirInternal,"numbers.txt" ,False)

La cartella DirInternal mi risulta essere a sola lettura, non puoi scriverci dentro

Crea un mini-progetto con le sole righe di codice che servono e pubblicalo qui, così lo scarichiamo e lo proviamo
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
DirAssets è di sola lettura perché è virtuale. DirInternal è lettura/scrittura
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Azzzz hai ragione, si vede che è tanto che non programmo in B4A
 

3394509365

Active Member
Licensed User
Longtime User
adesso sto facendo un sacco di prove sommarie, quello che voglio dare è caricare un file txt che ho sulla memoria del telefono, che contiene una lista di numeri di telefono e poi periodicamente mandare un sms ai numeri. dopo mandado volevo fleggare il numero per non mandarlo due volte, tutto qui

ecco le mie prove:
B4X:
#Region  Project Attributes
    #ApplicationLabel: sms23
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
   
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    Dim numbersList As List
    Dim currentNumberIndex As Int = 0
    'Dim smsSent As Boolean = False
    'Dim timer1 As Timer
    Dim numbersList As List
    Dim cc As ContentChooser
    Dim in As InputStream
   
    'Dim Directory As String = File.DirInternal  
    'Dim NomeFile As String= "numbers.txt"
   
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    OOOO   GGGG     GGGGG    IIII    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
End Sub

Sub Globals
   
    Private Button2 As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")  
    ' Creiamo un timer per inviare un SMS ogni minuto
    'timer1.Initialize("timer1", 500)
   
       
End Sub


Sub Button1_Click
   
    ' mi metto in attesa dei permessi che ricevo dalla seguente funzione
    Wait For(PermessoCartella) Complete (Result As Boolean)
   
    If Result Then 'se ho i permessi faccio il resto  
        ToastMessageShow("Result true .", True)  
       
        cc.Show("text/plain", "Seleziona un file di testo")  
   
    Else' se non ho le autorizzazioni esco subito
        ToastMessageShow("Result false .", True)
        'ExitApplication
    End If
   
End Sub

Sub cc_Result (Success As Boolean, Dir As String, FileName As String)
   

    If Success = True  Then
        'Directory=Dir
        'NomeFile=FileName
        Log("Directory= " & Dir)
        Log("NomeFile= " & FileName)
        ' Leggiamo i numeri di telefono dal file
        'numbersList = LoadNumbersFromFile
       
        'Copia il file dalla memoria interna alla memoria esterna
        File.Copy(Dir, FileName, File.DirInternal, "numberscopiato.txt")
        ToastMessageShow("copiato .", True)
               
        ' se tutto ok  allora copio il file in una nuova directory dove posso scrivere
        If File.Exists(File.DirInternal, "numberscopiato.txt") = True Then

            Log("File exist")
       
            'Carico numeri in memoria
            cariconumeri
        Else
           
            Log("File nuovo no esiste exist")
            ToastMessageShow("File non copiato, riprovare.", True)
        End If
   
    Else If Success Then
        ' Mostriamo un messaggio di errore se l'utente seleziona un file di tipo non supportato
        ToastMessageShow("Tipo di file non supportato.", True)
       
    Else
        ' Mostriamo un messaggio di errore se l'utente non seleziona un file
        ToastMessageShow("Nessun file selezionato.", True)
    End If
End Sub


Sub cariconumeri
   
    currentNumberIndex = 0
       
    numbersList.Initialize

    in = File.OpenInput(File.DirInternal, "numberscopiato.txt")
    Dim reader As TextReader
    reader.Initialize(in)
    Do While reader.Ready
        Dim number As String = reader.ReadLine.Trim
        If number <> ""  And  number.EndsWith("#") = False Then
            numbersList.Add(number)
        End If
    Loop
       
    reader.Close
    in.Close
   
    currentNumberIndex = 0
           
    Dim fileContents As String
    Dim in As InputStream
    in = File.OpenInput(File.DirInternal, "numberscopiato.txt")
   
    Dim reader As TextReader
    reader.Initialize(in)
    fileContents = reader.ReadAll
   
    reader.Close
    in.Close
   
    ' Leggi i numeri di telefono dal file di testo
    Dim phoneNumbers() As String
    phoneNumbers = Regex.Split("#", fileContents)
   
    ' Invia gli SMS
   
    'xxxxxxxxxxxxxxxxxxxxxxxxx    questa parte non funziona  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    For i = 0 To phoneNumbers.Length - 1
        If phoneNumbers(i).EndsWith("#") =False Then
            ' faccio quello che devo fare e poi aggiungo un # alla fine del numero
            File.WriteString(File.DirInternal, "numberscopiato.txt", phoneNumbers(i) & "#" & CRLF)
               
        End If
    Next
       
       
       
End Sub







Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


   
public Sub PermessoCartella() As ResumableSub  
    Dim  rp As RuntimePermissions  
    rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)' permesso singolo  
   
    Wait For Activity_PermissionResult (permission As String, Result As Boolean)      
    If Result = True Then
        cc.Initialize("CC")              
    Else
        ToastMessageShow("No permission!!!", True)
        'ExitApplication
    End If
    ' valore restituito
    Return Result
End Sub


Private Sub Button2_Click' solo per debug
   
  
    If File.Exists(File.DirInternal, "numberscopiato.txt") = True Then
        numbersList.Initialize
    '        Dim in As InputStream
        'in = File.OpenInput(File.DirInternal, "numbers.txt")
        in = File.OpenInput(File.DirInternal, "numberscopiato.txt")
        Dim reader As TextReader
        reader.Initialize(in)
        Do While reader.Ready
            Dim number As String = reader.ReadLine.Trim
            If number <> ""  And  number.EndsWith("#") = False Then
                numbersList.Add(number)
            End If
        Loop
           
        reader.Close
        in.Close
   
    End If
End Sub
 

Sagenut

Expert
Licensed User
Longtime User
Per capire:
La lista dei numeri la fornisci tu insieme alla app?
Questa lista può essere modificata (aggiungere numeri) dalla app o userà solo la lista iniziale che verrà magari aggiornata con successive versioni della app?
 

3394509365

Active Member
Licensed User
Longtime User
no, la lista viene presa dal file scelto.
certamente mi sarebbe piaciuto modificarla man mano che invio gli sms, eliminando quelli inviati, ma non riesco a farlo per problemi di permessi di scrittura.
Allora la mia idea era caricare la lista dalla memoria del telefono, poi copiarla in una locazione dove mi farebbe scrivere e fare i miei invii. dopo ogni invio eliminerei il numero dalla lista, fino a che non rimane vuota.
come detto sono arrivato fino a copiare la lista iniziale, ma non riesco ne a modificare ne a eliminare le righe già eleborate.
 

Sagenut

Expert
Licensed User
Longtime User
I numeri poi non ti servono più dopo un invio?
 

3394509365

Active Member
Licensed User
Longtime User
no infatti avrei provato anche a svuotare man mano la lista, ma significa che ci dovrebbe essere una funzione che elimina una riga specifica.
In b4a non la conosco
 

Sagenut

Expert
Licensed User
Longtime User
Se lavori sempre con il primo numero della lista è
B4X:
Lista.RemoveAt(0)
Ora non sono al PC quindi non sono sicuro della sintassi.
 

udg

Expert
Licensed User
Longtime User
caricare un file txt che ho sulla memoria del telefono
A me incuriosisce questo punto.
Presumiamo di essere un utente della tua app, come creo questo file? come lo trasferisco sul mio telefono? devo rispettare un formato particolare, un nome specifico?

Un altro aspetto ad considerare: l'invio massivo di SMS (ed anche mail) non è gradito alla maggior parte di provider e servizi telefonici. Esistono dei servizi appositi, anche a basso costo, che evitano il rischio di essere "bannati" o comunque posti in black-list.
 

Sagenut

Expert
Licensed User
Longtime User
Se proprio serve, non conviene salvare il file in
B4X:
RP.GetSafeDirDefaultExternal
che è la dir accessibile solo dalla app stessa e che non dovrebbe richiedere altri permessi o cose strane?
RP è l'istanza di RuntimePermissions.
 

3394509365

Active Member
Licensed User
Longtime User
intanto ho fatto questo e sembra funzionare, solo che ogni volta devo riscrivere l' intera lista depo il delete.
B4X:
Private Sub Button_Click' solo per debug
        
        ' leggo lista
    If File.Exists(File.DirInternal, "numberscopiato.txt") = True Then
        numbersList.Initialize
            
        in = File.OpenInput(File.DirInternal, "numberscopiato.txt")
        Dim reader As TextReader
        reader.Initialize(in)
        Do While reader.Ready
            Dim number As String = reader.ReadLine.Trim
            If number <> ""  And  number.EndsWith("#") = False Then
                numbersList.Add(number)
            End If
        Loop
            
        reader.Close
        in.Close
    
        'elimino dalla lista ma devo riscrivere l' intero file
        numbersList=File.ReadList(File.DirInternal, "numberscopiato.txt")
        numbersList.RemoveAt(0)
    File.WriteList(File.DirInternal, "numberscopiato.txt",numbersList)
        
    'rileggo
    
        numbersList.Initialize
        '        Dim in As InputStream
        'in = File.OpenInput(File.DirInternal, "numbers.txt")
        in = File.OpenInput(File.DirInternal, "numberscopiato.txt")
        Dim reader As TextReader
        reader.Initialize(in)
        Do While reader.Ready
            Dim number As String = reader.ReadLine.Trim
            If number <> ""  And  number.EndsWith("#") = False Then
                numbersList.Add(number)
            End If
        Loop
            
        reader.Close
        in.Close
        
    End If
End Sub


comunque è una cosa mia personale, non devo vendere e non devo pubblicarla da nessuna parte.

solo che devo inviare un tot di sms e non voglio farlo manualmente, non sono uno spammer.

app che uso una volta all' anno.

Sicuramente ci sarà un modo migliore ma al momento non mi viene nulla di meglio
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…