c# - 在 Window Phone 8.1 中从服务器收到原始推送通知后执行某些功能

标签 c# windows windows-phone-8.1 windows-phone microsoft-metro

即使应用程序未运行,我也想在收到推送通知时执行我自己的函数。用户不需要单击操作栏中的通知。

BackgroundTask.cs中,我有以下代码片段:

namespace BackgroundTasks
{
public sealed class SampleBackgroundTask : IBackgroundTask
{
    public void Run(IBackgroundTaskInstance taskInstance)
    {
        ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
        string taskName = taskInstance.Task.Name;
        Debug.WriteLine("Background " + taskName + " starting...");

        RawNotification notification = (RawNotification)taskInstance.TriggerDetails;
        settings.Values[taskName] = notification.Content;

        Debug.WriteLine("Background " + taskName + " completed!");
    }
}
}

这是我使用 PushNotificationTrigger 注册后台任务的代码:

private async void RegisterBackgroundTask()
    {

        BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder();
        PushNotificationTrigger trigger = new PushNotificationTrigger();


        taskBuilder.SetTrigger(trigger);

        taskBuilder.TaskEntryPoint = "BackgroundTasks.SampleBackgroundTask";
        taskBuilder.Name = "SampleBackgroundTask";

        try
        {
            BackgroundTaskRegistration task = taskBuilder.Register();
        }
        catch (Exception ex)
        {
        }
    }

enter image description here

我已经在Package.appmanifest中设置了所有必要的内容,在执行RegisterBackgroundTask之后,假设必须注册BackgroundTask。但就我而言,我没有找到任何已注册的 BackgroundTask:

enter image description here

以下是获取 channel Uri 的代码片段:

 private async void OpenChannelAndRegisterTask()
    {
        try
        {
          PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
          string uri = channel.Uri;
          RegisterBackgroundTask();
        }
        catch (Exception ex)
        {
        }
    }

我从网络服务发送原始通知,如下所示:

namespace SendToast
{

public partial class SendToast : System.Web.UI.Page
{
    private string sid = "PACKAGE SID";
    private string secret = "CLIENT SECRET";
    private string accessToken = "";

    [DataContract]
    public class OAuthToken
    {
        [DataMember(Name = "access_token")]
        public string AccessToken { get; set; }
        [DataMember(Name = "token_type")]
        public string TokenType { get; set; }
    }

    OAuthToken GetOAuthTokenFromJson(string jsonString)
    {
        using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
        {
            var ser = new DataContractJsonSerializer(typeof(OAuthToken));
            var oAuthToken = (OAuthToken)ser.ReadObject(ms);
            return oAuthToken;
        }
    }

    public void getAccessToken()
    {
        var urlEncodedSid = HttpUtility.UrlEncode(String.Format("{0}", this.sid));
        var urlEncodedSecret = HttpUtility.UrlEncode(this.secret);

        var body =
          String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret);

        var client = new WebClient();
        client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

        string response = client.UploadString("https://login.live.com/accesstoken.srf", body);
        var oAuthToken = GetOAuthTokenFromJson(response);
        this.accessToken = oAuthToken.AccessToken;
    }

    protected string PostToCloud(string uri, string xml, string type = "wns/raw")
    {
        try
        {
            if (accessToken == "")
            {
                getAccessToken();
            }
            byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);

            WebRequest webRequest = HttpWebRequest.Create(uri);
            HttpWebRequest request = webRequest as HttpWebRequest;
            webRequest.Method = "POST";

            webRequest.Headers.Add("X-WNS-Type", type);
            webRequest.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken));

            Stream requestStream = webRequest.GetRequestStream();
            requestStream.Write(contentInBytes, 0, contentInBytes.Length);
            requestStream.Close();

            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

            return webResponse.StatusCode.ToString();
        }
        catch (WebException webException)
        {
            string exceptionDetails = webException.Response.Headers["WWW-Authenticate"];
            if ((exceptionDetails != null) && exceptionDetails.Contains("Token expired"))
            {
                getAccessToken();
                return PostToCloud(uri, xml, type);
            }
            else
            {
                return "EXCEPTION: " + webException.Message;
            }
        }
        catch (Exception ex)
        {
            return "EXCEPTION: " + ex.Message;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        string channelUri = "https://hk2.notify.windows.com/?token=AwYAAAAL4AOsTjp3WNFjxNFsXmFPtT5eCknoCeZmZjE9ft90H2o7xCOYVYZo7o10IAl6BpK9wTxpgIKIeF0TGF2GJZhWAExYd7qEAIlJQNvApQ3V7SA36%2brEow%2bN3NwVDGz4UI%3d";

        if (Application["channelUri"] != null)
        {
            Application["channelUri"] = channelUri;
        }
        else
        {
            Application.Add("channelUri", channelUri);
        }

        if (Application["channelUri"] != null)
        {
            string aStrReq = Application["channelUri"] as string;
            string rawMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
            "<root>" +
                "<Value1>" + "Hello" + "<Value1>" +
                "<Value2>" + "Raw" + "<Value2>" +
            "</root>";
            Response.Write("Result: " + PostToCloud(aStrReq, rawMessage));
        }
        else
        {
            Response.Write("Application 'channelUri=' has not been set yet");
        }
        Response.End();
    }
}
}

我只想在收到原始通知时触发我的 BackgroundTask,即使应用程序未运行也是如此。请帮我。提前致谢。

最佳答案

尝试使用原始通知触发后台任务。您必须使用 PushNotificationTrigger 注册后台任务。这是Documentation链接。

关于c# - 在 Window Phone 8.1 中从服务器收到原始推送通知后执行某些功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32136390/

相关文章:

c# - HTTP 请求未经客户端身份验证方案 'Ntlm' 授权

windows - 导出符号时必须指定 extern "C"吗?

.net - WCF Windows 服务超时

c# - 如何在 TextBox Windows Phone 8.1 中更改文本的垂直对齐方式

c# - 使用图像填充 ListView 时出现内存不足异常 (Windows Phone 8.1)

c# - MongoDB C# 驱动程序 - POCO 引用的序列化?

c# - Quartz C# 每小时运行一次

c# - XtraGrid 中列中的唯一值列表

c# - 延迟 Windows 注销(XP、Vista 和 7)

javascript - 完全关闭我自己在 Windows Phone 8.1 和 Windows 8.1 上开发的应用程序