Android可视化显示手机电池电量信息

最近做了个小功能,打算写出来分享一下。文笔不好,标题起得不怎么样,一眼看去可能看不出是要说什么内容,但是又不想起个特别长的标题,就这样吧,随缘

进入正文,最近学习了Python,结合自己当前从事的Android开发的工作,想到了一个小功能,就是通过Python解析android log,提取其中电量的日志进行可视化显示。这是一个很小众的功能,估计基本上不会有人用得上,但是个人感觉是很有趣的一件事。

先上效果图:

Android可视化显示手机电池电量信息_第1张图片
battery_level.html

文章内容主要是通过以下几个方面描述,尽可能通俗易懂

  1. 获取日志
  2. 脚本编写
  3. 运行结果

1. 获取日志

电池电量信息我们可以从android日志的events log中获取,events log可通过以下命令获取

adb logcat -b events > events.log

其中,电池电量的关键字是battery_level

11-19 06:15:40.076  1502  1538 I battery_level: [91,4164,302]
11-19 06:18:36.180  1502  2042 I battery_level: [90,4224,325]
11-19 06:26:30.404  1502  2042 I battery_level: [89,4203,338]
11-19 06:33:11.701  1502  2042 I battery_level: [88,4179,345]
11-19 06:40:53.762  1502  2042 I battery_level: [87,4184,349]
11-19 06:46:58.554  1502  2042 I battery_level: [86,4160,355]
11-19 06:52:14.718  1502  2042 I battery_level: [85,4150,359]
11-19 06:58:37.736  1502  2042 I battery_level: [84,4143,352]

battery_level在代码中的描述如下:

 battery_level (level|1|6),(voltage|1|1),(temperature|1|1)
  • 第一个参数level表示当前电池电量
  • 第二个参数voltage表示当前电池电压
  • 第三个参数temperature表示当前电池温度

2. 脚本编写

通过battery_level的log格式可以大致得出以下步骤:

  1. 定义Battery相关类
  2. 逐行读取events log的日志并提取出battery_level行,解析行转换成Battery类
  3. 通过highcharts显示数据

2.1 定义Battery类

class Battery:
    # 日期
    date = ''
    # 时间
    timestamp = ''
    # 电量
    level = 0
    # 电压
    voltage = 0
    # 温度,log中单位需要除以10才是摄氏度的单位,用浮点数表示
    temperature = 0.0

2.2 解析日志

# events.log
inputfile = ''

def check_battery():
    if os.path.exists(inputfile):
        battery_array = []
        f = open(inputfile, 'rb')
        line = f.readline()
        while line:
            if "battery_level" in line:
                battery = Battery()
                temp_line = line.split()
                battery.date = temp_line[0]
                battery.timestamp = temp_line[1]
                # 有些日志可能会有些奇怪的问题,这里加个判断规避异常情况
                if len(temp_line) > 6:
                    # 这里应该是可以用正则表达式进行优化
                    conf = temp_line[6].replace("[", "").replace("]", "").split(",")
                    battery.level = int(conf[0])
                    battery.voltage = int(conf[1])
                    battery.temperature = int(conf[2]) / 10.0
                battery_array.append(battery)
            line = f.readline()
        f.close()
        if len(battery_array) > 0:
            # 生成报告,可视化显示,在2.3节中介绍
            generate_report(battery_array)
    else:
        print ("No evnet log file found")
    print ("Done")

2.3 可视化显示

结果是通过html显示,用到的是highchart显示折线图。这里不详细介绍highcharts的使用,有兴趣的可自行搜索了解。这里简单介绍一下highcharts的参数

  • title: 标题
  • xAxis: 横坐标的值和描述
  • tooltip: 折线弹出气泡
  • legend: 图表样式
  • series: 折线数据

先将运行后生成的html简化后内容贴出来会比较容易理解生成报告的脚本,以下内容直接复制到一个文本文件,修改后缀为html打开后就是文章前面截图的效果










脚本没什么特别的地方,就是打开文件写内容:

# report.html
outputfile = ''

def write_report(line):
    f = open(outputfile, 'a+')
    f.write(line)
    f.write('\n')
    f.close()

def battery_report(battery_array):
    write_report("")

def generate_report(battery_array):
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("
") write_report("
") write_report("
") write_report("") # 电池电量可视化 battery_report(battery_array) write_report("")

3. 运行结果

附上所有代码,加上命令行传参功能:

import getopt
import os
import sys


inputfile = ''
outputfile = 'report.html'


class Battery:
    date = ''
    timestamp = ''
    level = 0
    voltage = 0
    temperature = 0.0


def write_report(line):
    f = open(outputfile, 'a+')
    f.write(line)
    f.write('\n')
    f.close()


def battery_report(battery_array):
    write_report("")


def generate_report(battery_array):
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("")
    write_report("
") write_report("
") write_report("
") write_report("") battery_report(battery_array) write_report("") def check_battery(): if os.path.exists(inputfile): battery_array = [] f = open(inputfile, 'rb') line = f.readline() while line: if "battery_level" in line: battery = Battery() temp_line = line.split() battery.date = temp_line[0] battery.timestamp = temp_line[1] if len(temp_line) > 6: conf = temp_line[6].replace("[", "").replace("]", "").split(",") battery.level = int(conf[0]) battery.voltage = int(conf[1]) battery.temperature = int(conf[2]) / 10.0 battery_array.append(battery) line = f.readline() f.close() if len(battery_array) > 0: generate_report(battery_array) else: print ("No evnet log file found") print ("Done") def remove_report(): if os.path.exists(outputfile): os.remove(outputfile) def help(): print ("python check_battery.py -i event.log -o report.html") def main(argv): if len(argv) < 1: print ("args must more than one. please use -h to see more") sys.exit() try: opts, args = getopt.getopt(argv, "hi:o:",["inputfile=", "outputfile="]) except getopt.GetoptError: sys.exit(2) for opt, arg in opts: if opt == "-h": help() sys.exit() elif opt in ("-i", "--inputfile"): global inputfile inputfile = arg elif opt in ("-o", "--outputfile"): if not arg.endswith(".html"): arg = arg + ".html" global outputfile outputfile = arg remove_report() check_battery() if __name__ == "__main__": main(sys.argv[1:])

运行:

$ python check_battery.py -i event.log

输出结果:report.html

Android可视化显示手机电池电量信息_第2张图片
report.html

总结

python确实是个特别好的工具,工作中有很大的帮助。工作中我不止写了解析电池的脚本,还写了解析属性文件、应用信息、系统设置的脚本,后续还会考虑使用脚本解析anr、watchdog等trace log。当然,这个解析工作有些复杂,特别是watchdog类型的trace要考虑的情况比较多,先立个flag,共勉。

你可能感兴趣的:(Android可视化显示手机电池电量信息)