Universal App - 操作 Secondary Tiles
上一篇<Universal App - 操作 Tiles>說明了簡易操作 Tile templates 來更新 default tile,該篇將介紹如何操作 Secondary Tiles。
[注意]
a. 如要取得 non-default tile (或稱 Secondary Tile)的話,需先藉由 TileNotification.content 取得已存在的 Tile 內容加以修改;
b. Only users can pin a secondary tile; apps cannot pin secondary tiles programmatically without user approval.;
》Secondary tiles 概要:
作用於推廣某些特定的內容與 deep links (一種可參考至特定 app 中的內容或功能),藉由 pin to start 的方式將 tile 加入 start screen。
建議 App 為了某些特殊需求(例如:即時新聞、比賽狀況、價位波動、新的部落格文章、RSS News …等)可加入 Secondary tiles 的運用。
由於 secondary tile 用戶可以手動移除或加入,所以在加入或更新時要記得給予識別值。
〉Secondary tile 的基本特性:
a. 需要擁有一個 unique ID;
b. 可藉由初始化 notification、push notification、local notification 或 schedule notification 的方式更新它;
c. 可利用 app 或手動從 start screen 移除或新增 secondary tile;
d. app 需要處理用戶藉由 secondary tile 啟動 app 所帶入的 deep links;
〉Secondary tiles 與 default app Tiles 的差別:
相似點:
a. 使用 tile templates 決定 secondary tiles 通知更新的內容;
b. 必需包括 150x150 pixel logo 為 default tile content;
c. 可選擇使用 310x150 pixel wide logo 為 default tile content;
d. 支援 notifications 與 badges 的操作;
e. 支援在 start screen 上重排;
f. 當 app 被刪除時,secondary tiles 一併被自動刪除;
g. 能被顯示於 start screen 與 lock screen (Windows Store app)中;
差異點:
a. 用戶可任何時刪除掉 secondary tiles;
b. secondary tiles 需在 run time 中由用戶手動增加;(default tile 由安裝時自動加入)
c. 可利用 flyout 提供用戶在加入 secondary tiles 時的確認;
d. Windows 能自動備份並移植 secondary tiles 至第二個設備;
e. (Windows Store app) secondary tiles 不能自動加入至 lock screen 中,需要藉由手動經「Settings –> Personalize -> PC Settings」;
f. 一個 App 可以有多個 secondary tiles,每一個 secondary tile 具有一個識別值。
〉Syncing a secondary tile across devices:
secondary tiles 的建立或刪除可以被 roaming 在不同的 PCs 或 tables。 windows 8.1 預設與 onedrvice 整合會自動同步這些設定。
可要在建立或更新 secondary tile 的 notification 指定「SecondaryTile.RoamingEnabled = false」取消同步,(WP 8.1 預設 false)。
更多詳細的內容可參考<Secondary tiles overview (Windows Runtime apps)>與<Guidelines for secondary tiles>。
負責建立、列舉與呈現相關一個 secondary tile 的資訊。詳細的屬性、方法如下:
類型 | 名稱 | 說明 |
Constructor | SecondaryTile() | Creates a SecondaryTile object. The caller must then set any mandatory properties through the object before attempting to pin, update, or delete the tile. |
SecondaryTile(String) | Creates a SecondaryTile object with a specific ID. This form of the constructor should be used to create a secondary tile object to perform a tile update or deletion. | |
Event | VisualElementsRequested | Fired when a call is made to RequestCreateAsync. |
Method | Exists | Checks whether a specific secondary tile exists for the calling app. |
FindAllAsync() | Retrieves a list of secondary tiles created for the calling app. | |
FindAllAsync(String) | Retrieves a list of secondary tiles created for another app in the same package as the calling app. | |
FindAllForPackageAsync | Retrieves a list of secondary tiles created for all of the apps in the package of the calling app. | |
RequestCreateAsync() | Displays the Pin to Start flyout, through which the user can confirm that they want to create the secondary tile, which in turn creates the tile. Overloads of this method let you specify the on-screen location of the flyout. | |
RequestDeleteAsync() | Displays the Unpin from Start flyout. This flyout lets the user confirm removal of the secondary tile. | |
UpdateAsync | Updates a secondary tile after that tile is pinned to the Start screen. | |
Properties | Arguments | Read/write. Gets or sets an app-defined set of information that is passed from the secondary tile to the app on activation. This property is required when you create a tile. |
BackgroundColor | Read/write. Gets or sets the tile's background color. | |
DisplayName | Read/write. Gets or sets a name that is associated with and displayed on the tile. This name is displayed on the tile in Start, in the tile's tooltip, next to the small tile representation in the Apps list, and in some Control Panel applications. This property is required when you create a tile. | |
ForegroundText | Read/write. Gets or sets whether the tile should use dark or light text. | |
LockScreenBadgeLogo | Read/write. Gets or sets the location of a badge logo image to represent the secondary tile on the lock screen. By supplying this image, you declare that the secondary tile is eligible to display a badge on the lock screen. | |
LockScreenDisplayBadgeAndTileText | Read/write. Gets or sets whether the secondary tile is eligible to display both a badge and a detailed tile on the lock screen. | |
Logo | Read/write. Gets or sets the logo image used in a medium tile. This property is required when you create either a square or a wide tile. | |
PhoneticName | Read/write. Gets or sets a phonetic version of the secondary tile name. Used with character-based languages for UI sorting purposes. | |
RoamingEnabled | Read/write. Gets or sets a value that determines whether the secondary tile will be reacquired through the cloud when the parent app is installed by the user, using their Microsoft account, on another computer. | |
ShortName | Read/write. Gets or sets a short name to display directly on the tile. As of Windows 8.1, this property is ignored and the display name declared in the manifest is used in its place. | |
SmallLogo | Read/write. Gets or sets the small logo image, used in search results, the All Programs list, and other locations in the UI. | |
TileId | Read/write. Gets or sets a unique string to identify the tile within the package. This property is required when you create or delete a tile. | |
TileOptions | Read/write. Gets or sets options available to a secondary tile. | |
VisualElements | Read-only. Gets an object through which you can get or set a secondary tile's background color, foreground text, tile images, and app name display options. | |
WideLogo | Read/write. Gets or sets the logo image used in a wide secondary tile. This property is required when you create a wide secondary tile and gives the user the option of a wide tile when they resize the tile. |
以上介紹了 Secondary Tile class 的重要屬性,其中以 required 的屬性為優先閱讀,接著可關注需要在 lock screen 呈現何種內容。
Methods 的部分我沒有寫完,因為蠻多 methods 都只是參數的不同。
[範例]
事前準備對應需要的 Secondary tile 圖示:square150x150Logo、wide310x150Logo、square310x310Logo、square30x30Logo,以符合 Windows 與
Windows Phone 所需要的圖示大小。
1. 建立 secondary tile;
public async void PinTile(String tileId, String displayName)
{
// 準備四種 sizes 的 tile 圖示支援 Windows 與 Windows Phone 的 Tile 大小
Uri square150x150Logo = new Uri("ms-appx:///Assets/square150x150Tile.png");
Uri wide310x150Logo = new Uri("ms-appx:///Assets/wide310x150Tile.png");
Uri square310x310Logo = new Uri("ms-appx:///Assets/square310x310Tile.png");
Uri square30x30Logo = new Uri("ms-appx:///Assets/square30x30Tile.png");
// 指定觸發 secondary tile 的 id 與 arguments
string tileActivationArguments = tileId +
"?WasPinnedAt=" +
DateTime.Now.ToLocalTime().ToString();
SecondaryTile secondaryTile = new SecondaryTile(tileId,
displayName,
tileActivationArguments,
square150x150Logo,
TileSize.Square150x150);
// 指定 secondary tile 呈現前景文字的 color 與 background color
secondaryTile.VisualElements.ForegroundText = ForegroundText.Light;
secondaryTile.VisualElements.BackgroundColor = Windows.UI.Color.FromArgb(0x00, 0x00, 0xff, 0xaa);
// Like the background color, the square30x30 logo is inherited from the parent application tile by default.
// Let's override it, just to see how that's done.
secondaryTile.VisualElements.Square30x30Logo = square30x30Logo;
// The display of the secondary tile name can be controlled for each tile size.
// The default is false.
secondaryTile.VisualElements.ShowNameOnSquare150x150Logo = true;
secondaryTile.VisualElements.ShowNameOnSquare310x310Logo = true;
secondaryTile.VisualElements.ShowNameOnWide310x150Logo = true;
// Set this to false if roaming doesn't make sense for the secondary tile.
// The default is true;
secondaryTile.RoamingEnabled = false;
#if WINDOWS_APP
// Only support of the small and medium tile sizes is mandatory.
// To have the larger tile sizes available the assets must be provided.
secondaryTile.VisualElements.Wide310x150Logo = wide310x150Logo;
secondaryTile.VisualElements.Square310x310Logo = square310x310Logo;
var created = await secondaryTile.RequestCreateAsync();
if (created)
{
MessageDialog dialog = new MessageDialog("Secondary tile successfully pinned.");
dialog.ShowAsync();
}
else
{
MessageDialog dialog = new MessageDialog("Secondary tile not pinned.");
dialog.ShowAsync();
}
#endif
#if WINDOWS_PHONE_APP
await secondaryTile.RequestCreateAsync();
#endif
}
關於 SecondaryTile 建構子裡有一個 desiredSize 的設定,需要注意在 Windows 與 Windows Phone 有些許不同如下的說明:
〉desiredSize:
The size of tile to pin. This value must be Default (which provides Windows 8 behavior), Square150x150, or Wide310x150. Any other TileSize value causes an exception to be thrown during runtime. The desiredSize parameter is ignored on Windows Phone 8.1. On the phone, all tiles including secondary tiles are pinned at as medium tiles, after which they can be resized by the user. |
在請求建立 Secondary tile 時對於 Windows 與 Windows Phone 呈現方式有些不同;
a. Windows App 請求增加 Secondary tile 是可以直接取得執行結果的回傳值;
Windows Phone 則會直接離開 App 回到 Start Screen 建立 Secondary Tile;
b. Windows App 建立 Secondary tile 會出現預設系統提供的預覽畫面供用戶選擇預設要呈現的 Size;
Windows Phone 則如同上方說明預設為 Square150x150 的 Size;
2. 更新指定的 secondary tile:
public async void UpdateTileByNotification(String id)
{
var existTile = await GetTile(id);
if (existTile == null)
{
MessageDialog dialog = new MessageDialog("the tile id not exist in the all secondary tiles");
dialog.ShowAsync();
}
else
{
// 建議使用 NotificationsExtensions 藉由物件化取得要操作的 Tile template
XmlDocument tileTemplateDom = TileUpdateManager.GetTemplateContent(
TileTemplateType.TileSquare150x150PeekImageAndText01);
// feed text elements
XmlNodeList textXmls = tileTemplateDom.GetElementsByTagName("text");
textXmls[0].InnerText = "update secondary tile";
Dictionary<String, String> imgCollection = new Dictionary<string, string>
{
{"img0","ms-appx:///Assets/Tiles/01.png"},
{"img1","ms-appx:///Assets/Tiles/02.png"},
{"img2","ms-appx:///Assets/Tiles/03.png"},
{"img3","ms-appx:///Assets/Tiles/04.png"},
};
XmlNodeList tileImageAttributes = tileTemplateDom.GetElementsByTagName("image");
for (int i = 0; i < imgCollection.Count; i++)
{
String key = String.Format("img{0}", i);
if (i <= tileImageAttributes.Count - 1)
{
((XmlElement)tileImageAttributes[i]).SetAttribute("src", imgCollection[key]);
((XmlElement)tileImageAttributes[i]).SetAttribute("alt", key);
}
}
// 取得要求更新的 TileNotification
TileNotification tile = new TileNotification(tileTemplateDom);
// 藉由 CreateTileUpdateForSecondaryTile 與指定 Id 來更新
TileUpdateManager.CreateTileUpdaterForSecondaryTile(id).Update(tile);
MessageDialog dialog = new MessageDialog("by notificatino update tile id");
dialog.ShowAsync();
}
}
c. 刪除指定的 secondary tile:
public async void UnPinTile(String id)
{
var existTile = await GetTile(id);
if (existTile == null)
{
MessageDialog dialog = new MessageDialog("the tile id not exist in the all secondary tiles");
dialog.ShowAsync();
}
else
{
// 利用 id 重新建立一個 secondary tile 物件
SecondaryTile secondaryTile = new SecondaryTile(id);
// 發出請求刪除的功能
var result = await secondaryTile.RequestDeleteAsync();
String msg = "";
if (result)
{
msg = "Secondary tile successfully unpinned.";
}
else
{
msg = "Secondary tile not unpinned.";
}
MessageDialog dialog = new MessageDialog(msg);
dialog.ShowAsync();
}
}
d. 取得 Secondary tile 指定要處理的 Arguments;
用戶點擊了 Secondary tile 會觸發 App 的 OnLaunched 的事件,此時 App 會識別一些該有的任務,例如:Suspending 的還原,
初始畫面的操作…等。因此,可藉由在此時對於目前畫面做一些處理或導向其他屬於 secondary tile 應該出現的內容。
d-1. 改寫 App.xaml.cs.OnLaunched 增加識別 secondary tile 傳入的參數與導向不同畫面的邏輯;
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// ... 以上省略
// 如果 rootFrame 中已有 Page 則要識別要導向那一個 Page
// 該內容通常可參考過去 UriMapping 的概念進行處理
if (rootFrame.Content.GetType() == typeof(MainPage))
{
rootFrame.Navigate(typeof(SecondaryPage), e.Arguments);
}
else
{
SecondaryPage page = rootFrame.Content as SecondaryPage;
if (page != null)
{
page.LaunchParam(e.Arguments);
}
}
// Ensure the current window is active
Window.Current.Activate();
}
d-2. 為 SecondaryPage.xaml.cs 增加顯示 secondary tile 傳入參數的代碼;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// 由於傳入的方式來自 Navigate 或直接使用,所以獨立一個處理方法
LaunchParam(e);
}
public void LaunchParam(object e)
{
if (e != null && String.IsNullOrEmpty(e.ToString()) == false)
{
MessageDialog dialoag = new MessageDialog("", "from secondary tile");
// 識別是否為 Secondary tile 傳入的參數
String param = e.ToString();
if (param.Contains("?WasPinnedAt"))
{
dialoag.Content = param;
dialoag.ShowAsync();
}
else
{
dialoag.Content = "not from secondary tile arguments";
dialoag.ShowAsync();
}
}
}
更完整的詳細範例可以參考:<Secondary tiles sample>。
對於 application tile 與 secondary tile 的差別可以參考<CreateBadgeUpdaterForApplication>與<CreateBadgeUpdaterForSecondaryTile.>
[範例程式]
======
以上是介紹如何操作 Secondary tiles 的說明,希望對大家操作 Tiles 有所幫助,謝謝。
References:
〉Secondary tiles overview (Windows Runtime apps) & SecondaryTile.VisualElements
〉Guidelines for secondary tiles & Guidelines for tiles and badges
〉TileTemplateType enumeration & App tiles and badges sample
〉Using live tiles with different app types (Windows Runtime apps) & Tile and toast image sizes
〉How to use the notification queue with local notifications (XAML)
〉Using the notification queue (Windows Runtime apps)
〉Packaging your Store app by using Visual Studio
〉Quickstart: Pinning a secondary tile (XAML)
〉Guidelines and checklist for secondary tiles (重要)
〉Quickstart: Sending a notification to a secondary tile
〉How to activate an app (XAML)
〉Optimizing Apps for Lower Cost Devices