31

現在、iOS 4用に開発しているアプリのバックグラウンドオーディオを設定しようとしています。viewControllerただし、Pandoraなどの他のバックグラウンドオーディオアプリとは異なり、アプリには専用の音楽プレーヤーがありません。紛らわしい。

適切なInfo.plist設定を正しく設定AVAudioPlayerし、アプリデリゲートにどこからでもアクセスできるオブジェクトがあります。AVAudioPlayerユーザーが曲を再生するときに、曲で初期化された新しい曲に置き換えて再生します。これはすべてうまく機能しますが、リモートコントロールイベントをサポートする方法がわかりません。

Appleのドキュメントに基づいて、私はこれを持っています:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
    switch(event.subtype) {
        case UIEventSubtypeRemoteControlTogglePlayPause:
            if([iPhoneAppDelegate backgroundAudioPlayer].playing)
                [iPhoneAppDelegate pauseBackgroundAudioPlayer];
            else
                [iPhoneAppDelegate playBackgroundAudioPlayer];
            break;
    }
}

問題は、これをどこに置くかということです。Appleのドキュメントでは、これはどこかのView Controllerに組み込まれるべきだと示唆されているようですが、私のアプリには多くのViewControllerとNavigationControllerがあります。これをどこに置いても、何らかの理由でマルチタスクトレイのリモコンの[再生/一時停止の切り替え]ボタンをタップすると、曲が一時停止してから一時停止が解除されるか、何らかの理由で曲が2回再生されます。

4

7 に答える 7

37

ドキュメントの例は少し誤解を招く可能性がありますが、どこにもサブクラス化する必要はありません。remoteControlReceivedWithEvent:を配置する正しい場所は、アプリがフォアグラウンドにあるかどうかに関係なく、レスポンダーチェーンに残るため、アプリケーションデリゲートにあります。また、リモートコントロールイベントの受信の開始/終了は、ランダムビューの可視性ではなく、実際にイベントが必要かどうかに基づいている必要があります。

于 2012-01-14T23:09:27.800 に答える
19

少し検索した後、AppleDeveloperForumsでグローバルリモートコントロールイベントを受信するための解決策をいくつか見つけました。

1つの方法は、そのをサブクラス化UIWindowしてオーバーライドすることremoteControlReceivedWithEvent:です。

2番目の、おそらくより良い方法は、をサブクラス化UIApplicationしてオーバーライドすることsendEvent:です。これにより、すべてのリモートコントロールイベントをインターセプトしてグローバルに処理でき、レスポンダーチェーンの後半で他のレスポンダーに処理させることはできません。

- (void)sendEvent:(UIEvent *)event {
     if (event.type == UIEventTypeRemoteControl) {
          // Handle event
     }
     else
          [super sendEvent:event];
}
于 2010-08-11T17:51:40.050 に答える
4

2番目のメソッドは私にsendEventは機能せず、呼び出されることはありませんでした。ただし、最初のメソッドはうまく機能しました(サブクラス化UIWindow)。

于 2010-12-19T09:59:22.653 に答える
3

私はしばらくこれに苦労しましたが、上記の答えはどれもうまくいきませんでした。私のコードのバグは、誰かがこれを読むのに役立つことを願っていますが、AudioSessionを他の人とミックスするように設定していたことです。リモートコントロールイベントを取得するには、フォアグラウンドオーディオプレーヤーになりたいと考えています。次のような誤ったコードがあるかどうかを確認してください。

    [[AVAudioSession sharedInstance] setDelegate: self];
    [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
    UInt32 doSetProperty = 0;
    AudioSessionSetProperty (
                             kAudioSessionProperty_OverrideCategoryMixWithOthers,
                             sizeof (doSetProperty),
                             &doSetProperty
                             );
    NSError *activationError = nil;
    [[AVAudioSession sharedInstance] setActive: YES error: &activationError];       

そして、AudioSessionSetPropertyを削除するか、doSetPropertyを1に変更します。

于 2012-05-29T20:33:28.437 に答える
0

Windowをサブクラス化したり、イベントを転送したりする必要はありません。メインのViewControllerから処理するだけです。詳細については、オーディオミキサー(MixerHost)の例を参照してください。

http://developer.apple.com/LIBRARY/IOS/#samplecode/MixerHost/Listings/Classes_MixerHostViewController_m.html

于 2011-07-27T02:19:37.120 に答える
0

ドキュメントはそれを非常によく説明しています。 https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/Remote-ControlEvents/Remote-ControlEvents.html

于 2013-09-04T21:02:56.700 に答える
0

この動作に影響を与えると思われるものの1つは、setCategory:error:の代わりにsetCategory:withOptions:error:を使用してAVAudioSessionに設定したカテゴリオプションです。特に、試行錯誤の結果、AVAudioSessionCategoryOptionMixWithOthersを設定した場合、リモートコントロールイベントは取得されないようです。現在再生中のコントロールは引き続きiPodアプリを制御します。AVAudioSessionCategoryOptionDuckOthersを設定すると、リモートコントロールイベントが発生しますが、どのアプリが制御されているかに関してあいまいさが存在する可能性があります。categoryOptionsを0に設定するか、setCategory:error:を呼び出すだけで最適に機能します。

于 2014-09-21T22:37:48.693 に答える