我正在尝试使用Kivy和buildozer制作一个简单的android应用程序,在那里我对WhatsApp导出的聊天作出反应。目前,我仅尝试将来自应用程序的最后三则消息打印到屏幕上。问题是无法正确读取表情符号。例如,我聊天时最后三则消息是:
14-11-19 09:17-MyName:这是一个测试消息
14-11-19 09:17-MyName:带有表情符号?
14-11-19 09:17-我的名字:??
?表情符号应该是U + 0001F602
sup表情符号应为U + 0001F44C U + 0001F3FB
如果我将聊天导出为.txt,然后在桌面上使用同一程序,则输出正确: 。
这是我的代码:
intent_filters.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>
Main.kv
<AuxScreen>:
BoxLayout:
Label:
text: "Nothing here"
<MainScreen>
loadinglabel : loadinglabel
BoxLayout:
Label:
id : loadinglabel
text: "loading..."
text_size: self.width,None
halign: 'center'
Main.py
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几乎一无所知,因此欢迎对这些功能进行任何评论。
如果无法解决,我也很高兴对此行为做出解释。