简体   繁体   中英

java.io.FileNotFoundException: /sdcard/testwrite.txt: open failed: EACCES (Permission denied)

Please Help.

I am developing Android App.

Here is the problem. I can't write a file at /sdcard. what is wrong?

Developement tool: Android studio 3.5.2

Device: AVD Pixel 2 API 29

I coded Permission Request . I can write a file with old android device. Why I can't write with this device?

Please Help.

Error Log

E: Unknown bits set in runtime_flags: 0x8000
E: --> WRITE_EXTERNAL_STORAGE=true
E: --> READ_EXTERNAL_STORAGE=true
E: ====================================================================
E: --> TEST: Writing.. /sdcard/testwrite.txt
E: --> Writing..
E: --> Error..
E: java.io.FileNotFoundException: /sdcard/testwrite.txt: open failed: EACCES (Permission denied)

AndroidManifest.xml

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

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

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

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

</manifest>

MainActivity.java

package com.myapp.TestWrite;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.util.Log;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate( Bundle savedInstanceState ) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main );

        Log.wtf( "TAG", "--> WRITE_EXTERNAL_STORAGE=" + hasPermission( Manifest.permission.WRITE_EXTERNAL_STORAGE ) );
        Log.wtf( "TAG", "--> READ_EXTERNAL_STORAGE=" + hasPermission( Manifest.permission.READ_EXTERNAL_STORAGE ) );

        if( Build.VERSION.SDK_INT >= 23 )
        if( hasPermission( Manifest.permission.WRITE_EXTERNAL_STORAGE ) )
        if( hasPermission( Manifest.permission.READ_EXTERNAL_STORAGE ) ) {
            writeTest( "/sdcard/testwrite.txt" );
            return;
        }

        Log.wtf( "TAG", "--> Request permission\n" );
        ActivityCompat.requestPermissions(
                this,
                new String[]{
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE
                },
                1
        );
    }

    void writeTest( String fn ) {
        Log.wtf( "TAG", "====================================================================" );
        Log.wtf( "TAG", "--> TEST: Writing.. " + fn );
        File file = new File( fn );
        try {
            Log.wtf( "TAG", "--> Writing.." );;
            FileWriter fw = new FileWriter(file, false);
            fw.write( "Test Doc !!!!!" );
            fw.close();
            Log.wtf( "TAG", "--> Success.." );
        } catch( IOException e) {
            e.printStackTrace();
            Log.wtf( "TAG", "--> Error.." );
            Log.wtf( "TAG", e.toString() );
        }
    }

    public boolean hasPermission( String strPerm ) {
        if ( ContextCompat.checkSelfPermission( this, strPerm ) == PackageManager.PERMISSION_GRANTED )
            return true;
        return false;
    }

    @Override
    public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults ) {
        Log.wtf( "TAG", ":onRequestPermissionsResult\n" );
        switch ( requestCode ) {
            case 1:
            {
                // If request is cancelled, the result arrays are empty.
                if ( grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED ) {
                    Log.wtf( "TAG", "--> Permission granted.\n" );
                    finish();
                    startActivity( getIntent() );
                }
                else {
                    Log.wtf( "TAG", "--> Permission denied. Quitting.\n" );
                    finish();
                }
            }
        }
    }
}

You're running your app in Android 10 without including the legacy support attribute in your manifest. Edit your manifest as per the suggestion below:

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10 or higher. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

( source )

Note that is is only a temporary fix, since this is going to default to false with the release of the next android version. If the files are private to your app, consider acquiring the path dynamically using getExternalFilesDir() . read more about the scoped storage changes in the developers' website .

You should try to create file in device first and check the path with pwd .
It might not /sdcard/testwrite.txt .

How about using one of the following code?

        /** internal: start with /data/user/0/{applicationId}/ */
        String cacheDirPath = mStorageManager.getCachedDir().getPath();

        String filesDirPath = mStorageManager.getFileDir().getAbsolutePath();

        String dirNamePath = mStorageManager.getDir("dirname").getPath();

        String codeCacheDirPath = mStorageManager.getCodeCacheDir().getPath();

        String noBackupFilesDir = mStorageManager.getNoBackupFilesDir().getPath();

        /** external start with /storage/emulated/0/Android/data/ */
        String externalCacheDirPath = mStorageManager.getExternalCacheDir().getPath();

        String externalFilesDirPath = mStorageManager.getExternalFilesDir().getPath();

        /** obb start with /storage/emulated/0/Android/obb/ */
        String obbDirPath = mStorageManager.getObbDir().getPath();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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