为什么Kivy Plyer Storagepath不将文件保存到Android home和app目录?

2024-09-30 16:22:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我用Kivy制作了两个简单的应用程序,将一个应用程序的sqlite3db文件和另一个应用程序的json文件保存到plyer.storagepath内置目录中。其目的首先是测试android环境可以接受什么,其次是体验plyer项目的简单性和天才性。你知道吗

问题是plyer.storagepath不想将文件保存到android环境中的storagepath.get_home_dir()storagepath.get_root_dir()storagepath.get_application_dir()目录。我理解为什么文件不会保存到根目录,但为什么不保存到home和app目录?你知道吗

试过

1]授予应用程序存储权限。

2] 使用python的os.path库获取带有__file__参数的App目录和带有../../..参数的Home目录。这确实有效,但我仍然想知道为什么当我试图保存到主目录和应用程序目录时plyer.storagepath会使应用程序崩溃?你知道吗

Sqlite3文件用python创建代码操作系统路径

import kivy
kivy.require('1.11.0')

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.modalview import ModalView
from kivy.uix.button import Button
import os
from os.path import dirname
import sqlite3 as sl
import datetime
import threading, time
import plyer

Builder.load_string('''
#: import Window kivy.core.window.Window
<theData>:
    color: (0,0,0,1)
    background_normal: ''
    background_color: (0.72,0,0,1)
    on_release: app.root.test_file(self)
<ActionButton>:
    background_normal: ''
<DataLabel>:
    size_hint_x: 0.5
    color: (0,0,0,1)
    text: ''
    on_release: app.root.get_ins(self)
    background_normal: ''
    background_color: (0, 0.89, 0.32, 1)
    size_hint_y: None
    text_size: self.width, None
    height: self.texture_size[1]
<Data_Viewer>:
    id: mod_view
    size_hint: (0.8, 0.9)
    background_normal: ''
    background_color: (1, 1, 1, 0)
    background: 'white.png'
    ScrollView:
        size_hint_y: None
        size: mod_view.width, mod_view.height
        GridLayout:
            id: the_dat
            cols: 1
            size_hint_y: None
            height: self.minimum_height
            space: 5
            padding: [0,7,0,7]

<ActionBar>:
    canvas:
        Color:
            rgba: (0.14,0.5,0.71,1)
        Rectangle:
            pos: self.pos
            size: self.size
<TestAn>:
    canvas.before:
        Color:
            rgba: (1,1,1,1)
        Rectangle:
            pos: self.pos
            size: self.size
    ActionBar:
        pos_hint: {'top': 1, 'right': 1}
        ActionView:
            use_separator: True
            ActionPrevious:
                title: ''
                with_previous: False
                app_icon: ''
            ActionButton:
                text: 'Test'
                color: (0,0,0.56,1)
            ActionButton:
                id: view_gps
                Image:
                    source: 'i_5478.png'
                    center_y: self.parent.center_y
                    center_x: self.parent.center_x
                    size: self.parent.width /1.7, self.parent.height/ 1.7
                    allow_stretch: True
    Button:
        id: one_but
        pos_hint: {'top': 0.9, 'right': 1}
        size_hint: [1,0.2]
        text: 'Hello User. Do you want to create a db file?'
        on_release: app.root.sow_dir()
    GridLayout:
        id: view_data
        cols: 1
        size_hint_x: 1
        size_hint_y: None
        height: Window.height / 4
        spacing: 2
        pos_hint: {'right': 1,'top': 0.7}


''')
class DataLabel(Button):
    pass
class theData(Button):
    pass
class Data_Viewer(ModalView):
    pass
class TestAn(FloatLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.ids.view_data.add_widget(theData(text= str(os.path.dirname(os.path.abspath(__file__)))))
        self.ids.view_data.add_widget(theData(text= str(os.path.abspath(os.path.join(__file__ ,"../..")))))
        self.ids.view_data.add_widget(theData(text= str(os.path.abspath(os.path.join(__file__ ,"../../..")))))
        self.ids.view_data.add_widget(theData(text= str(plyer.storagepath.get_home_dir())))
        self.ids.view_data.add_widget(theData(text= str(plyer.storagepath.get_application_dir())))
        self.ids.view_data.add_widget(theData(text= str(plyer.storagepath.get_root_dir())))
    def sow_dir(self):
        m = Data_Viewer()
        m.ids.the_dat.clear_widgets()
        ff = App._get_user_data_dir
        if os.path.exists(os.path.abspath(__file__)):
            m.ids.the_dat.add_widget(DataLabel(text=str(os.path.basename(__file__))))
            m.ids.the_dat.add_widget(DataLabel(text=str(os.path.dirname(os.path.abspath(__file__)))))
            m.ids.the_dat.add_widget(DataLabel(text=str(os.path.abspath(os.path.join(__file__ ,"../..")))))
            m.ids.the_dat.add_widget(DataLabel(text=str(os.path.abspath(os.path.join(__file__ ,"../../..")))))
            m.ids.the_dat.add_widget(DataLabel(text= str(plyer.storagepath.get_home_dir())))
            m.ids.the_dat.add_widget(DataLabel(text= str(plyer.storagepath.get_application_dir())))
            m.ids.the_dat.add_widget(DataLabel(text= str(plyer.storagepath.get_root_dir())))
        m.open()
    def get_ins(self, instance):
        the_db = my_db()
        conn = the_db.create_db(instance.text)
        cur = conn.cursor()
        the_db.create_log_table(cur)
        the_db.log_data_entry(conn,cur, instance.text)
        cur.close()
        conn.close()
    def test_file(self, instance):
        the_path = (instance.text + '/test_entry.db')

        if os.path.isfile(the_path):
            ntitle = 'File Existence'
            nmessage = 'File Exists!'
            the_app_name = str(App.get_running_app().name)
            plyer.notification.notify(title=ntitle, message=nmessage,app_name=the_app_name,timeout=4,ticker='New Incoming Notification',toast=True)

class my_db():
    sql_err = (sl.IntegrityError, sl.OperationalError, sl.ProgrammingError, sl.InterfaceError)
    def create_db(self, db_dir):
        the_path = (db_dir + '/test_entry.db')
        conn = sl.connect(the_path)
        return conn
    def create_log_table(self, cur):
        cur.execute('CREATE TABLE IF NOT EXISTS test_logs(\
                    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\
                    user_id INTEGER NOT NULL,\
                    test_file BLOB NOT NULL, \
                    date_created TEXT NOT NULL)')
    def log_data_entry(self,conn, cur, ins):
        ur = 1
        dte_created = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')
        try:
            cur.execute("INSERT INTO test_logs(user_id, test_file, date_created)\
                        VALUES(?,?, ?)", (ur, ins, dte_created))
            conn.commit()
        except self.sql_err as err:
            cur.close()
class TheAnTestApp(App):
    title = 'The test App'
    def build(self):
        self.icon = 'find_folderpath.png'
        return TestAn()

if __name__ == '__main__':
    TheAnTestApp().run()

Json文件创建代码

import kivy
kivy.require('1.10.0')

from kivy.app import App
import plyer
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty, StringProperty
from kivy.utils import platform

import datetime, json, os

Builder.load_string('''
#: import storagepath plyer.storagepath
<ThePlyThing>:
    Button:
        pos_hint: {'top': 1, 'right': 0.9}
        size_hint: [0.8, 0.05]
        text: 'Get Bluetooth status'
        on_release:
            root.get_info()
    Label:
        pos_hint: {'top': 0.95, 'right': 0.9}
        size_hint: [0.8, 0.04]
        text: str(root.text)
    Label:
        pos_hint: {'top': 0.91, 'right': 0.9}
        size_hint: [0.8, 0.04]
        text: str(root.info)
    TextInput:
        id: tit_notify
        pos_hint: {'top': 0.87, 'x': 0.05}
        size_hint: [0.9, 0.05]
        hint_text: 'Title'
    TextInput:
        id: mess_notify
        pos_hint: {'top': 0.82, 'x': 0.05}
        size_hint: [0.9, 0.05]
        hint_text: 'Message'
    Button:
        pos_hint: {'top': 0.77, 'x': 0.3}
        size_hint: [0.4, 0.08]
        text: 'Get notified true..?'
        on_release: root.get_notified()
    Button:
        pos_hint: {'top': 0.67, 'x': 0.3}
        size_hint: [0.4, 0.04]
        text: 'Home'
        on_press: label.text = str(storagepath.get_home_dir())
    Button:
        pos_hint: {'top': 0.63, 'x': 0.3}
        size_hint: [0.4, 0.04]
        text: 'External Storage'
        on_press:
            label.text = str(storagepath.get_external_storage_dir())
    Button:
        pos_hint: {'top': 0.59, 'x': 0.3}
        size_hint: [0.4, 0.04]
        text: 'Root'
        on_press: label.text = str(storagepath.get_root_dir())
    Button:
        pos_hint: {'top': 0.55, 'x': 0.3}
        size_hint: [0.4, 0.04]
        text: 'Documents'
        on_press: label.text = str(storagepath.get_documents_dir())
    Button:
        pos_hint: {'top': 0.51, 'x': 0.3}
        size_hint: [0.4, 0.04]
        text: 'Downloads'
        on_press: label.text = str(storagepath.get_downloads_dir())
    Button:
        pos_hint: {'top': 0.47, 'x': 0.3}
        size_hint: [0.4, 0.04]
        text: 'Videos'
        on_press: label.text = str(storagepath.get_videos_dir())
    Button:
        pos_hint: {'top': 0.43, 'x': 0.3}
        size_hint: [0.4, 0.04]
        text: 'Music'
        on_press: label.text = str(storagepath.get_music_dir())
    Button:
        pos_hint: {'top': 0.39, 'x': 0.3}
        size_hint: [0.4, 0.04]
        text: 'Pictures'
        on_press: label.text = str(storagepath.get_pictures_dir())
    Button:
        pos_hint: {'top': 0.35, 'x': 0.3}
        size_hint: [0.4, 0.04]
        text: 'Applications'
        on_press: label.text = str(storagepath.get_application_dir())
    Button:
        pos_hint: {'top': 0.67, 'x': 0}
        size_hint: [0.3, 0.04]
        text: 'New File'
        on_press: root.create_file()
    Button:
        pos_hint: {'top': 0.67, 'x': 0.7}
        size_hint: [0.3, 0.04]
        text: 'Existence'
        on_press:
            root.test_file()
    Label:
        canvas.before:
            Color:
                rgba: (0.57,0.57,0.57,1)
            Rectangle:
                pos: self.pos
                size: self.size
        id: label
        pos_hint: {'top': 0.31, 'x': 0}
        size_hint: [1, 0.1]
    Button:
        pos_hint: {'top': 0.20, 'x': 0.05}
        size_hint: [0.4, 0.05]
        text: 'Vibrate'
        on_press: root.get_vibe()
''')
class ThePlyThing(FloatLayout):
    info = ObjectProperty()
    text = StringProperty()
    dte = StringProperty()
    fil = StringProperty()
    text = "Bluetooth: "
    def get_notified(self):
        if self.ids.tit_notify.text != '' and self.ids.mess_notify.text != '':
            ntitle = str(self.ids.tit_notify.text)
            nmessage = str(self.ids.mess_notify.text)
            the_app_name = str(App.get_running_app().name)
            plyer.notification.notify(title=ntitle, message=nmessage,app_name=the_app_name,timeout=4,ticker='New Incoming Notification',toast=True)
    def get_info(self):
        if platform == 'android' or platform == 'ios': 
            self.info = str(plyer.bluetooth.info)
        else:
            self.info = 'Not supported'
    def get_vibe(self):
        if platform == 'android' or platform == 'ios':
            if plyer.vibrator.exists():
                plyer.vibrator.vibrate(4)
            else:
                the_app_name = str(App.get_running_app().name)
                plyer.notification.notify(title='No Vibrator', message='No Vibrator',app_name=the_app_name,timeout=4,ticker='New Incoming Notification',toast=True)
    def create_file(self):
        self.fil = self.ids.label.text
        if self.fil != "":
            self.dte = datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S')
            dat = {}
            dat['newfile'] = []  
            dat['newfile'].append({  
                'name': 'File Exists!',
                'thedate': self.dte,
                'from': 'Herman'
            })

            with open(self.fil + '/data_file.txt', 'w') as outfile:  
                json.dump(dat, outfile)
    def test_file(self):
        self.fil = self.ids.label.text
        if self.fil != "":
            self.fil = self.fil + '/data_file.txt'
            if os.path.isfile(self.fil):
                the_app_name = str(App.get_running_app().name)
                with open(self.fil) as json_file:
                    rd_dat = json.load(json_file)
                    for p in rd_dat['newfile']:
                        if p['name']:
                            mess = p['name']
                        if p['thedate']:
                            mess = mess + ' ' + p['thedate']
                if mess != "":
                    plyer.notification.notify(title='File Exists', message=mess,app_name=the_app_name,timeout=4,ticker='New Incoming Notification',toast=True)
class AndyApp(App):
    title = 'The Ply Test'
    def build (self):
        self.icon = 'test_all_limits.png'
        return ThePlyThing()
    def on_pause(self):
        return True

AndyApp().run()

预期结果

我想在主目录和应用程序目录中创建一个文件使用plyer开箱即用。

当前为每个plyer storagepath返回的目录是:

storagepath.get_home_dir()/data

storagepath.get_root_dir()/system

storagepath.get_application_dir()/data/user/0


Tags: thepathtextposimportselfappsize