Android 10でディレクトリを作成できません


10

Android 10でディレクトリを作成できません。AndroidOreoまではデバイスで動作します。

フォルダを作成する方法を2つ試しました。

使用 File.mkdir()

   File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
                    if (!f.isFile()) {
                        if (!(f.isDirectory())) {
                               success =  f.mkdir();
                        }

ここでは、変数success は常にfalseです。つまり、ディレクトリは作成されません。

使用 Files.createDirectory()

   File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
                    if (!f.isFile()) {
                        if (!(f.isDirectory())) {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                try {
                                    Files.createDirectory(Paths.get(f.getAbsolutePath()));
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    Toast.makeText(getApplicationContext(), R.string.unable_to_download, Toast.LENGTH_LONG).show();
                                }
                            } else {
                                f.mkdir();
                            }
                        }

これはこの例外を引き起こします:

pzy64.pastebinpro W/System.err: java.nio.file.AccessDeniedException: /storage/emulated/0/Pastebin
pzy64.pastebinpro W/System.err:     at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:391)
pzy64.pastebinpro W/System.err:     at java.nio.file.Files.createDirectory(Files.java:674)

ランタイム権限を実装しました

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

すべて設定されました。

回答:


27

2019年3月に最初に開示されたように、デフォルトでは外部ストレージの任意の場所やAndroid 10 以降のリムーバブルストレージにアクセスできません。これにはEnvironment.getExternalStorageDirectory()、およびの他のメソッドが含まれますEnvironment(例:getExternalStoragePublicDirectory()

Android 10の場合、マニフェストの要素に追加できandroid:requestLegacyExternalStorage="true"ます<application>。これにより、レガシーストレージモデルが選択され、既存の外部ストレージコードが機能します。ただし、Android R以降では機能しないため、これは短期的な修正にすぎません。

選択肢は次のとおりです。

  • Contextなどののメソッドを使用getExternalFilesDir()して、アプリが書き込むことができる外部ストレージのディレクトリに移動します。Android 4.4以降でこれらのディレクトリを使用するための権限は必要ありません。ただし、アプリをアンインストールすると、そこに保存したデータは削除されます。

  • ACTION_OPEN_DOCUMENTおよびなどのストレージアクセスフレームワークを使用しACTION_CREATE_DOCUMENTます。

  • コンテンツがメディアの場合、を使用MediaStoreして、メディアを標準のメディアの場所に配置できます。


1
Android Qで自分のディレクトリを作成する方法はないと言っていますか?
Xihuny

1
@Xihuny:がgetExternalFilesDir()提供するのサブディレクトリと同様の場所を作成できますContext。ファイルシステムAPIを使用して、外部またはリムーバブルストレージのルートから直接サブディレクトリを作成することはできません。
CommonsWare、

1
ユーザーがアプリをアンインストールするとファイルが削除されるので、私はそれをしたくありません。
Xihuny

1
@Xihuny:次に、ストレージアクセスフレームワークを使用して、ユーザーのコンテンツを配置するユーザーのデバイス上の場所をユーザーが選択できるようにします。
CommonsWare、

1
試しましたが、自分のディレクトリを作成できませんでした。SAFを使用して独自のカスタム名前付きディレクトリを作成する方法はありますか?
Xihuny

3

Android 10の場合、追加できます

android:requestLegacyExternalStorage="true"

マニフェストの要素に。これにより、レガシーストレージモデルが選択され、既存の外部ストレージコードが機能します。ただし、この修正はAndroid R以降では機能しないため、これは短期的な修正にすぎません。


1

Qベータ4以降、次の方法でその機能をオプトアウトすることができます。

requestLegacyExternalStorageマニフェスト属性を使用してAPI 28(またはそれ以下)をターゲットにする:

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

-1

これは私にとってはうまくいき、Android 10でも機能すると思います>

            ContentResolver resolver = getContentResolver();
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Folder Example");
            String path = String.valueOf(resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues));
            File folder = new File(path);
            boolean isCreada = folder.exists();
            if(!isCreada) {
                folder.mkdirs();
            }

を照会しているFileため、android:requestLegacyExternalStorage="true"Android 10>をターゲットにする場合は追加する必要があります。その場合は、を使い続けることもできgetExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)ます。
HB。

getExternalStoragePublicDirectoryはAPIレベル29で廃止されました
JP711

はいそして?ドキュメントに記載されてWhen an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessibleいるようandroid:requestLegacyExternalStorage="true"に、マニフェストにある場合でも、それを使用できます。
HB。

"はいそして?" そして、ドキュメンテーションはApps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT私がこれに新しいと述べていますが、それから私の質問は、私の提案は間違っているのですか、それともなぜ反対票が投じられているのですか?これがどのように機能するのかよくわかりませんが、続行する方が良いgetExternalStoragePublicDirectoryですか?
JP711

1
フォルダーを作成する必要はありません。Uriフォルダーに書き込むと、フォルダーが自動的に作成されます。
HB。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.