web-dev-qa-db-ja.com

Android上で例外 'open failed:EACCES(Permission denied)'が発生しました

私はなっています

開けませんでした:EACCES (Permission denied)

OutputStream myOutput = new FileOutputStream(outFileName);行目

私はルートを調べ、そしてAndroid.permission.WRITE_EXTERNAL_STORAGEを試しました。

どうすればこの問題を解決できますか?

try {
    InputStream myInput;

    myInput = getAssets().open("XXX.db");

    // Path to the just created empty db
    String outFileName = "/data/data/XX/databases/"
            + "XXX.db";

    // Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    // Transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }

    // Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
    buffer = null;
    outFileName = null;
}
catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}
227
Mert

私は同じ問題を抱えていました... <uses-permissionは間違った場所にありました。これは正しいです:

 <manifest>
        <uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>
        ...
        <application>
            ...
            <activity> 
                ...
            </activity>
        </application>
    </manifest> 

uses-permissionタグはapplicationタグの外側にある必要があります。

225
user462990

API 23以降の場合は、既にマニフェストに含まれている場合でも読み取り/書き込み権限を要求する必要があります。

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

/**
 * Checks if the app has permission to write to device storage
 *
 * If the app does not has permission then the user will be prompted to grant permissions
 *
 * @param activity
 */
public static void verifyStoragePermissions(Activity activity) {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

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

AndroidManifest.xml

<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />

API 23+のための許可を要求することに関する公式のドキュメンテーションに関しては、 https://developer.Android.com/training/permissions/requesting.html をチェックしてください

310
Justin Fiedler

エミュレータ内でアプリケーションを実行したときに、私はこれを一度観察しました。エミュレータ設定では、外部記憶装置( "SDカード")のサイズを正しく指定する必要があります。デフォルトでは、「external storage」フィールドは空です。これはおそらく、そのようなデバイスがなく、許可がマニフェストで付与されている場合でもEACCESがスローされることを意味します。

57
h22

すべての答えに加えて、あなたがUSBストレージとしてあなたの電話を使用していないことを確認してください。

私は有効になっているUSBストレージモードでHTCセンセーションに同じ問題を抱えていました。アプリをデバッグ/実行することはできますが、外部記憶装置に保存することはできません。

49
john

私の問題はあなたのminSdkVersionが以下の場合に必要とされる "TargetApi(23)" 23でした。

だから、私は次のスニペットで許可を要求している

protected boolean shouldAskPermissions() {
    return (Build.VERSION.SDK_INT > Build.VERSION_CODES.Lollipop_MR1);
}

@TargetApi(23)
protected void askPermissions() {
    String[] permissions = {
            "Android.permission.READ_EXTERNAL_STORAGE",
            "Android.permission.WRITE_EXTERNAL_STORAGE"
    };
    int requestCode = 200;
    requestPermissions(permissions, requestCode);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
// ...
    if (shouldAskPermissions()) {
        askPermissions();
    }
}
28
Piroxiljin

私は同じことを経験しています。私が見つけたのは、あなたが 設定 - >アプリケーションマネージャ - >あなたのアプリ - >許可 - >ストレージを有効にする の順に進んでいけば、問題が解決するということです。

13
Atul Kaushik

結局のところ、私は自分の電話をデスクトップPCに接続させていてこれに気付かなかったのでそれはばかげた間違いだった。

だから私はUSB接続をオフにしなければならなかった、そしてすべてがうまくいった。

13
Tobias Reich

私はCM 12.1を実行している、Samsung Galaxy Note 3でも同じ問題を抱えていました。私にとっての問題は、私が持っていたということでした

<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"
    Android:maxSdkVersion="18"/>

ユーザーの写真を撮って保存するためにそれを使わなければなりませんでした。私がImageLoaderにそれらの同じ写真をロードしようとしたとき、私は(Permission denied)エラーを得ました。解決策は明示的に追加することでした

<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE"/>

上記のパーミッションは、書き込みパーミッションをAPIバージョン18までに制限しているだけで、それと一緒に読み取りパーミッションも制限しています。

13
ZooS

すべての回答に加えて、クライアントがAndroid 6.0を使用している場合、Androidは新しい 許可モデル (Marshmallow)を追加しました。

トリック: バージョン22以下をターゲットにしている場合、アプリケーションはMarshmallow以下のOSを実行しているデバイスと同様に、インストール時にすべての権限を要求します。エミュレータを試しているのであれば、Android 6.0以降では、settings-> apps-> YOURAPP - > permissionsの順に選択して、許可があれば変更してください。

8

/system/etc/permission/platform.xmlのパーミッションプロパティを変更してください
とグループは以下のように言及する必要があります。

<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE">
    <group Android:gid="sdcard_rw" />
    <group Android:gid="media_rw" />    
</uses-permission>
5
Prabakaran

/dataの下にあるものはすべて "internal storage"に属しているはずです。ただし、/sdcardに書き込むことができるはずです。

5
ovenror

私は同じ問題を抱えていたし、提案のどれも助けにはならなかった。しかし、物理的なデバイスでは Galaxy Tab という興味深い理由が見つかりました。

USBストレージがオンになっていると、外部ストレージの読み取りおよび書き込み許可は無効になります。 USBストレージをオフにするだけで、正しいアクセス許可があれば、問題は解決します。

5
Hamlet Kraskian

Galaxy S5(Android 6.0.1)のDCIM/cameraフォルダに画像を書き込もうとしたときに同じエラーが発生し、このフォルダのみが制限されていることがわかりました。私はDCIM /任意のフォルダに書き込むことができましたが、カメラにはできませんでした。これはブランドベースの制限/カスタマイズです。

4
Mahdi Mehrizi

アプリケーションがシステムアプリケーションに属している場合は、SDカードにアクセスできません。

4
will

不思議なことにスラッシュを置いた後に "/" 私の newFileの前に 私の問題は解決した。私はこれを変えました:

File myFile= new File(Environment.getExternalStorageDirectory() + "newFile");

これに:

File myFile= new File(Environment.getExternalStorageDirectory() + "/newFile");
4
Darush

私の場合は ファイルピッカーライブラリ を使用していました - これは外部ストレージへのパスを返しましたが、それは/root/から始まりました。実行時にWRITE_EXTERNAL_STORAGE権限が付与されていても、エラー EACCES(権限が拒否されました) が発生します。
したがって、外部記憶装置への正しいパスを取得するにはEnvironment.getExternalStorageDirectory()を使用してください。

例:
書き込みできません/root/storage/emulated/0/newfile.txt
書き込み可能:/storage/emulated/0/newfile.txt

boolean externalStorageWritable = isExternalStorageWritable();
File file = new File(filePath);
boolean canWrite = file.canWrite();
boolean isFile = file.isFile();
long usableSpace = file.getUsableSpace();

Log.d(TAG, "externalStorageWritable: " + externalStorageWritable);
Log.d(TAG, "filePath: " + filePath);
Log.d(TAG, "canWrite: " + canWrite);
Log.d(TAG, "isFile: " + isFile);
Log.d(TAG, "usableSpace: " + usableSpace);

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

出力1:

externalStorageWritable: true
filePath: /root/storage/emulated/0/newfile.txt
isFile: false
usableSpace: 0

出力2:

externalStorageWritable: true
filePath: /storage/emulated/0/newfile.txt
isFile: true
usableSpace: 1331007488
3
vovahost

多分答えはこれです:

aPIが23以上のデバイスでは、アプリをインストールすると(アプリはシステムアプリではありません)、 "Setting - applications"で保存許可を確認する必要があります。すべてのアプリの許可リストがあります。やってみる

3
Jason Zhu

あなたがマニフェストにすべての正しい許可を設定したとしても、覚えておいてください:サードパーティ製のアプリがあなたの外部カードに書くことを許される唯一の場所は、書き込もうとしているそれ以外の場所では、例外が発生します。EACCES(Permission denied)

2
Elad

私は私のinit.rcの/ data /の下にフォルダを作成しています(Nexus 7のaospと一緒にいじっている)そしてまさにこの問題を抱えていました。

フォルダのrw(666)パーミッションを与えることは十分ではなく、それはrwx(777)でなければならないことが判明しました、そしてそれはすべてうまくいきました!

2
lane

以下のadbコマンドを使用して根ざしたデバイスを使用している場合は、6.0以降の記憶許可の適用を回避できます。

[email protected]:/ # getenforce
getenforce
Enforcing
[email protected]:/ # setenforce 0
setenforce 0
[email protected]:/ # getenforce
getenforce
Permissive
2
Zakir

マニフェストに権限を追加します。

<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission Android:name="Android.permission.READ_INTERNAL_STORAGE" />
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>
1
Harman Khera
Environment.getExternalStoragePublicDirectory();

Android 29以降のこの非推奨のメソッドを使用すると、同じエラーが表示されます。

Java.io.FileNotFoundException: open failed: EACCES (Permission denied)

ここでの解決策:

getExternalStoragePublicDirectoryはAndroid Qで非推奨

1
user2965003

User462990が回答に基づいた構築

ユーザーが許可要求ダイアログに応答したときに通知を受けるには、これを使用します。(kotlinのコード)

override fun onRequestPermissionsResult(requestCode: Int,
                           permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
    MY_PERMISSIONS_REQUEST_READ_CONTACTS -> {
        // If request is cancelled, the result arrays are empty.
        if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {

            // permission was granted, yay! Do the
            // contacts-related task you need to do.

        } else {

            // permission denied, boo! Disable the
            // functionality that depends on this permission.

        }
        return
    }

    // Add other 'when' lines to check for other
    // permissions this app might request.

    else -> {
        // Ignore all other requests.
    }
}

}

0
user3561494

私の場合はエラーが線に現れていました

      target.createNewFile();

私はSDカードに新しいファイルを作成することができなかったので、私はDocumentFileアプローチを使用しなければなりませんでした。

      documentFile.createFile(mime, target.getName());

上記の質問では、このアプローチで問題を解決できます。

    fos=context.getContentResolver().openOutputStream(documentFile.getUri());

このスレッドも参照してください。 Android 5.0(Lollipop)用に発表された新しいSDカードアクセスAPIの使い方。

0
Tarasantan

課題依存関係を追加する

implementation 'com.karumi:dexter:4.2.0'

あなたの主な活動に以下のコードを追加してください。

import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {


                checkMermission();
            }
        }, 4000);
    }

    private void checkMermission(){
        Dexter.withActivity(this)
                .withPermissions(
                        Android.Manifest.permission.READ_EXTERNAL_STORAGE,
                        Android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Android.Manifest.permission.ACCESS_NETWORK_STATE,
                        Manifest.permission.INTERNET
                ).withListener(new MultiplePermissionsListener() {
            @Override
            public void onPermissionsChecked(MultiplePermissionsReport report) {
                if (report.isAnyPermissionPermanentlyDenied()){
                    checkMermission();
                } else if (report.areAllPermissionsGranted()){
                    // copy some things
                } else {
                    checkMermission();
                }

            }
            @Override
            public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                token.continuePermissionRequest();
            }
        }).check();
    }
0
ethemsulan

許可を追加した後に私の問題を解決した

<uses-permission Android:name="Android.permission.INTERNET"/>
0
saigopi

私は同じ問題を抱えていた(API> = 23)。

解決策 https://stackoverflow.com/a/13569364/1729501 私のために働いたが、デバッグのためにアプリを切断するのは実用的ではありませんでした。

私の解決策は、Windowsに適切なadbデバイスドライバをインストールすることでした。 Google USBドライバが私のデバイスでは動作しませんでした。

ステップ1:お使いのデバイスブランド用のadbドライバをダウンロードします。

ステップ2:デバイスマネージャに移動 - >他のデバイス - > Word "adb"でエントリを探す - >ドライバの更新を選択 - >ステップ1で場所を指定

0
user13107