How to access system files in Android? java.io.FileNotFoundException: open failed: EACCES (Permission denied)

Question:

When I try to write something to the COM port via the command line in android, I just write in the shell: echo 123abc > /dev/ttyO0 and I get it in the terminal. It's simple. If I try to do the same in android:

final byte[] request = {0x0A, 0x10, 0, (byte)0x99, 0, 0x01, (byte)0xD0, (byte)0x9D};
    final String comPortAddress = "/dev/ttyO0";
    final OutputStream fileOutputStream = new FileOutputStream(comPortAddress);
    fileOutputStream.write(request);
    fileOutputStream.flush();
    fileOutputStream.close();

Then I get an exception:

W/System.err: java.io.FileNotFoundException: /dev/ttyO0: open failed: EACCES (Permission denied)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:416)
W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:128)
W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:117)
W/System.err:     at keppowertesting.com.modbustesterapp.TryStreams.go(TryStreams.java:15)
W/System.err:     at keppowertesting.com.modbustesterapp.MainActivity.button2Click(MainActivity.java:49)
W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err:     at java.lang.reflect.Method.invoke(Method.java:511)
W/System.err:     at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
W/System.err:     at android.view.View.performClick(View.java:4204)
W/System.err:     at android.view.View$PerformClick.run(View.java:17355)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:725)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err:     at android.os.Looper.loop(Looper.java:137)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5041)
W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err:     at java.lang.reflect.Method.invoke(Method.java:511)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
W/System.err:     at dalvik.system.NativeStart.main(Native Method)
W/System.err: **Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)**
W/System.err:     at libcore.io.Posix.open(Native Method)
W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:400)
W/System.err:   ... 19 more

I have a line in my manifest:

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

But it is clearly not enough. Route access on the device is present.

Answer:

If you use methods available only to root, then add the appropriate line to AndroidManifest.xml :

<uses-permission android:name="android.permission.ACCESS_SUPERUSER">

WRITE_EXTERNAL_STORAGE refers to dangerous permissions, therefore, to obtain this permission (with targetSdk 23 and higher), in addition to the corresponding line in AndroidManifest.xml you must also request this permission from the user at runtime .

Here's a sketchy example of asking for the permission you need:

public class MainActivity extends AppCompatActivity {
    private final int MY_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 1;

    private Button mButton;

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

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != getPackageManager().PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_WRITE_EXTERNAL_STORAGE);
                }
            }
        });


    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_WRITE_EXTERNAL_STORAGE: {
                if (grantResults.length > 0 && grantResults[0] == getPackageManager().PERMISSION_GRANTED) {
                    Toast.makeText(MainActivity.this, "Разрешение получено", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "Разрешение отклонено", Toast.LENGTH_SHORT).show();
                }
                return;
            }
        }
    }
}

When the button is pressed, permission is requested, after the user's reaction, a Toast displayed with information about whether the requested permission has been received or not.

Scroll to Top