android img push到手机上,Android测试--adb push媒体文件到设备中并更新图库

背景

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

思路

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

实践

一、获取设备

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的源码也会发现这根本行不通。

c7c572ad921d

不过仍然可以另辟蹊径,通过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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值