当用户启动活动时,我试图让我的应用向我的自定义AccessibilityService宣布一些信息。我有一个TextView在活动开始时调用requestFocus(),然后我发送一个AccessibilityEvent让AccessibilityService读取TextView的内容描述。我已将问题分解为一个小应用程序。
这是主要活动:
package com.example.ttstest;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View v = findViewById(R.id.textView1);
v.requestFocus();
v.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT);
}
}
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.ttstest.MainActivity" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:contentDescription="Secondarily focused text view"
android:text="@string/hello_world" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView2"
android:layout_marginLeft="54dp"
android:layout_marginTop="145dp"
android:layout_toRightOf="@+id/textView2"
android:contentDescription="Initially focused text view"
android:focusable="true"
android:focusableInTouchMode="true"
android:text="Initially focused text view" />
</RelativeLayout>
AccessibilityService:
package com.example.ttstest;
import android.accessibilityservice.AccessibilityService;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
public class TextToSpeechService extends AccessibilityService {
private static TextToSpeech textToSpeech = null;
private static boolean ttsReady = false;
@Override
protected void onServiceConnected() {
super.onServiceConnected();
Log.e("TextToSpeechService", "Got to onServiceConnected()");
textToSpeech = new TextToSpeech(this.getApplicationContext(), new OnInitListener() {
@Override
public void onInit(int status) {
if(status == TextToSpeech.SUCCESS) {
ttsReady = true;
}
}
});
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.e("TextToSpeechService", "Entering onAccessibilityEvent().");
Log.e("TextToSpeechService", "Event type: " + event.getEventType() + ", from class " + event.getClassName());
if(event.getContentDescription() != null) {
Log.e("TextToSpeechService", "" + event.getContentDescription());
}
if(textToSpeech != null && ttsReady == true) {
if(event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
CharSequence contentDescription = event.getContentDescription();
if(contentDescription != null) {
String say = contentDescription.toString();
textToSpeech.speak(say, TextToSpeech.QUEUE_FLUSH, null);
}
} else if (event.getEventType() == AccessibilityEvent.TYPE_ANNOUNCEMENT) {
CharSequence contentDescription = event.getContentDescription();
if(contentDescription != null) {
textToSpeech.speak(event.getContentDescription().toString(), TextToSpeech.QUEUE_FLUSH, null);
}
}
}
Log.e("TextToSpeechService", "Exiting onAccessibilityEvent().");
}
@Override
public void onInterrupt() {
Log.e("TextToSpeechService", "Entering onInterrupt()");
if(textToSpeech != null && ttsReady == true) {
textToSpeech.stop();
}
}
}
这已添加到我的AndroidManifest.xml中的适当位置:
<service android:name="com.example.ttstest.TextToSpeechService"
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/accessibilityservice"/>
</service>
我的accessibilityservice.xml设置:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:notificationTimeout="100"
android:accessibilityFeedbackType="feedbackSpoken"
android:accessibilityFlags="flagDefault"
android:canRetrieveWindowContent="true"
android:packageNames="com.example.ttstest"/>
最后,问题。当我第一次启动应用程序时,TextView从requestFocus()获得焦点或者调用sendAccessibilityEvent()实际上都没有向AccessibilityService发送任何内容。如果我通过附加物理键盘来浏览TextViews,则会收到焦点事件 。我确保在设置中打开AccessibilityService,并且我从我创建此示例的应用程序中得到证据,即在调用requestFocus()和sendAccessibilityEvent()时启用了AccessibilityService。这没有用。似乎首次启动Activity时,这些方法都不会向AccessibilityService发送任何内容。我也试过调用announceForAccessibility()并得到类似的结果。
我这样做错了吗?我该如何解决它,或者至少绕过它?具体来说,我想在活动首次启动时向我的AccessibilityService发送一个事件。
更多信息:我尝试将requestFocus()和sendAccessibilityEvent()调用移动到onStart()和onWindowFocusChanged();这些都不起作用。
答案 0 :(得分:0)
我可能会弄错,但是在调用onResume()之前“UI”还没有准备就绪,这可能就是问题了吗?