Я создал два простых приложения с Kivy, которые сохраняют файл Sqlite3 db с одним приложением и файл json с другим приложением во встроенные каталоги plyer.storagepath
.Во-первых, цель состояла в том, чтобы проверить, что является приемлемым для среды Android, и, во-вторых, испытать простоту и гениальность проекта plyer.
Проблема в том, что plyer.storagepath
не хочет сохранять файлы вкаталоги storagepath.get_home_dir()
, storagepath.get_root_dir()
и storagepath.get_application_dir()
в среде Android.Я понимаю, почему файлы не будут сохранены в корневом каталоге, но почему бы не домашнему каталогу и каталогу приложений?
Пробовал
1] Предоставил разрешения на хранение приложениям.
2] Использованобиблиотека os.path
python для получения каталога приложения с параметром __file__
и домашнего каталога с параметром ../../..
.Это на самом деле сработало, но я все еще хочу знать, почему plyer.storagepath
вызывал сбой приложения при попытке сохранить в домашний каталог и каталог приложений?
Файл Sqlite3 создает код с помощью python os.path
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()
Ожидаемый результат
Я хочу создать файл в каталогах home и application с помощью plyer из коробки.
В данный моменткаталоги, возвращаемые для каждого пути хранения plyer:
storagepath.get_home_dir()
: /data
storagepath.get_root_dir()
: /system
storagepath.get_application_dir()
: /data/user/0