Mercurial > libervia-desktop-kivy
view cagou/core/platform_/android.py @ 324:4374cb741eb5
core (common widgets): added a DelayedBoxLayout class:
DelayedBoxLayout delay the sizing, this is useful when sizing is complex and resource
consuming.
Thanks to https://blog.kivy.org/2019/07/a-delayed-resize-layout-in-kivy/
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 06 Dec 2019 13:23:03 +0100 |
parents | e2b51663d8b8 |
children | 89799148f894 |
line wrap: on
line source
#!/usr/bin/env python3 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client # Copyright (C) 2016-2019 Jérôme Poisson (goffi@goffi.org) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import sys from jnius import autoclass, cast from android import activity from sat.core import log as logging from cagou.core.constants import Const as C from cagou import G from kivy.clock import Clock log = logging.getLogger(__name__) service = autoclass('org.salutatoi.cagou.ServiceBackend') mActivity = autoclass('org.kivy.android.PythonActivity').mActivity ImagesMedia = autoclass('android.provider.MediaStore$Images$Media') AudioMedia = autoclass('android.provider.MediaStore$Audio$Media') VideoMedia = autoclass('android.provider.MediaStore$Video$Media') DATA = '_data' STATE_RUNNING = b"running" STATE_PAUSED = b"paused" STATE_STOPPED = b"stopped" SOCKET_DIR = "/data/data/org.salutatoi.cagou/" SOCKET_FILE = ".socket" # cache for callbacks to run when profile is plugged cache = [] def on_new_intent(intent): log.debug("on_new_intent") Intent = autoclass('android.content.Intent') action = intent.getAction(); intent_type = intent.getType(); if action == "android.intent.action.SEND": # we have receiving data to share, we parse the intent data # and show the share widget data = {} text = intent.getStringExtra(Intent.EXTRA_TEXT) if text is not None: data['text'] = text item = intent.getParcelableExtra(Intent.EXTRA_STREAM) if item is not None: uri = cast('android.net.Uri', item) data['uri'] = uri.toString() path = getPathFromUri(uri) if path is not None: data['path'] = path else: uri = None path = None Clock.schedule_once(lambda *args: G.host.share(intent_type, data), 0) else: text = None uri = None path = None msg = (f"NEW INTENT RECEIVED\n" f"type: {intent_type}\n" f"action: {action}\n" f"text: {text}\n" f"uri: {uri}\n" f"path: {path}") log.debug(msg) def onProfilePlugged(profile): log.debug("ANDROID profilePlugged") global cache for method, *args in cache: method(*args) del cache G.host.removeListener("profilePlugged", onProfilePlugged) def init_platform(): # sys.platform is "linux" on android by default # so we change it to allow backend to detect android sys.platform = "android" C.PLUGIN_EXT = 'pyc' def host_init(host): argument = '' service.start(mActivity, argument) activity.bind(on_new_intent=on_new_intent) cache.append((on_new_intent, mActivity.getIntent())) host.addListener('profilePlugged', onProfilePlugged) def getPathFromUri(uri): cursor = mActivity.getContentResolver().query(uri, None, None, None, None) if cursor is None: return uri.getPath() else: cursor.moveToFirst() # FIXME: using DATA is not recommended (and DATA is deprecated) # we should read directly the file with # ContentResolver#openFileDescriptor(Uri, String) col_idx = cursor.getColumnIndex(DATA); if col_idx == -1: return uri.getPath() return cursor.getString(col_idx)