comparison cagou/core/platform_/android.py @ 322:e2b51663d8b8

core, android: new share widget + added Cagou to "share" menu: - new intent filter to add Cagou to share menu for all media types - minimum Kivy version is now 1.11.0 - new "Share" widget to display data to share via SàT and select the target - new core.platform_ module (the suffix "_" avoid trouble with standard "platform" module), for platform specific code. - Android intent are now checked on startup and "on_new_intent" events - if a android.intent.action.SEND action is received (i.e. some data is shared), the "Share" widget is shown - new Cagou.share method to share data using "Share" widget - new Cagou.getAncestorWidget method to easily retrieve an instance of a specific class in a widget's ancestors - ContactList's Avatar and ContactItem widgets have been moved to core.common
author Goffi <goffi@goffi.org>
date Fri, 06 Dec 2019 13:23:03 +0100
parents
children 89799148f894
comparison
equal deleted inserted replaced
321:a6eb154ba266 322:e2b51663d8b8
1 #!/usr/bin/env python3
2
3 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client
4 # Copyright (C) 2016-2019 Jérôme Poisson (goffi@goffi.org)
5
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Affero General Public License for more details.
15
16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 import sys
20 from jnius import autoclass, cast
21 from android import activity
22 from sat.core import log as logging
23 from cagou.core.constants import Const as C
24 from cagou import G
25 from kivy.clock import Clock
26
27
28 log = logging.getLogger(__name__)
29
30 service = autoclass('org.salutatoi.cagou.ServiceBackend')
31 mActivity = autoclass('org.kivy.android.PythonActivity').mActivity
32 ImagesMedia = autoclass('android.provider.MediaStore$Images$Media')
33 AudioMedia = autoclass('android.provider.MediaStore$Audio$Media')
34 VideoMedia = autoclass('android.provider.MediaStore$Video$Media')
35 DATA = '_data'
36
37
38 STATE_RUNNING = b"running"
39 STATE_PAUSED = b"paused"
40 STATE_STOPPED = b"stopped"
41 SOCKET_DIR = "/data/data/org.salutatoi.cagou/"
42 SOCKET_FILE = ".socket"
43
44 # cache for callbacks to run when profile is plugged
45 cache = []
46
47
48 def on_new_intent(intent):
49 log.debug("on_new_intent")
50 Intent = autoclass('android.content.Intent')
51 action = intent.getAction();
52 intent_type = intent.getType();
53 if action == "android.intent.action.SEND":
54 # we have receiving data to share, we parse the intent data
55 # and show the share widget
56 data = {}
57 text = intent.getStringExtra(Intent.EXTRA_TEXT)
58 if text is not None:
59 data['text'] = text
60 item = intent.getParcelableExtra(Intent.EXTRA_STREAM)
61 if item is not None:
62 uri = cast('android.net.Uri', item)
63 data['uri'] = uri.toString()
64 path = getPathFromUri(uri)
65 if path is not None:
66 data['path'] = path
67 else:
68 uri = None
69 path = None
70
71 Clock.schedule_once(lambda *args: G.host.share(intent_type, data), 0)
72 else:
73 text = None
74 uri = None
75 path = None
76
77 msg = (f"NEW INTENT RECEIVED\n"
78 f"type: {intent_type}\n"
79 f"action: {action}\n"
80 f"text: {text}\n"
81 f"uri: {uri}\n"
82 f"path: {path}")
83
84 log.debug(msg)
85
86
87 def onProfilePlugged(profile):
88 log.debug("ANDROID profilePlugged")
89 global cache
90 for method, *args in cache:
91 method(*args)
92 del cache
93 G.host.removeListener("profilePlugged", onProfilePlugged)
94
95
96 def init_platform():
97 # sys.platform is "linux" on android by default
98 # so we change it to allow backend to detect android
99 sys.platform = "android"
100 C.PLUGIN_EXT = 'pyc'
101
102
103 def host_init(host):
104 argument = ''
105 service.start(mActivity, argument)
106
107 activity.bind(on_new_intent=on_new_intent)
108 cache.append((on_new_intent, mActivity.getIntent()))
109 host.addListener('profilePlugged', onProfilePlugged)
110
111
112 def getPathFromUri(uri):
113 cursor = mActivity.getContentResolver().query(uri, None, None, None, None)
114 if cursor is None:
115 return uri.getPath()
116 else:
117 cursor.moveToFirst()
118 # FIXME: using DATA is not recommended (and DATA is deprecated)
119 # we should read directly the file with
120 # ContentResolver#openFileDescriptor(Uri, String)
121 col_idx = cursor.getColumnIndex(DATA);
122 if col_idx == -1:
123 return uri.getPath()
124 return cursor.getString(col_idx)