storage/emulated/0/YourName.png:打开失败:EPERM(不允许操作)

问题描述 投票:0回答:2

我想截取用户屏幕截图,我使用了这段代码。我获得了 3 个权限,READ_EXTERNAL_STORE、WRITE_EXTERNAL_STORE 和 READ_EXTERNAL_STORAGE。问题没有解决。显示打开失败:EPERM(不允许操作)

public void tackeAndSaveScreenShot(Activity mActivity) {
        View MainView = mActivity.getWindow().getDecorView();
        MainView.setDrawingCacheEnabled(true);
        MainView.buildDrawingCache();
        Bitmap MainBitmap = MainView.getDrawingCache();
        Rect frame = new Rect();

        mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        //to remove statusBar from the taken sc
        int statusBarHeight = frame.top;
        //using screen size to create bitmap
        int width = mActivity.getWindowManager().getDefaultDisplay().getWidth();
        int height = mActivity.getWindowManager().getDefaultDisplay().getHeight();
        Bitmap OutBitmap = Bitmap.createBitmap(MainBitmap, 0, statusBarHeight, width, height - statusBarHeight);
        MainView.destroyDrawingCache();
        try {

            String path = Environment.getExternalStorageDirectory().toString();
            OutputStream fOut = null;
            //you can also using current time to generate name
            String name="YourName";
            File file = new File(path, name + ".png");
            fOut = new FileOutputStream(file);

            OutBitmap.compress(Bitmap.CompressFormat.PNG, 1000, fOut);
            fOut.flush();
            fOut.close();

            //this line will add the saved picture to gallery
            MediaStore.Images.Media.insertImage(getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

当我检查 Logcat 时。他们表明问题出在

fOut = new FileOutputStream(file);

我已正确获得许可。

private void userPermission2(){
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.MANAGE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},REQUEST_CODE1);
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE && grantResults.length > 0
        && grantResults[0] == PackageManager.PERMISSION_GRANTED){
            Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
            userPermission2();
        }else {
            Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();

        }

    }

我尝试了很多为什么但不起作用。每次都是同样的问题。

日志是。

D/CompatibilityChangeReporter: Compat change id reported: 147798919; UID 10351; state: ENABLED
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/YourName.png: open failed: EPERM (Operation not permitted)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:492)
W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
W/System.err:     at com.example.myapplication.MainActivity.tackeAndSaveScreenShot(MainActivity.java:93)
W/System.err:     at com.example.myapplication.MainActivity$1.onClick(MainActivity.java:64)
W/System.err:     at android.view.View.performClick(View.java:7570)
W/System.err:     at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1202)
W/System.err:     at android.view.View.performClickInternal(View.java:7525)
W/System.err:     at android.view.View.access$3900(View.java:836)
W/System.err:     at android.view.View$PerformClick.run(View.java:28680)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:938)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err:     at android.os.Looper.loop(Looper.java:254)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:8243)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1006)
W/System.err: Caused by: android.system.ErrnoException: open failed: EPERM (Operation not permitted)
W/System.err:     at libcore.io.Linux.open(Native Method)
W/System.err:     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
W/System.err:     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
W/System.err:     at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8125)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:478)
W/System.err:   ... 16 more
java android android-studio
2个回答
3
投票
        String path = Environment.getExternalStorageDirectory().toString();

更改为:

            String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).toString();

对于 Android 10 设备,将

android:legacyExternalStorage="true"
添加到清单文件中的应用程序标记中。

对于 Android 13+ 设备,您不需要任何权限。


0
投票
val path: String = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).toString()

这对我在jetpack compose相关的android应用程序开发中有用。

© www.soinside.com 2019 - 2024. All rights reserved.