我很好奇,前几天我看到这个应用程序允许它打开其他应用程序并自动为您设置某些功能。我已经意识到它必须使用某种类型的屏幕点击功能,但我似乎找不到任何类似这样的文档。例如,如果我们知道来自其他应用程序的屏幕文本是“就绪”,是否有办法阅读该文本并可能执行以下操作:
protected void processText(String text)
{
if (text.contains("Ready"))
// click the ready text
}
答案 0 :(得分:4)
我使用AccessibilityService
完成了此操作。它只能在API级别> = 16上正常工作。
您需要延长AccessibilityService
。例如,这个类将获得USSD响应的文本并关闭对话框。
// ....
public class UssdAccessibilityService extends AccessibilityService {
public UssdAccessibilityService() {
}
@TargetApi(16)
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (!"com.android.phone".equalsIgnoreCase((String)event.getPackageName())){
// In this example we are only interested in events comming
// from "com.android.phone" package
event.recycle();
return;
}
String className = (String)event.getClassName();
if (className == null || (!className.contains("AlertDialog") && !className.contains("AlertDialog"))){
// Class is not an USSD dialog
event.recycle();
return;
}
AccessibilityNodeInfo source = event.getSource();
if (source == null) {
// getSource() is annotated @Nullable, so we do this to be
// safe just in case
event.recycle();
return;
}
AccessibilityNodeInfo acceptButton = null;
String ussdText = null;
int childCount = source.getChildCount();
for (int i = 0; i < childCount; i++){
AccessibilityNodeInfo current = source.getChild(i);
if (current == null)
continue;
String currentText = (String)current.getText();
if (current.isClickable()){
// In the case of USSD dialogs, there is only one clickable.
// May be necessary to do more robust search in other scenarios
acceptButton = current;
continue;
}
ussdText = currentText;
current.recycle();
}
if (ussdText!= null) {
if (acceptButton != null)
acceptButton.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
source.recycle();
event.recycle();
}
// ....
}
您必须在<application>
<service
android:name=".UssdAccessibilityService"
android:enabled="true"
android:label="Read USSD codes and dismiss"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>
在res/xml
下创建accessibility_service_config.xml
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/accessibility_service_description"
android:packageNames="com.android.phone,com.ats.android.activationcodebot"
android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
android:accessibilityFlags="flagDefault"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
/>
当然,您必须根据自己的需要调整此代码。
最后,您必须在设置&gt;上手动启用辅助功能服务。 Android中的辅助功能(或要求用户执行此操作)。
答案 1 :(得分:3)
为了能够从其他应用程序执行此操作,您需要捕获屏幕并使用文本识别服务确定文本位置。
当另一个应用程序处于活动状态时,您的应用程序应处于活动状态以便能够捕获屏幕。所以你只能使用总是有背景的android服务。
但要为您的活动捕获ScreenShot,您需要查看activity
的视图,以及service
中不存在哪一个,因此您必须制作一个TimerTask
每小时致电您的活动,并activity
使用当前显示的视图回复您的活动,您可以从中捕获ScreenShot。
或者如果您想拍摄当前设备屏幕(任何应用程序)的ScreenShot,那么您必须获得root权限,并阅读framebuffer
以获取当前设备屏幕的原始数据屏幕然后将其转换为位图或您可以在服务中执行的任何图片文件。
简而言之,有根电话可能。否则,如果您没有根,则无法截取其他应用的屏幕截图。仅允许截取您的应用的屏幕截图。
能够分析屏幕是否有“就绪”文本。您的应用程序应该是活动/活动的,以便能够捕获屏幕。
答案 2 :(得分:0)
使用广播接收器而不是尝试阅读文本,并在每次广播检查时设置文本视图长度,启动应用程序或做任何你想做的事情。