需求
最近在做UWP的項目,其中有這樣一個的需求:統計用戶使用APP的時長。
思路
在用戶打開app的時候,記錄一個時間點t1
;然後在關閉app的時候記錄第二個時間點t2
。在APP退出前上傳時間差t2-t1
。關鍵問題點是如何知道關掉APP的時刻,也就是說需要知道關掉APP的事件纔行。
實現
帶着這樣的問題,我們就開始在uwp
中尋找這樣的事件。在uwp
的CoreApplication
類中還真發現有一個貌似滿足我們需求的事件,Exiting
事件,那我們就趕緊在App.xaml.cs
中去處理這個事件。
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
CoreApplication.Exiting += (s, e) =>
{
Debug.WriteLine("CoreApplication.Exiting");
};
}
我們在第7行處加入斷點看看程序在關掉app的時候能否跑進來。結果讓人比較失望,發現在關閉app的時候,程序並沒有執行到斷點處。然後查找文檔,微軟的文檔告訴我們“Windows Phone 8,This API is supported in native apps only.”看來此路不通。
於是開始啓用面向谷歌編程的能力,發現uwp在Windows 10 Creators Update (10.0.15063.0)之後引入了一個類SystemNavigationManagerPreview
,這個類只做一件事情,就是向用戶提供了一種能夠響應關閉程序的方法。也就是CloseRequested
事件。微軟的文檔告訴我們:在用戶點擊了標題欄上的X
關閉按鈕時會觸發該事件。同時文檔說,要想使用這個事件,需要先開啓一個confirmAppClose
受限功能。
開啓方法如下:
在工程的Package.appxmanifest
中添加以下代碼。
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
<rescap:Capability Name="confirmAppClose"/>
受限功能開啓後,我們需要在代碼中去處理CloseRequested
事件。
public MainPage()
{
this.InitializeComponent();
。 SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += (s, e) =>
{
var deferral = e.GetDeferral();
//Do extra task here
Debug.WriteLine("Do extra task here");
deferral.Complete();
};
}
迫不及待的運行起來,實驗證明:在關掉app的時候,output中確實有Do extra task here
的日誌輸出。這說明CloseRequested
事件是有效的。
說明:代碼var deferral = e.GetDeferral();
和deferral.Complete();
是必須要加的,這讓uwp應用程序會確保extra task做完後再退出去。
小結
找到了CloseRequested
事件,我們的需求就能夠解決了。當然我們還可以在這個事件裏面做更多的事情以提升用戶體驗,比如在關閉APP的時候彈出一個對話框,詢問用戶是否保存用戶數據等等。
程序員的工作就是不斷填坑的過程。好記性不如爛筆頭,寫此博文,記錄下自己填坑的過程,避免第二次填坑時仍然填的那麼費力。如能幫到有需要的小夥伴,那將是我的榮幸。
參考
- special-and-restricted-capabilities(https://docs.microsoft.com/en-us/windows/uwp/packaging/app-capability-declarations?redirectedfrom=MSDN#special-and-restricted-capabilities)
- https://docs.microsoft.com/en-us/windows/uwp/packaging/app-capability-declarations?redirectedfrom=MSDN