【问题标题】:Error writing file: screenshot.png (External)写入文件时出错:screenshot.png(外部)
【发布时间】:2021-02-25 07:01:32
【问题描述】:

我正在尝试截图,但是一直出现错误,我尝试了网站上建议的所有方法,我也在清单文件中写道:

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

我也尝试使用方法:local(),getExternalStoragePath(),getLocalStoragePath()

这是我尝试编写文件的一种方式:

if (Gdx.input.isTouched() && !flag)
    {
        flag = true;
        try
        {
            byte[] pixels = ScreenUtils.getFrameBufferPixels(0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), true);

            for (int i = 4; i < pixels.length; i += 4)
            {
                pixels[i - 1] = (byte) 255;
            }

            Pixmap pixmap = new Pixmap(Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), Pixmap.Format.RGBA8888);
            BufferUtils.copy(pixels, 0, pixmap.getPixels(), pixels.length);
            FileHandle fh = Gdx.files.external("screenshot.png");
            PixmapIO.writePNG(fh, pixmap);
            System.out.println(fh.exists()); // return true
            scaner.scanFile(fh);
            pixmap.dispose();
        } catch (Exception e)
        {
            e.printStackTrace();
        }

我仍然得到错误

W/System.err: com.badlogic.gdx.utils.GdxRuntimeException: Error writing file: screenshot.png (External)
    at com.badlogic.gdx.files.FileHandle.write(FileHandle.java:302)
    at com.badlogic.gdx.graphics.PixmapIO$PNG.write(PixmapIO.java:222)
    at com.badlogic.gdx.graphics.PixmapIO.writePNG(PixmapIO.java:67)
    at com.badlogic.gdx.graphics.PixmapIO.writePNG(PixmapIO.java:79)
    at com.repress.game.Start.render(Start.java:130)
    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:494)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1553)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1253)
Caused by: java.io.FileNotFoundException: /storage/emulated/0/screenshot.png (Permission denied)
    at java.io.FileOutputStream.open(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
    at com.badlogic.gdx.files.FileHandle.write(FileHandle.java:298)

【问题讨论】:

标签: java android libgdx


【解决方案1】:

您必须在您的 java 类中授予运行时权限 在 oncreate 方法中调用此函数: requestStoragePermission()

并在 onCreate 之外定义以下方法

//请求权限

private void requestStoragePermission() {
    if ((ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) || (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED))
        return;

    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
        //If the user has denied the permission previously your code will come to this block
        //Here you can explain why you need this permission
        //Explain here why you need this permission
    }
    //And finally ask for the permission
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}

//当用户点击允许或拒绝时会调用该方法

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    //Checking the request code of our request
    if (requestCode == STORAGE_PERMISSION_CODE) {

        //If permission is granted
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //Displaying a toast
            Toast.makeText(this, "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
        } else {
            //Displaying another toast if permission is not granted
            Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
        }
    }
}

【讨论】:

  • 感谢您的回答。我不太明白参数:STORAGE_PERMISSION_CODE,我没有AndroidLauncher类可以建议的这样一个常量,也许我不太了解Android特定代码
  • @zackscript 是一个随机整数,只是为了识别权限结果:- private static final int STORAGE_PERMISSION_CODE = 123;
  • 我必须在设备本身的应用程序设置中授予权限,它对我有用,我也无法在 onCreate () 方法中正确调用 requestStoragePermission () 方法,因为我得到了一堆错误
【解决方案2】:

我建议您使用以下代码将视图的图片作为位图拍摄:

public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);                
Canvas c = new Canvas(b);
v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
v.draw(c);
return b;

}

然后写入外部存储。 最重要的是认为 android 在 android 10 中更改了我们的隐私政策。在此隐私政策中,您不会在未经许可的情况下将数据写入外部存储。但不用担心,在您的清单文件中添加此标签

requestlegacyexternalstorage="true"

【讨论】:

    【解决方案3】:

    我仍然会回答我自己的问题。 为了授予用户写入和读取文件的权限,我检查用户是否已授予外部存储权限,并请求权限。 感谢这个人:HERE

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2014-06-08
      相关资源
      最近更新 更多