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

huangapple go评论65阅读模式
英文:

Android - How can I read text files from external storage

问题

我是相对新手的Android Studio尝试运行下面的代码以访问和读取外部存储中的.txt文件并相应地设置我的textView区域您可以在下面看到有关问题的详细说明

```java
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;
    }
}

我可以访问文件并查看目录,但是文本文件中的字符串没有设置在textView中。

简而言之,performFileSearch() 的工作正常,但是 readText(String input) 不起作用。LOGCAT 显示以下行的错误:

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

由于有问题的 BufferedReader 行,会发生 FileNotFound 异常,如下所示:

java.io.FileNotFoundException: /storage/emulated/0/document/acc=1;doc=encoded=yGpDfmZooF+Ikc2k92OckqR7fUXB5WDXoFvDOrmxSLkLTN2N2r8= (No such file or directory)

我已经在 AndroidManifest.xml 中包含了权限:


您可以查看下面的日志,任何帮助都将不胜感激。

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.(FileInputStream.java:146)
...
(以下省略)


<details>
<summary>英文:</summary>
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. 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 &gt;= Build.VERSION_CODES.M &amp;&amp; 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(), &quot;devices&quot;).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(&quot;\n&quot;);
}
br.close();
}catch (IOException e){
e.printStackTrace();
Log.e(&quot;Exception caught&quot;, e.toString());
}
return text.toString();
}
private void performFileSearch (){
Intent intent = new Intent (Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(&quot;text/*&quot;);
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 &amp;&amp; resultCode == Activity.RESULT_OK) {
if (data != null) {
Uri uri = data.getData();
String path = uri.getPath();
if (path.contains(&quot;emulated&quot;)) {
path = path.substring(path.indexOf(&quot;0&quot;) + 1);
}
path = path.substring(path.indexOf(&quot;:&quot;) + 1);
Toast.makeText(this, &quot;&quot; + path, Toast.LENGTH_SHORT).show();
tv_output.setTextColor(Color.RED);
String s = &quot;abc&quot;;
tv_output.setText(readText(path));
System.out.println(&quot;read loop activated&quot;);
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, &quot;Permission granted!&quot;, Toast.LENGTH_SHORT).show();
System.out.println(&quot;Permission Granted&quot;);
} else{
Toast.makeText(this, &quot;Permission not granted!&quot;, Toast.LENGTH_SHORT).show();
System.out.println(&quot;Permission Granted&quot;);
finish();
}
}
}
@Override
public void onBackStackChanged() {
getSupportActionBar().setDisplayHomeAsUpEnabled(getSupportFragmentManager().getBackStackEntryCount()&gt;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.
Shortly, performFileSearch() works as expected however readText (String input) doesnt work. LOGCAT shows error for the following lines;
1)  BufferedReader br = new BufferedReader(new FileReader(file));
2)  tv_output.setText(readText(path));
and FileNotFound Exception occurs due to problematic BufferedReader line, as follow;
java.io.FileNotFoundException: /storage/emulated/0/document/acc=1;doc=encoded=yGpDfmZooF+Ikc2k92OckqR7fUXB5WDXoFvDOrmxSLkLTN2N2r8= (No such file or directory)
I have already included permissions in AndroidManifest.xml;
&lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot;/&gt;
&lt;uses-permission android:name = &quot;android.permission.WRITE_EXTERNAL_STORAGE&quot;/&gt;
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.&lt;init&gt;(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.&lt;init&gt;(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&#160;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.&lt;init&gt;(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.&lt;init&gt;(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&#160;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
</details>
# 答案1
**得分**: 1
```java
Uri uri = data.getData();
现在直接使用这个 uri 调用
readText(uri);
在 readText( Uri uri) 函数中,使用 InputStream 而不是 FileReader 打开一个输入流。
InputStream is = getContentResolver().openInputStream(uri);
然后从 is 中读取,就像你之前从文件读取器中尝试的一样。
BufferedReader br = new BufferedReader(is);
英文:
 Uri uri = data.getData();

Now use that uri directly in a call to

 readText(uri);

And in that function readText( Uri uri) open an InputStream instead of that FileReader.

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

Then read from is like you tried from file reader.

BufferedReader br = new BufferedReader(is); 

答案2

得分: 0

安装完文件管理器(ES文件管理器 | 文件浏览器)后,我可以读取 .txt 文件并相应地设置 textView。您需要第三方文件管理器。

英文:

After installing File Manager (ES File Manager | File Explorer), I am able to read the .txt file and set the textView accordingly. You need 3rd party file manager.

huangapple
  • 本文由 发表于 2020年9月15日 21:51:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63903385.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定