5

DownloadManager를 사용하여 샘플 PDF 파일을 다운로드 디렉토리에 다운로드하는 Android 앱을 프로그래밍했습니다. 코드는 다음과 같습니다.다운로드 관리자 Android 권한 오류 : 외부 저장소 쓰기

이제 내 Xperia Z3 Android 6.0의 Android Studio에서 디버깅을 시도했습니다. 나는 다운로드 버튼 클릭으로 이 오류가 발생합니다

대상 VM, 주소에서 연결이 끊긴
E/AndroidRuntime: FATAL EXCEPTION: main 
       Process: com.example.markwitt.schul_app, PID: 29297 
       java.lang.SecurityException: No permission to write to /storage/emulated/0/Download/hrpsampletable.pdf: Neither user 10047 nor current process has android.permission.WRITE_EXTERNAL_STORAGE. 
        at android.os.Parcel.readException(Parcel.java:1627) 
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183) 
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135) 
        at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476) 
        at android.content.ContentResolver.insert(ContentResolver.java:1240) 
        at android.app.DownloadManager.enqueue(DownloadManager.java:946) 
        at com.example.markwitt.schul_app.Vertretungsplan$1.onClick(Vertretungsplan.java:59) 
        at android.view.View.performClick(View.java:5280) 
        at android.view.View$PerformClick.run(View.java:21239) 
        at android.os.Handler.handleCallback(Handler.java:739) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:224) 
        at android.app.ActivityThread.main(ActivityThread.java:5526) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

: '로컬 호스트 : 8600'전송 '소켓'

(세 번째 줄에)를 외부 저장 장치에 대한 쓰기 권한이 없다고 표시합니다.

하지만 내 AndroidManifest를 올바르게 설정 :

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.markwitt.schul_app"> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<application 
    android:launchMode="singleTop" 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 

    <activity android:name=".Stundenplan"> 


     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

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

내가 무엇을해야합니까?

+0

https : // stackoverflow.com/questions/32635704/android-permission-doesnt-work-even-if-i-have-declared-it – CommonsWare

답변

11

앱이 Android 6.0 (API 레벨 23)에서 실행 중이기 때문에이 오류가 발생합니다. From API level> = 23 런타임에 권한을 확인해야합니다.

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); 

총 물건 외모 : 다음 요청 메시지를 표시하지 않으면

if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { 
    Log.e("Permission error","You have permission"); 
    return true; 
} 

: 사용자가 스토리지를 사용할 수있는 권한을 부여했다 경우 아래 코드는 수준 그래서 먼저 확인하시기 바랍니다 (23)에 대해 잘입니다 같은 :

public boolean haveStoragePermission() { 
    if (Build.VERSION.SDK_INT >= 23) { 
     if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) 
       == PackageManager.PERMISSION_GRANTED) { 
      Log.e("Permission error","You have permission"); 
      return true; 
     } else { 

      Log.e("Permission error","You have asked for permission"); 
      ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); 
      return false; 
     } 
    } 
    else { //you dont need to worry about these stuff below api level 23 
     Log.e("Permission error","You already have the permission"); 
     return true; 
    } 
} 

그리고 마지막 : 콜백에 의해 결과가 나타납니다

@Override 
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
     if(grantResults[0]== PackageManager.PERMISSION_GRANTED){ 
      //you have the permission now. 
      DownloadManager.Request request = new DownloadManager.Request(Uri.parse(myurl)); 
      request.setTitle("Vertretungsplan"); 
      request.setDescription("wird heruntergeladen"); 
      request.allowScanningByMediaScanner(); 
      request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); 
      String filename = URLUtil.guessFileName(myurl, null, MimeTypeMap.getFileExtensionFromUrl(myurl)); 
      request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); 
      DownloadManager manager = (DownloadManager) c.getSystemService(Context.DOWNLOAD_SERVICE); 
      manager.enqueue(request); 
     } 
    } 



또는, 당신은 매우 쉽게 모든 구현을 처리하기 위해 내 사용자 정의 클래스 PermissionCheck를 사용할 수 있습니다.

import android.Manifest; 
import android.app.Activity; 
import android.content.Context; 
import android.content.pm.PackageManager; 
import android.support.v4.app.ActivityCompat; 

/** 
* Created by Tushar on 6/30/2017. 
*/ 

public class PermissionCheck{ 
    public static boolean readAndWriteExternalStorage(Context context){ 
     if(ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ 
      ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1); 
      return false; 
     }else{ 
      return true; 
     } 

    } 

    public static boolean audioRecord(Context context){ 
     if(ActivityCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED){ 
      ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.RECORD_AUDIO}, 2); 
      return false; 
     }else{ 
      return true; 
     } 

    } 

    public static boolean readAndWriteContacts(Context context){ 
     if(ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED){ 
      ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS}, 3); 
      return false; 
     }else{ 
      return true; 
     } 

    } 

    public static boolean vibrate(Context context){ 
     if(ActivityCompat.checkSelfPermission(context, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED){ 
      ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.VIBRATE}, 4); 
      return false; 
     }else{ 
      return true; 
     } 

    } 

    public static boolean sendSms(Context context){ 
     if(ActivityCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED){ 
      ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.SEND_SMS}, 5); 
      return false; 
     }else{ 
      return true; 
     } 

    } 

    //Just like this you can implement rest of the permissions. 
} 


가 사용 : 다음은 클래스

if(PermissionCheck.readAndWriteExternalStorage(context)){ 
    //Your read write code. 
} 

if(PermissionCheck.sendSms(context)){ 
    //Your sms sending code. 
} 

이 **이 공지 사항은, 이러한 방법은 자동으로 또한 onRequestPermissionsResult 해고 될 권한을 요청합니다 요청합니다. :)

+0

대단히 감사합니다. –

+0

문자열 배열의 1이 무엇을 의미하는지 말해 줄 수 있습니까? –

+1

만약 누군가가'Manifest.permission.WRITE_EXTERNAL_STORAGE'로 문제가 생기면 대신'android.Manifest.permission.WRITE_EXTERNAL_STORAGE'을 사용하십시오. –

0

내 API 23 에뮬레이터 (24 및 25는 잘 수행)에서 동일한 문제가 발생하여 맞춤 탭 앱이 실행되었습니다. 나는이 솔루션과 다른 변형을 시도했지만, 나는 허가를 받았다는 것을 알았지 만 어떤 다운로드 시도에도 문제가 남아 있었다. 실제 기기 (앱 권한 요청 코드)에서 앱을 실행했을 때 Google에서 내 앱이 아닌 저장 용량에 액세스 할 수 있도록 허용할지 묻는 메시지가 자동으로 표시되었습니다. 런타임 권한에 대한 코드를 제거하고 브라우저에 대한 권한 (에뮬레이터의 기본값)을 설정하여 저장소에 액세스하고 내 응용 프로그램이 정상적으로 작동했습니다. 다음 게시물은 에뮬레이터에서 발생할 수있는 일에 대한 통찰력을 제공합니다. Requesting and allowing WRITE_EXTERNAL_STORAGE permission at runtime has no effects on the current session