Programing

열기 실패 : EACCES (권한 거부 됨)

lottogame 2021. 1. 5. 07:42
반응형

열기 실패 : EACCES (권한 거부 됨)


일부 장치에서 스토리지에 액세스하는 데 매우 이상한 문제가 있습니다. 이 앱은 내 테스트 장치 (Nexus 4 및 7, Samsung GS5)에서 작동합니다. Android 4.4.2를 실행하는 모든 기기. 하지만 사용자들로부터 앱이 저장소 (내부 저장소도 SD 카드도 아님)에 쓸 수 없다는 이메일을 많이 받았습니다. 사용자 피드백에서받은 로그 파일에서 문제가 다음 코드임을 알 수 있습니다.

try {
    if (fStream == null) {
    fStream = new FileOutputStream(filename, true);
}
    fStream.write(data, 0, bytes);
    return;
} catch (IOException ex) {
    ex.printStackTrace();
}

fStream = new FileOutputStream (filename, true); 줄에서 예외가 발생합니다. FileOutputStream을 만들 때.

스택 로그는 다음과 같습니다.

W/System.err( 8147): Caused by: java.io.FileNotFoundException: /storage/emulated/0/my_folder/test_file_name.png: open failed: EACCES (Permission denied)
w/System.err( 8147):    at libcore.io.IoBridge.open(IoBridge.java:409)
W/System.err( 8147):    at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
W/System.err( 8147):    at java.io.FileOutputStream.<init>(FileOutputStream.java:128)
W/System.err( 8147):    at myapp.save(SourceFile:515)
W/System.err( 8147):    ... 8 more
W/System.err( 8147): Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
W/System.err( 8147):    at libcore.io.Posix.open(Native Method)
W/System.err( 8147):    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
W/System.err( 8147):    at libcore.io.IoBridge.open(IoBridge.java:393)
W/System.err( 8147):    ... 11 more

AndroidManifest.xml에는 다음 권한이 선언되어 있습니다.

 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19"/>
    <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

사용자가 SD 카드에서 올바른 앱의 비공개를 사용하고 있음을 확인했습니다. 그리고 더 이상한 점은 내부 저장소에도 쓰지 못한다는 것입니다. 읽기 및 쓰기 권한이 모두있는 경우 어떻게해야합니까? 사용자는 당시 장치를 PC에 연결하지 않는다고 말합니다.

최신 정보

Open and close FileOutputStream을 너무 자주 호출하여 FileNotFoundException을 발생시키는 것으로 나타났습니다. 스레딩 문제처럼 들립니다.


얼마 전에 비슷한 문제가 발생했습니다.

두 가지 다른 영역에 문제가있을 수 있습니다. 쓸 파일을 작성하는 방법이거나 전화에 의존한다는 점에서 작성 방법에 결함이있을 수 있습니다.

SD 카드의 특정 위치에 파일을 쓰는 경우 환경 변수를 사용해보십시오. 항상 유효한 위치를 가리켜 야합니다. 다음은 다운로드 폴더에 쓰는 예입니다.

java.io.File xmlFile = new java.io.File(Environment
    .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
     + "/Filename.xml");

애플리케이션의 내부 저장소에 파일을 쓰는 경우. 이 예를 시도하십시오.

java.io.File xmlFile = new java.io.File((getActivity()
   .getApplicationContext().getFileStreamPath("FileName.xml")
   .getPath()));

개인적으로 파일 스트리밍을 처리하기 위해 외부 라이브러리에 의존합니다. 이것은 아직 나를 실패하지 않았습니다.

org.apache.commons.io.FileUtils.copyInputStreamToFile(is, file);

실패한 쓰기 명령으로 데이터를 너무 많이 잃어 버렸기 때문에 IO 무거운 작업을 위해 잘 알려져 있고 테스트 된 라이브러리에 의존합니다.

파일이 큰 경우 백그라운드에서 IO를 실행하거나 콜백을 사용할 수도 있습니다.

이미 환경 변수를 사용하고 있다면 권한 문제 일 수 있습니다. 아래 Justin Fiedler의 답변을 확인하십시오.


API 23+의 경우 이미 매니페스트에 있더라도 읽기 / 쓰기 권한을 요청해야합니다.

// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};

/**
 * Checks if the app has permission to write to device storage
 *
 * If the app does not has permission then the user will be prompted to grant permissions
 *
 * @param activity
 */
public static void verifyStoragePermissions(Activity activity) {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(
                activity,
                PERMISSIONS_STORAGE,
                REQUEST_EXTERNAL_STORAGE
        );
    }
}

AndroidManifest.xml

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

기본적으로 Android Q대상으로하는 앱 에는 외부 저장소에 대한 필터링 된보기가 제공됩니다. 이에 대한 빠른 수정은 AndroidManifest.xml에 다음 코드를 추가하는 것입니다.

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

여기에서 자세히 알아보세요 : https://developer.android.com/preview/privacy/scoped-storage


제 경우에는 잘못된 경우가있었습니다.

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

android.permission 소문자 여야하고 소스에서 전체 문자열이 대문자 여야합니다.


I also faced the same issue. After lot of hard work, I found what was wrong in my case. My device was connected to computer via USB cable. There are types for USB connections like Mass Storage, Media Device(MTP), Camera(PTP) etc. My connection type was - 'Mass Storage', and this was causing the problems. When I changed the connection type, the issue was solved.

Always remember while accessing filesystem on android device :-

DON'T CONNECT AS MASS STORAGE to the computer/pc.


In my case it was permissions issue. The catch is that on device with Android 4.0.4 I got access to file without any error or exception. And on device with Android 5.1 it failed with ACCESS exception (open failed: EACCES (Permission denied)). Handled it with adding follow permission to manifest file:

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

So I guess that it's the difference between permissions management in OS versions that causes to failures.


First give or check permissions like

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

If these two permissions are OK, then check your output streams are in correct format.

Example:

FileOutputStream fos=new FileOutputStream(Environment.getExternalStorageDirectory()+"/rahul1.jpg");

I ran into the same problem and found that I have to request the permissions at run time, even if I have declared it in the manifest. Just as stated as Justin Fiedler's answer.

The official documentation about this are here: https://developer.android.com/training/permissions/requesting.html

My implementation is slightly different from Justin Fiedler's answer that it also implement v4 fragment's onRequestPermissionsResult method to handle the permissions request response.

public static final int REQUEST_EXTERNAL_PERMISSION_CODE = 666;

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public static final String[] PERMISSIONS_EXTERNAL_STORAGE = {
        READ_EXTERNAL_STORAGE,
        WRITE_EXTERNAL_STORAGE
};

public boolean checkExternalStoragePermission(Activity activity) {
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
        return true;
    }

    int readStoragePermissionState = ContextCompat.checkSelfPermission(activity, READ_EXTERNAL_STORAGE);
    int writeStoragePermissionState = ContextCompat.checkSelfPermission(activity, WRITE_EXTERNAL_STORAGE);
    boolean externalStoragePermissionGranted = readStoragePermissionState == PackageManager.PERMISSION_GRANTED &&
            writeStoragePermissionState == PackageManager.PERMISSION_GRANTED;
    if (!externalStoragePermissionGranted) {
        requestPermissions(PERMISSIONS_EXTERNAL_STORAGE, REQUEST_EXTERNAL_PERMISSION_CODE);
    }

    return externalStoragePermissionGranted;
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        if (requestCode == REQUEST_EXTERNAL_PERMISSION_CODE) {
            if (checkExternalStoragePermission(getActivity())) {
                // Continue with your action after permission request succeed
            }
        }
    }
}

In my case I used the option android:isolatedProcess="true" for a service in the AndroidManifest.xml.

As soon as I removed it, the error disappeared...


Also I found solving for my way.

Before launch app i granted root to file-explorer and did not disable permission on write/read when exit from app.

My app can not use external memory while i did restrat device for resetting all permissions.


I got the same issue but Sometimes, the most dificult issue get simple answer.

I recheck the manifest permisions and there WAS_NOT write permision shame of me!!!


If the clients are using Android 6.0, Android added new permission model for (Marshmallow).

Trick: If you are targeting version 22 or below, your application will request all permissions at install time just as it would on any device running an OS below Marshmallow


In my case the issue was the WIFI Configuration that was static had a conflict with another device using the same IP Address.


@Uriel Frankel is correct that the Android 10 storage access has changed. But the right way is not to use legacy storage flag but to request the storage of your app like so:

val screenShotDirPath = getApplication<Application>().getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.path

getExternalFilesDir is what you need.


in my case i forgot to add / in front of file name after i added i got rid of from it

bitmap.compress(Bitmap.CompressFormat.PNG,100,new FileOutputStream(Environment.getExternalStorageDirectory()+"/arjunreddy.png"));

ReferenceURL : https://stackoverflow.com/questions/23527767/open-failed-eacces-permission-denied

반응형