我正在尝试使用 Kivy 和 buildozer 制作一个简单的 android 应用程序,我在其中对 WhatsApp 导出的聊天做出反应。现在我只尝试将应用程序中的最后三条消息打印到屏幕上。问题是表情符号没有正确读取。例如,我有一个聊天,其中最后三条消息是:
14-11-19 09:17 - MyName:这是一个测试消息
14-11-19 09:17 - 我的名字:带有表情符号
19 年 14 月 11 日 09:17 - 我的名字:
表情符号应该是 U+0001F602
表情符号应该是 U+0001F44C U+0001F3FB
如果我将聊天导出为 .txt,然后在桌面上使用相同的程序,我的输出是正确的: .
这是我的代码:
意图过滤器.xml
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="multipart/*" />
<data android:mimeType="text/*" />
<data android:mimeType="text/plain" />
</intent-filter>
主文件.kv
<AuxScreen>:
BoxLayout:
Label:
text: "Nothing here"
<MainScreen>
loadinglabel : loadinglabel
BoxLayout:
Label:
id : loadinglabel
text: "loading..."
text_size: self.width, None
halign: 'center'
主文件
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.utils import platform
from kivy.clock import Clock
from kivy.uix.screenmanager import ScreenManager, Screen
if platform == "android":
from jnius import autoclass
APP_NAME = "Test"
Builder.load_file("main.kv")
testfile = "mytest.txt" # for debugging on desktop
class RootWidget(ScreenManager):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.parent_app = App.get_running_app()
if not (self.parent_app.intent or self.parent_app.chatdata):
self.add_widget(AuxScreen(name = "aux"))
else:
self.add_widget(MainScreen(name="main"))
class AuxScreen(Screen):
pass
class MainScreen(Screen):
loadinglabel = ObjectProperty(None)
def on_enter(self):
Clock.schedule_once(lambda x: self.start_processing(), 1)
def start_processing(self):
if not self.manager.parent_app.chatdata:
self.manager.parent_app.get_chatdata()
self.loadinglabel.text = "".join(str(x.encode('unicode-escape')) + "\n" for x in self.manager.parent_app.chatdata[-4:])
class MyApp(App):
title = APP_NAME
def __init__(self, intent, **kwargs):
super().__init__(**kwargs)
self.intent = intent
self.chatdata = None
# For debugging on linux desktop
if platform == "linux":
filename = testfile # Put here the name of your testfile
f = open(filename, "r")
self.chatdata = "".join(l for l in f.readlines()).split('\n')
f.close()
def build(self):
return RootWidget()
def get_chatdata(self):
InputStreamReader = autoclass('java.io.InputStreamReader')
BufferedReader = autoclass('java.io.BufferedReader')
StringBuilder = autoclass('java.lang.StringBuilder')
PythonActivity = autoclass('org.renpy.android.PythonActivity')
activity = PythonActivity.mActivity
uri = self.intent.getClipData().getItemAt(0).getUri()
inputstream = activity.getContentResolver().openInputStream(uri)
reader = InputStreamReader(inputstream, "UTF-8")
recv_stream = BufferedReader(reader)
data = StringBuilder()
while True:
line = recv_stream.readLine()
if line:
data.append(line)
data.append('\n')
else:
nextchar = recv_stream.read()
if nextchar == -1:
break
data.append(chr(nextchar))
self.chatdata = data.toString().split('\n')
inputstream.close()
def get_android_intent():
if platform == "android":
PythonActivity = autoclass('org.renpy.android.PythonActivity')
activity = PythonActivity.mActivity
intent = activity.getIntent()
intent_action = intent.getAction()
if intent and "SEND_MULTIPLE" in intent_action:
return intent
return False
if __name__ == "__main__":
intent = get_android_intent()
MyApp(intent).run()
buildozer.spec 文件需要
android.manifest.intent_filters = intent_filters.xml
问题出在 get_android_intent 或 get_chatdata 函数中。我现在对 Java 几乎一无所知,因此欢迎对这些函数发表任何评论。
如果无法解决,我也很高兴能解释这种行为。