无法使用LibGDX写入或读取外部存储器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法使用LibGDX写入或读取外部存储器相关的知识,希望对你有一定的参考价值。

我的create方法看起来像这样:

@Override
public void create () {
    batch = new SpriteBatch();

    FileHandle file = Gdx.files.external("file.txt");
    file.writeString("My god, it's full of stars", false);
}

我还包括:

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

我得到的例外是这样的:

02-13 14:45:51.858 12439-12466/com.snowdevs.tweetiebirds E/AndroidRuntime: FATAL EXCEPTION: GLThread 1120
Process: com.snowdevs.tweetiebirds, PID: 12439
com.badlogic.gdx.utils.GdxRuntimeException: Error writing file: file.txt (External)
    at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:353)
    at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:339)
    at com.snowdevs.tweetiebirds.TweetieBirdsGame.create(TweetieBirdsGame.java:22)
    at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:254)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1519)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
 Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Error writing file: file.txt (External)
    at com.badlogic.gdx.files.FileHandle.writer(FileHandle.java:330)
    at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:350)
    at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:339) 
    at com.snowdevs.tweetiebirds.TweetieBirdsGame.create(TweetieBirdsGame.java:22) 
    at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:254) 
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1519) 
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240) 
 Caused by: java.io.FileNotFoundException: /storage/emulated/0/file.txt: open failed: EACCES (Permission denied)
    at libcore.io.IoBridge.open(IoBridge.java:452)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
    at com.badlogic.gdx.files.FileHandle.writer(FileHandle.java:322)
    at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:350) 
    at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:339) 
    at com.snowdevs.tweetiebirds.TweetieBirdsGame.create(TweetieBirdsGame.java:22) 
    at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:254) 
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1519) 
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240) 
 Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
    at libcore.io.Posix.open(Native Method)
    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
    at libcore.io.IoBridge.open(IoBridge.java:438)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:87) 
    at com.badlogic.gdx.files.FileHandle.writer(FileHandle.java:322) 
    at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:350) 
    at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:339) 
    at com.snowdevs.tweetiebirds.TweetieBirdsGame.create(TweetieBirdsGame.java:22) 
    at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:254) 
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1519) 
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240) 

我使用带有Android 6 Marshmallow的Nexus 5进行测试。我搜索并发现Android 6使用运行时权限,但LibGDX开发人员说它甚至可以在Android 6上运行。是否有修复,无论是否有运行时权限?

答案

我通过检查用户是否已授予外部存储许可来解决问题,如果未通过使用授权请求权限请求:

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                     this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_REQUEST_CODE);
            }

所有这些都是特定于android的代码,因此驻留在AndroidLauncher类中。

另一答案

我不相信Nexus 5有外部存储(SD卡)。

用这个测试来找出 -

boolean isExtAvailable = Gdx.files.isExternalStorageAvailable();

你可以找到更多信息here

另一答案

我有相同的情况(Android 6,Nexus 4没有SD卡,libGDX 1.9.3): 我检查了外部存储

Gdx.files.isExternalStorageAvailable() // returns true

然后获取fileHandle

FileHandle file = Gdx.files.external("file.txt"); // no exception

然后打电话

file.writeString("text",false); // throws GdxRuntimeException

所以我检查了android端是这个代码真正可用的外部存储:

Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); // returns true

这也是真的。所以这不是libGDX问题,而是Android问题。

然后我通过捕获异常来解决它,并在那种情况下将文件写入本地存储。

以上是关于无法使用LibGDX写入或读取外部存储器的主要内容,如果未能解决你的问题,请参考以下文章

在读取/写入文件到内部/外部存储android时使用啥类和方法?

课堂整理:写入和读取外部存储文件

Libgdx FileHandle 读写多行

更新后本地文件是否存在? (LibGDX)

写入和读取外部存储文件

从 BigQuery 读取数据并将其写入云存储上的 avro 文件格式