从Crashlytics捕获SQLiteException(代码14):DownloadManager下载遇异常
android.database.sqlite.SQLiteException (code 14) with DownloadManager Hey there, let's break down this android.database.sqlite.SQLiteException: unable to open database file (code 14) issue you're hitting while using DownloadManager. Even though your code focuses on file downloads, this error ties back to the system-level SQLite database that DownloadManager uses to track download tasks. Here's why it's happening and how to fix it:
Common Causes
- Missing or Denied Storage Permissions:
DownloadManagerneeds write access to external storage to save files, and the system's download task database also relies on proper permissions to operate. On Android 6.0+, this requires dynamic permission requests (not just manifest declarations). - Invalid/Unwritable Storage Path: The folder you're trying to use for downloads might not exist, or your code isn't properly creating it. A missing or unreadable directory can break the underlying database operations
DownloadManagerdepends on. - Corrupted System Download Database: Rare, but sometimes the system's built-in download database (stored in
/data/data/com.android.providers.downloads/databases/) can get corrupted, leading to this error. - Insufficient Storage Space: If the device's internal storage or SD card is full, the system can't create or write to the SQLite database file.
Step-by-Step Fixes
1. Fix Storage Permissions
First, make sure you have the necessary permissions set up:
- Add these to your
AndroidManifest.xml:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- For Android 13+, use READ_MEDIA_IMAGES/READ_MEDIA_AUDIO if targeting media files --> - For Android 6.0+, request permissions dynamically before starting downloads:
private static final int REQUEST_STORAGE_PERMISSION = 101; // Check and request permission if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE_PERMISSION); } else { // Proceed with download logic startDownload(); } // Handle permission result @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_STORAGE_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startDownload(); } else { Toast.makeText(this, "Storage permission is required to save downloads", Toast.LENGTH_LONG).show(); } } }
2. Ensure Your Download Folder is Valid & Writable
Your current code only checks if folder is null—it doesn't verify if the folder exists or can be created. Update your folder handling logic:
File folder = new File(dir + File.separator + (isAudio ? AUDIO : IMAGES)); // Validate external storage availability first if (dir == null || !Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(this, "External storage is unavailable", Toast.LENGTH_SHORT).show(); return; } // Create folder if it doesn't exist if (!folder.exists()) { boolean folderCreated = folder.mkdirs(); // Creates parent directories automatically if (!folderCreated) { Log.e("DownloadError", "Failed to create folder: " + folder.getAbsolutePath()); Toast.makeText(this, "Could not create download directory", Toast.LENGTH_SHORT).show(); return; } } // Set the download destination properly request.setDestinationInExternalPublicDir(folder.getAbsolutePath(), "your_target_file_name.ext");
Pro tip: Use system-standard directories like Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) to avoid path-related permission headaches.
3. Fix Corrupted System Download Database (User-Side)
If the issue persists on specific devices, guide users to:
- Go to Settings > Apps > Download Manager
- Tap Storage > Clear Data and Clear Cache
- Restart the device and try downloading again
4. Check for Insufficient Storage
Add a quick check to ensure there's enough space before starting the download:
StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getPath()); long availableSpace = statFs.getAvailableBytes(); long requiredSpace = 100 * 1024 * 1024; // Example: 100MB minimum if (availableSpace < requiredSpace) { Toast.makeText(this, "Not enough storage space to complete the download", Toast.LENGTH_SHORT).show(); return; }
Bonus: Android 10+ Partition Storage Adaptation
For apps targeting Android 10 (API 29)+, consider using request.setDestinationInExternalFilesDir() instead of custom paths. Partition storage restricts direct access to external storage, and this method lets you save files to your app's dedicated directory without needing the WRITE_EXTERNAL_STORAGE permission.
内容的提问来源于stack exchange,提问作者Ramesh Kumar

