javaandroidandroid-permissionsandroid-anr-dialogandroid-storage

Read document file in android R 11 getting java.io.FileNotFoundException: /document/document:3796: open failed: ENOENT (No such file or directory)


Update:

I've edited the readFile method like the following

private void readFile() throws IOException {
        try {

            StringBuilder sb = new StringBuilder();
            String line;

            if (SDK_INT >= Build.VERSION_CODES.R) {

                inputStream = getContentResolver().openInputStream(selectedFileURI);
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

            } else {
                fileReader = new FileReader(file);
                bufferedReader = new BufferedReader(fileReader);
            }
            while ((line = bufferedReader.readLine()) != null) {
               sb.append(line).append("\n");
            }

            activityMainBinding.textView.setText(sb.toString());

        } catch (IOException e) {
            Log.e("IOException", e.getMessage());
            Log.e("IOException2", e.getCause() + "");
            Log.e("IOException3", "exception", e);
            Toast.makeText(MainActivity.this, "Cannot read this file", Toast.LENGTH_LONG).show();

        } finally {
            if (inputStream != null) {
                inputStream.close();
            } else if (bufferedReader != null) {
                bufferedReader.close();
            } else if (fileReader != null) {
                fileReader.close();
            }
        }

    }

the app hanged / stucks and I go this ANR error

  E  ANR in com.filechooserexample.filechooserexample (com.filechooserexample.filechooserexample/.MainActivity)
PID: 27389
Reason: Input dispatching timed out (d457abb com.filechooserexample.filechooserexample/com.filechooserexample.filechooserexample.MainActivity (server) is not responding. Waited 5000ms for KeyEvent)
Parent: com.filechooserexample.filechooserexample/.MainActivity
Load: 16.54 / 17.2 / 15.46
CPU usage from 0ms to 11944ms later (٢٠٢٢-١٠-٠٧ ٢٠:١٩:٢٩.٢٣٣ to ٢٠٢٢-١٠-٠٧ ٢٠:١٩:٤١.١٧٨) with 99% awake:
145% 11791/com.gold.android.youtube: 124% user + 20% kernel / faults: 155587 minor 104 major95% 27389/zygote64: 44% user + 50% kernel / faults: 2262086 minor 43 major
55% 1406/system_server: 31% user + 23% kernel / faults: 27320 minor 58 major37% 585/logd: 12% user + 24% kernel / faults: 5057 minor 16 major
                                                                                                      28% 11830/com.gogoogle.android.gms: 24% user + 4.6% kernel / faults: 11497 minor 27 major
20% 949/adbd: 5.1% user + 15% kernel / faults: 103 minor
17% 27101/us.zoom.videomeetings:conf: 12% user + 5.3% kernel / faults: 8584 minor 61 major
17% 25083/in.sweatco.app: 11% user + 6.3% kernel / faults: 9222 minor 356 major
15% 784/android.hardware.sensors@1.0-service: 6.2% user + 9.7% kernel / faults: 167 minor
15% 2712/com.android.systemui: 12% user + 3.6% kernel / faults: 11269 minor 31 major
9.2% 828/surfaceflinger: 5.6% user + 3.6% kernel / faults: 1925 minor 7 major
9% 152/kswapd0: 0% user + 9% kernel
7.4% 27527/logcat: 2% user + 5.3% kernel / faults: 34 minor
7.4% 29146/logcat: 2.2% user + 5.1% kernel / faults: 34 minor
7% 6362/com.touchtype.swiftkey: 4.7% user + 2.2% kernel / faults: 13363 minor 1729 major
6.4% 9624/com.facebook.orca: 5.5% user + 0.9% kernel / faults: 5959 minor 24 major
6.2% 16749/kworker/u17:0: 0% user + 6.2% kernel
6% 820/audioserver: 4.4% user + 1.5% kernel / faults: 539 minor 7 major
5.5% 695/netd: 4.6% user + 0.8% kernel / faults: 337 minor
5.4% 766/android.hardware.audio.service: 2.1% user + 3.2% kernel / faults: 99 minor 7 major
                                                                                                      5.4% 11039/kworker/u17:1: 0% user + 5.4% kernel
4.8% 456/mmc-cmdqd/0: 0% user + 4.8% kernel
4.1% 17016/com.google.android.as: 1.2% user + 2.8% kernel / faults: 5799 minor 2163 major
4% 1159/media.codec: 2.5% user + 1.5% kernel / faults: 11890 minor 29 major
4% 18095/com.google.android.apps.nexuslauncher: 3% user + 0.9% kernel / faults: 7735 minor 48 major
3.8% 8812/com.facebook.katana: 2.2% user + 1.5% kernel / faults: 6904 minor 22 major                                                     3.4% 777/android.hardware.graphics.composer@2.1-service: 1.9% user + 1.5% kernel / faults: 320 minor
3% 682/lspd: 1% user + 2% kernel / faults: 31 minor

Old question probelm

I am trying to practice on permission and some other component in android, in this app I am trying to get document file path then read it and show it in textview, the code was working normally before android 11 , I know there are some challenges to manage storge in this api, I tried most of ways in this questions:

How can I read a text file in Android?

How to read text file in Android?

Reading a text file line by line in android

but it's gives the same result error

E/IOException: /document/document:3796: open failed: ENOENT (No such file or directory)
E/IOException2: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
E/IOException3: exception
    java.io.FileNotFoundException: /document/document:3796: open failed: ENOENT (No such file or directory)
        at libcore.io.IoBridge.open(IoBridge.java:492)
        at java.io.FileInputStream.<init>(FileInputStream.java:160)
        at java.io.FileReader.<init>(FileReader.java:72)
        at com.filechooserexample.filechooserexample.MainActivity.readFile(MainActivity.java:191)
        at com.filechooserexample.filechooserexample.MainActivity.lambda$onStart$1$com-filechooserexample-filechooserexample-MainActivity(MainActivity.java:122)
        at com.filechooserexample.filechooserexample.MainActivity$$ExternalSyntheticLambda1.onClick(Unknown Source:2)
        at android.view.View.performClick(View.java:7455)
        at android.view.View.performClickInternal(View.java:7432)
        at android.view.View.access$3600(View.java:810)
        at android.view.View$PerformClick.run(View.java:28313)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7663)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
        at libcore.io.Linux.open(Native Method)
        at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
        at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
        at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
        at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7549)
        at libcore.io.IoBridge.open(IoBridge.java:478)
        at java.io.FileInputStream.<init>(FileInputStream.java:160) 
        at java.io.FileReader.<init>(FileReader.java:72) 
        at com.filechooserexample.filechooserexample.MainActivity.readFile(MainActivity.java:191) 
        at com.filechooserexample.filechooserexample.MainActivity.lambda$onStart$1$com-filechooserexample-filechooserexample-MainActivity(MainActivity.java:122) 
        at com.filechooserexample.filechooserexample.MainActivity$$ExternalSyntheticLambda1.onClick(Unknown Source:2) 
        at android.view.View.performClick(View.java:7455) 
        at android.view.View.performClickInternal(View.java:7432) 
        at android.view.View.access$3600(View.java:810) 
        at android.view.View$PerformClick.run(View.java:28313) 
        at android.os.Handler.handleCallback(Handler.java:938) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7663) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

this manifest file

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

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />



    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:requestLegacyExternalStorage="true"
        android:supportsRtl="false"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:theme="@style/AppTheme"
        tools:replace="allowBackup,supportsRtl">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

I used this way to take all permission that needed My main activity

public class MainActivity extends AppCompatActivity {
    private File file;
    private Uri selectedFile;
    private static final int REQUEST_CODE_DOC = 1;

    private static final String TAG = "MainActivity";

    private ActivityMainBinding activityMainBinding = null;

    @Override
    protected void onDestroy() {
        super.onDestroy();
        activityMainBinding = null;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());

        setContentView(activityMainBinding.getRoot());


    }

    @Override
    protected void onStart() {
        super.onStart();
        activityMainBinding.textView.setMovementMethod(new ScrollingMovementMethod());
        activityMainBinding.browseButton.setOnClickListener(view -> {





            browseDocuments();
        });

        activityMainBinding.read.setOnClickListener(view -> {
            if (TextUtils.isEmpty(activityMainBinding.editTextPath.getText())) {
                activityMainBinding.editTextPath.setError("The file path cannot be empty");
            } else {
                readFile();
            }
        });

        activityMainBinding.clear.setOnClickListener(view -> activityMainBinding.textView.setText(null));
    }

    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_DOC && resultCode == Activity.RESULT_OK) {
            
            try {

                if (data != null) {
                    
                    selectedFile = data.getData();
                    file = new File(selectedFile.getPath());
                    activityMainBinding.editTextPath.setText(file.getAbsolutePath());
                    Log.d(TAG, "onActivityResult: " + file.getAbsolutePath());

                } else {
                    Toast.makeText(this, "Allow permission for storage access!", Toast.LENGTH_SHORT).show();
                }

                String mimeType = getContentResolver().getType(selectedFile);
                Log.i("Type of file", mimeType + "");
            } catch (Exception exception) {

                if (exception.getMessage() != null) {

                    Log.e("test Exception", exception.getMessage());

                } else if (exception.getCause() != null) {
                    Log.e("test Exception", Objects.requireNonNull(exception.getCause()).toString());
                }




            }
        }

    }

    public String getPath(Uri uri) {
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
        if (cursor == null) return null;
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String s = cursor.getString(column_index);
        cursor.close();
        return s;
    }


    private void readFile() {
        try {
            FileReader fileReader = new FileReader(file);
            BufferedReader br = new BufferedReader(fileReader);
            String line;
            while ((line = br.readLine()) != null) {
                activityMainBinding.textView.append(line + "\n");
            }
            br.close();
            fileReader.close();
        } catch (IOException e) {
            Log.e("IOException", e.getMessage());
            Log.e("IOException2", e.getCause() + "");
            Log.e("IOException3", "exception", e);
            Toast.makeText(MainActivity.this, "Cannot read this file", Toast.LENGTH_LONG).show();

        }

    }






    private boolean checkPermission() {
        if (SDK_INT >= Build.VERSION_CODES.R) {
            return Environment.isExternalStorageManager();
        } else {
            int result = ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE);
            int result1 = ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE);
            return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
        }
    }

    private void requestPermission() {
        if (SDK_INT >= Build.VERSION_CODES.R) {
            try {
                Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                intent.addCategory("android.intent.category.DEFAULT");
                intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
                startActivityForResult(intent, 1);
            } catch (Exception e) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                startActivityForResult(intent, 1);
            }
        } else {
            
            ActivityCompat.requestPermissions(this, new String[]{READ_EXTERNAL_STORAGE,
                    WRITE_EXTERNAL_STORAGE}, 1);
        }
    }

Solution

  • This method reads the files but it's making the app hanging, I'll post another question about this problem later

    private void readFile() throws IOException {
            try {
    
                StringBuilder sb = new StringBuilder();
                String line;
    
                if (SDK_INT >= Build.VERSION_CODES.R) {
    
                    inputStream = getContentResolver().openInputStream(selectedFileURI);
                    bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    
                } else {
                    fileReader = new FileReader(file);
                    bufferedReader = new BufferedReader(fileReader);
                }
                while ((line = bufferedReader.readLine()) != null) {
                   sb.append(line).append("\n");
                }
    
                activityMainBinding.textView.setText(sb.toString());
    
            } catch (IOException e) {
                Log.e("IOException", e.getMessage());
                Log.e("IOException2", e.getCause() + "");
                Log.e("IOException3", "exception", e);
                Toast.makeText(MainActivity.this, "Cannot read this file", Toast.LENGTH_LONG).show();
    
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                } else if (bufferedReader != null) {
                    bufferedReader.close();
                } else if (fileReader != null) {
                    fileReader.close();
                }
            }
    
        }