# Native Folder Access

> Read and write a real folder on the phone, with permission that survives reboots.

- **Applies to:** AppMint and Appwright
- **Source:** the Integration Guide shipped inside the app; this page is generated from it.
- **HTML:** https://freewebtoapk.com/docs/native-folder-access

Use SAF-backed local folders from WebView and offline HTML apps

### 1. What This Feature Does

This feature gives your web app controlled access to one user-picked Android folder using the Storage Access Framework (SAF). It works well for offline HTML apps, editors, backup/restore flows, and import/export tools.

It does NOT give unrestricted device storage access. The user explicitly chooses one folder, and your app can only work inside that granted tree.

### 2. Enable in the Generator

In Step 4 of the generator, turn ON 'Native Folder Access (SAF)'. Then generate the app.

When enabled, your website gets a high-level helper at window.WebToApkFS in addition to the raw window.WebToApk bridge.

⚠️ Android 11+ Storage Note: On Android 11 and above, reading the shared storage requires the special 'All Files Access' permission. When your generated app launches for the first time and the storage permission is enabled, it automatically opens the Android Settings screen to let the user grant this permission. The user just taps the toggle in Settings and returns to the app - no manual navigation required.

### 3. Browser-Safe Capability Check

Always guard your code so it still runs in Chrome/Safari where the Android bridge does not exist:

```
function canUseNativeFiles() {
  return !!(window.WebToApkFS && window.WebToApkFS.isAvailable());
}

if (canUseNativeFiles()) {
  console.log('Android native folder access available');
}
```

### 4. Ask User to Pick a Folder

Call requestAccess() from a button click or other clear user action. It opens Android's folder picker and returns the chosen folder URI.

```
async function connectFolder() {
  const result = await window.WebToApkFS.requestAccess();
  if (!result.success) {
    alert('Folder access was not granted');
    return false;
  }
  console.log('Granted folder:', result.folderUri);
  return true;
}
```

### 5. Basic File Operations

Once access is granted, you can list folders, create directories, read text files, write text files, rename entries, and delete entries.

```
// Create folders
window.WebToApkFS.mkdir('notes');
window.WebToApkFS.mkdir('notes/2026');

// Write a file
window.WebToApkFS.writeText('notes/2026/today.txt', 'Hello from offline app');

// Read it back
const text = window.WebToApkFS.readText('notes/2026/today.txt');
console.log(text);

// List folder contents
const entries = window.WebToApkFS.list('notes/2026');
console.log(entries);
```

### 6. Rename and Delete

Rename changes only the final entry name. Delete supports both non-recursive and recursive directory deletion.

```
// Rename file or folder
window.WebToApkFS.rename('notes/2026/today.txt', 'journal.txt');

// Delete a single file
window.WebToApkFS.delete('notes/2026/journal.txt');

// Delete a folder tree
window.WebToApkFS.delete('notes/2026', { recursive: true });
```

### 7. Good Use Cases

✅ Offline note or journal apps  
✅ CSV / JSON import-export tools  
✅ Simple local backup and restore  
✅ Static HTML editors that save user content  
✅ Dashboard apps that export reports as text or CSV

### 8. Limitations

⚠️ This is Android-only. It will not exist in normal desktop/mobile browsers.

⚠️ Current helper is designed around folder listing and text files. Binary workflows need additional APIs.

⚠️ Access is scoped to the one folder the user granted.

⚠️ Call these APIs after the page is loaded so the helper has been injected.

### 9. Full Working Example

This example connects a folder, creates a workspace directory, writes a JSON file, and renders the folder listing:

```
async function setupWorkspace() {
  if (!window.WebToApkFS || !window.WebToApkFS.isAvailable()) {
    console.log('Native folder access not available in this browser');
    return;
  }

  if (!window.WebToApkFS.hasAccess()) {
    const granted = await window.WebToApkFS.requestAccess();
    if (!granted.success) return;
  }

  window.WebToApkFS.mkdir('workspace');
  window.WebToApkFS.writeText(
    'workspace/config.json',
    JSON.stringify({ updatedAt: new Date().toISOString(), mode: 'offline' }, null, 2)
  );

  const files = window.WebToApkFS.list('workspace');
  document.getElementById('output').textContent = JSON.stringify(files, null, 2);
}
```

