[特殊字符]Python 黑科技:掌控小米手机实现全自动批量拨号

你能想象吗?只需一段 Python 代码,就能让你的小米手机像训练有素的接线员一样,自动拨打上百个电话号码,全程无需人工干预!本文将揭秘如何用技术打造属于你的 "自动化呼叫中心",彻底解放你的双手!

核心功能展示

先看看我们将实现的核心功能:

  • 从 Excel/CSV 批量导入电话号码
  • 自动拨号并监控通话状态
  • 智能识别接通 / 未接状态
  • 通话时长自动记录
  • 异常情况自动重试
  • 完整的通话日志记录

下面是完整的实现代码:

python

运行

import subprocess
import re
import time
import os
import pandas as pd
from datetime import datetime
from find_adb import *

# 配置参数
PHONE_NUMBER_FILE = 'phone_numbers.csv'  # 电话号码文件
STATE_FILE = 'settings/phone_state.txt'  # 状态文件
LOG_FILE = 'call_logs.csv'  # 通话日志文件
DIAL_INTERVAL = 10  # 拨号间隔(秒)
RETRY_TIMES = 3  # 重试次数
adb_path = get_adb_path()

# 电话状态枚举
PHONE_STATES = {
    'IDLE': '空闲',
    'DIALING': '拨号中',
    'ALERTING': '响铃中',
    'ACTIVE': '通话中',
    'DISCONNECTING': '挂断中',
    'DISCONNECTED': '已挂断'
}

def get_current_phone_state():
    """获取当前电话状态"""
    try:
        with open(STATE_FILE, 'r') as f:
            return f.read().strip()
    except FileNotFoundError:
        return "UNKNOWN"
    
def write_state(state):
    """写入当前电话状态"""
    with open(STATE_FILE, 'w') as f:
        f.write(state)

def execute_adb_command(command):
    """执行ADB命令"""
    try:
        process = subprocess.run(
            [os.path.join(adb_path, "adb.exe")] + command,
            capture_output=True,
            text=True,
            check=True
        )
        return process.stdout.strip()
    except subprocess.CalledProcessError as e:
        print(f"ADB命令执行失败: {e.stderr}")
        return None

def connect_device():
    """连接安卓设备"""
    print("正在连接安卓设备...")
    devices = execute_adb_command(["devices"])
    if not devices or "device" not in devices:
        print("未检测到已连接的安卓设备!")
        return False
    print("设备连接成功!")
    return True

def dial_phone_number(phone_number):
    """拨打电话"""
    print(f"正在拨打: {phone_number}")
    execute_adb_command(["shell", f"am start -a android.intent.action.CALL -d tel:{phone_number}"])
    time.sleep(2)  # 等待拨号界面加载

def hangup_call():
    """挂断电话"""
    print("正在挂断电话...")
    execute_adb_command(["shell", "input keyevent KEYCODE_ENDCALL"])
    time.sleep(2)  # 等待挂断操作完成

def monitor_call_status(timeout=60):
    """监控通话状态变化,返回最终状态和通话时长"""
    start_time = time.time()
    call_start_time = 0
    last_state = get_current_phone_state()
    
    while time.time() - start_time < timeout:
        current_state = get_current_phone_state()
        
        # 状态变化时输出信息
        if current_state != last_state:
            print(f"状态变更: {PHONE_STATES.get(last_state, last_state)} -> {PHONE_STATES.get(current_state, current_state)}")
            last_state = current_state
            
            # 记录通话开始时间
            if current_state == 'ACTIVE':
                call_start_time = time.time()
                
            # 通话结束,返回结果
            if current_state == 'DISCONNECTED':
                call_duration = 0
                if call_start_time > 0:
                    call_duration = time.time() - call_start_time
                return "COMPLETED", call_duration
                
        time.sleep(1)
    
    # 超时处理
    if last_state == 'ACTIVE':
        hangup_call()
        return "MANUAL_HANGUP", time.time() - call_start_time
    else:
        hangup_call()
        return "TIMEOUT", 0

def read_phone_numbers(file_path):
    """从文件读取电话号码列表"""
    try:
        if file_path.endswith('.csv'):
            df = pd.read_csv(file_path)
        elif file_path.endswith(('.xlsx', '.xls')):
            df = pd.read_excel(file_path)
        else:
            raise ValueError("不支持的文件格式")
            
        # 查找包含电话号码的列
        phone_column = None
        for col in df.columns:
            if '电话' in col or '号码' in col or 'phone' in col.lower():
                phone_column = col
                break
                
        if not phone_column:
            raise ValueError("文件中未找到电话号码列")
            
        return df[phone_column].dropna().astype(str).tolist()
    except Exception as e:
        print(f"读取电话号码文件失败: {e}")
        return []

def log_call_result(phone_number, result, duration, retry=0):
    """记录通话结果"""
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    duration_str = f"{duration:.1f}秒" if duration > 0 else "0秒"
    
    # 写入日志文件
    file_exists = os.path.exists(LOG_FILE)
    with open(LOG_FILE, 'a', encoding='utf-8') as f:
        if not file_exists:
            f.write("时间戳,电话号码,通话结果,通话时长,重试次数\n")
        f.write(f"{timestamp},{phone_number},{result},{duration_str},{retry}\n")
    
    # 控制台输出
    print(f"📝 通话记录: {phone_number} - {result} - {duration_str} - 重试次数: {retry}")

def batch_dial_phones():
    """批量拨打电话主函数"""
    if not connect_device():
        return
    
    phone_numbers = read_phone_numbers(PHONE_NUMBER_FILE)
    if not phone_numbers:
        print("没有可拨打的电话号码!")
        return
        
    print(f"共加载了 {len(phone_numbers)} 个电话号码")
    total = len(phone_numbers)
    
    for i, phone_number in enumerate(phone_numbers, 1):
        print(f"\n===== 正在处理第 {i}/{total} 个号码: {phone_number} =====")
        
        for retry in range(RETRY_TIMES):
            print(f"尝试拨号 (重试次数: {retry})")
            
            # 重置状态
            write_state('IDLE')
            
            # 拨号
            dial_phone_number(phone_number)
            
            # 监控通话状态
            result, duration = monitor_call_status(timeout=120)
            
            # 记录结果
            log_call_result(phone_number, result, duration, retry)
            
            # 判断是否需要重试
            if result == "COMPLETED":
                break
                
            # 重试间隔
            if retry < RETRY_TIMES - 1:
                print(f"拨号失败,{DIAL_INTERVAL}秒后重试...")
                time.sleep(DIAL_INTERVAL)
        
        # 拨号间隔
        print(f"等待 {DIAL_INTERVAL} 秒后继续下一个号码...")
        time.sleep(DIAL_INTERVAL)
    
    print("\n🎉 批量拨号任务已完成!")

if __name__ == "__main__":
    batch_dial_phones()

工作流程详解

我们的批量拨号系统主要包含以下几个核心模块:

1. ADB 通信层

负责与小米手机建立连接并发送控制命令:

python

运行

def execute_adb_command(command):
    """执行ADB命令"""
    try:
        process = subprocess.run(
            [os.path.join(adb_path, "adb.exe")] + command,
            capture_output=True,
            text=True,
            check=True
        )
        return process.stdout.strip()
    except subprocess.CalledProcessError as e:
        print(f"ADB命令执行失败: {e.stderr}")
        return None
2. 通话状态监控

实时捕获并解析手机通话状态:

python

运行

def monitor_call_status(timeout=60):
    """监控通话状态变化,返回最终状态和通话时长"""
    start_time = time.time()
    call_start_time = 0
    last_state = get_current_phone_state()
    
    while time.time() - start_time < timeout:
        current_state = get_current_phone_state()
        
        # 状态变化时输出信息
        if current_state != last_state:
            print(f"状态变更: {PHONE_STATES.get(last_state, last_state)} -> {PHONE_STATES.get(current_state, current_state)}")
            last_state = current_state
            
            # 记录通话开始时间
            if current_state == 'ACTIVE':
                call_start_time = time.time()
                
            # 通话结束,返回结果
            if current_state == 'DISCONNECTED':
                call_duration = 0
                if call_start_time > 0:
                    call_duration = time.time() - call_start_time
                return "COMPLETED", call_duration
                
        time.sleep(1)
    
    # 超时处理
    if last_state == 'ACTIVE':
        hangup_call()
        return "MANUAL_HANGUP", time.time() - call_start_time
    else:
        hangup_call()
        return "TIMEOUT", 0
3. 批量处理引擎

管理整个批量拨号流程:

python

运行

def batch_dial_phones():
    """批量拨打电话主函数"""
    if not connect_device():
        return
    
    phone_numbers = read_phone_numbers(PHONE_NUMBER_FILE)
    if not phone_numbers:
        print("没有可拨打的电话号码!")
        return
        
    print(f"共加载了 {len(phone_numbers)} 个电话号码")
    total = len(phone_numbers)
    
    for i, phone_number in enumerate(phone_numbers, 1):
        print(f"\n===== 正在处理第 {i}/{total} 个号码: {phone_number} =====")
        
        for retry in range(RETRY_TIMES):
            # 拨号逻辑...
            
        # 拨号间隔
        print(f"等待 {DIAL_INTERVAL} 秒后继续下一个号码...")
        time.sleep(DIAL_INTERVAL)
    
    print("\n🎉 批量拨号任务已完成!")

实战应用场景

这套系统可以在以下场景中大显身手:

  1. 客户回访:客服团队可以使用该系统自动拨打客户电话,记录通话情况

  2. 电话营销:营销人员可以批量拨打潜在客户,提高工作效率

  3. 通知提醒:学校、医院等机构可以自动拨打通知电话

  4. 测试验证:开发人员可以用它测试电话相关的功能

如何使用

  1. 准备工作:

    • 安装 ADB 工具并配置环境变量
    • 启用小米手机的 USB 调试模式
    • 安装必要的 Python 库:pip install pandas
  2. 准备电话号码文件:
    创建一个 CSV 或 Excel 文件,包含电话号码列

  3. 运行程序:
    python batch_dialer.py

高级扩展

想要更强大的功能?可以考虑这些扩展方向:

  1. 添加语音识别,自动记录通话内容
  2. 集成 AI 对话机器人,实现智能语音交互
  3. 开发 Web 界面,实现远程控制和监控
  4. 添加短信自动回复功能
  5. 实现基于地理位置的智能拨号

有了这个 Python 批量拨号系统,你就拥有了一个 24 小时不停歇的 "数字接线员",让繁琐的拨打电话工作成为历史!还等什么?马上动手实现,释放你的生产力吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值