2

인터넷에서 PDF 파일을 SD 카드로만 다운로드하려는 앱을 개발 중입니다.열기 실패 : EACCES (사용 권한이 거부 됨)

나는 android kitkat (4.4.4)을 사용하고 있습니다. 파일을 다운로드하는 중 오류가 발생했습니다. java.io.FileNotFoundException: /storage/sdcard1/pdf/953.pdf: open failed: EACCES (Permission denied). 그리고 내가 android (4.2)을 사용할 때 잘 동작합니다.

Environment.getExternalStorageDirectory();android 4.4.4에 입력하면 내부 저장 장치가 반환됩니다. 어디로 android 4.2로 내게 SD 카드 위치를 반환합니다.

여기 내 코드입니다.

의 AndroidManifest.xml

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

    <uses-permission android:name="android.permission.INTERNET"/> 
    <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:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity android:name=".MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

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

MainActivity.java

public class MainActivity extends AppCompatActivity { 

private Button bt_Download; 
private ProgressDialog progressDialog; 
public static final int progress_bar_type = 0; 
private static String file_url = "http://my_website_url/Data/953.pdf"; 

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

    bt_Download = (Button) findViewById(R.id.bt_Download); 

    bt_Download.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      new DownloadFile().execute(file_url); 
     } 
    }); 
} 

@Override 
protected Dialog onCreateDialog(int id) { 
    switch (id) { 
     case progress_bar_type: 
      progressDialog = new ProgressDialog(this); 
      progressDialog.setMessage("Downloading..."); 
      progressDialog.setMax(100); 
      progressDialog.setCancelable(true); 
      progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
      progressDialog.setIndeterminate(false); 
      progressDialog.show(); 
      return progressDialog; 
     default: 
      return null; 
    } 
} 

class DownloadFile extends AsyncTask<String, String, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     showDialog(progress_bar_type); 
    } 

    @Override 
    protected String doInBackground(String... fileUrl) { 
     int count; 
     try { 
      URL url = new URL(fileUrl[0]); 
      URLConnection conection = url.openConnection(); 
      conection.connect(); 

      int lenghtOfFile = conection.getContentLength(); 

      InputStream input = new BufferedInputStream(url.openStream(), 8192); 

      File file = new File("/storage/sdcard1/pdf","953.pdf"); 

      OutputStream output = new FileOutputStream(file); 

      byte data[] = new byte[1024]; 

      long total = 0; 

      while ((count = input.read(data)) != -1) { 
       total += count; 
       publishProgress(""+(int)((total*100)/lenghtOfFile)); 

       output.write(data, 0, count); 
      } 

      output.flush(); 

      output.close(); 
      input.close(); 

     } catch (Exception e) { 
      Log.e("Error: ", e.getMessage()); 
     } 

     return null; 
    } 

    protected void onProgressUpdate(String... progress) { 
     progressDialog.setProgress(Integer.parseInt(progress[0])); 
    } 

    @Override 
    protected void onPostExecute(String fileUrl) { 
     dismissDialog(progress_bar_type); 
    } 

} 
} 

이는 예외에 걸려있다. 여기에 내 예외 메시지가 있습니다. java.io.FileNotFoundException: /storage/sdcard1/pdf/953.pdf: open failed: EACCES (Permission denied)

android 4.4.4 이상으로 SD 카드에 쓸 수 없는지 알 수 없습니다.

인터넷에서 너무 많이 검색했지만 구체적인 답변을 얻을 수 없습니다. 다른 방법이 있습니까? 저에게 알려주세요.

답변

1

인터넷에서 PDF 파일을 SD 카드로만 다운로드하려는 앱을 개발 중입니다.

Android 4.4 이상에서는 removable storage에 대한 임의의 파일 시스템 액세스 권한이 없습니다.

이 코드를 실행할 때 Environment.getExternalStorageDirectory(); 안드로이드 4.4.4에서 내부 저장소를 반환합니다.

Android SDK에서 정의한대로 external storage을 반환합니다. 그것은 아마이하는 당신의 1 개 테스트 장치에 나에게 SD 카드 위치

을 반환 안드로이드 4.2로

. 대부분의 최신 Android 기기에서 외부 저장소는 이동식 저장소가 아닙니다.

왜 안드로이드 4.4.4 이상에서 내가 SD 카드에 글을 쓸 수 없는지 모르겠다.

Android 4.4 이상에서는 removable storage에 대한 임의의 파일 시스템 액세스 권한이 없습니다.

다른 방법이 있습니까?

안드로이드 4.4 이상에서 사용자가 어디에 내용을 배치하기로 결정 할 수 있도록 the Storage Access Framework —의 ACTION_CREATE_DOCUMENT — 일부를 사용합니다. Uri이 표시됩니다. ContentResolveropenOutputStream()과 함께 사용하면 Uri으로 식별되는 위치에 콘텐츠를 쓸 수 있습니다. 또한 사용자는 Google 드라이브, Dropbox 또는 앱의 저장 업체에서 관리하는 다른 장소와 같이 사용자가 원하는 곳에 파일을 배치 할 수있는 유연성을 사용자에게 제공합니다.

+0

파일/폴더 선택 도구를 사용하여 파일을 쓸 수 있습니까? –

+0

@AshishKudale : 그것이 바로'ACTION_CREATE_DOCUMENT'입니다. – CommonsWare

+0

감사합니다. 이제 파일 선택기를 볼 수 있습니다. 하지만 문서를 저장하는 동안 토스트에'문서를 저장할 수 없습니다 '라고 표시됩니다. –