@@ -125,64 +125,49 @@ <h1>Android File System Demo</h1>
125125 }
126126 } ) ;
127127
128- // 3. OPEN DIRECTORY (Fixed for Android)
128+ // 3. ROBUST DIRECTORY WRITE ( Android Safe )
129129 document . getElementById ( 'btnDir' ) . addEventListener ( 'click' , async ( ) => {
130130 try {
131131 log ( "Requesting directory access..." ) ;
132- const dirHandle = await window . showDirectoryPicker ( {
133- mode : "readwrite"
134- } ) ;
135-
136- log ( `📂 Directory selected: ${ dirHandle . name } ` ) ;
137-
138- // 1. Verify Directory Permission
139- const options = { mode : 'readwrite' } ;
140- if ( ( await dirHandle . queryPermission ( options ) ) !== 'granted' ) {
141- if ( ( await dirHandle . requestPermission ( options ) ) !== 'granted' ) {
142- throw new Error ( "Directory write permission denied." ) ;
143- }
144- }
145-
146- // List contents
147- const entries = [ ] ;
148- for await ( const entry of dirHandle . values ( ) ) {
149- entries . push ( entry ) ;
150- }
151- log ( `Files found: ${ entries . length } ` ) ;
152-
153- // 2. Create/Get the File Handle
154- const fileName = 'session-log.txt' ;
155- let fileHandle ;
132+ const dirHandle = await window . showDirectoryPicker ( { mode : "readwrite" } ) ;
156133
134+ // 1. Create the file handle (This usually works)
135+ let fileHandle ;
157136 try {
158- fileHandle = await dirHandle . getFileHandle ( fileName , { create : true } ) ;
137+ fileHandle = await dirHandle . getFileHandle ( 'session-log.txt' , { create : true } ) ;
159138 } catch ( e ) {
160- throw new Error ( `Could not create file handle: ${ e . message } ` ) ;
139+ log ( "Could not create file handle." , 'error' ) ;
140+ return ;
161141 }
162142
163- // --- THE FIX: Request Permission on the FILE handle explicitly ---
164- // Android does not always inherit permission from the parent folder.
165- if ( ( await fileHandle . queryPermission ( options ) ) !== 'granted' ) {
166- log ( "⚠️ Requesting permission for the specific file..." ) ;
167- if ( ( await fileHandle . requestPermission ( options ) ) !== 'granted' ) {
168- throw new Error ( "File write permission denied." ) ;
143+ // 2. Try to write directly (Works on Desktop, often fails on Android)
144+ try {
145+ log ( "Attempting direct write..." ) ;
146+ const writable = await fileHandle . createWritable ( ) ;
147+ await writable . write ( `Log Entry: ${ new Date ( ) . toISOString ( ) } ` ) ;
148+ await writable . close ( ) ;
149+ log ( "✅ Success! Direct write worked." ) ;
150+ } catch ( err ) {
151+ // 3. Catch the specific "Read-only" error
152+ if ( err . message . includes ( "read-only" ) || err . name === "NoModificationAllowedError" ) {
153+ log ( "⚠️ Direct write failed (Android Restriction)." ) ;
154+ log ( "🔄 Falling back to Save Picker..." ) ;
155+
156+ // Fallback: Ask user to explicitly save this specific file
157+ const saveHandle = await window . showSaveFilePicker ( {
158+ suggestedName : 'session-log.txt' ,
159+ } ) ;
160+ const writable = await saveHandle . createWritable ( ) ;
161+ await writable . write ( `Log Entry: ${ new Date ( ) . toISOString ( ) } ` ) ;
162+ await writable . close ( ) ;
163+ log ( "✅ Saved via fallback!" ) ;
164+ } else {
165+ throw err ; // Re-throw other errors
169166 }
170167 }
171- // ------------------------------------------------------------------
172-
173- log ( "Attempting to write..." ) ;
174- const writable = await fileHandle . createWritable ( ) ;
175-
176- // Read existing content if possible to append (optional)
177- const timestamp = new Date ( ) . toISOString ( ) ;
178- await writable . write ( `\nLog Entry: ${ timestamp } ` ) ;
179- await writable . close ( ) ;
180-
181- log ( `✅ Success! Wrote to ${ fileName } ` ) ;
182168
183169 } catch ( err ) {
184- if ( err . name === 'AbortError' ) log ( "User cancelled." ) ;
185- else log ( `Error: ${ err . message } ` , 'error' ) ;
170+ log ( `Error: ${ err . message } ` , 'error' ) ;
186171 }
187172 } ) ;
188173 </ script >
0 commit comments