{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Kivy指南-3-Android录音app\n", "\n", "> 做一个录音app来演示Python-Java交互的Pyjnius模块卓越的性能\n", "\n", "- toc: true \n", "- badges: true\n", "- comments: true\n", "- categories: [jupyter,Kivy,Android,iOS]\n", "- image: kbpic/3.7appui.png" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在上一章,我们简要介绍过Kivy要实现跨平台应用,可能在不同的平台需要选择不同的代码,为一些用户增强体验效果,实现具体平台的任务。\n", "\n", "有时,这些都很简单;比如,如果Kivy发现目标系统支持它,多点触控就会启动——不需要写任何代码,但是要考虑一些点击事件原来的功能可能会与多点触控产生冲突。\n", "\n", "另外一些平台相关的任务,像代码不能在其他系统上运行,是有很多原因造成的。还记得画图app的鼠标光标吗?代码要用Pygame封装的底层SDL光标功能,如果你熟悉SDL和Pygame那就很简单。因此,为了让app可以跨平台,我们要尽量避免在系统兼容性不好的代码;因为那样可能导致程序崩溃。\n", "\n", "然而,Kivy应用具有良好的平台兼容性——Mac,Windows,Linux,iOS,Android和Raspberry Pi——都没什么大问题。\n", "![](kbpic/3.1Kivysupportsplatforms.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "教学大纲:\n", "\n", "- 通过Pyjnius实现Python与Java的交互\n", "- 在Android系统设备上测试Kivy应用\n", "- 用Python调用Android的声音API,允许我们记录和播放声频文件\n", "- 制作一个紧凑型用户界面,类似Windows Phone\n", "- 用图标字体改进app矢量图标的显示" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 平台相关代码" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这本书绝大多数app都是平台无关代码,因为Kivy具有高度移植性。但这一次我们做一个仅支持Android平台的应用。这么做肯定会减少我们的用户,但是它能让我们接触到一些具体平台功能的处理方法。\n", "\n", "这种需求可以实现,是立足于Kivy不断努力支持多个平台,使得用户在不同平台上具有类似的体验。因此,我们可以真正简单的做到一次编写,处处运行。\n", "\n", "但是,要实现跨平台,你就要用每个系统支持的功能。不同系统功能的最大公约数集合包括屏幕可以显示图像,如果有声卡就获取声音,接受用户的输入等等。\n", "\n", "每个Kivy应用,本质上都基于Python,还支持Python的标准模块。可以利用网络编程,支持大量的协议操作,还提供很多通用性的算法和功能。\n", "\n", "还有就是在大多数平台上,纯kivy程序的IO能力会受到限制,通用计算机系统的一小部分都是这样,像智能手机和平板电脑。\n", "\n", "让我们看看现代移动设备的API接口,这里以Android为例。我们把每个API分成两部分:一部分是Python/Kivy支持的,另一部分不是。\n", "\n", "Python/Kivy支持的特性如下:\n", "\n", "- 图形硬件加速\n", "- 支持多点触控输入\n", "- 播放声音\n", "- 支持网络\n", "\n", "Python/Kivy不支持的特性如下:\n", "\n", "- 调制解调器,语言电话和短信\n", "- 内置摄像头拍照和录像\n", "- 内置麦克录音\n", "- 数据云存储\n", "- 蓝牙和其他近场通信\n", "- 位置服务和GPS\n", "- 指纹识别\n", "- 传感器类,加速器、陀螺仪\n", "- 屏幕亮度调节\n", "- 振动功能\n", "- 电池充电百分比\n", ">这些不支持的列表里面,不同的Python模块已经支持,像Audiostream可以录音,Plyer可以实现很多功能。\n", ">因此,这些特性并非完全不能支持;实际上,这些功能在不同的平台上都是十分碎片化的,即使在Android系统上也没有统一的版本;因此,你写完具体平台的代码后,还是会发现没法儿移植。\n", "\n", "从前面的比较中可以看出,Android有一堆功能,只要一部分被Python/Kivy支持。这无疑为你用Kivy开发Android应用留下了大量的自由想象空间。你会学到Python调用Android API的知识,可以让Kivy做任何事情。\n", "\n", "另一个优势就是,你可以编写全新的类去支持具体特定硬件的移动设备,包括虚拟现实app,支持的陀螺仪游戏,全景拍摄相机等等。" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### Pyjnius介绍" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "要充分利用Android功能,就要用Java写的一堆API。我们要做的录音app,类似于Android和iOS的应用,很简单的功能。不像纯Kivy程序要从头开始,Android API为我们提供一堆录音的功能。\n", "\n", "下面我们就通过做录音app来演示Python-Java交互的[Pyjnius](https://github.com/kivy/pyjnius)模块卓越的性能,同样是Kivy开发者的项目。我们要开发的内容很简单——录音,回放功能——你会发现这种交互很简单,不需要一堆错综复杂的细节去实现这点小功能。\n", "\n", "Pyjnius最有趣的属性就是它并非在Android上面添加一个层来调用API,而是运行你直接通过Python运行Java。这样你就可以完全使用原生的Android API,可以参考适合Java开发的Android文档,不过不是Python文档。但是,这比没有API文档要好。\n", ">我们这里说Pyjnius是用来做Android开发的,其实也可以开发Java桌面应用。这是很有趣的,因为还有一个Java API的Python模块叫Jython,很慢而且不完整。Pyjnius可以让你直接使用CPython,再加上Numpy就可以让程序飞起来。\n", ">总之,让你想通过Python用Java,考虑Pyjnius吧。" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### Android模拟器" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这章做的app是要运行在Android上的,不能运行在我们的电脑上,因此我们需要用到Android设备,如果你没有设备,也可以安装Android模拟器。一个方便高效的Android模拟器可以让你事半功倍。\n", "\n", "推荐一个模拟器,就是[Genymotion](http://www.genymotion.com/),你可以下载一个免费版来用。不同的系统安装方法不同,我们就不提供教程了,自行谷歌之,还是比较简单的。\n", "\n", "用虚拟机安装Android模拟器的时候,下面一些建议供参考:\n", "\n", "- 建议保持Android最新版本,向后兼容性比较差;旧版本的系统级别的调试问题没有完全解决。\n", "- Android社区资源丰富,如果有问题就检索,你遇到的坑别人也踩过。\n", "- Kivy Launcher app是很不错的测试工具,你可以在[官方网站](http://kivy.org/)找到apk,建议装到手机上,方便程序调试。\n", "- 不同的模拟器质量和兼容性层次不齐。如果你发现一次没搞定,建议你换个虚拟机或模拟器试试。\n", "\n", "下面这个截图就是Genymotion启动的模拟器,完全支持Kivy Launcher。\n", "![Genymotion](kbpic/3.2AndroidGenymotion.png)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Metro UI" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "现在让我们用Window Phone的主屏风格来建立一个用户界面。这些不同大小的矩形彩色网格,被称为**Metro UI**风格,不过后来更名为**Modern UI**。我们的app就是要仿这个。\n", "![metroui](kbpic/3.3metroui.png)\n", "\n", "当然,我们并不是要做出这样,只是用一下风格来构建我们的界面。下面是对风格的总结:\n", "\n", "- 每个元素都是一个矩形网格\n", "- IU元素呈现扁平化特征(第一章讨论过,表面纯色,没有阴影,也没有圆角)\n", "- 格子可以根据需要变大,方便点击\n", "\n", "看起来非常简单吧。其实用Kivy实现起来也很简单。" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### 按钮" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "现在开始吧,首先做个按钮`Button`类,就像我们在之前的应用里做的,这里我们重用第二章画图app的按钮:\n", "```yaml\n", "