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

Android 11选择存储CSV文件后应用自动关闭问题求助

问题:Android 11设备选中CSV文件后应用闪退,ActivityResultLauncher未触发

在Android 11设备开发应用时,尝试读取存储中的CSV文件,打开文件选择器并选中文件后应用自动关闭。已在AndroidManifest.xml中声明READ_EXTERNAL_STORAGE权限且申请了运行时权限,但无任何异常或错误提示,同时activityResultLauncher未被调用。


相关代码

UnitTestMarksActivity.java

package com.suyogbauskar.attenteachers;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.PopupMenu;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.suyogbauskar.attenteachers.pojos.StudentData;
import com.suyogbauskar.attenteachers.pojos.UnitTestMarks;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

import cn.pedant.SweetAlert.SweetAlertDialog;

public class UnitTestMarksActivity extends AppCompatActivity {

private Button uploadBtn;
private int selectedSemester;
private FirebaseUser user;
private TableLayout table;
private boolean isFirstRow;
private String subjectCodeTeacher;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_unit_test_marks);
    setTitle("Unit Test Marks");
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    init();
}

private void init() {
    user = FirebaseAuth.getInstance().getCurrentUser();
    findAllViews();
    uploadBtn.setOnClickListener(view -> uploadFile());
}

private void findAllViews() {
    uploadBtn = findViewById(R.id.uploadBtn);
}

ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> {
            if (result.getResultCode() == Activity.RESULT_OK) {
                Toast.makeText(UnitTestMarksActivity.this, "Success", Toast.LENGTH_SHORT).show();
            }
        }
);

private void uploadFile() {
    Intent data = new Intent(Intent.ACTION_GET_CONTENT);
    Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath());
    data.setDataAndType(uri, "text/csv");
    data = Intent.createChooser(data, "Choose unit test marks");
    activityResultLauncher.launch(data);
}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission
        android:name="com.google.android.gms.permission.AD_ID"
        tools:node="remove" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:requestLegacyExternalStorage="true"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AttenTeachers"
        tools:targetApi="31">
        <activity
            android:name=".UnitTestMarksActivity"
            android:exported="false"
            android:noHistory="true"/>
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:noHistory="true"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

应用闪退演示

应用闪退演示


修复方案

1. 移除android:noHistory="true"属性

UnitTestMarksActivity的Manifest配置中添加了android:noHistory="true",该属性会让Activity在离开(比如启动文件选择器)时被系统销毁,导致返回时找不到原Activity,直接引发闪退。

修改后的Activity配置:

<activity
    android:name=".UnitTestMarksActivity"
    android:exported="false"/>

2. 调整文件选择Intent写法

Android 11及以上版本禁止直接通过Environment.getExternalStorageDirectory()指定路径,且ACTION_GET_CONTENT无需设置初始Uri,正确写法如下:

private void uploadFile() {
    Intent data = new Intent(Intent.ACTION_GET_CONTENT);
    data.setType("text/csv");
    data.addCategory(Intent.CATEGORY_OPENABLE);
    Intent chooser = Intent.createChooser(data, "Choose unit test marks");
    activityResultLauncher.launch(chooser);
}

3. 补充权限校验(可选)

虽然已申请运行时权限,可在打开文件选择器前添加权限校验,确保权限已获取:

private void uploadFile() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        ActivityResultLauncher<String> permissionLauncher = registerForActivityResult(
                new ActivityResultContracts.RequestPermission(),
                isGranted -> {
                    if (isGranted) {
                        openFileChooser();
                    } else {
                        Toast.makeText(this, "需要存储权限才能读取文件", Toast.LENGTH_SHORT).show();
                    }
                }
        );
        permissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
        return;
    }
    openFileChooser();
}

private void openFileChooser() {
    Intent data = new Intent(Intent.ACTION_GET_CONTENT);
    data.setType("text/csv");
    data.addCategory(Intent.CATEGORY_OPENABLE);
    Intent chooser = Intent.createChooser(data, "Choose unit test marks");
    activityResultLauncher.launch(chooser);
}

内容的提问来源于stack exchange,提问作者Suyog

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:45:53