Android应用运行时崩溃排查及SQLite备份跨机型异常求助
Hey there, let's work through your Android backup issues and crash troubleshooting questions one by one!
Your current code has two key compatibility issues that are likely causing crashes on non-Redmi devices:
Hardcoded Database Path
You’re using a hardcoded path (/data/data/com.scbpfsdgis.fdrmobile/databases/FEMobile.db) to access the database. This breaks on devices with custom ROMs or newer Android versions (where app data directory structures might differ). Instead, use the system-provided getDatabasePath() method to reliably get your database file:
File dbFile = getDatabasePath("FEMobile.db");
Scoped Storage & Permission Limitations
Directly using Environment.getExternalStorageDirectory() can trigger access errors on Android 10+ (due to Scoped Storage rules) or devices with strict permission policies. Switch to your app’s private external storage directory—this requires no extra permissions on Android 10+ and is fully compliant:
File backupDir = new File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "Backups");
Revised Backup Code
Here’s the updated, more compatible version of your backup function (with try-with-resources to avoid stream leaks):
private void backupDB() throws IOException { // Create app-specific backup directory File backupDir = new File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "Backups"); if (!backupDir.exists()) { backupDir.mkdirs(); } // Get database file via system API File dbFile = getDatabasePath("FEMobile.db"); if (!dbFile.exists()) { throw new FileNotFoundException("Database file not found at: " + dbFile.getAbsolutePath()); } // Generate timestamped backup filename DateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss", Locale.getDefault()); String bakFileName = "BAK_" + df.format(new Date()) + ".db"; this.backupFileName = bakFileName; File backupFile = new File(backupDir, bakFileName); // Transfer database content with auto-closing streams try (FileInputStream fis = new FileInputStream(dbFile); FileOutputStream output = new FileOutputStream(backupFile)) { byte[] buffer = new byte[1024]; int length; while ((length = fis.read(buffer)) > 0) { output.write(buffer, 0, length); } } }
Don’t forget to handle permissions for Android 6.0-9.0: declare the permission in your AndroidManifest.xml and request it dynamically before running the backup.
There are three easy ways to capture logcat logs for crash analysis:
Using Android Studio
- Connect your device to your computer and open Android Studio.
- Go to View > Tool Windows > Logcat to open the log window.
- Filter logs by your app’s package name (
com.scbpfsdgis.fdrmobile) to narrow down relevant entries. - Click the export icon (downward arrow) in the top-right corner of Logcat, then save the log as a
.txtfile.
Using ADB Command Line
- Ensure ADB is installed on your computer and your device has USB debugging enabled.
- Open a terminal/command prompt and run:
adb logcat -d -f /sdcard/backup_crash_log.txt com.scbpfsdgis.fdrmobile:V *:S-d: Outputs logs and exits (doesn’t keep listening).-f: Specifies the save path on your device.com.scbpfsdgis.fdrmobile:V: Shows only verbose logs from your app.*:S: Mutes logs from all other apps.
- You’ll find the log file at
/sdcard/backup_crash_log.txton your device.
Within Your App (Android 9 or Lower)
For older devices, you can add code to save logs directly to a file (note: Android 10+ restricts the READ_LOGS permission to system apps):
private void saveLogcat() { try { File logFile = new File(getExternalFilesDir(null), "app_crash_log.txt"); Process process = Runtime.getRuntime().exec("logcat -d com.scbpfsdgis.fdrmobile:V *:S"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder logContent = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { logContent.append(line).append("\n"); } FileWriter writer = new FileWriter(logFile); writer.write(logContent.toString()); writer.close(); } catch (IOException e) { e.printStackTrace(); } }
When your app stops unexpectedly, follow these steps to diagnose the issue:
- Check Logcat Immediately: Look for
AndroidRuntimeentries in the log—these will show the exact exception (e.g.,FileNotFoundException,SecurityException) and the line of code causing the crash. Pay close attention to theCaused bysection for root causes. - Add Exception Handling: Wrap your backup function in a try-catch block to capture errors and notify the user (while logging details):
try { backupDB(); Toast.makeText(this, "Backup successful!", Toast.LENGTH_SHORT).show(); } catch (IOException e) { Log.e("BackupError", "Failed to backup database", e); Toast.makeText(this, "Backup failed: " + e.getMessage(), Toast.LENGTH_LONG).show(); } - Test on Multiple Android Versions: Use Android Studio’s emulator to test your app on different API levels (e.g., Android 8.0, 10, 13) to rule out version-specific issues.
- Verify File Access: Print the absolute paths of your database and backup directory to Logcat to confirm they exist and are writable:
Log.d("BackupDebug", "Database path: " + dbFile.getAbsolutePath()); Log.d("BackupDebug", "Backup dir path: " + backupDir.getAbsolutePath());
内容的提问来源于stack exchange,提问作者William Ernesto

