屏蔽EditText 聚焦自动弹出输入框

本文提供了解决方案,通过调用this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);来实现只有在点击EditText时才会自动弹出输入框的功能。

比如我进入一个设置界面,里面如果EditText,那么这时候输入框就会自动弹出,那么如何屏蔽这个输入框呢? 到我们点击EditText的时候才弹出输入框呢?

 this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

转载处:http://www.shouyanwang.org/thread-292-1-1.html

from appium import webdriver from appium.options.android import UiAutomator2Options from selenium.common.exceptions import ElementClickInterceptedException, StaleElementReferenceException from appium.webdriver.common.appiumby import AppiumBy from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time import hashlib # ==================== 目标应用配置 ==================== TARGET_PACKAGE = "com.brother.ptouch.iprintandlabel" # ==================== 配置 Appium Options ==================== options = UiAutomator2Options() options.set_capability("platformName", "Android") options.set_capability("deviceName", "emulator-5554") # 确保设备在线 options.set_capability("automationName", "UiAutomator2") options.set_capability("noReset", True) options.set_capability("fullReset", False) options.set_capability("autoGrantPermissions", True) options.set_capability("newCommandTimeout", 600) # 启动 App driver = webdriver.Remote(command_executor='http://localhost:4723', options=options) # 存储已处理的元素签名(全局去重) processed_elements = set() # ================== 工具类:MobileElementActions ================== class MobileElementActions: def __init__(self, driver): self.driver = driver self.processed_inputs = set() # 已填写的输入框 def get_element_signature(self, element): """生成唯一标识符:resourceId + text + desc + className""" try: attrs = [ element.get_attribute("resourceId") or "", element.get_attribute("text") or "", element.get_attribute("contentDescription") or "", element.get_attribute("className") or "" ] raw_sig = "||".join(attrs) return hashlib.md5(raw_sig.encode()).hexdigest()[:16] except Exception as e: print(f"⚠️ 获取元素签名失败: {e}") return None def is_interactable(self, element): """判断是否为真正可交互的 UI 元素(排除容器)""" try: clickable = element.get_attribute("clickable") == "true" enabled = element.get_attribute("enabled") == "true" focusable = element.get_attribute("focusable") == "true" scrollable = element.get_attribute("scrollable") == "true" clazz = element.get_attribute("className") # 排除布局容器类 ignored_classes = { 'android.widget.LinearLayout', 'android.widget.RelativeLayout', 'android.widget.FrameLayout', 'android.widget.ConstraintLayout', 'android.widget.ScrollView', 'android.widget.HorizontalScrollView', 'android.view.View', 'android.view.ViewGroup' } if clazz in ignored_classes: return False return (clickable or (focusable and not scrollable)) and enabled except: return False def safe_click(self, element): """安全点击,支持坐标 fallback""" try: element.click() return True except ElementClickInterceptedException: print("⚠️ 元素被遮挡,尝试坐标点击") try: loc = element.location size = element.size x = loc['x'] + size['width'] // 2 y = loc['y'] + size['height'] // 2 self.driver.tap([(x, y)]) return True except Exception as e: print(f"❌ 坐标点击失败: {e}") return False except Exception as e: print(f"❌ 点击失败: {e}") return False def wait_for_page_load(self, timeout=2): """等待页面加载完成""" time.sleep(timeout) def handle_alerts(self): """自动关闭弹窗""" alert_texts = ['OK', '确定', 'Cancel', '取消', '知道了', '同意'] for text in alert_texts: try: btn = self.driver.find_element( AppiumBy.XPATH, f"//*[@text='{text}' or @contentDescription='{text}']") if btn.is_displayed() and btn.is_enabled(): btn.click() print(f"✅ 自动关闭弹窗: {text}") return True except: continue return False def handle_input_fields(self): """填写输入框""" try: inputs = self.driver.find_elements( AppiumBy.XPATH, "//android.widget.EditText | " "//android.widget.TextView[@focusable='true' and @editable='true']" ) for inp in inputs: try: if not inp.is_displayed() or not inp.is_enabled(): continue sig = self.get_element_signature(inp) if sig in self.processed_inputs: continue current_value = inp.get_attribute("text") or "" hint = inp.get_attribute("hint") or "" print(f"📝 发现输入框 - 当前文本: '{current_value}', 提示: '{hint}'") inp.clear() inp.send_keys("AutoInputTest") self.processed_inputs.add(sig) except Exception as e: print(f"⚠️ 输入失败: {e}") except Exception as e: print(f"🔍 查找输入框异常: {e}") def get_current_page_hash(self): """获取当前页面结构哈希""" try: src = self.driver.page_source return hashlib.md5(src.encode('utf-8')).hexdigest() except Exception as e: print(f"⚠️ 获取页面源码失败: {e}") return None # ================== 主流程:自动化遍历 ================== class MobileAutomationWorkflow: def __init__(self, driver): self.driver = driver self.actions = MobileElementActions(driver) self.max_iterations = 300 self.iteration_count = 0 def get_all_interactable_elements(self): """获取当前页面所有可交互且未处理过的元素""" try: all_elements = self.driver.find_elements(AppiumBy.XPATH, "//*") candidates = [] for elem in all_elements: if not self.actions.is_interactable(elem): continue sig = self.actions.get_element_signature(elem) if sig and sig not in processed_elements: candidates.append((elem, sig)) return candidates except Exception as e: print(f"❌ 获取可交互元素失败: {e}") return [] def run(self): print("📱 开始移动应用自动化遍历...") stack_depth = 0 # 记录递归深度(用于调试) try: while self.iteration_count < self.max_iterations: print(f"\n🔄 第 {self.iteration_count + 1} 轮:扫描当前页面") print("Current Activity:", self.driver.current_activity) # ✅ 检查是否仍在目标 App 内 if self.driver.current_package != TARGET_PACKAGE: print(f"⚠️ 当前不在目标应用 ({self.driver.current_package}),返回中...") try: self.driver.back() time.sleep(1.5) if self.driver.current_package != TARGET_PACKAGE: print("🔚 已退出目标应用,结束遍历") break except: break continue # 🔍 获取当前页面所有【未点击过的】可交互元素 interactable_list = self.get_all_interactable_elements() if not interactable_list: print("✅ 当前页面无可点击的新元素,准备返回") try: self.driver.back() time.sleep(1.5) stack_depth -= 1 except: print("🔚 已达根页面,无法返回") break continue print(f"找到 {len(interactable_list)} 个新可点击元素") # 📝 从列表中取第一个未点击的元素进行点击 element, sig = interactable_list[0] try: text = element.get_attribute("text") or "No Text" desc = element.get_attribute("contentDescription") or "" clazz = element.get_attribute("className").split(".")[-1] print(f"👉 尝试点击: [{clazz}] '{text}' (描述: '{desc}')") if self.actions.safe_click(element): processed_elements.add(sig) # 标记为已处理 self.actions.wait_for_page_load() # 处理可能弹出的弹窗或输入框 self.actions.handle_alerts() self.actions.handle_input_fields() stack_depth += 1 else: # 如果点击失败,仍标记为已处理防止无限循环 processed_elements.add(sig) except StaleElementReferenceException: print("⚠️ 元素已失效,跳过") processed_elements.add(sig) except Exception as e: print(f"⚠️ 处理元素时出错: {e}") processed_elements.add(sig) self.iteration_count += 1 print(f"🏁 自动化完成,共执行 {self.iteration_count} 次操作。") except Exception as e: print(f"🚨 自动化过程发生严重错误: {e}") finally: self.driver.quit() # ================== 启动入口 ================== if __name__ == "__main__": workflow = MobileAutomationWorkflow(driver) workflow.run() 1.退出app后driverback没有使其从桌面进入到app 2.点击混乱 3.输入框的内容由用户输入,设置等待时间为3s并在控制台输出用户的输入内容 日志如下: C:\own\app\python_code\.venv\Scripts\python.exe C:\own\app\python_code\work\IBL_click_all\click_all.py 📱 开始移动应用自动化遍历... 🔄 第 1 轮:扫描当前页面 Current Activity: .module.home.home.HomeActivity 找到 3 个新可点击元素 👉 尝试点击: [RecyclerView] 'No Text' (描述: 'null') 🔄 第 2 轮:扫描当前页面 Current Activity: .module.home.home.HomeActivity 找到 2 个新可点击元素 👉 尝试点击: [Button] 'DOWNLOAD TEMPLATES' (描述: 'null') 🔄 第 3 轮:扫描当前页面 Current Activity: .module.home.home.HomeActivity 找到 1 个新可点击元素 👉 尝试点击: [Button] 'NEW LABEL' (描述: 'null') 📝 发现输入框 - 当前文本: '', 提示: 'null' 🔄 第 4 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 5 个新可点击元素 👉 尝试点击: [ImageButton] 'No Text' (描述: 'Navigate up') 🔄 第 5 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 2 个新可点击元素 👉 尝试点击: [Button] 'CANCEL' (描述: 'null') 🔄 第 6 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 6 个新可点击元素 👉 尝试点击: [TextView] 'Undo' (描述: 'null') 🔄 第 7 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 5 个新可点击元素 👉 尝试点击: [TextView] 'Save' (描述: 'null') 📝 发现输入框 - 当前文本: '', 提示: 'null' 🔄 第 8 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 2 个新可点击元素 👉 尝试点击: [EditText] 'AutoInputTest' (描述: 'null') 📝 发现输入框 - 当前文本: 'AutoInputTest', 提示: 'null' 🔄 第 9 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 1 个新可点击元素 👉 尝试点击: [Button] 'SAVE' (描述: 'null') 🔄 第 10 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 4 个新可点击元素 👉 尝试点击: [TextView] 'Print' (描述: 'null') 🔄 第 11 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 5 个新可点击元素 👉 尝试点击: [ImageButton] 'No Text' (描述: 'null') 🔄 第 12 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 3 个新可点击元素 👉 尝试点击: [ImageView] 'No Text' (描述: 'null') 🔄 第 13 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 1 个新可点击元素 👉 尝试点击: [ExpandableListView] 'No Text' (描述: 'null') 🔄 第 14 轮:扫描当前页面 Current Activity: com.google.android.apps.contacts.activities.leaf.ui.picker.ContactPickerActivity ⚠️ 当前不在目标应用 (com.google.android.contacts),返回中... 🔄 第 14 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 2 个新可点击元素 👉 尝试点击: [TextView] '0.70"' (描述: 'null') ✅ 自动关闭弹窗: OK 🔄 第 15 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity 找到 1 个新可点击元素 👉 尝试点击: [TextView] '100%' (描述: 'null') 🔄 第 16 轮:扫描当前页面 Current Activity: .edit.EditLabelActivity ✅ 当前页面无可点击的新元素,准备返回 🔄 第 16 轮:扫描当前页面 Current Activity: .module.home.home.HomeActivity ✅ 当前页面无可点击的新元素,准备返回 🔄 第 16 轮:扫描当前页面 Current Activity: .NexusLauncherActivity ⚠️ 当前不在目标应用 (com.google.android.apps.nexuslauncher),返回中... 🔚 已退出目标应用,结束遍历 🏁 自动化完成,共执行 15 次操作。 Process finished with exit code 0
最新发布
10-16
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值