Android测试--adb push媒体文件到设备中并更新图库

背景

需要批量往多设备中拷贝若干测试图片(几百张),然后对这些图片做一些的事。

思路

通过adb -s deviceName push remote_path local_path拷贝图片,然后通过广播更新媒体库。具体的原理就不说了。。。

实践

一、获取设备

获取设备跟另一篇的方法差不多Android测试--用Python批量给多设备安装app应用

    connectdeviceid = []
    p = os.popen('adb devices')
    outstr = p.read()
    print outstr
    connectdeviceid = re.findall(r'(\w+)\s+device\s', outstr)
    return connectdeviceid
二、刷新媒体库

一开始使用的是ACTION_MEDIA_SCANNER_SCAN_FILE,在adb的相关命令中介绍过Android测试 adb常用命令。通过adb shell am broadcast来实现。

adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file_path

图片文件较多,循环遍历一下,

    for device in connectdeviceid:
        for path, subdirs, files in os.walk(indir):
            for filename in files:
                refresh_pic(filename, device)

实际测试中,在用adb shell发送广播时,遇到了问题。当使用os.popen这类命令时,一条一条的非常之慢。使用mulprocessing或者subprocess时候,却又太快,会导致adb连接出现connect reset peeer或者error: protocol fault (couldn't read status): Undefined error: 0等错误。

于是换个方向,看能不能直接刷新文件夹。去官网搜搜有关MEDIA Action相关资料。可以很清晰的看到并没有讹传的android.intent.action.MEDIA_SCANNER_SCAN_DIR,当然通过查看MediaScannerReceiver.java的源码也会发现这根本行不通。


不过仍然可以另辟蹊径,通过ACTION_MEDIA_MOUNTED来实现刷新文件夹。
官方是这么介绍的:
ACTION_MEDIA_MOUNTED
added in API level 1
String ACTION_MEDIA_MOUNTED
Broadcast Action: External media is present and mounted at its mount point. The path to the mount point for the mounted media is contained in the Intent.mData field. The Intent contains an extra with name "read-only" and Boolean value to indicate if the media was mounted read only.

Constant Value: "android.intent.action.MEDIA_MOUNTED"

命令仍然一样,试验一下是可以成功的,比坑纸坑纸一个文件一个文件的刷要方便太多了。

adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d path

剩下的组织一下脚本就ok了。

#!usr/bin/python
# -*- coding:utf-8 -*-
# Author:John Hao
# 拷贝媒体文件到设备中。例如图片、MP4文件等
# 原理:拷贝之后,自动发送媒体广播,让设备实时更新图库
import os
import subprocess
import multiprocessing
import re
import threading
import time
import sys

device_name = "85UABM7HEBC2"   # 指定单一的设备,如果为空则执行全部链接设备
indir = '/Users/johnhao/Pictures/marcelsiebert'   # 输入文件夹
sdcard_path = "/sdcard/DCIM/marcelsiebert"   # 拷贝到设备的路径
# exstr = ""   # 设备中要刷新的文件的扩展名,例如".jpeg"。为空时,刷新全部文件夹;不为空,刷新指定文件结尾格式的文件

# 获取设备name
def get_conn_dev():
    connectdeviceid = []
    p = os.popen('adb devices')
    outstr = p.read()
    print outstr

    if device_name == "":
        print "未指定设备,执行全部"   
        connectdeviceid = re.findall(r'(\w+)\s+device\s', outstr)
        return connectdeviceid
    elif device_name in outstr:
        print "执行设备: ", device_name
        connectdeviceid.append(device_name)
        return connectdeviceid
    else:
        print "指定设备未连接,请重新检查device name" 
        sys.exit()

# 拷贝媒体到设备中
def cpoy_to_devices(command):
    print "拷贝图片并刷新"
    print command
    os.popen(command)

# 刷新单图
def refresh_pic(filename, deviceid):
    cmd_refresh = "adb -s %s shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///storage/emulated/0/%s/%s" % (deviceid, sdcard_path[8:], filename)
    print cmd_refresh
    subprocess.Popen(cmd_refresh, shell=True)

# 刷新文件夹
def refresh_folder(deviceid):
    cmd_refresh = "adb -s %s shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///storage/emulated/0/%s/" % (deviceid, sdcard_path[8:])
    print cmd_refresh
    subprocess.Popen(cmd_refresh, shell=True)

def main():
    connectdevice = get_conn_dev()
    commands = []

    for device in connectdevice:
        cmd_push = "adb -s %s push %s %s" % (device, indir, sdcard_path)
        commands.append(cmd_push)

    threads = []
    threads_count = len(commands)

    for i in range(threads_count):
        t = threading.Thread(target = cpoy_to_devices, args = (commands[i],))
        threads.append(t)

    for i in range(threads_count):
        time.sleep(1)  # 防止adb连接出错
        threads[i].start()

    for i in range(threads_count):
        threads[i].join() 

    for device in connectdevice:
        refresh_folder(device)
        time.sleep(0.5)
        # 刷新单张图片
        # for path, subdirs, files in os.walk(indir):
        #     for filename in files:
        #         if exstr == "":
        #             refresh_pic(filename, device)
        #         elif filename.endswith(exstr):
        #             refresh_pic(filename, device) 

if __name__ == '__main__':
    main()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容