[解決済み] オープンに失敗しました。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();
}
FileOutputStreamの作成時に、fStream = new FileOutputStream(filename, true);という行で例外がスローされます。
スタックログは
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 に接続していないと言います。
アップデート
FileOutputStreamのopenとcloseを頻繁に呼び出していることが判明し、ある時点でFileNotFoundExceptionをスローしています。スレッドの問題のように聞こえます。
どのように解決するのですか?
しばらく前に同じような問題に遭遇しました。
あなたの問題は 2 つの異なる領域にある可能性があります。書き込むファイルをどのように作成しているか、または、書き込む方法が電話に依存しているという点で欠陥がある可能性があります。
SD カード上の特定の場所にファイルを書き込んでいる場合は、環境変数を使用してみてください。 これらは常に有効な場所を指しているはずです。 以下は、downloads フォルダに書き込む例です。
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 の回答を参照してください。
関連
-
[解決済み】例外「open failed: Androidで「EACCES (Permission denied)」という例外が発生する。
-
[解決済み] Androidの連絡先リストを呼び出すには?
-
[解決済み] Android Studio - あいまいなメソッド呼び出し getClass()
-
[解決済み] TabLayoutに対応したandroidデザインでタブテキストのフォントを変更する
-
[解決済み] onCreate(Bundle savedInstanceState)とは?
-
[解決済み] ProjectScopeServices に Factory タイプのサービスはありません。
-
[解決済み] PendingIntentの "requestCode "は何に使うのですか?
-
[解決済み] Androidでツールバーの戻るボタンの色を変えるには?
-
[解決済み] Android: xml リソースからの整数値
-
[解決済み] Google Play ストア内部テストのロールアウトが開始できない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] プログラムでソフトキーボードを開く
-
[解決済み] handler.postDelayed()を停止する。
-
[解決済み] Android - Snackbar vs Toast - 使い方と違い。
-
[解決済み] Androidアプリケーションのヒープサイズを大きくするには?
-
[解決済み] アンドロイドでシェイクを検出するには?
-
[解決済み] Android端末がHDPI画面かMDPI画面かを確認する方法は?
-
[解決済み] APKが署名済みかデバッグビルドかを確認するには?
-
[解決済み] AndroidでTextViewの下にアンダーラインを引くには
-
[解決済み] サポートライブラリのアクションバーをPreferenceActivityに追加するには?
-
[解決済み] Androidの環境設定。ユーザーが環境設定画面を使用していない場合、デフォルト値を読み込むにはどうすればよいですか?