Getting [Errno 1] Operation is not permitted error when trying to write to /storage/emulated/0 with Kivy and Python on Android

huangapple go评论94阅读模式
英文:

Getting [Errno 1] Operation is not permitted error when trying to write to /storage/emulated/0 with Kivy and Python on Android

问题

I have been around the mulberry bush for a few weeks now trying to implement the writing of a file on an android phone. My development setup is on a Windows PC with Anaconda and Pycharm. I am using kivy and buildozer to create the android app. My test app is simply trying to write a file (test.txt) to the root directory of the SD card on the phone.

The directory is: /storage/emulated/0

The error I am getting is: [Errno 1] Operation is not permitted: '/storage/emulated/0/test.txt'

I ask for permissions in the code, but the permissions are not prompted at application startup or installation.

Here is the code;

import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.utils import platform
import os

class MyGridLayout(GridLayout):
    def __init__(self, **kwargs):
        super(MyGridLayout, self).__init__(**kwargs)

        self.cols = 1

        self.dir_button = Button(text="Show Directory")
        self.dir_button.bind(on_press=self.press_dir)
        self.add_widget(self.dir_button)

        self.write_button = Button(text="Write File")
        self.write_button.bind(on_press=self.press_write)
        self.add_widget(self.write_button)

        self.text_field = TextInput(multiline=True)
        self.add_widget(self.text_field)

    def press_dir(self, instance):
        if platform == 'android':
            from android.storage import primary_external_storage_path
            self.file_dir = primary_external_storage_path()
        else:
            self.file_dir = App.get_running_app().user_data_dir

        if not os.path.exists(self.file_dir):
            os.mkdir(self.file_dir)

        self.text_field.text = self.file_dir

    def press_write(self, instance):
        self.file_name = "test.txt"
        self.full_name = os.path.join(self.file_dir, self.file_name)
        try:
            with open(self.full_name, "w") as outfile:
                outfile.write("Hello World")
        except Exception as e:
            self.text_field.text = str(e)

class TestWriteApp(App):
    def build(self):
        return MyGridLayout()

if platform == 'android':
    from android.permissions import request_permissions, Permission
    request_permissions([Permission.WRITE_EXTERNAL_STORAGE,
                         Permission.READ_EXTERNAL_STORAGE])

testwriteapp = TestWriteApp()
testwriteapp.run()

Here are the screenshots during testing;
Show Directory button
enter image description here

Write File button
enter image description here

Thanks for your help.

I tried a number of things...adding permissions in the buildozer.spec file, changing the output location to the internal user_data_dir (which worked, I think, but I need the user to be able to use the Files app to get the generated file)

英文:

I have been around the mulberry bush for a few weeks now trying to implement the writing of a file on an android phone. My development setup is on a Windows PC with Anaconda and Pycharm. I am using kivy and buildozer to create the android app. My test app is simply trying to write a file (test.txt) to the root directory of the SD card on the phone.

The directory is: /storage/emulated/0

The error I am getting is: [Errno 1] Operation is not permitted: '/storage/emulated/0/test.txt'

I ask for permissions in the code, but the permissions are not prompted at application startup or installation.

Here is the code;

import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.utils import platform
import os
class MyGridLayout(GridLayout):
def __init__(self, **kwargs):
super(MyGridLayout, self).__init__(**kwargs)
self.cols = 1
self.dir_button = Button(text="Show Directory")
self.dir_button.bind(on_press=self.press_dir)
self.add_widget(self.dir_button)
self.write_button = Button(text="Write File")
self.write_button.bind(on_press=self.press_write)
self.add_widget(self.write_button)
self.text_field = TextInput(multiline=True)
self.add_widget(self.text_field)
def press_dir(self, instance):
if platform == 'android':
from android.storage import primary_external_storage_path
self.file_dir = primary_external_storage_path()
else:
self.file_dir = App.get_running_app().user_data_dir
if not os.path.exists(self.file_dir):
os.mkdir(self.file_dir)
self.text_field.text = self.file_dir
def press_write(self, instance):
self.file_name = "test.txt"
self.full_name = os.path.join(self.file_dir, self.file_name)
try:
with open(self.full_name, "w") as outfile:
outfile.write("Hello World")
except Exception as e:
self.text_field.text = str(e)
class TestWriteApp(App):
def build(self):
return MyGridLayout()
if platform == 'android':
from android.permissions import request_permissions, Permission
request_permissions([Permission.WRITE_EXTERNAL_STORAGE,
Permission.READ_EXTERNAL_STORAGE])
testwriteapp = TestWriteApp()
testwriteapp.run()

Here are the screenshots during testing;
Show Directory button
enter image description here

Write File button
enter image description here

Thanks for your help.

I tried a number of things...adding permissions in the buildozer.spec file, changing the output location to the internal user_data_dir (which worked, I think, but I need the user to be able to use the Files app to get the generated file)

答案1

得分: 0

在 Android 11+ 设备上,您不能再像您尝试的那样写入外部存储的根目录。

而是请使用已经存在的公共目录,如文档和下载。

在 Android 13 设备上,您无需任何权限来执行此操作。

英文:

On Android 11+ devices you cannot write anymore to root of external storage as you try to do.

Instead use public directories that are already there like Documents and Download.

On Android 13 devices you do not need any permission to do so.

huangapple
  • 本文由 发表于 2023年5月29日 23:05:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76358425.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定