IT story

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

hot-time 2020. 12. 29. 07:54
반응형

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


나는 uses-permission포함 하여 .WRITE_EXTERNAL_STORAGEMOUNT_UNMOUNT_FILESYSTEMSREAD_EXTERNAL_STORAGEAndroidManifest.xml

Nexus5 (Android 6.0)에서 내 애플리케이션을 실행하려고 할 때 아래와 같은 예외가 발생했습니다.

java.io.IOException: open failed: EACCES (Permission denied)

그리고 다른 안드로이드 폰 (안드로이드 5.1)을 시도했는데, 모든 것이 정상입니다.

private File createImageFile() throws IOException {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(imageFileName, ".jpg", storageDir);
    currentPhotoPath = image.getAbsolutePath();
    return image;
}

Android 6.0은 권한에 차이가 있습니까?


Android는 Android 6.0 (Marshmallow)에 대한 새로운 권한 모델을 추가했습니다 .

http://www.captechconsulting.com/blogs/runtime-permissions-best-practices-and-how-to-gracefully-handle-permission-removal

따라서 다음을 확인해야합니다 Runtime Permission.

런타임 권한이란 무엇입니까?

Android 6.0 Marshmallow에서 Google은 사용자가 애플리케이션이 특정 권한을 요청하는 이유를 더 잘 이해할 수있는 새로운 권한 모델을 도입했습니다. 사용자가 설치시 모든 권한을 맹목적으로 수락하는 대신 응용 프로그램 사용 중에 필요한 권한을 수락하라는 메시지가 사용자에게 표시됩니다.

새 모델을 언제 구현해야합니까?

애플리케이션에서 버전 23을 대상으로 선택하기 전까지는 완전한 지원이 필요하지 않습니다. 버전 22 이하를 대상으로하는 경우 애플리케이션은 Marshmallow 이하의 OS를 실행하는 모든 장치에서와 마찬가지로 설치시 모든 권한을 요청합니다.

이 정보는 여기에서 가져 왔습니다.

이 링크에서 구현 방법을 확인하십시오.

http://www.captechconsulting.com/blogs/runtime-permissions-best-practices-and-how-to-gracefully-handle-permission-removal


에서 안드로이드 6 (산들 바람) 에도 불구하고, 사용자는 설치시 모든 권한, 그들은 나중에 멀리에서 그 권한의 일부를 가지고 결정할 수 있습니다 받아 들였다.

빠른 솔루션이 아닌 권장 : 당신이 당신을 변경 어쩌면 경우 targetSdkVersion위해 Gradle을에 22, 문제가 해결 될 것입니다.

구현 방법 (모범 사례)

  1. 먼저 사용자의 기기가 Marshmallow 기기인지 확인합니다.

    private boolean shouldAskPermission(){
    
    return(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1);
    
    }
    
  2. 경우 shouldAskPermission()반환 true허가 요청이 필요합니다

    String[] perms = {"android.permission.WRITE_EXTERNAL_STORAGE"};
    
    int permsRequestCode = 200;
    
    requestPermissions(perms, permsRequestCode);
    

이 메서드 requestPermissions(String[] permissions, int requestCode);는 Android Activity 클래스 내부에있는 공개 메서드입니다.

  1. 아래와 같이 onRequestPermissionResult 메서드에서 요청 결과를 받게됩니다.

    @Override
    public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
    
    switch(permsRequestCode){
    
        case 200:
    
            boolean writeAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
    
            break;
    
    }
    
    }
    

결과를받은 후 적절하게 처리해야합니다.

제안 된 권한 흐름 :

여기에 이미지 설명 입력

더 많은 정보:

Marshmallow 기기를 사용하는 사용자는 이제 애플리케이션 설정을 통해 위험한 권한 을 취소 할 수 있습니다.

Android는 일부 권한을 ' 위험 ' 으로 정의 하고 일부 권한을 ' 정상 ' 으로 정의합니다 . 둘 다 애플리케이션의 매니페스트에 필요하지만 위험한 권한에만 런타임 요청이 필요합니다.

새로운 권한 모델 (런타임 요청)을 구현하지 않기로 선택한 경우 권한 취소로 인해 원치 않는 사용자 경험이 발생하고 경우에 따라 애플리케이션이 중단 될 수 있습니다.

아래 표에는 현재의 모든 위험한 권한과 해당 그룹이 나열되어 있습니다.

여기에 이미지 설명 입력

사용자가 그룹 / 카테고리에서 하나의 권한을 수락하면 전체 그룹을 수락합니다!

출처 : http://www.captechconsulting.com

Dexter 라이브러리 사용 :

You can use Dexter. Android library that simplifies the process of requesting permissions at runtime.


You can also use ActivityCompat.requestPermissions for backwards compatible.

example:

private static final int REQUEST_CODE = 0x11;

String[] permissions = {"android.permission.WRITE_EXTERNAL_STORAGE"};
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE); // without sdk version check

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode == REQUEST_CODE) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // save file
        } else {
            Toast.makeText(getApplicationContext(), "PERMISSION_DENIED", Toast.LENGTH_SHORT).show();
        }
    }
}

From API-23 you need to declare the permission in activity even if you have already declared in manifest.

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

//persmission method.
 public static void verifyStoragePermissions(Activity activity) {
    // Check if we have read or write permission
    int writePermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    int readPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);

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

To use simply call verifyStoragePermissions(this); in onCreate. That should do it hopefully.


If you are lazy, just downgrade targetSdkVersion to 22 (before lollipop)


This worked for me.

Go to Settings -> Applications -> YourApp -> Provide permissions to Storage, Contacts etc.


For me, my phone connected as USB as MTP was the issue even after doing everything stated here. Switched it to "Charging Only" worked for me.


I met the same trouble.

전화 보안 메커니즘 때문일 수 있습니다. 쓰기 / 읽기 권한을 승인하려면 '설정'으로 이동할 수 있습니다.

참조 URL : https://stackoverflow.com/questions/33030933/android-6-0-open-failed-eacces-permission-denied

반응형