简体   繁体   English

Android - 如何从外部存储读取文本文件

[英]Android - How can I read text files from external storage

I am relatively new to Android Studio and trying to run code below in order to access and read .txt file and set my textView area accordingly from external storage.我对 Android Studio 比较陌生,并尝试运行下面的代码以访问和读取 .txt 文件并相应地从外部存储设置我的 textView 区域。 You can see detailed explation of the problem below;您可以在下面看到问题的详细解释;

package simple_bluetooth_terminal;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentManager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener {

    private static final int PERMISSION_REQUEST_STORAGE = 1000;
    private static final int READ_REQUEST_CODE = 42;
    Button b_load;
    TextView tv_output;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
        {
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_STORAGE);
        }

        b_load = (Button) findViewById(R.id.read);
        tv_output = (TextView) findViewById(R.id.textView);
        b_load.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            performFileSearch();
            }
        });
        setSupportActionBar(toolbar);
        getSupportFragmentManager().addOnBackStackChangedListener(this);
        if (savedInstanceState == null)
            getSupportFragmentManager().beginTransaction().add(R.id.fragment, new DevicesFragment(), "devices").commit();
        else
            onBackStackChanged();
    }

    private String readText (String input) {
        File file = new File (Environment.getExternalStorageDirectory(),input);
        StringBuilder text = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));

            String line;
            while ((line=br.readLine())!=null){
                text.append(line);
                System.out.println(line);
                text.append("\n");
            }
            br.close();
        }catch (IOException e){
            e.printStackTrace();
            Log.e("Exception caught", e.toString());
        }
        return text.toString();
    }

  
    private void performFileSearch (){
        Intent intent = new Intent (Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("text/*");
        startActivityForResult(intent, READ_REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
            if (data != null) {
                Uri uri = data.getData();
                String path = uri.getPath();
                if (path.contains("emulated")) {
                    path = path.substring(path.indexOf("0") + 1);
                }
                path = path.substring(path.indexOf(":") + 1);
                Toast.makeText(this, "" + path, Toast.LENGTH_SHORT).show();
                tv_output.setTextColor(Color.RED);
                String s = "abc";

                tv_output.setText(readText(path));
                System.out.println("read loop activated");
                System.out.println(s);
                System.out.println(readText(path));

            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode== PERMISSION_REQUEST_STORAGE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                Toast.makeText(this, "Permission granted!", Toast.LENGTH_SHORT).show();
                System.out.println("Permission Granted");
            } else{
                Toast.makeText(this, "Permission not granted!", Toast.LENGTH_SHORT).show();
                System.out.println("Permission Granted");
                finish();
            }
        }
    }

    @Override
    public void onBackStackChanged() {
        getSupportActionBar().setDisplayHomeAsUpEnabled(getSupportFragmentManager().getBackStackEntryCount()>0);
    }

    @Override
    public boolean onSupportNavigateUp() {
        onBackPressed();
        return true;
    }

}

I can access the file and see the directory however string in text file is not set in textView.我可以访问文件并查看目录,但是文本文件中的字符串未在 textView 中设置。

Shortly, performFileSearch() works as expected however readText (String input) doesnt work.很快, performFileSearch() 按预期工作,但 readText(字符串输入)不起作用。 LOGCAT shows error for the following lines; LOGCAT 显示以下行的错误;

  1. BufferedReader br = new BufferedReader(new FileReader(file)); BufferedReader br = new BufferedReader(new FileReader(file));
  2. tv_output.setText(readText(path)); tv_output.setText(readText(path));

and FileNotFound Exception occurs due to problematic BufferedReader line, as follow;由于有问题的 BufferedReader 行出现 FileNotFound 异常,如下;

java.io.FileNotFoundException: /storage/emulated/0/document/acc=1;doc=encoded=yGpDfmZooF+Ikc2k92OckqR7fUXB5WDXoFvDOrmxSLkLTN2N2r8= (No such file or directory) java.io.FileNotFoundException: /storage/emulated/0/document/acc=1;doc=encoded=yGpDfmZooF+Ikc2k92OckqR7fUXB5WDXoFvDOrmxSLkLTN2N2r8=(没有这样的文件或目录)

I have already included permissions in AndroidManifest.xml;我已经在 AndroidManifest.xml 中包含了权限;

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>

You can check log below, any help would be highly appreciated.您可以查看下面的日志,任何帮助将不胜感激。

2020-09-15 16:26:00.442 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err: java.io.FileNotFoundException: /storage/emulated/0/document/acc=1;doc=encoded=yGpDfmZooF+Ikc2k92OckqR7fUXB5WDXoFvDOrmxSLkLTN2N2r8= (No such file or directory)
2020-09-15 16:26:00.442 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at java.io.FileInputStream.open(Native Method)
2020-09-15 16:26:00.442 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at java.io.FileInputStream.<init>(FileInputStream.java:146)
2020-09-15 16:26:00.442 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at java.io.FileReader.<init>(FileReader.java:72)
2020-09-15 16:26:00.442 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at de.kai_morich.simple_bluetooth_terminal.MainActivity.readText(MainActivity.java:74)
2020-09-15 16:26:00.442 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at de.kai_morich.simple_bluetooth_terminal.MainActivity.onActivityResult(MainActivity.java:114)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.Activity.dispatchActivityResult(Activity.java:7010)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread.deliverResults(ActivityThread.java:4187)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread.handleSendResult(ActivityThread.java:4234)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread.-wrap20(ActivityThread.java)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1584)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.os.Looper.loop(Looper.java:154)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6316)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
2020-09-15 16:26:00.443 24764-24764/de.kai_morich.simple_bluetooth_terminal E/Exception caught: java.io.FileNotFoundException: /storage/emulated/0/document/acc=1;doc=encoded=yGpDfmZooF+Ikc2k92OckqR7fUXB5WDXoFvDOrmxSLkLTN2N2r8= (No such file or directory)
2020-09-15 16:26:00.444 24764-24764/de.kai_morich.simple_bluetooth_terminal I/System.out: read loop activated
2020-09-15 16:26:00.444 24764-24764/de.kai_morich.simple_bluetooth_terminal I/System.out: abc
2020-09-15 16:26:00.447 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err: java.io.FileNotFoundException: /storage/emulated/0/document/acc=1;doc=encoded=yGpDfmZooF+Ikc2k92OckqR7fUXB5WDXoFvDOrmxSLkLTN2N2r8= (No such file or directory)
2020-09-15 16:26:00.447 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at java.io.FileInputStream.open(Native Method)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at java.io.FileInputStream.<init>(FileInputStream.java:146)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at java.io.FileReader.<init>(FileReader.java:72)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at de.kai_morich.simple_bluetooth_terminal.MainActivity.readText(MainActivity.java:74)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at de.kai_morich.simple_bluetooth_terminal.MainActivity.onActivityResult(MainActivity.java:117)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.Activity.dispatchActivityResult(Activity.java:7010)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread.deliverResults(ActivityThread.java:4187)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread.handleSendResult(ActivityThread.java:4234)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread.-wrap20(ActivityThread.java)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1584)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.os.Looper.loop(Looper.java:154)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6316)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
2020-09-15 16:26:00.448 24764-24764/de.kai_morich.simple_bluetooth_terminal W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
2020-09-15 16:26:00.449 24764-24764/de.kai_morich.simple_bluetooth_terminal E/Exception caught: java.io.FileNotFoundException: /storage/emulated/0/document/acc=1;doc=encoded=yGpDfmZooF+Ikc2k92OckqR7fUXB5WDXoFvDOrmxSLkLTN2N2r8= (No such file or directory)
2020-09-15 16:26:00.472 24764-24787/de.kai_morich.simple_bluetooth_terminal D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000
2020-09-15 16:26:00.498 24764-24787/de.kai_morich.simple_bluetooth_terminal D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000
2020-09-15 16:26:00.544 24764-24764/de.kai_morich.simple_bluetooth_terminal I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@249dda8 time:23517629
 Uri uri = data.getData();

Now use that uri directly in a call to现在直接在调用中使用该 uri

 readText(uri);

And in that function readText( Uri uri) open an InputStream instead of that FileReader.在该函数中 readText(Uri uri) 打开一个 InputStream 而不是那个 FileReader。

 InputStream is = getContentResolver().openInputStream(uri);

Then read from is like you tried from file reader.然后读取就像您从文件阅读器中尝试过一样。

BufferedReader br = new BufferedReader(is); 

After installing File Manager (ES File Manager | File Explorer), I am able to read the .txt file and set the textView accordingly.安装文件管理器(ES 文件管理器 | 文件资源管理器)后,我可以读取 .txt 文件并相应地设置 textView。 You need 3rd party file manager.您需要第 3 方文件管理器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM