Android TXT文件保存求助:扫码信息无法存入Documents文件夹
问题分析与修复方案
你的代码存在几个核心问题导致文件无法正常保存:
btn_store的点击事件被重复绑定了两次,后一次会覆盖前一次逻辑(虽逻辑相同,但属于冗余错误)- 针对Android 10+的Scoped Storage机制,直接用
FileOutputStream操作公共Documents目录的方式已不合规,且权限申请逻辑不完整 Environment.getExternalStoragePublicDirectory在API 29已被废弃,需改用合规的公共存储写入方式
修复步骤
1. 移除重复的点击事件绑定
删除MainActivity.java中重复的btn_store.setOnClickListener(...)代码块,仅保留一份即可。
2. 适配Scoped Storage,用MediaStore写入公共Documents目录
替换原文件写入逻辑,改用MediaStore API写入公共Documents文件夹,无需特殊MANAGE_EXTERNAL_STORAGE权限,符合Android 10+存储规范:
// 替换原文件写入代码块 String filename = "Inventario.txt"; String content = textToSave + " " + textToSave2; // 使用MediaStore写入公共Documents目录 ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DISPLAY_NAME, filename); values.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain"); values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS); Uri uri = getContentResolver().insert(MediaStore.Files.getContentUri("external"), values); if (uri != null) { try (OutputStream outputStream = getContentResolver().openOutputStream(uri)) { outputStream.write(content.getBytes()); builder2.setMessage("SALVATO"); } catch (IOException e) { e.printStackTrace(); builder2.setMessage("Errore durante il salvataggio del file"); } } else { builder2.setMessage("Impossibile creare il file"); }
需添加的导入:
import android.content.ContentValues; import android.net.Uri; import android.provider.MediaStore; import java.io.OutputStream;
3. 完善权限请求逻辑
相机权限请求
在执行扫码前,先检查并请求CAMERA权限:
private void scanCode() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityResultContracts.RequestPermission requestPermission = new ActivityResultContracts.RequestPermission(); registerForActivityResult(requestPermission, isGranted -> { if (isGranted) { launchScanner(); } else { Toast.makeText(this, "Permesso fotocamera richiesto", Toast.LENGTH_SHORT).show(); } }).launch(Manifest.permission.CAMERA); } else { launchScanner(); } } // 抽离原扫码逻辑为单独方法 private void launchScanner() { ScanOptions options = new ScanOptions(); options.setPrompt("Volume su per la torcia"); options.setBeepEnabled(true); options.setOrientationLocked(true); options.setCaptureActivity(CaptureAct.class); barLauncher.launch(options); }
移除不必要的权限
删除AndroidManifest.xml中的MANAGE_EXTERNAL_STORAGE权限,使用MediaStore无需该权限:
<!-- 移除该行 --> <uses-permission android:name="MANAGE_EXTERNAL_STORAGE"/>
4. 可选:改为追加写入(避免覆盖原有内容)
若需每次保存追加到文件末尾而非覆盖,修改MediaStore写入逻辑:
// 先查询是否已有目标文件 String[] projection = {MediaStore.MediaColumns._ID}; String selection = MediaStore.MediaColumns.DISPLAY_NAME + " = ? AND " + MediaStore.MediaColumns.RELATIVE_PATH + " = ?"; String[] selectionArgs = {filename, Environment.DIRECTORY_DOCUMENTS + "/"}; Cursor cursor = getContentResolver().query(MediaStore.Files.getContentUri("external"), projection, selection, selectionArgs, null); Uri uri = null; if (cursor != null) { if (cursor.moveToFirst()) { long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)); uri = ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), id); } cursor.close(); } if (uri == null) { // 文件不存在,创建新文件 ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DISPLAY_NAME, filename); values.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain"); values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS); uri = getContentResolver().insert(MediaStore.Files.getContentUri("external"), values); } if (uri != null) { try (OutputStream outputStream = getContentResolver().openOutputStream(uri, "wa")) { // 使用"wa"模式追加 outputStream.write((content + "\n").getBytes()); // 换行分隔每条记录 builder2.setMessage("SALVATO"); } catch (IOException e) { e.printStackTrace(); builder2.setMessage("Errore durante il salvataggio del file"); } } else { builder2.setMessage("Impossibile creare il file"); }
验证
修复后,扫描两个条码并点击保存,文件会写入系统Documents文件夹,可通过文件管理器直接访问查看。
内容的提问来源于stack exchange,提问作者Paolo Morello
相关产品推荐
相关产品推荐

