handleWatchKitExtensionRequest 在 iphone 上播放背景音频
handleWatchKitExtensionRequest play background audio on iphone
我正在试验一个 WatchKit 应用程序,它将在 iphone 上触发音频警报。我已将其设置为触发,每 5 秒重复一次。在 iphone 上,我有在后台播放短音频 wav 文件的逻辑。它被设计为即使应用程序被最小化并播放音频也能正常工作。我已经在 iphone 上测试了它的独立运行情况。
不起作用的步骤是手表上的触发器告诉父 Iphone 应用程序播放音频。它大部分都有效,除了 2 秒的音频警报被剪掉了大约 0.5 秒。它播放第一部分的啁啾声并被切断。每次我触发它时,它都会对整个 wav 声音进行剪裁。
来自父应用的回复没问题,我想知道回复一返回是否所有后台处理都被完全切断。
我在应用程序中启用了音频背景模式。
如何让手表触发应用程序在后台播放整个音频警报?
// WatchApp InterfaceController
- (void)pingIphone {
[WKInterfaceController openParentApplication:@{@"requestString":@"findphone"} reply:^(NSDictionary *replyInfo, NSError *error) {
NSLog(@"\nReply info: %@\nError: %@",replyInfo, error);
}];
}
// Iphone AppDelegate
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
NSString * request = [userInfo objectForKey:@"requestString"];
NSDictionary * replyContent = @{@"state":(application.applicationState == UIApplicationStateBackground ? @"back" : @"not back")};
if ([request isEqualToString:@"findphone"]){
ViewController *vc = [[ViewController alloc] init];
[vc pingIphone];
}
reply(replyContent);
}
// Iphone ViewController
@property (strong, nonatomic) AVQueuePlayer *player;
- (void)viewDidLoad {
[super viewDidLoad];
// get device's default audio level on start
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionSetActive(true);
Float32 volume;
UInt32 dataSize = sizeof(Float32);
AudioSessionGetProperty (
kAudioSessionProperty_CurrentHardwareOutputVolume,
&dataSize,
&volume
);
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[[AVAudioSession sharedInstance] addObserver:self forKeyPath:@"outputVolume" options:NSKeyValueObservingOptionNew context:nil];
}
(void)pingIphone {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if([userDefaults boolForKey:@"vibrate_bool"] == YES){
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}
for(int i = 0; i < 5; i++){
[_player insertItem:[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"alarm" withExtension:@"wav"]] afterItem:nil];
}
//NSLog(@"volume: %f",[userDefaults floatForKey:@"volume"]);
if (!(_player.rate > 0 && !_player.error)) {
[self startAudio];
}
}
- (void)startAudio {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[[AVAudioSession sharedInstance] setDelegate: self];
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
NSString* path = [[NSBundle mainBundle] pathForResource:@"alarm" ofType:@"wav"];
_player = [[AVQueuePlayer alloc] init];
for(int i = 0; i < 5; i++){
[_player insertItem:[AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:path]] afterItem:nil];
}
_player.volume = [userDefaults floatForKey:@"volume"];
[_player play];
if (setCategoryError)
NSLog(@"Error setting category! %@", setCategoryError);
}
听起来您的应用程序正在被 OS 终止。查看此答案以获取一些建议:
是的,如果您不使用后台任务,一旦您调用 reply()
,处理就会结束。
我正在试验一个 WatchKit 应用程序,它将在 iphone 上触发音频警报。我已将其设置为触发,每 5 秒重复一次。在 iphone 上,我有在后台播放短音频 wav 文件的逻辑。它被设计为即使应用程序被最小化并播放音频也能正常工作。我已经在 iphone 上测试了它的独立运行情况。
不起作用的步骤是手表上的触发器告诉父 Iphone 应用程序播放音频。它大部分都有效,除了 2 秒的音频警报被剪掉了大约 0.5 秒。它播放第一部分的啁啾声并被切断。每次我触发它时,它都会对整个 wav 声音进行剪裁。
来自父应用的回复没问题,我想知道回复一返回是否所有后台处理都被完全切断。
我在应用程序中启用了音频背景模式。
如何让手表触发应用程序在后台播放整个音频警报?
// WatchApp InterfaceController
- (void)pingIphone {
[WKInterfaceController openParentApplication:@{@"requestString":@"findphone"} reply:^(NSDictionary *replyInfo, NSError *error) {
NSLog(@"\nReply info: %@\nError: %@",replyInfo, error);
}];
}
// Iphone AppDelegate
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
NSString * request = [userInfo objectForKey:@"requestString"];
NSDictionary * replyContent = @{@"state":(application.applicationState == UIApplicationStateBackground ? @"back" : @"not back")};
if ([request isEqualToString:@"findphone"]){
ViewController *vc = [[ViewController alloc] init];
[vc pingIphone];
}
reply(replyContent);
}
// Iphone ViewController
@property (strong, nonatomic) AVQueuePlayer *player;
- (void)viewDidLoad {
[super viewDidLoad];
// get device's default audio level on start
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionSetActive(true);
Float32 volume;
UInt32 dataSize = sizeof(Float32);
AudioSessionGetProperty (
kAudioSessionProperty_CurrentHardwareOutputVolume,
&dataSize,
&volume
);
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[[AVAudioSession sharedInstance] addObserver:self forKeyPath:@"outputVolume" options:NSKeyValueObservingOptionNew context:nil];
}
(void)pingIphone {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if([userDefaults boolForKey:@"vibrate_bool"] == YES){
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}
for(int i = 0; i < 5; i++){
[_player insertItem:[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"alarm" withExtension:@"wav"]] afterItem:nil];
}
//NSLog(@"volume: %f",[userDefaults floatForKey:@"volume"]);
if (!(_player.rate > 0 && !_player.error)) {
[self startAudio];
}
}
- (void)startAudio {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[[AVAudioSession sharedInstance] setDelegate: self];
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
NSString* path = [[NSBundle mainBundle] pathForResource:@"alarm" ofType:@"wav"];
_player = [[AVQueuePlayer alloc] init];
for(int i = 0; i < 5; i++){
[_player insertItem:[AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:path]] afterItem:nil];
}
_player.volume = [userDefaults floatForKey:@"volume"];
[_player play];
if (setCategoryError)
NSLog(@"Error setting category! %@", setCategoryError);
}
听起来您的应用程序正在被 OS 终止。查看此答案以获取一些建议:
是的,如果您不使用后台任务,一旦您调用 reply()
,处理就会结束。