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

做~自己de王妃 提交于 2019-12-13 03:55:18

问题


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();
                }
            }
        }
    }
}

回答1:


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.




回答2:


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();



来源:https://stackoverflow.com/questions/58935670/java-io-filenotfoundexception-sdcard-testwrite-txt-open-failed-eacces-permi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!