2

インターネットからPDFファイルをSDカードでのみダウンロードしたいアプリを開発しています。open failed: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を返します。それはおそらく、それがないあなたの一つのテスト装置上で私のSDカードの場所

を返しアンドロイド4.2のように

。最近のAndroid搭載デバイスの大部分では、外部ストレージはリムーバブルストレージではありません。

私はなぜアンドロイド4.4.4以上で私がSDカードに書き込むことができないのか分かりません。

Android 4.4以降では、removable storageへの任意のファイルシステムアクセス権がありません。

これを行う方法は他にありますか?

のAndroid 4.4以降では、ユーザーがどこコンテンツを配置する場所を決めることができるようにthe Storage Access Framework —のACTION_CREATE_DOCUMENT —一部を使用しています。 Uriが返ってきます。 ContentResolveropenOutputStream()でそれを使用して、Uriで識別される場所にコンテンツを書き込むことができます。これにより、ユーザーは、Googleドライブ、Dropbox、またはアプリのストレージプロバイダが管理する他の場所など、ユーザーが望む場所にファイルを配置できる柔軟性も得られます。

+0

ファイル/フォルダピッカーを使用してファイルを書き込むことはできますか? –

+0

@AshishKudale:これは、「ACTION_CREATE_DOCUMENT」の動作です。ありがとう。 – CommonsWare

+0

今私はファイルピッカーを見ることができます。文書を保存しているうちに文書を保存できませんでした。 –

関連する問題