This question询问如何知道Android Talkback是否有效;直到果冻豆工作。从Android 4.1开始,该步骤不再有效,因为上述游标为空。
说完了,我想问一下是否有办法在Jelly Bean中进行相同的检查。
修改 我试图搜索TalkBack代码,我发现它here。 要检查TalkBack是否处于活动状态,我使用以下代码:
Intent screenReaderIntent = new Intent("android.accessibilityservice.AccessibilityService");
screenReaderIntent.addCategory("android.accessibilityservice.category.FEEDBACK_SPOKEN");
List<ResolveInfo> screenReaders = getPackageManager().queryIntentServices(screenReaderIntent, 0);
Cursor cursor = null;
ContentResolver cr = getContentResolver();
for (ResolveInfo screenReader : screenReaders) {
cursor = cr.query(Uri.parse("content://" + screenReader.serviceInfo.packageName
+ ".providers.StatusProvider"), null, null, null, null);
//here, cursor is not null, but calling cursor.moveToFirst() returns false, which means the cursor is empty
}
说完这个,如果光标为空,我们怎么知道TalkBack是否正在运行?
编辑2 根据@JoxTraex建议,我现在发送广播来查询是否启用了TalkBack:
Intent i = new Intent();
i.setAction("com.google.android.marvin.talkback.ACTION_QUERY_TALKBACK_ENABLED_COMMAND");
sendBroadcast(i);
现在我应该如何收到回复?
我尝试将以下内容添加到清单中,但我的收件人没有收到任何回复:
<receiver android:name="my.package.MyBroadcastReceiver"
android:permission="com.google.android.marvin.talkback.PERMISSION_SEND_INTENT_BROADCAST_COMMANDS_TO_TALKBACK">
<intent-filter>
<action android:name="com.google.android.marvin.talkback.ACTION_QUERY_TALKBACK_ENABLED_COMMAND" />
</intent-filter>
答案 0 :(得分:18)
使用AccessibilityManager
可以更轻松地实现这一目标。
AccessibilityManager am = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);
boolean isAccessibilityEnabled = am.isEnabled();
boolean isExploreByTouchEnabled = am.isTouchExplorationEnabled();
答案 1 :(得分:0)
在查看TalkBackService.java时,我发现了这些代码段。这些细分应提供有关如何查询状态的一些见解。
/**
* {@link Intent} broadcast action for querying the state of TalkBack. </p>
* Note: Sending intent broadcast commands to TalkBack must be performed
* through {@link Context#sendBroadcast(Intent, String)}
*/
@Deprecated
// TODO(caseyburkhardt): Remove when we decide to no longer support intent broadcasts for
// querying the current state of TalkBack.
public static final String ACTION_QUERY_TALKBACK_ENABLED_COMMAND = "com.google.android.marvin.talkback.ACTION_QUERY_TALKBACK_ENABLED_COMMAND";
/**
* Result that TalkBack is enabled.
*
* @see #ACTION_QUERY_TALKBACK_ENABLED_COMMAND
*/
public static final int RESULT_TALKBACK_ENABLED = 0x00000001;
/**
* Result that TalkBack is disabled.
*
* @see #ACTION_QUERY_TALKBACK_ENABLED_COMMAND
*/
public static final int RESULT_TALKBACK_DISABLED = 0x00000002;
/**
* Permission to send {@link Intent} broadcast commands to TalkBack.
*/
public static final String PERMISSION_SEND_INTENT_BROADCAST_COMMANDS_TO_TALKBACK = "com.google.android.marvin.talkback.PERMISSION_SEND_INTENT_BROADCAST_COMMANDS_TO_TALKBACK";
/**
* Tag for logging.
*/
private static final String LOG_TAG = "TalkBackService";
public static final String ACTION_QUERY_TALKBACK_ENABLED_COMMAND = "com.google.android.marvin.talkback.ACTION_QUERY_TALKBACK_ENABLED_COMMAND";
..
} else if (ACTION_QUERY_TALKBACK_ENABLED_COMMAND.equals(intentAction)) {
// TODO(caseyburkhardt): Remove this block when we decide to no
// longer support
// intent broadcasts for determining the state of TalkBack in
// favor of the content
// provider method.
if (sInfrastructureInitialized) {
setResultCode(RESULT_TALKBACK_ENABLED);
} else {
setResultCode(RESULT_TALKBACK_DISABLED);
}
}
...
}
您必须使用以下操作向TalkBackService发送Intent广播:
public static final String ACTION_QUERY_TALKBACK_ENABLED_COMMAND = "com.google.android.marvin.talkback.ACTION_QUERY_TALKBACK_ENABLED_COMMAND";
然后检查Extras的内容并相应地处理它。
ALSO 确保您拥有正确的权限:
public static final String PERMISSION_SEND_INTENT_BROADCAST_COMMANDS_TO_TALKBACK = "com.google.android.marvin.talkback.PERMISSION_SEND_INTENT_BROADCAST_COMMANDS_TO_TALKBACK";
答案 2 :(得分:0)
我不确定这是实现建议的最佳方式,但我设法通过使用以下代码来完成这项工作:
Intent screenReaderIntent = new Intent("android.accessibilityservice.AccessibilityService");
screenReaderIntent.addCategory("android.accessibilityservice.category.FEEDBACK_SPOKEN");
List<ResolveInfo> screenReaders = getPackageManager().queryIntentServices(screenReaderIntent, 0);
Cursor cursor = null;
int status = 0;
ContentResolver cr = getContentResolver();
List<String> runningServices = new ArrayList<String>();
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
runningServices.add(service.service.getPackageName());
}
for (ResolveInfo screenReader : screenReaders) {
cursor = cr.query(Uri.parse("content://" + screenReader.serviceInfo.packageName
+ ".providers.StatusProvider"), null, null, null, null);
if (cursor != null && cursor.moveToFirst()) { //this part works for Android <4.1
status = cursor.getInt(0);
cursor.close();
if (status == 1) {
//screen reader active!
} else {
//screen reader inactive
}
} else { //this part works for Android 4.1+
if (runningServices.contains(screenReader.serviceInfo.packageName)) {
//screen reader active!
} else {
//screen reader inactive
}
}
}
可能这不是最好的方法,但它是我能想到的唯一可以在Jelly Bean和以前的Android版本中运行的方式
答案 3 :(得分:0)
您可以检查已启用的语音访问服务器
fun Context.isScreenReaderEnabled(): Boolean {
val accessibilityManager = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
if (!accessibilityManager.isEnabled)
return false
val serviceInfoList = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN)
if (serviceInfoList.isNullOrEmpty())
return false
return true
}