6

プッシュ通知を利用する Windows Phone 7 アプリケーションを作成しており、MS Notification Server とクラウド内のサービスとの間のやり取りを管理するクラスがあります。ただし、デバイスでチャネルを開こうとすると、HttpNotificationChannel は「チャネルを開くことができませんでした」というメッセージで InvalidOperationException をスローしています。MSDNによると 、チャネルをもう一度開いてみる必要があります。

プッシュ通知を開くための私のコード スニペットは、次の標準パターンに従っています。

public class HttpNotification {
  private const string kChannelName = "MyApp.PushNotification";

  private HttpNotificationChannel _Channel;

  public void Register() {
    try {
      _Channel = HttpNotificationChannel.Find(kChannelName);
      if (_Channel == null) {
        _Channel = new HttpNotificationChannel(kChannelName);
        InstallEventHandlers();

        // This line throws
        _Channel.Open();
      } else {
        InstallEventHandlers();
      };
    } catch (InvalidOperationException ex) {
      MessageBox.Show(string.Format("Failed to initialise Push Notifications - {0}", ex.Message));
    };
  }
}

MSDN の「チャンネルをもう一度開いてみてください」という言葉が何を意味するのか正確にはわかりません。Open() の呼び出しを try/catch でラップし、試行の間に 5 秒間スヌーズしましたが、成功しません。また、メソッド全体で同じアプローチを試みました (つまり、スローするたびに HttpNotificationChannel.Find() を呼び出します) が役に立ちませんでした。

私はこれが少し曖昧であることを知っています - しかし、誰かがこれを処理するための提案を持っているかどうか疑問に思っていました? この同じコードはエミュレーターでは問題なく動作しますが、アプリケーションをアンインストールして再インストールした後でも、実際のデバイスでは毎回失敗します。これが私の実際の電話であることを考えると、この問題が解決されることを期待してハードウェアのリセットを行うのは少し気が進まない.

更新: 追加のポイントとして、認証されていないチャネルを使用しているため、クラウドベースのサービス用に証明書がインストールされていません。

更新 #2: さらに、Microsoft Phone Push Recipe を自分のデバイスに展開しようとしたところ、同じ例外がスローされました。

4

2 に答える 2

6

あなたのコメントから、エミュレーターでは機能しますが、電話では機能しないことがわかりますよね? ひょっとして、別の/以前のアプリケーションでチャンネル名を使用していませんか?

問題は、エミュレータが閉じるたびにデフォルトの状態にリセットされることです。電話機はそうではありません。特定のチャネル名は、1 つのアプリケーションでのみ使用できます。そのため、チャネル名が同じ電話の別のアプリケーションで使用されていた場合、そのアプリにまだ登録されており、アプリからアクセスできません。

逆に、アプリは複数のチャネルを登録することもできません。そのため、関連付けられた別の名前のチャネルが既に存在する場合、古いチャネルを登録解除してデバイスを再起動するまで、新しいチャネルを登録することはできません。また、アプリに関連付けられているチャンネルをリクエストする方法もありません。

最終的に、このループに陥ったときに、チャネルの名前とアプリケーションの ProductID を WMAppManifest.xml に登録して変更したところ、再び機能しました。

<App xmlns="" ProductID="{d57ef66e-f46c-4b48-ac47-22b1e924184b}"

更新 今週末、私のコンピューターがクラッシュしました。WHS とバックアップに感謝します。とにかく以下は私のソースコードです。私は2つの違いに気づきました。

  1. RepeatAttemptExecuteMethod()まず、実行中のコード全体をデリゲートとして渡すメソッドを作成しました。最後のどこかに浮かぶ 10 は、再試行する必要がある回数です。メソッドを 5 秒ごとに再試行しただけの場合.Open、違いは、Find および New メソッドも再度呼び出すという点にある可能性があります...

  2. もう 1 つの違いは、コードが _appChannel.ChannelUri を null にできると想定していることです。その場合、チャネルがイベントを発生させるのを待ってから、そこにある実際のチャネルに関連付けられた作業を行います。しかし、あなたのサンプルコードはそのような仕事をしていないので、あなたが探しているものになるとは思えません

    protected override void Load(PhoneApplicationPage parent)
    {
        Verkeer.Helper.ExternalResources.RepeatAttemptExecuteMethod(() => 
        {
            _appChannel = HttpNotificationChannel.Find(CHANNELNAME);
            if (_appChannel == null)
            {
                _appChannel = new HttpNotificationChannel(CHANNELNAME);
                SetUpDelegates();
            }
            else
            {
                SetUpDelegates();
                //if (_appChannel.ChannelUri != null) this.NotificationChannel = _appChannel.ChannelUri;
            }
            if (_appChannel.ChannelUri != null) this.NotificationChannel = _appChannel.ChannelUri;
            else
            {
                try
                {
                    _appChannel.Open();
                }
                catch { }
            }
    
            BindToShellTile();
    
            App.ViewModel.TrafficInfo.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(TrafficInfo_PropertyChanged);
    
            if (App.ViewModel.TrafficInfo.TrafficImage != null && this.NotificationChannel != null)
            {
                CreateTiles();
            }
        },10);
    }
    
    private void BindToShellTile()
    {
        if (!_appChannel.IsShellTileBound && App.ViewModel.PanItemSettings.AutomaticallyUpdateTile)
        {
            Collection<Uri> ListOfAllowedDomains = new Collection<Uri> { new Uri("http://m.anwb.nl/") };
            _appChannel.BindToShellTile(ListOfAllowedDomains);
        }
    }
    
    
    void TrafficInfo_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "TrafficImage")
        {
            if (App.ViewModel.PanItemSettings.AutomaticallyUpdateTile && this.NotificationChannel != null)
            {
                CreateTiles();
            }
        }
    }
    
于 2011-03-02T09:29:49.930 に答える
0

@slaad ..これらをまだ試していない限り、私がチェックするいくつかのことを次に示します。

  1. 実際のデバイスにはデータ接続がありますよね? ああ:)
  2. 分離ストレージに既存のチャネルをどのように保存していますか? Find() が機能していることと、例外につながる存在するチャネルを再作成しようとしていないことを確認してください。
  3. チャンネルの作成にドメイン名または証明書に関する問題があるかどうかを確認してください。このリンクを試してください
  4. これに対してプロセスのすべてのステップをチェックしてください

申し訳ありませんが、これ以上の助けにはなりません。

于 2011-03-01T14:07:10.820 に答える