3

Android M でファイルを作成するのに問題があります。

Android 6.0.1でNexus 9を使用しています。次に、プロジェクトに次のように設定します。

AndroidManifest.xml

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

build.gradle

android {
    defaultConfig {
        targetSdkVersion 23
        ...
    }
}

MainActivity.Java

public class MainActivity extends AppCompatActivity {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
    String rootPath = storagePath + "/test";
    String fileName = "/test.zip";

    File root = new File(rootPath);
    if(!root.mkdirs()) {
        Log.i("Test", "This path is already exist: " + root.getAbsolutePath());
    }

    File file = new File(rootPath + fileName);
    try {
        if (!file.createNewFile()) {
            Log.i("Test", "This file is already exist: " + file.getAbsolutePath());
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

ビルドは成功し、アプリケーションが起動されましたが、次のような例外メッセージが表示されました:

IO例外

01-07 18:13:40.669 18027-18027/com.sample.myapplication W/System.err: java.io.IOException: open failed: ENOENT (No such file or directory)
01-07 18:13:40.669 18027-18027/com.sample.myapplication W/System.err:     at java.io.File.createNewFile(File.java:939)
01-07 18:13:40.669 18027-18027/com.sample.myapplication W/System.err:     at com.sample.myapplication.MainActivity.onCreate(MainActivity.java:36)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err:     at android.app.Activity.performCreate(Activity.java:6251)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err:     at android.app.ActivityThread.-wrap11(ActivityThread.java)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at android.os.Looper.loop(Looper.java:148)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5417)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at libcore.io.Posix.open(Native Method)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:     at java.io.File.createNewFile(File.java:932)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err:   ... 13 more

どうすればこの問題を解決できますか? 見逃したものをキャッチしない....

助けてください。

4

2 に答える 2

0

私は同じ問題を抱えていました。file.createNewFile で IOException が発生しました。例外を詳しく見てみると、それは「アクセス許可が拒否された」ことが原因であることがわかります。私は getFilesDir に書き込んでいたので、このタスクを達成するために Android マニフェストに を必要としないはずです。もちろん、外部ストレージに READ 権限と WRITE 権限の両方を追加しましたが、もちろん問題は解決しませんでした。

SDK 26 の NEXUS 6 エ​​ミュレーターを使用してコードをテストしていました。コードを変更せずに、SDK 26 の PIXEL C エミュレーターを使用してテストを試みましたが、問題は発生しませんでした。したがって、Nexus 6 エミュレーターに問題があるようです。

これが常に問題であるとは限らず、このエミュレータ インスタンスが破損していると思われますが、確認していません。ファイルを作成していたディレクトリのLinuxファイルのアクセス許可を調べるのに時間をかけましたが、「drwxrwxrwx」と報告されましたが、これは正しいです。新しいファイルを作成しようとしているディレクトリへのパスを持つ FileProvider を実装したことを追加します。私が使用しているコードは、Kae10 が示すコードとほぼ同じように見えます。

問題を UnixFileSystem の次のコードまでたどりました。

public boolean createFileExclusively(String path) throws IOException {
    BlockGuard.getThreadPolicy().onWriteToDisk();
    return createFileExclusively0(path);
}

デバッグできない createFileExlussively0 から例外がスローされます。私はこの問題をこれ以上調査していません (つまり、1.) avd インスタンスを削除して再作成すると役立つでしょう。私の推測では、2.) 使用すべき新しいシステム イメージはありますか?)

于 2018-04-27T21:19:18.907 に答える