mirror of
https://gitee.com/shuto-github/phonegap-mobile-accessibility.git
synced 2026-05-26 00:00:06 +08:00
Detect and receive notification of more iOS accessibility features
Adds following methods for detecting iOS accessibility features: MobileAccessibility.isGuidedAccessEnabled() MobileAccessibility.isInvertColorsEnabled() MobileAccessibility.isGuidedAccessEnabled() MobileAccessibility.isInvertColorsEnabled() MobileAccessibility.isMonoAudioEnabled() Adds corresponding window events to subscribe to notifications of accessibility feature status updates: “guidedaccessstatusdidchange”, "invertcolorsstatusdidchange”, "monoaudiostatusdidchange" Adds following method for posting a notification as a string to be announced by VoiceOver: MobileAccessibility.postAnnouncementNotification()
This commit is contained in:
@@ -21,12 +21,28 @@
|
||||
|
||||
@interface CDVMobileAccessibility : CDVPlugin {
|
||||
NSString* callbackId;
|
||||
NSString* commandCallbackId;
|
||||
BOOL voiceOverRunning;
|
||||
BOOL closeCaptioningEnabled;
|
||||
BOOL guidedAccessEnabled;
|
||||
BOOL invertColorsEnabled;
|
||||
BOOL monoAudioEnabled;
|
||||
}
|
||||
|
||||
@property (strong) NSString* callbackId;
|
||||
@property (strong) NSString* commandCallbackId;
|
||||
@property BOOL voiceOverRunning;
|
||||
@property BOOL closeCaptioningEnabled;
|
||||
@property BOOL guidedAccessEnabled;
|
||||
@property BOOL invertColorsEnabled;
|
||||
@property BOOL monoAudioEnabled;
|
||||
|
||||
- (void) isVoiceOverRunning:(CDVInvokedUrlCommand*)command;
|
||||
- (void) isClosedCaptioningEnabled:(CDVInvokedUrlCommand*)command;
|
||||
- (void) isGuidedAccessEnabled:(CDVInvokedUrlCommand*)command;
|
||||
- (void) isInvertColorsEnabled:(CDVInvokedUrlCommand*)command;
|
||||
- (void) isMonoAudioEnabled:(CDVInvokedUrlCommand*)command;
|
||||
- (void) postAnnouncementNotification:(CDVInvokedUrlCommand*)command;
|
||||
- (void) start:(CDVInvokedUrlCommand*)command;
|
||||
- (void) stop:(CDVInvokedUrlCommand*)command;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#import "CDVMobileAccessibility.h"
|
||||
#import <Cordova/CDVAvailability.h>
|
||||
#import <MediaAccessibility/MediaAccessibility.h>
|
||||
|
||||
@interface CDVMobileAccessibility ()
|
||||
// add any property overrides
|
||||
@@ -27,6 +28,12 @@
|
||||
@implementation CDVMobileAccessibility
|
||||
|
||||
@synthesize callbackId;
|
||||
@synthesize commandCallbackId;
|
||||
@synthesize voiceOverRunning;
|
||||
@synthesize closeCaptioningEnabled;
|
||||
@synthesize guidedAccessEnabled;
|
||||
@synthesize invertColorsEnabled;
|
||||
@synthesize monoAudioEnabled;
|
||||
|
||||
// //////////////////////////////////////////////////
|
||||
|
||||
@@ -45,6 +52,8 @@
|
||||
if ([self settingForKey:setting]) {
|
||||
// set your setting, other init here
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onPause) name:UIApplicationDidEnterBackgroundNotification object:nil];
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////
|
||||
@@ -52,6 +61,9 @@
|
||||
- (void)dealloc
|
||||
{
|
||||
[self stop:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)onReset
|
||||
@@ -59,24 +71,126 @@
|
||||
[self stop:nil];
|
||||
}
|
||||
|
||||
- (void) onPause {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResume) name:UIApplicationWillEnterForegroundNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)onResume
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onPause) name:UIApplicationDidEnterBackgroundNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onApplicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)onApplicationDidBecomeActive
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
[self performSelector:@selector(sendMobileAccessibilityStatusChangedCallback) withObject:nil afterDelay:0.1 ];
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////
|
||||
|
||||
#pragma Plugin interface
|
||||
|
||||
- (void)isVoiceOverRunning:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:UIAccessibilityIsVoiceOverRunning()];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
||||
[self.commandDelegate runInBackground:^{
|
||||
self.voiceOverRunning = UIAccessibilityIsVoiceOverRunning();
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.voiceOverRunning];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)isClosedCaptioningEnabled:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:UIAccessibilityIsClosedCaptioningEnabled()];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
||||
[self.commandDelegate runInBackground:^{
|
||||
self.closeCaptioningEnabled = [self getClosedCaptioningEnabledStatus];
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.closeCaptioningEnabled];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)isGuidedAccessEnabled:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
[self.commandDelegate runInBackground:^{
|
||||
self.guidedAccessEnabled = UIAccessibilityIsGuidedAccessEnabled();
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.guidedAccessEnabled];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)isInvertColorsEnabled:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
[self.commandDelegate runInBackground:^{
|
||||
self.invertColorsEnabled = UIAccessibilityIsInvertColorsEnabled();
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.invertColorsEnabled];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)isMonoAudioEnabled:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
[self.commandDelegate runInBackground:^{
|
||||
self.monoAudioEnabled = UIAccessibilityIsMonoAudioEnabled();
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.monoAudioEnabled];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)postAnnouncementNotification:(CDVInvokedUrlCommand *)command
|
||||
{
|
||||
CDVPluginResult* result = nil;
|
||||
NSString* notificationString = [command.arguments objectAtIndex:0];
|
||||
|
||||
if (UIAccessibilityIsVoiceOverRunning() &&
|
||||
notificationString != nil && [notificationString length] > 0) {
|
||||
self.commandCallbackId = command.callbackId;
|
||||
[self.commandDelegate runInBackground:^{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityAnnouncementDidFinish:) name:UIAccessibilityAnnouncementDidFinishNotification object:nil];
|
||||
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, notificationString);
|
||||
}];
|
||||
} else {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mobileAccessibilityAnnouncementDidFinish:(NSNotification *)dict
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityAnnouncementDidFinishNotification object:nil];
|
||||
|
||||
NSString* valueSpoken = [[dict userInfo] objectForKey:UIAccessibilityAnnouncementKeyStringValue];
|
||||
NSString* wasSuccessful = [[dict userInfo] objectForKey:UIAccessibilityAnnouncementKeyWasSuccessful];
|
||||
|
||||
NSMutableDictionary* data = [NSMutableDictionary dictionaryWithCapacity:2];
|
||||
[data setObject:valueSpoken forKey:@"stringValue"];
|
||||
[data setObject:wasSuccessful forKey:@"wasSuccessful"];
|
||||
|
||||
if (self.commandCallbackId) {
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:data];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:self.commandCallbackId];
|
||||
self.commandCallbackId = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)getClosedCaptioningEnabledStatus
|
||||
{
|
||||
BOOL status = false;
|
||||
if (&MACaptionAppearanceGetDisplayType) {
|
||||
status = (MACaptionAppearanceGetDisplayType(kMACaptionAppearanceDomainUser) > kMACaptionAppearanceDisplayTypeAutomatic);
|
||||
} else {
|
||||
status = UIAccessibilityIsClosedCaptioningEnabled();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
- (void)mobileAccessibilityStatusChanged:(NSNotification *)notification
|
||||
{
|
||||
[self sendMobileAccessibilityStatusChangedCallback];
|
||||
}
|
||||
|
||||
- (void)sendMobileAccessibilityStatusChangedCallback
|
||||
{
|
||||
if (self.callbackId) {
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self getMobileAccessibilityStatus]];
|
||||
@@ -88,38 +202,59 @@
|
||||
/* Get the current mobile accessibility status. */
|
||||
- (NSDictionary*)getMobileAccessibilityStatus
|
||||
{
|
||||
NSMutableDictionary* mobileAccessibilityData = [NSMutableDictionary dictionaryWithCapacity:2];
|
||||
[mobileAccessibilityData setObject:[NSNumber numberWithBool:UIAccessibilityIsVoiceOverRunning()] forKey:@"isVoiceOverRunning"];
|
||||
[mobileAccessibilityData setObject:[NSNumber numberWithBool:UIAccessibilityIsClosedCaptioningEnabled()] forKey:@"isClosedCaptioningEnabled"];
|
||||
self.voiceOverRunning = UIAccessibilityIsVoiceOverRunning();
|
||||
self.closeCaptioningEnabled = [self getClosedCaptioningEnabledStatus];
|
||||
self.guidedAccessEnabled = UIAccessibilityIsGuidedAccessEnabled();
|
||||
self.invertColorsEnabled = UIAccessibilityIsInvertColorsEnabled();
|
||||
self.monoAudioEnabled = UIAccessibilityIsMonoAudioEnabled();
|
||||
|
||||
NSMutableDictionary* mobileAccessibilityData = [NSMutableDictionary dictionaryWithCapacity:5];
|
||||
[mobileAccessibilityData setObject:[NSNumber numberWithBool:self.voiceOverRunning] forKey:@"isVoiceOverRunning"];
|
||||
[mobileAccessibilityData setObject:[NSNumber numberWithBool:self.closeCaptioningEnabled] forKey:@"isClosedCaptioningEnabled"];
|
||||
[mobileAccessibilityData setObject:[NSNumber numberWithBool:self.guidedAccessEnabled] forKey:@"isGuidedAccessEnabled"];
|
||||
[mobileAccessibilityData setObject:[NSNumber numberWithBool:self.invertColorsEnabled] forKey:@"isInvertColorsEnabled"];
|
||||
[mobileAccessibilityData setObject:[NSNumber numberWithBool:self.monoAudioEnabled] forKey:@"isMonoAudioEnabled"];
|
||||
return mobileAccessibilityData;
|
||||
}
|
||||
|
||||
|
||||
/* turn on MobileAccessibility monitoring*/
|
||||
/* start MobileAccessibility monitoring */
|
||||
- (void)start:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
self.callbackId = command.callbackId;
|
||||
[self.commandDelegate runInBackground:^{
|
||||
self.callbackId = command.callbackId;
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityVoiceOverStatusChanged object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityClosedCaptioningStatusDidChangeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityGuidedAccessStatusDidChangeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityInvertColorsStatusDidChangeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityMonoAudioStatusDidChangeNotification object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:)
|
||||
name:UIAccessibilityVoiceOverStatusChanged object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:)
|
||||
name:UIAccessibilityClosedCaptioningStatusDidChangeNotification object:nil];
|
||||
// Update the callback on start
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self getMobileAccessibilityStatus]];
|
||||
[result setKeepCallbackAsBool:YES];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:self.callbackId];
|
||||
}];
|
||||
}
|
||||
|
||||
/* stop MobileAccessibility monitoring */
|
||||
- (void)stop:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
// callback one last time to clear the callback function on JS side
|
||||
if (self.callbackId)
|
||||
{
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self getMobileAccessibilityStatus]];
|
||||
[result setKeepCallbackAsBool:NO];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:self.callbackId];
|
||||
}
|
||||
self.callbackId = nil;
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
name:UIAccessibilityVoiceOverStatusChanged object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
name:UIAccessibilityClosedCaptioningStatusDidChangeNotification object:nil];
|
||||
[self.commandDelegate runInBackground:^{
|
||||
// callback one last time to clear the callback function on JS side
|
||||
if (self.callbackId)
|
||||
{
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self getMobileAccessibilityStatus]];
|
||||
[result setKeepCallbackAsBool:NO];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:self.callbackId];
|
||||
}
|
||||
self.callbackId = nil;
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityVoiceOverStatusChanged object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityClosedCaptioningStatusDidChangeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityGuidedAccessStatusDidChangeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityInvertColorsStatusDidChangeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityAnnouncementDidFinishNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityMonoAudioStatusDidChangeNotification object:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user