{"id":28043,"date":"2016-11-15T12:00:43","date_gmt":"2016-11-15T20:00:43","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=28043"},"modified":"2016-11-15T12:00:43","modified_gmt":"2016-11-15T20:00:43","slug":"android-nougat-quick-setting-tiles","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/android-nougat-quick-setting-tiles\/","title":{"rendered":"Android Nougat Quick Setting Tiles"},"content":{"rendered":"<p>\t\t\t\t<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/QuickSettings.png\" alt=\"quicksettings\" width=\"200\" class=\"alignright size-full wp-image-28045\" \/>Android&#8217;s Quick Setting Tiles enable users to quickly access important system settings and applications with a simple swipe and click. These tiles represent several system settings, including Wi-Fi, Bluetooth, location, and rotation, but there has never been a way for non-system applications to participate. That has all changed with the release of Android Nougat and the Quick Settings Tile API, which empowers any developer to add their own setting with just a few lines of code. These new APIs have been enabled in the latest release of Xamarin.Android, now available as part of <a href=\"https:\/\/releases.xamarin.com\/stable-release-cycle-8-service-release-1\/\">Cycle 8 Service Release 1<\/a>.<\/p>\n<h2>Adding a Tile Service<\/h2>\n<p>Quick Setting Tiles are completely controlled by a new <a href=\"https:\/\/developer.xamarin.com\/guides\/android\/application_fundamentals\/services\/\">Android service<\/a>, a <strong>TileService<\/strong> that can be executed without the application running. We can create our own TileService by inheriting from it once the compile and target APIs have been set to 24 (Android Nougat):<\/p>\n<pre class=\"theme:vs2012 lang:csharp decode:true\">\nusing Android.App;\nusing Android.Graphics.Drawables;\nusing Android.Service.QuickSettings;\nusing Android.Views;\nusing Java.Lang;\n\npublic class GetMonkeyService : TileService\n{\n}\n<\/pre>\n<h3>Manifest Settings<\/h3>\n<p>Inheriting and creating the TileService will not be enough to actually get a Quick Setting Tile to show up, as we must specify particular metadata and intent filters for our new service. This can be accomplished with a few attributes on top of the class we just created:<\/p>\n<pre class=\"theme:vs2012 lang:csharp decode:true\">\n[Service(Name = \"com.refractored.monkeysapp.GetMonkeyService\",\n             Permission = Android.Manifest.Permission.BindQuickSettingsTile,\n             Label = \"@string\/tile_name\",\n             Icon = \"@drawable\/ic_tile_default\")]\n[IntentFilter(new[] { ActionQsTile })]\npublic class GetMonkeyService : TileService\n{\n\n}\n<\/pre>\n<p>The Service&#8217;s Label and Icon will show up in the Quick Settings area, so be sure to set those specific to your application. With just this code, the tile will show up and the user could possibly add it to their Quick Settings.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot_20161011-130432.png\" width=\"400\" class=\"aligncenter size-full wp-image-28052\" \/><\/p>\n<h3>Quick Setting Events<\/h3>\n<p>Our new tile has four extremely important events that it can respond to: when it&#8217;s added or removed and when it&#8217;s visible or not. Each of these events are exposed with a simple override:<\/p>\n<pre class=\"theme:vs2012 lang:csharp decode:true\">\n\/\/First time tile is added to quick settings\npublic override void OnTileAdded()\n{\n  base.OnTileAdded();\n}\n\n\/\/Called each time tile is visible\npublic override void OnStartListening()\n{\n  base.OnStartListening();\n}\n\n\/\/Called when tile is no longer visible\npublic override void OnStopListening()\n{\n  base.OnStopListening();\n}\n\n\/\/Called when tile is removed by the user\npublic override void OnTileRemoved()\n{\n  base.OnTileRemoved();\n}\n<\/pre>\n<h2>Updating Quick Setting Tiles<\/h2>\n<p>Once the user has added the tile, our service will receive an OnStartListening each time the user swipes down. This gives us an opportunity to update the tile with additional information. We can update the tile by getting reference to the QsTile and then modifying properties and applying an Update() such as the following:<\/p>\n<pre class=\"theme:vs2012 lang:csharp decode:true\">\npublic override void OnStartListening()\n{\n  base.OnStartListening();\n\n  \/\/Tile associated with the service\n  var tile = QsTile;\n\n  \/\/Update label, icon, description, and state\n  tile.Icon = Icon.CreateWithResource(this, Resource.Drawable.ic_tile_default);\n  tile.Label = GetString(Resource.String.tile_name);\n  \/\/Set state here and UI will respond automatically\n  tile.State = TileState.Active;\n  tile.UpdateTile();\n}\n<\/pre>\n<h2>Responding to Tile Clicks<\/h2>\n<p>Now it&#8217;s time to actually respond to clicks on our fancy new tile. This is done with another method that we can override, conveniently named &#8220;OnClick&#8221;. When the tile is clicked, we can do one of three things:<\/p>\n<ul>\n<li>Start a background service to process information<\/li>\n<li>Open Dialog if the user needs more context<\/li>\n<li>Start an activity<\/li>\n<\/ul>\n<p>In this example, we&#8217;ll open a new dialog that will show an adorable monkey. It&#8217;s important to remember that our tile can be visible even if the phone is locked, so we must prompt the user to unlock first before opening it.<\/p>\n<pre class=\"theme:vs2012 lang:csharp decode:true\">\npublic override void OnClick()\n{\n  base.OnClick();\n\n  if (IsLocked)\n  {\n    \/\/Open Dialog is unavailable here\n    \/\/Option 1: Kick of background service\n    \/\/Option 2: Prompt user to unlock\n    UnlockAndRun(new Runnable(() =&gt;\n    {\n      \/\/Show Dialog when unlocked\n      ShowDialog(MonkeyDialog);\n    }));\n  }\n  else\n  {\n    \/\/Show Dialog\n    ShowDialog(MonkeyDialog);\n  }\n  \/\/Additionally, update tile if needed here.\n}\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot_20161011-130453.png\" width=\"600\" class=\"aligncenter size-full wp-image-28053\" \/><\/p>\n<h2>Learn More<\/h2>\n<p>You can grab the full source code from my Monkeys App sample on <a href=\"https:\/\/github.com\/jamesmontemagno\/MonkeysApp-AppIndexing\">GitHub<\/a>, or download the app today on <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.refractored.monkeysapp\">Google Play<\/a>. Be sure to dive through the <a href=\"https:\/\/developer.android.com\/reference\/android\/service\/quicksettings\/Tile.html\">API documentation on the new Tile API<\/a>.\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Android&#8217;s Quick Setting Tiles enable users to quickly access important system settings and applications with a simple swipe and click. These tiles represent several system settings, including Wi-Fi, Bluetooth, location, and rotation, but there has never been a way for non-system applications to participate. That has all changed with the release of Android Nougat and [&hellip;]<\/p>\n","protected":false},"author":544,"featured_media":28052,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[5,4],"class_list":["post-28043","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-android","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>Android&#8217;s Quick Setting Tiles enable users to quickly access important system settings and applications with a simple swipe and click. These tiles represent several system settings, including Wi-Fi, Bluetooth, location, and rotation, but there has never been a way for non-system applications to participate. That has all changed with the release of Android Nougat and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/28043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/544"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=28043"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/28043\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=28043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=28043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=28043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}