Resolving java.io.FileNotFoundException: EACCES (Permission denied) in Android Development

Nov 27, 2025 · Programming · 10 views · 7.8

Keywords: Android Permissions | Runtime Permissions | File Operations | EACCES Error | External Storage

Abstract: This technical article provides an in-depth analysis of the common java.io.FileNotFoundException: EACCES (Permission denied) error in Android development. Focusing on the runtime permissions mechanism introduced in Android 6.0 and above, it offers detailed code examples and permission request workflows to help developers properly handle external storage read/write permissions in modern Android systems.

Problem Background and Error Analysis

File operations are common requirements in Android application development. However, many developers encounter the java.io.FileNotFoundException: /storage/emulated/0/New file.txt: open failed: EACCES (Permission denied) error when attempting to read or write to external storage. This error indicates that the application lacks sufficient permissions to access the specified file path.

Evolution of Android Permission Mechanism

The permission management system in Android has undergone significant changes. Before Android 6.0 Marshmallow (API 23), applications requested all declared permissions during installation. Starting from Android 6.0, the system introduced runtime permissions, requiring dynamic user authorization for dangerous permissions such as storage read/write operations.

Runtime Permissions Implementation

To resolve the EACCES error, developers need to implement runtime permission requests in their code. Here's a comprehensive permission request example:

public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_STORAGE_PERMISSION = 1;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // Check permission status
        if (ContextCompat.checkSelfPermission(this, 
            Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            
            // Request permission
            ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_STORAGE_PERMISSION);
        } else {
            // Permission already granted, perform file operation
            performFileOperation();
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_STORAGE_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted, perform file operation
                performFileOperation();
            } else {
                // Permission denied, notify user
                Toast.makeText(this, "Storage permission denied, cannot perform file operation", Toast.LENGTH_LONG).show();
            }
        }
    }
    
    private void performFileOperation() {
        // Execute specific file encryption operation
        String filePath = editText.getText().toString();
        EncAndDec.encrypt(aesKey, filePath);
    }
}

Best Practices for Permission Requests

When implementing runtime permissions, consider the following best practices:

Storage Restrictions in Android 10 and Above

Starting from Android 10 (API 29), Google introduced Scoped Storage, further restricting application access to external storage. While runtime permissions remain necessary, applications can only access their own dedicated directories and specific types of media files by default.

Compatibility Considerations

For applications requiring backward compatibility, you can temporarily disable scoped storage by adding the android:requestLegacyExternalStorage="true" attribute in AndroidManifest.xml:

<application
    android:allowBackup="true"
    android:requestLegacyExternalStorage="true"
    ...>

However, note that starting from Android 11, the effectiveness of this flag is limited, and developers should gradually migrate to using Scoped Storage APIs.

Conclusion

The key to resolving the java.io.FileNotFoundException: EACCES (Permission denied) error lies in properly implementing Android's runtime permissions mechanism. Developers need to understand the evolution of Android's permission system, dynamically request necessary permissions in their code, and appropriately handle various permission grant and denial scenarios. As Android systems continue to evolve, timely adaptation to new storage access strategies is crucial for ensuring smooth application operation.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.