Android studio 抛出 IOException:不允许操作

2024-01-20

现在,我正在为自己创建一个应用程序,它将数据附加到几个文件中。但是当我尝试创建文件 - 或者实际上打开它们 - 时,程序会抛出java.io.IOException: Operation not permitted.

如您所见,已授予存储权限。 (这个应用程序是专门为我自己设计的,所以我不太担心其他用户会是什么样子。)

直接通过手机本身或通过我的计算机检查文件系统不会显示这些文件。

注意:创建目录(即dir.mkdirs();) does not即使我事先删除了目录,也会引发错误。然而,处理这些文件确实会引发错误。

我运行的是 Android 11,并且我的 Android Studio 设置为在 Lollipop 中工作。

MainActivity.java:

public class MainActivity extends AppCompatActivity {
    
    public static File dir = new File(new File(Environment.getExternalStorageDirectory(), "bleh"), "bleh");
    
    @Override protected void onCreate(Bundle savedInstanceState) {
        
        //bleh
        
        dir.mkdirs();
        dir.setWritable(true)
        addButtons();
        
    }
    
    public void addButtons() throws IOException {
        
        Option.A.init(R.id.A);
        Option.B.init(R.id.B);
        Option.C.init(R.id.C);
        Option.D.init(R.id.D);
        Option.E.init(R.id.E);
        Option.F.init(R.id.F);
        
        // This is beyond the scope of my 
        // question, but if you could also 
        // show me a better way to do this, 
        // that would be great.
        
    }
    
}

Option.java:

public enum Option {
    
    A, B, C, D, E, F, ;
    
    public File data;
    public PrintWriter printer;
    
    Option() {
        
        data = new File(MainActivity.dir, name().toLowerCase() + ".data");
        
    }
    
    public void init(int buttonid) {
        
        try {
            
            data.createNewFile();
            printer = new PrintWriter(data);
            // Both of these lines throw this exception.
            
        } catch (IOException ex) {
            
            ex.printStackTrace(System.err);
            
        }
        
    }
    
}

对于 Android 11,仅拥有存储权限不足以像我们以前那样将文件写入共享存储。由于 Android 11 中的存储更新:https://developer.android.com/about/versions/11/privacy/storage https://developer.android.com/about/versions/11/privacy/storage

所以有两种方法:

1) MANAGE_EXTERNAL_STORAGE允许

如果您将此代码保留给自己并且不希望将其上传到 Play 商店,那么这是一种简单的方法。因为如果没有充分的理由,大多数应用程序都不会被允许。

我创建了一个示例代码。

在您的清单中声明依赖项:

<uses-permission
        android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        android:minSdkVersion="30" />

在你的代码中:

您需要检查您的应用程序是否已经是存储管理器。Environment.isExternalStorageManager()&如果没有则重定向到设置ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION您将在其中获得允许的选项。您应该会看到您的应用程序列在那里。

一旦允许,您将能够创建目录/文件。

public class MainActivity extends AppCompatActivity {

    public static File dir = new File(new File(Environment.getExternalStorageDirectory(), "bleh"), "bleh");


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn = findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                askForPermissions();
            }
        });

    }

    @Override
    protected void onResume() {
        super.onResume();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                createDir();
            }
        }
    }

    public void askForPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                startActivity(intent);
                return;
            }
            createDir();
        }
    }

    public void createDir(){
        if (!dir.exists()){
            dir.mkdirs();
        }
    }

}

您可以在这里阅读更多相关内容:https://developer.android.com/training/data-storage/manage-all-files https://developer.android.com/training/data-storage/manage-all-files

您可以在这里找到示例:https://github.com/android/storage-samples/tree/main/FileManager https://github.com/android/storage-samples/tree/main/FileManager

2) 遵循范围存储指南。

这方面也有一些方法。我将向您展示如何添加文件Documents目录。这是一个共享空间。为此,您不需要许可。

您可以使用getContentResolver&插入文件到外部存储&并将相对位置设置为DIRECTORY_DOCUMENTS.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn = findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    saveFileToExternalStorage(String.valueOf(System.currentTimeMillis()),"Test");
                }
            }
        });

    }

    @RequiresApi(Build.VERSION_CODES.Q)
    private void saveFileToExternalStorage(String displayName, String content) {
        Uri externalUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);

        String relativeLocation = Environment.DIRECTORY_DOCUMENTS;

        ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, displayName + ".txt");
        contentValues.put(MediaStore.Files.FileColumns.MIME_TYPE, "application/text");
        contentValues.put(MediaStore.Files.FileColumns.TITLE, "Test");
        contentValues.put(MediaStore.Files.FileColumns.DATE_ADDED, System.currentTimeMillis() / 1000);
        contentValues.put(MediaStore.Files.FileColumns.RELATIVE_PATH, relativeLocation);
        contentValues.put(MediaStore.Files.FileColumns.DATE_TAKEN, System.currentTimeMillis());

        Uri fileUri = getContentResolver().insert(externalUri, contentValues);
        try {
            OutputStream outputStream =  getContentResolver().openOutputStream(fileUri);
            outputStream.write(content.getBytes());
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

} 

您可以在这里阅读更多相关内容:https://www.androidcentral.com/what-scoped-storage https://www.androidcentral.com/what-scoped-storage

您可以在这里找到合适的示例:https://github.com/android/storage-samples/tree/main/ScopedStorage https://github.com/android/storage-samples/tree/main/ScopedStorage

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android studio 抛出 IOException:不允许操作 的相关文章

  • 带有自定义阵列适配器的微调器不允许选择项目

    我使用自定义阵列适配器作为微调器 但是 当在下拉列表中选择一个项目时 下拉列表保留在那里 并且微调器不会更新 这是错误行为 与使用带有字符串的通用数组适配器相比 这是自定义类 我错过了什么吗 谢谢 public class Calendar
  • 迁移到 java 17 后有关“每个进程的内存映射”和 JVM 崩溃的 GC 警告

    我们正在将 java 8 应用程序迁移到 java 17 并将 GC 从G1GC to ZGC 我们的应用程序作为容器运行 这两个基础映像之间的唯一区别是 java 的版本 例如对于 java 17 版本 FROM ubuntu 20 04
  • Flutter 深度链接

    据Flutter官方介绍深层链接页面 https flutter dev docs development ui navigation deep linking 我们不需要任何插件或本机 Android iOS 代码来处理深层链接 但它并没
  • ROOM迁移过程中如何处理索引信息

    CODE Entity tableName UserRepo indices Index value id unique true public class GitHubRepo PrimaryKey autoGenerate true p
  • Java中接口作为方法参数

    前几天去面试 被问到了这样的问题 问 反转链表 给出以下代码 public class ReverseList interface NodeList int getItem NodeList nextNode void reverse No
  • 从 android 简单上传到 S3

    我在网上搜索了从 android 上传简单文件到 s3 的方法 但找不到任何有效的方法 我认为这是因为缺乏具体步骤 1 https mobile awsblog com post Tx1V588RKX5XPQB TransferManage
  • Spring Data 与 Spring Data JPA 与 JdbcTemplate

    我有信心Spring Data and Spring Data JPA指的是相同的 但后来我在 youtube 上观看了一个关于他正在使用JdbcTemplate在那篇教程中 所以我在那里感到困惑 我想澄清一下两者之间有什么区别Spring
  • 使用 Matrix.setPolyToPoly 选择位图上具有 4 个点的区域

    我正在 Android 上使用位图 在使用 4 个点选择位图上的区域时遇到问题 并非所有 4 点组都适合我 在某些情况下 结果只是一个空白位图 而不是裁剪后的位图 如图所示 并且 logcat 中没有任何错误 甚至是内存错误 这是我用来进行
  • 归并排序中的递归:两次递归调用

    private void mergesort int low int high line 1 if low lt high line 2 int middle low high 2 line 3 mergesort low middle l
  • Android Webview 图像未加载

    我制作了一个简单的应用程序WebView 但有些图片无法加载 正确 在我的电脑上 错误 在模拟器中 Correct 错误 没有横幅 于是我用Chrome debug进行调试 发现我的代码被改变了 我不添加像noscript or style
  • 检查 protobuf 消息 - 如何按名称获取字段值?

    我似乎无法找到一种方法来验证 protobuf 消息中字段的值 而无需显式调用其 getter 我看到周围的例子使用Descriptors FieldDescriptor实例到达消息映射内部 但它们要么基于迭代器 要么由字段号驱动 一旦我有
  • org.jdesktop.application 包不存在

    几天以来我一直在构建一个 Java 桌面应用程序 一切都很顺利 但是今天 当我打开Netbeans并编译文件时 出现以下编译错误 Compiling 9 source files to C Documents and Settings Ad
  • Android 设备上的静默安装

    我已经接受了一段时间了 在 Android 上静默安装应用程序是不可能的 也就是说 让程序安装捆绑为 APK 的应用程序 而不提供标准操作系统安装提示并完成应用程序安装程序活动 但现在我已经拿到了 Appbrain 快速网络安装程序的副本
  • 如何配置eclipse以保持这种代码格式?

    以下代码来自 playframework 2 0 的示例 Display the dashboard public static Result index return ok dashboard render Project findInv
  • 如何测试 spring-security-oauth2 资源服务器安全性?

    随着 Spring Security 4 的发布改进了对测试的支持 http docs spring io spring security site docs 4 0 x reference htmlsingle test我想更新我当前的
  • Python 读取未格式化的直接访问 Fortran 90 给出不正确的输出

    这是数据的写入方式 它是一个二维浮点矩阵 我不确定大小 open unit 51 file rmsd nn output form unformatted access direct status replace recl Npoints
  • 在webview android中加载本地html文件

    我正在尝试在 android 的 webview 中加载 html 文件的内容 但是 它给了我 网页不可用错误 如果我尝试使用谷歌或雅虎等网站 它们就会起作用 html文件位于src gt main gt assests gt index
  • 为什么Android的ImageReader类这么慢?

    我尝试了适用于 Android 3 4 1 的全新 OpenCVJavaCamera2View但它太慢了 仅显示相机视图约 15 fps 当我尝试较旧的JavaCameraView相反 它给了我很好的结果 30fps 这是我相机的极限 我想
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个
  • 如何删除因 Google Fitness API 7.5.0 添加的权限

    将我的 play services fitness api 从 7 0 0 更新到 7 5 0 后 我注意到当我将新版本上传到 PlayStore 时 它 告诉我正在添加一个新权限和 2 个新功能 我没有这样做 有没有搞错 在做了一些研究来

随机推荐

  • 元组列表到数据帧的转换[重复]

    这个问题在这里已经有答案了 我有一个类似于以下内容的元组列表 date1 ticker1 value1 date1 ticker1 value2 date1 ticker1 value3 我想将其转换为 DataFrameindex dat
  • 如何在PHP中获取新推送项目的数字键?

    arr new item 是否可以通过编程方式获取新推送的项目 请注意 这不是必需的count arr 1 arr 1 2 arr new item 在上面的例子中 就是2 end 完成工作 返回价值 如果对你有帮助 您可以使用key 之后
  • RuntimeBinderException - C# .NET 4 动态关键字 - 帮助我理解为什么方法不匹配

    我为 HttpModule 构建了一个通用配置系统 允许可插入的 HTTP 标头检查器 作为参考 这里是代码的基本布局 这应该足以让我了解我正在做的事情 public interface IHttpHeaderInspectingAuthe
  • 如何为我的 Java 应用程序指定一个唯一的进程名称?

    我注意到 当我启动 Netbeans 时 它在任务管理器中显示为netbeans exe因为我自己的所有 Java 应用程序都显示为java exe or javaw exe 我怎样才能改变它 以便我的进程名称显示为myapp exe 进程
  • 在 R 中创建空间数据

    我有一个 100 x 200 米区域内物种及其大致位置的数据集 数据框的位置部分不是我认为可用的格式 在这个 100 x 200 米的矩形中 有 200 个 10 x 10 米的正方形 分别命名为 A 到 CV 每个 10 x 10 的正方
  • 如何动态添加导航栏到 jQuery Mobile 应用程序

    如何动态地将导航栏添加到我的 jquery 移动应用程序中 我希望能够从 javascript 将导航栏元素添加到 dom 然后解析它们 我发现我可以根据需要将元素添加到 DOM 然后在元素上调用 navbar 它将执行导航栏解析 例如我可
  • Ormlite Android 批量插入

    谁能解释一下为什么我的插入在 Ormlite 中花费了这么长时间 在桌面上的一个 SQLite 事务中执行 1 700 次插入只需不到一秒 然而 当使用 Ormlite for Android 时 大约需要 70 秒 并且我可以在调试消息中
  • .NET几何库[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在 NET 中启动一个新项目 该项目需要一些几何算法 例如 检查点是否在多边形内部 贝塞尔曲线 线交
  • 在 C# 类库中使用 MATLAB MWArray.dll

    我正在尝试使用 dll 在 MATLAB 中使用 Matlab net Complier 构建 C 类库 但是每次初始化 MWArray dll 中的对象时程序都会引发异常 例如 MWNumericArray m new MWNumeric
  • json.dump 在看似有效的对象上抛出“TypeError:{...} 不是 JSON 可序列化”?

    背景 我正在编写一个 python 程序来管理我的音乐文件 它抓取目录并将文件及其元数据 通过诱变剂 以 JSON 编码 作为简单的 数据库 放入文件中 我的目录搜索很好 但是当我尝试保存数据库或编码为 JSON 时 它会抛出 TypeEr
  • 维护 web.config 文件

    我很想知道其他人如何维护已部署应用程序的 web config 文件 假设没有自动部署机制 这超出了这个问题的范围 因此 在开发过程中 一些开发人员可能会利用 web config 转换 构建 发布他们的项目 调试 发布 测试 实时配置 然
  • 如何撤消clearPackagePreferredActivities("com.android.launcher");

    我想做的是复制 ToddlerLock 应用程序的功能 我已经设法清除默认启动器 PackageManager localPackageManager getPackageManager localPackageManager clearP
  • 使用 Apollo/graphQL/React 访问和刷新令牌

    经过长时间的搜索 当访问令牌过期时 我为我的应用程序制定了这个解决方案 与其他服务的区别在于 我必须使用外部服务 在使用我的谷歌帐户登录时为我提供访问和刷新令牌 然后 当访问令牌过期时 我需要检索刷新令牌 将其发送到为我提供新访问和刷新令牌
  • C - 求结构的尺寸

    我被问到这个问题作为面试问题 无法回答 编写一个 C 程序来查找结构的大小 而不使用sizeof操作员 struct XYZ int x float y char z int main struct XYZ arr 2 int sz cha
  • ServiceStack.Text 是否提供 JSON 的漂亮打印?

    TL DR ServiceStack Text 中是否有内置方法来生成打印精美的 JSON 我在用ServiceStack Text https github com ServiceStack ServiceStack Text用于进行 J
  • 如何在 Angular2 的 Pipe 中将数组作为 arg 传递

    我创建了一个管道 其目的是根据标签列表过滤列表 Pipe name tagfilter export class TagFilterPipe implements PipeTransform transform items Event ar
  • 更改操作栏溢出的样式

    我在我当前的 android 应用程序中使用 Theme Holo 上面是我当前主题的溢出 UI 我想将溢出菜单的背景颜色自定义为 RGB 245 243 239 将字体颜色自定义为 RGB 64 64 64 以下是我正在使用的 style
  • 在 ActionBar 上放置一个进度条

    我试图在操作栏上放置一个不确定的进度栏 例如 我使用 actionView 来放置进度条 例如 Google 应用程序
  • 如何将模式模板的 let-c="close" 传递给其他组件的 html Angular 5

    我是 Angular 4 的新手 请帮助我 我有一个具有模式模板的组件 成分 import Component from angular core import NgbModal ModalDismissReasons from ng bo
  • Android studio 抛出 IOException:不允许操作

    现在 我正在为自己创建一个应用程序 它将数据附加到几个文件中 但是当我尝试创建文件 或者实际上打开它们 时 程序会抛出java io IOException Operation not permitted 如您所见 已授予存储权限 这个应用