You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:22:04