Jan-24-2024, 06:28 PM
Hi all, I have app using Kivy and I need open / save csv files. Under Windows/Linux it works well but not under Android. I see folders but no files. Testing on Android 13 but must works also on 10,11,12.
Any suggestion? Thank you.
Part of open/save code:
android.permissions = INTERNET, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE
Any suggestion? Thank you.
Part of open/save code:
# OPEN FILE DOALOG ==================================================================================================
def show_load(self):
self.root.ids.sm.current = 'open_screen'
open_layout = self.root.ids.open_layout
open_layout.clear_widgets()
if platform == 'android':
default_path = '/storage/emulated/0/'
else:
default_path = '.'
file_chooser = FileChooserIconView(size_hint=(1, 1), path=default_path)
file_chooser.filters = ['*.csv'] # Show only CSV files
open_layout.add_widget(file_chooser)
status_label = Label(text='', size_hint=(1, None), height=dp(40))
open_layout.add_widget(status_label)
open_button = Button(text="Open", size_hint=(1, None), height=dp(40))
open_button.bind(on_release=lambda instance: self.open_file(file_chooser.selection[0],
file_chooser.path, status_label))
open_layout.add_widget(open_button)
exit_layout = BoxLayout(orientation='horizontal', size_hint_y=None, height=dp(40))
exit_button = Button(text="Exit")
exit_button.bind(on_release=self.switch_to_main)
exit_layout.add_widget(exit_button)
open_layout.add_widget(exit_layout)
# OPEN FILE AND LOAD DATA ===================================================================================
def open_file(self, file_name, path, status_label):
if not file_name:
status_label.text = "Error: No file selected."
return
file_path = os.path.join(path, file_name)
if not os.path.exists(file_path):
status_label.text = "Error: File does not exist."
return
try:
with open(file_path, 'r') as file:
file_content = file.read().replace(';', '')
file_like_object = StringIO(file_content)
data = np.loadtxt(file_like_object, dtype="float")
if len(data) == 0:
status_label.text = "Error: No data in file."
return
self.accel_data = data
self.SPS = len(self.accel_data)
data_sps_button = self.root.ids.data_SPS
data_sps_button.text = f"SPS: {self.SPS}"
self.switch_to_main(None)
except IOError as io_err:
status_label.text = f"Error opening file: {io_err}"
except ValueError as val_err:
status_label.text = f"Error in file format: {val_err}"
except Exception as e:
status_label.text = f"An unexpected error occurred: {e}"
# SAVE FILE DIALOG ===================================================================================
def show_save(self):
self.root.ids.sm.current = 'save_screen'
save_layout = self.root.ids.save_layout
save_layout.clear_widgets()
file_name_input = TextInput(hint_text="Enter file name (e.g., my_file.csv)",
size_hint=(1, None), height=dp(40))
save_layout.add_widget(file_name_input)
if platform == 'android':
default_path = '/storage/emulated/0/'
else:
default_path = '.'
file_chooser = FileChooserIconView(size_hint=(1, 1), path=default_path)
save_layout.add_widget(file_chooser)
status_label = Label(text='', size_hint=(1, None), height=dp(40))
save_layout.add_widget(status_label)
save_button = Button(text="Save", size_hint=(1, None), height=dp(40))
save_button.bind(on_release=lambda instance: self.save_file(file_name_input.text,
file_chooser.path, status_label))
save_layout.add_widget(save_button)
exit_layout = BoxLayout(orientation='horizontal', size_hint_y=None, height=dp(40))
exit_button = Button(text="Exit")
exit_button.bind(on_release=self.switch_to_main)
exit_layout.add_widget(exit_button)
save_layout.add_widget(exit_layout)
# SAVE FILE ==============================================================================================================
def save_file(self, file_name, path, status_label):
if path and file_name:
if not file_name.lower().endswith('.csv'):
file_name += '.csv'
file_path = os.path.join(path, file_name)
if not hasattr(self, 'accel_data') or self.accel_data is None:
status_label.text = "Error: No acceleration data available."
return
data = self.accel_data
if len(data) == 0 or not isinstance(data, np.ndarray):
status_label.text = "Error: Invalid data. Data must be a non-empty numpy array."
return
try:
np.savetxt(file_path, data, delimiter=',')
status_label.text = f"File saved as: {file_path}"
except IOError as io_err:
status_label.text = f"Error saving file: {io_err}"
except Exception as e:
status_label.text = f"An unexpected error occurred: {e}"
else:
status_label.text = "Please enter a file name and select a save location."When I compile to APK, I use this in buildozer.spec:android.permissions = INTERNET, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE
