384

私は得ています

開くことができませんでした: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();
}
4

33 に答える 33

371

GoogleにはAndroidQの新機能があります外部ストレージ用のフィルターされたビュー。そのための簡単な修正は、AndroidManifest.xmlファイルに次のコードを追加することです。

<manifest ... >
    <!-- This attribute is "false" by default on apps targeting Android Q. -->
    <application android:requestLegacyExternalStorage="true" ... >
     ...
    </application>
</manifest>

詳細については、https ://developer.android.com/training/data-storage/use-casesをご覧ください。

編集:この回答はAndroid 11では古くなっているため、反対票を獲得し始めています。したがって、この回答を見た人は、上のリンクにアクセスして手順を読んでください。

于 2019-09-05T11:38:49.513 に答える
363

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を確認してください。

于 2015-10-22T23:52:40.127 に答える
248

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

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

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

于 2012-03-28T12:33:39.987 に答える
75

android:requestLegacyExternalStorage = "true"をAndroidマニフェストに追加します。これは、SDK29以降のAndroid10(Q)または
AndroidXの 移行後に機能します。

 <application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:hardwareAccelerated="true"
    android:icon=""
    android:label=""
    android:largeHeap="true"
    android:supportsRtl=""
    android:theme=""
    android:requestLegacyExternalStorage="true">
于 2019-12-10T11:42:02.193 に答える
59

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

于 2013-01-17T09:14:26.600 に答える
53

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

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

于 2012-11-19T08:42:23.337 に答える
30

私の問題は、minSdkVersionが23未満の場合に必要な「TargetApi(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();
    }
}
于 2016-10-27T06:09:59.650 に答える
30

解決策に注意してください:

<application ...
    android:requestLegacyExternalStorage="true" ... >

一時的なものですが、遅かれ早かれ、アプリを移行して使用する必要がありますScoped Storage

Android 10では、提案されたソリューションを使用してシステム制限を回避できますが、Android 11 (R) it is mandatory to use scoped storageでは、古いロジックを使用し続けるとアプリが破損する可能性があります。

このビデオは良い助けになるかもしれません。

于 2020-06-23T13:13:14.900 に答える
19

私も同じことを経験しています。私が見つけたのは、[設定]->[アプリケーションマネージャー]->[アプリ]->[アクセス許可]->[ストレージを有効にする]に移動すると、問題が解決することです。

于 2018-02-08T06:26:46.843 に答える
19

Android 10(API 29)では、スコープストレージが導入されています。マニフェストを変更してレガシーストレージを要求することは、長期的な解決策ではありません。

Environment.getExternalStorageDirectory()以前のインスタンス(API 29で非推奨)をに置き換えたときに問題を修正しましたcontext.getExternalFilesDir(null)

保存場所が利用できない場合はnullを返す可能性があることに注意context.getExternalFilesDir(type)してください。そのため、外部権限があるかどうかを確認するときは必ず確認してください。

詳細はこちらをご覧ください

于 2019-10-21T15:05:21.837 に答える
14

電話をデスクトップPCに接続したままにしていて、これに気づかなかったので、それはばかげた間違いでした。

そのため、USB接続をオフにする必要があり、すべてが正常に機能しました。

于 2012-11-26T16:49:33.873 に答える
13

CM12.1を実行しているSamsungGalaxyNote3でも同じ問題が発生しました。私にとっての問題は私が持っていたということでした

<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までに制限するだけであり、それによって読み取り権限が制限されるためです。

于 2015-10-14T13:42:15.807 に答える
9

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

秘訣:バージョン22以下を対象としている場合、アプリケーションは、マシュマロより下のOSを実行しているデバイスの場合と同様に、インストール時にすべてのアクセス許可を要求します。エミュレーターを試してみる場合は、Android 6.0以降、[設定]->[アプリ]->[YOURAPP]-> [権限]に明示的に移動し、権限があれば変更する必要があります。

于 2016-04-06T22:53:45.160 に答える
9

不思議なことに、 newFileの前にスラッシュ「/」を付けた後、問題は解決しました。私はこれを変更しました:

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

これに:

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

更新:コメントで述べたように、これを行う正しい方法は次のとおりです。

File myFile= new File(Environment.getExternalStorageDirectory(), "newFile");
于 2016-12-17T21:51:40.873 に答える
6

私は同じ問題を抱えていましたが、どの提案も役に立ちませんでした。しかし、物理的なデバイスであるGalaxy Tabで、その興味深い理由を見つけました。

USBストレージがオンの場合、外部ストレージの読み取りおよび書き込み権限は効果がありません。USBストレージをオフにするだけで、適切な権限があれば問題は解決します。

于 2014-07-19T16:52:14.323 に答える
5

/data以下のすべてが「内部ストレージ」に属することを期待します。ただし、に書き込むことができるはず/sdcardです。

于 2012-01-13T17:09:24.927 に答える
5

あなたとグループの権限プロパティを変更するには、/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>
于 2013-12-04T15:47:27.550 に答える
5

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

于 2016-08-21T12:43:36.397 に答える
5

多分答えはこれです:

API> = 23デバイスで、アプリをインストールする場合(アプリはシステムアプリではありません)、[設定-アプリケーション]で保存権限を確認する必要があります。すべてのアプリの権限リストがあります。確認する必要があります。試す

于 2017-04-28T02:25:21.147 に答える
4

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

于 2012-11-21T07:41:44.350 に答える
4

マニフェストですべての正しい権限を設定した場合でも、サードパーティのアプリが外部カードに書き込むことができるのは、書き込みを試みる「独自のディレクトリ」(つまり、/ sdcard / Android / data /)のみであることに注意してください。他の場所:例外が発生します:EACCES(許可が拒否されました)

于 2018-12-25T20:31:38.823 に答える
4
Environment.getExternalStoragePublicDirectory();

Android 29以降でこの非推奨のメソッドを使用すると、同じエラーが発生します。

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

ここでの解決策:

getExternalStoragePublicDirectoryはAndroidQで非推奨になりました

于 2019-07-19T11:58:35.400 に答える
4

directoryアプリのディレクトリとは別のファイルをに保存することは、上記で制限されAPI 29+ています。したがって、新しいファイルを生成したり、新しいファイルを作成したりするには、次のようにアプリケーションディレクトリを使用します:-

したがって、正しいアプローチは次のとおりです:-

val file = File(appContext.applicationInfo.dataDir + File.separator + "anyRandomFileName/")

この生成されたファイルに任意のデータを書き込むことができます!

上記はアクセス可能ですが、独自に開発したアプリのディレクトリにあるためfile、アクセスできません。throw any exception

他のオプションは android:requestLegacyExternalStorage="true"manifest application tagによって提案されUrielたとおりですが、永続的な解決策ではありません!

于 2020-04-01T12:38:37.310 に答える
3

私の場合、外部ストレージへのパスを返すファイルピッカーライブラリ/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
于 2017-08-28T19:51:48.583 に答える
2

init.rcの/data/の下にフォルダーを作成しています(Nexus 7のaospをいじくり回しています)が、まさにこの問題がありました。

フォルダrw(666)のアクセス許可を与えるだけでは不十分であり、rwx(777)である必要があり、すべてが機能することが判明しました。

于 2015-01-06T10:56:20.360 に答える
2

次のadbコマンドを使用してルート化されたデバイスがある場合、6.0以降のストレージ権限の適用をバイパスできます。

root@msm8996:/ # getenforce
getenforce
Enforcing
root@msm8996:/ # setenforce 0
setenforce 0
root@msm8996:/ # getenforce
getenforce
Permissive
于 2016-04-07T01:22:39.500 に答える
1

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

<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"/>
于 2016-10-21T09:53:03.193 に答える
0

同じ問題が発生しました(API> = 23)。

ソリューションhttps://stackoverflow.com/a/13569364/1729501は私のために機能しましたが、デバッグのためにアプリを切断することは実用的ではありませんでした。

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

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

ステップ2:デバイスマネージャーに移動->他のデバイス->「adb」という単語を含むエントリを探す->[ドライバーの更新]を選択->ステップ1で場所を指定

于 2017-05-09T07:19:27.633 に答える
0

Gradleの依存関係を追加する

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();
    }
于 2018-04-08T17:06:44.373 に答える
0

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.
        }   
    }
}
于 2018-04-11T15:53:31.350 に答える
0

私の場合、エラーは行に表示されていました

      target.createNewFile();

SDカードに新しいファイルを作成できなかったため、DocumentFileアプローチを使用する必要がありました。

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

上記の質問の場合、このアプローチで問題を解決できる可能性があります。

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

このスレッドも参照してください 。Android5.0(Lollipop)用に提供されている新しいSDカードアクセスAPIの使用方法は?

于 2019-04-07T03:46:57.943 に答える
0

私は以下のプロセスを使用して、android11とtargetapi30のケースを処理します

  1. ルートディレクトリファイルのスコープストレージごとに事前に作成されたファイルディレクトリとして//<画像/ビデオ...要件ごと>

  2. 選択したファイルをコピーし、外部ストレージから選択するときにキャッシュディレクトリにファイルをコピーします

  3. 次に、アップロードするときに([送信/アップロード]ボタンをクリックして)、ファイルをキャッシュディレクトリからスコープストレージディレクトリにコピーしてから、アップロードプロセスを実行します

Playストアにアプリをアップロードすると、MANAGE_EXTERNAL_STORAGE権限の警告が生成され、私の場合はPlayストアから拒否されることがあるため、このソリューションを使用してください。

また、ターゲットAPI 30を使用したため、内部ストレージからアプリにファイルを共有または転送できません

于 2021-09-23T11:24:40.607 に答える
0

私はxiaomiデバイス(android 10)で同じエラーに直面しました。次のコードは私の問題を修正しました。ライブラリ:Dexter(https://github.com/Karumi/Dexter)およびImage picker(https://github.com/Dhaval2404/ImagePicker

マニフェストを追加します(android:requestLegacyExternalStorage = "true")

    public void showPickImageSheet(AddImageModel model) {
    BottomSheetHelper.showPickImageSheet(this, new BottomSheetHelper.PickImageDialogListener() {
        @Override
        public void onChooseFromGalleryClicked(Dialog dialog) {
            selectedImagePickerPosition = model.getPosition();
            Dexter.withContext(OrderReviewActivity.this)                   .withPermissions(Manifest.permission.READ_EXTERNAL_STORAGE)
                    .withListener(new MultiplePermissionsListener() {
                        @Override
                        public void onPermissionsChecked(MultiplePermissionsReport report) {
                            if (report.areAllPermissionsGranted()) {
                                ImagePicker.with(OrderReviewActivity.this)
                                        .galleryOnly()
                                        .compress(512)
                                        .maxResultSize(852,480)
                               .start();
                            }
                        }

                        @Override
                        public void onPermissionRationaleShouldBeShown(List<PermissionRequest> list, PermissionToken permissionToken) {
                            permissionToken.continuePermissionRequest();
                        }

                    }).check();

            dialog.dismiss();
        }

        @Override
        public void onTakePhotoClicked(Dialog dialog) {
            selectedImagePickerPosition = model.getPosition();
            ImagePicker.with(OrderReviewActivity.this)
                    .cameraOnly()
                    .compress(512)
                    .maxResultSize(852,480)
                    .start();

            dialog.dismiss();
        }

        @Override
        public void onCancelButtonClicked(Dialog dialog) {
            dialog.dismiss();
        }
    });
}
于 2021-11-29T07:47:54.337 に答える