Document - Tutorial Xamarin
Document - Tutorial Xamarin
Xamarin.Android
Getting Started
Setup and Installation
Windows Installation
Android SDK Setup
Android Emulator Setup
Hardware Acceleration
Device Manager
Device Properties
Troubleshooting
Android Device Setup
Microsoft OpenJDK Preview
Hello, Android
Part 1: Quickstart
Part 2: Deep Dive
Hello, Android Multiscreen
Part 1: Quickstart
Part 2: Deep Dive
Xamarin for Java Developers
Application Fundamentals
Accessibility
Android API Levels
Android Resources
Android Resource Basics
Default Resources
Alternate Resources
Creating Resources for Varying Screens
Application Localization and String Resources
Using Android Assets
Fonts
Activity Lifecycle
Walkthrough - Saving the Activity state
Android Services
Creating a Service
Bound Services
Intent Services
Started Services
Foreground Services
Out of Process Services
Service Notifications
Broadcast Receivers
Localization
Permissions
Graphics and Animation
CPU Architectures
Handling Rotation
Audio
Notifications
Local Notifications
Local Notifications Walkthrough
Touch
Touch in Android
Walkthrough – Using Touch in Android
Multi-Touch Tracking
HttpClient Stack and SSL/TLS
Writing Responsive Apps
User Interface
Android Designer
Using the Android Designer
Designer Basics
Resource Qualifiers and Visualization Options
Alternative Layout Views
Material Design Features
Material Theme
User Profile
Splash Screen
Layouts
LinearLayout
RelativeLayout
TableLayout
RecyclerView
Parts and Functionality
RecyclerView Example
Extending the Example
ListView
ListView Parts and Functionality
Populating a ListView With Data
Customizing a ListView's Appearance
Using CursorAdapters
Using a ContentProvider
ListView and the Activity Lifecycle
GridView
GridLayout
Tabbed Layouts
Navigation Tabs with the ActionBar
Controls
ActionBar
Auto Complete
Buttons
Radio Button
Toggle Button
CheckBox
Custom Button
Calendar
CardView
EditText
Gallery
Navigation Bar
Pickers
Date Picker
Time Picker
Popup Menu
Spinner
Switch
TextureView
Toolbar
Replacing the Action Bar
Adding a Second Toolbar
Toolbar Compatibility
ViewPager
ViewPager with Views
ViewPager with Fragments
WebView
Platform Features
Android Beam
Android Manifest
File Access with Xamarin.Android
External Storage
Fingerprint Authentication
Getting Started
Scanning for Fingerprints
Creating the CryptoObject
Responding to Authentication Callbacks
Guidance & Summary
Enrolling a Fingerprint
Android Job Scheduler
Firebase Job Dispatcher
Fragments
Implementing Fragments
Fragments Walkthrough - Part 1
Fragments Walkthrough - Part 2
Creating a Fragment
Managing Fragments
Specialized Fragment Classes
Providing Backwards Compatibility
App Linking
Android 8 Oreo
Android 7 Nougat
Android 6 Marshmallow
Android 5 Lollipop
Android 4.4 KitKat
Android 4.1 Jelly Bean
Android 4.0 Ice Cream Sandwich
Content Providers
How it Works
Using the Contacts ContentProvider
Creating a Custom ContentProvider
Maps and Location
Location
Maps
Maps Application
Maps API
Obtaining a Google Maps API Key
Using Android.Speech
Java Integration
Android Callable Wrappers
Working With JNI
Porting Java to C#
Binding a Java Library
Binding a .JAR
Binding an .AAR
Binding an Eclipse Library Project
Customizing Bindings
Java Bindings Metadata
Naming Parameters with Javadoc
Troubleshooting Bindings
Using Native Libraries
Renderscript
Xamarin.Essentials
Getting Started
Accelerometer
App Information
Battery
Clipboard
Compass
Connectivity
Data Transfer
Device Display Information
Device Information
Email
File System Helpers
Flashlight
Geocoding
Geolocation
Gyroscope
Magnetometer
Main Thread
Open Browser
Orientation Sensor
Phone Dialer
Power
Preferences
Screen Lock
Secure Storage
SMS
Text-to-Speech
Version Tracking
Vibrate
Troubleshooting
Data and Cloud Services
Azure Active Directory
Getting Started
Step 1. Register
Step 2. Configure
Accessing the Graph API
Azure Mobile Apps
Data Access
Introduction
Configuration
Using SQLite.NET ORM
Using ADO.NET
Using Data in an App
Google Messaging
Firebase Cloud Messaging
FCM Notifications Walkthrough
Google Cloud Messaging
GCM Notifications Walkthrough
Web Services
Walkthrough - Working with WCF
Deployment and Testing
App Package Size
Building Apps
Build Process
Building ABI-Specific APKs
Command Line Emulator
Debugging
Debug on the Emulator
Debug on a Device
Android Debug Log
Debuggable Attribute
Environment
GDB
Custom Linker Settings
Multi-core devices
Performance
Profiling
Preparing for Release
ProGuard
Signing the APK
Manually Signing the APK
Finding Your Keystore Signature
Publishing an App
Publishing to Google Play
Google Licensing Services
APK Expansion Files
Manually Uploading the APK
Publishing to Amazon
Publishing Independently
Install as System App
Advanced Concepts and Internals
Architecture
Available Assemblies
API Design
Garbage Collection
Limitations
Troubleshooting
Troubleshooting Tips
Frequently Asked Questions
Which Android SDK packages should I install?
Where can I set my Android SDK locations?
How do I update the Java Development Kit (JDK) version?
Can I use Java Development Kit (JDK) version 9?
How can I manually install the Android Support libraries required by the
Xamarin.Android.Support packages?
How do I install Google Play Services in an emulator?
What USB drivers do I need to debug Android on Windows?
Is it possible to connect to Android emulators running on a Mac from a Windows
VM?
How do I automate an Android NUnit Test project?
How do I enable Intellisense in Android .axml files?
Why can't my Android release build connect to the Internet?
Smarter Xamarin Android Support v4 / v13 NuGet Packages
How do I resolve a PathTooLongException?
What version of Xamarin.Android added Lollipop support?
Android.Support.v7.AppCompat - No resource found that matches the given
name: attr 'android:actionModeShareDrawable'
Adjusting Java memory parameters for the Android designer
My Android Resource.designer.cs file will not update
Resolving Library Installation Errors
Changes to the Android SDK Tooling
Xamarin.Android Errors Reference
Wear
Getting Started
Introduction to Android Wear
Setup & Installation
Hello, Wear
User Interface
Controls
GridViewPager
Platform Features
Creating a Watch Face
Screen Sizes
Deployment & Testing
Debug on an Emulator
Debug on a Wear Device
Packaging
Release Notes
Samples
Getting Started Series
5/2/2018 • 2 minutes to read • Edit Online
Hello, Android
In this two-part guide, you'll build your first Xamarin.Android application using Visual Studio, and you'll develop an
understanding of the fundamentals of Android application development with Xamarin. Along the way, this guide
introduces you to the tools, concepts, and steps required to build and deploy a Xamarin.Android application.
The topics in this section explain how to install and configure Xamarin.Android to work with Visual Studio on
Windows and macOS, how to use the Android SDK Manager to download and install Android SDK tools and
components that are required for building and testing your app, how to configure the Android emulator for
debugging, and how to connect a physical Android device to your development computer for debugging and final
testing your app.
Windows Installation
This guide walks you through the installation steps and configuration details required to install Xamarin.Android
on Windows. By the end of this article, you will have a working Xamarin.Android installation integrated into Visual
Studio, and you'll be ready to start building your first Xamarin.Android application.
Mac Installation
This article walks you through the installation steps and configuration details required to install Xamarin.Android
on a Mac. By the end of this article, you will have a working Xamarin.Android installation integrated into Visual
Studio for Mac, and you'll be ready to start building your first Xamarin.Android application.
This guide describes the steps for installing Xamarin.Android for Visual Studio on Windows, and it explains how to
configure Xamarin.Android for building your first Xamarin.Android application.
Overview
Because Xamarin is now included with all editions of Visual Studio at no extra cost and does not require a separate
license, you can use the Visual Studio installer to download and install Xamarin.Android tools. (The manual
installation and licensing steps that were required for earlier versions of Xamarin.Android are no longer necessary.)
In this guide, you will learn the following:
How to configure custom locations for the Java Development Kit, Android SDK, and Android NDK.
How to launch the Android SDK Manager to download and install additional Android SDK components.
How to prepare an Android device or emulator for debugging and testing.
How to create your first Xamarin.Android app project.
By the end of this guide, you will have a working Xamarin.Android installation integrated into Visual Studio, and
you will be ready to start building your first Xamarin.Android application.
Installation
For detailed information on installing Xamarin for use with Visual Studio on Windows, see the Windows Install
guide.
Configuration
Xamarin.Android uses the Java Development Kit (JDK) and the Android SDK to build apps. During installation, the
Visual Studio installer places these tools in their default locations and configures the development environment
with the appropriate path configuration. You can view and change these locations by clicking Tools > Options >
Xamarin > Android Settings:
For most users these default locations will work without further changes. However, you may wish to configure
Visual Studio with custom locations for these tools (for example, if you have installed the Java JDK, Android SDK,
or NDK in a different location). Click Change next to a path that you want to change, then navigate to the new
location.
Xamarin.Android uses JDK 8, which is required if you are developing for API level 24 or greater (JDK 8 also
supports API levels earlier than 24). You can continue to use JDK 7 if you are developing specifically for API level
23 or earlier.
IMPORTANT
Xamarin.Android does not support JDK 9.
You can use the Google Android SDK Manager to install versions of the Android SDK Tools package up to version
25.2.3. However, if you need to use a later version of the Android SDK Tools package, you must install the Xamarin
Android SDK Manager plugin for Visual Studio (available from the Visual Studio Marketplace). This is necessary
because Google's standalone SDK Manager was deprecated in version 25.2.3 of the Android SDK Tools package.
For more information about using the Xamarin Android SDK Manager, see Android SDK Setup.
Android Emulator
The Android Emulator can be helpful tool to develop and test a Xamarin.Android app. For example, a physical
device such as a tablet may not be readily available during development, or a developer may want to run some
integration tests on their computer before committing code.
Emulating an Android device on a computer involves the following components:
Google Android Emulator – This is an emulator based on QEMU that creates a virtualized device running on
the developer's workstation.
An Emulator Image – An emulator image is a template or a specification of the hardware and operating
system that is meant to be virtualized. For example, one emulator image would identify the hardware
requirements for a Nexus 5X running Android 7.0 with Google Play Services installed. Another emulator image
might specific a 10" table running Android 6.0.
Android Virtual Device (AVD ) – An Android Virtual Device is an emulated Android device created from an
emulator image. When running and testing Android apps, Xamarin.Android will start the Android Emulator,
starting a specific AVD, install the APK, and then run the app.
A significant improvement in performance when developing on x86 based computers can be achieved by using
special emulator images that are optimized for x86 architecture and one of two virtualization technologies:
1. Microsoft's Hyper-V – Available on computers running the Windows 10 April Update.
2. Intel's Hardware Accelerated Execution Manager (HAXM ) – Available on x86 computers running OS X, macOS,
or older version of Windows.
For more information about the Android Emulator, Hyper-V, and HAXM, please see Hardware Acceleration for
Emulator Performance guide.
NOTE
On older versions of Windows, HAXM is not compatible with Hyper-V. In this scenario it is necessary to either disable Hyper-
V or to use the slower emulator images that do not have the x86 optimizations.
Android Device
If you have a physical Android device to use for testing, this is a good time to set it up for development use. See
Set Up Device for Development to configure your Android device for development, then connect it to your
computer for running and debugging Xamarin.Android applications.
Create an Application
Now that you have installed Xamarin.Android, you can launch Visual Studio create a new project. Click File > New
> Project to begin creating your app:
In the New Project dialog, select Android under Templates and click Android App in the right pane. Enter a
name for your app (in the screenshot below, the app is called MyApp), then click OK:
That's it! Now you are ready to use Xamarin.Android to create Android applications!
Summary
In this article, you learned how to set up and install the Xamarin.Android platform on Windows, how to (optionally)
configure Visual Studio with custom Java JDK and Android SDK installation locations, how to launch the SDK
Manager to install additional Android SDK components, how to setup an Android device or emulator, and how to
start building your first application.
The next step is to have a look at the Hello, Android tutorials to learn how to create a working Xamarin.Android
app.
Related Links
Download Visual Studio
Installing Visual Studio Tools for Xamarin
System Requirements
Android SDK Setup
Android Emulator Setup
Set Up Device For Development
Run Apps on the Android Emulator
Setting up the Android SDK for Xamarin.Android
7/10/2018 • 8 minutes to read • Edit Online
Visual Studio includes an Android SDK Manager that you use to download Android SDK tools, platforms, and
other components that you need for developing Xamarin.Android apps.
Overview
This guide explains how to use the Xamarin Android SDK Manager in Visual Studio and Visual Studio for Mac.
NOTE
This guide applies only to Visual Studio 2017 and Visual Studio for Mac.
The Xamarin Android SDK Manager (installed as part of the Mobile development with .NET workload) helps
you download the latest Android components that you need for developing your Xamarin.Android app. It
replaces Google's standalone SDK Manager, which has been deprecated.
Visual Studio
Visual Studio for Mac
Requirements
To use the Xamarin Android SDK Manager, you will need the following:
Visual Studio 2017 (Community, Professional, or Enterprise edition). Visual Studio 2017 version 15.7 or
later is required.
Visual Studio Tools for Xamarin version 4.10.0 or later.
The Xamarin Android SDK Manager is not compatible with Visual Studio 2015. Users of Visual Studio 2015
should use the SDK Manager tools provided by Google in the Android SDK.
The Xamarin Android SDK Manager also requires the Java Development Kit (which is automatically installed
with Xamarin.Android). Xamarin.Android uses JDK 8, which is required if you are developing for API level 24 or
greater (JDK 8 also supports API levels earlier than 24). You can continue to use JDK 7 if you are developing
specifically for API level 23 or earlier.
IMPORTANT
Xamarin.Android does not support JDK 9.
SDK Manager
To start the SDK Manager in Visual Studio, click Tools > Android > Android SDK Manager:
The Xamarin Android SDK Manager opens in the Android SDKs and Tools screen. This screen has two tabs
– Platforms and Tools:
The Android SDKs and Tools screen is described in more detail in the following sections.
Android SDK Location
The Android SDK location is configured at the top of the Android SDKs and Tools screen, as seen in the
previous image. This location must be configured correctly before the Platforms and Tools tabs will function
properly. You may need to set the location of the Android SDK for one or more of the following reasons:
1. The Xamarin SDK Manager was unable to locate the Android SDK.
2. You have installed the Android SDK in a alternate (non-default) location.
To set the location of the Android SDK, click the … button to the far right of Android SDK Location. This opens
the Browse For Folder dialog to use for navigating to the location of the Android SDK. In the following
screenshot, the Android SDK under Program Files (x86)\Android is being selected:
When you click OK, the Xamarin Android SDK Manager will manage the Android SDK that is installed at the
selected location.
Tools Tab
The Tools tab displays a list of tools and extras. Use this tab to install the Android SDK tools, platform tools, and
build tools. Also, you can install the Android Emulator, the low -level debugger (LLDB ), the NDK, HAXM
acceleration, and Google Play libraries.
For example, to download the Google Android Emulator package, click the check mark next to Android
Emulator and click the Apply Changes button:
A dialog may be shown with the message, Some components can be updated. Do you want to update them
now? Click Yes. Next, a License acceptance dialog is shown:
Click Accept if you accept the Terms and Conditions. At the bottom of the window, a progress bar indicates
download and installation progress. After the installation completes, the Tools tab will show that the selected
tools and extras were installed.
Platforms Tab
The Platforms tab displays a list of platform SDK versions along with other resources (like system images) for
each platform.
This screen lists the Android version (such as Android 7.0), the code name (Nougat), the API level (such as 24),
and the status (Installed if the platform is installed). You use the Platforms tab to install components for the
Android API level that you want to target (for more information about Android versions and API levels, see
Understanding Android API Levels).
If all components of a platform are installed, a checkmark appears next to the platform name. If not all
components of a platform are installed, the box for that platform is filled.
You can expand a platform to see its components (and which components are installed) by clicking the + box to
the left of the platform. Click - to unexpand the component listing for a platform.
To add another platform to the SDK, click the box next to the platform until the checkmark appears to install all of
its components, then click Apply Changes:
To install only the SDK click the box next to the platform once. You can then select any individual components
that you need:
Notice that the number of components to install appears next to the Apply Changes button. In the above
example, six components are ready to install. After you click the Apply Changes button, you will see the License
Acceptance screen:
Click Accept if you accept the Terms and Conditions. You may see this dialog more than one time when there are
multiple components to install. At the bottom of the window, a progress bar will indicate download and
installation progress. When the download and installation process completes (this can take many minutes,
depending on how many components need to be downloaded), the added components are marked with a
checkmark and listed as Installed.
Summary
This guide explained how to install and use the Xamarin Android SDK Manager tool in Visual Studio and Visual
Studio for Mac.
Related Links
Changes to the Android SDK Tooling
Understanding Android API levels
sdkmanager
avdmanager
Android Emulator Setup
6/25/2018 • 2 minutes to read • Edit Online
This guide explain how to prepare the Android Emulator for testing your app.
Overview
The Android Emulator can be run in a variety of configurations to simulate different devices. Each configuration is
called a virtual device. When you deploy and test your app on the emulator, you select a pre-configured or custom
virtual device that simulates a physical Android device such as a Nexus or Pixel phone.
The sections listed below describe how to accelerate the Android emulator for maximum performance, how to use
the Android Device Manager to create and customize virtual devices, and how to customize the profile properties
of a virtual device. In addition, a troubleshooting section explains common emulator problems and workarounds.
Sections
Hardware Acceleration for Emulator Performance
How to prepare your computer for maximum Android Emulator performance. Because the Android Emulator can
be prohibitively slow without hardware acceleration, we recommend that you enable hardware acceleration on
your computer before you use the emulator.
Managing Virtual Devices with the Android Device Manager
How to use the Android Device Manager to create and customize virtual devices.
Editing Android Virtual Device Properties
How to use the Android Device Manager to edit the profile properties of a virtual device.
Android Emulator Troubleshooting
In this article, the most common warning messages and issues that occur while running the Android Emulator are
described, along with workarounds and tips.
After you have configured the Android Emulator, see Debugging on the Android Emulator for information about
how to launch the emulator and use it for testing and debugging your app.
NOTE
As of Android SDK Tools version 26.0.1 and later, Google has removed support for existing AVD/SDK managers in favor of
their new CLI (Command Line Interface) tools. Because of this deprecation change, Xamarin SDK/Device Managers are now
used instead of Google SDK/Device Managers for Android Tools 26.0.1 and later. For more information about the Xamarin
SDK Manager, see Setting up the Android SDK for Xamarin.Android.
Hardware Acceleration for Emulator Performance
6/27/2018 • 6 minutes to read • Edit Online
This article explains how to use your computer's hardware acceleration features to maximize Android Emulator
performance.
Overview
Visual Studio makes it easier for developers to test and debug their Xamarin.Android applications by using the
Android Emulator in situations where an Android device is unavailable or impractical. However, the Android
emulator runs too slowly if hardware acceleration is not available on the computer that runs it. You can drastically
improve the performance of the Android emulator by using special virtual device images that target x86 hardware
in conjunction with one of two virtualization technologies:
1. Microsoft's Hyper-V and the Hypervisor Platform. Hyper-V is a virtualization feature of Windows that
makes it possible to run virtualized computer systems on a physical host computer. This is the
recommended virtualization technology to use for accelerating the Android Emulator. To learn more about
Hyper-V, see Hyper-V on Windows 10.
2. Intel's Hardware Accelerated Execution Manager (HAXM ). HAXM is a virtualization engine for
computers running Intel CPUs. This is the recommended virtualization engine for computers that are
unable to run Hyper-V.
The Android Emulator will automatically make use of hardware acceleration if the following criteria are met:
Hardware acceleration is available and enabled on the development computer.
The emulator is running an emulator image specifically created for an x86-based virtual device.
For information about launching and debugging with the Android Emulator, see Debugging on the Android
Emulator.
Hyper-V
Visual Studio
Visual Studio for Mac
NOTE
Hyper-V support is currently in Preview.
Developers who are using Windows 10 (April 2018 Update or later) are strongly encouraged to use Microsoft's
Hyper-V to accelerate the Android Emulator. To use the Android Emulator with Hyper-V:
1. Update to Windows 10 April 2018 Update (build 1803) or later. To verify which version of Windows is
running, click in the Cortana search bar and type About. Select About your PC in the search results. Scroll
down in the About dialog to the Windows specifications section. The Version should be at least 1803:
2. Enable the Windows Hypervisor Platform. In the Cortana Search bar, type Turn Windows features
on or off. Scroll down in the Windows Features dialog and ensure that Windows Hypervisor Platform
is enabled:
Enabling Windows Hypervisor Platform automatically enables Hyper-V. It is a good idea to restart
Windows after making this change.
3. Install Visual Studio 15.8 Preview 1 or later. This version of Visual Studio provides IDE support for
running the Android Emulator with Hyper-V.
4. Install the Android Emulator package 27.2.7 or later. To install this package, navigate to Tools >
Android > Android SDK Manager in Visual Studio. Select the Tools tab and ensure that the Android
Emulator version is at least 27.2.7. Also ensure that the Android SDK Tools version is 26.1.1 or later:
5. If the emulator version is at least 27.2.7 but less than 27.3.1, the following workaround is required to use
Hyper-V:
a. In the C:\Users\username\.android folder, create a file called advancedFeatures.ini (if it doesn't
already exist).
b. Add the following line to advancedFeatures.ini:
WindowsHypervisorPlatform = on
Known Issues
If you are unable to update to emulator version 27.2.7 or later after updating to a Visual Studio preview,
you may have to directly install the preview installer to enable newer emulator versions.
Performance may be reduced when using certain Intel and AMD -based processors.
Android application may take an abnormal amount of time to load on deployment.
MMIO access error may intermittently prevent a boot of the Android emulator. Restarting the emulator
should resolve this.
HAXM
HAXM is a hardware-assisted virtualization engine (hypervisor) that uses Intel Virtualization Technology (VT) to
speed up Android app emulation on a host machine. Using HAXM in conjunction with Android x86 emulator
images provided by Intel allows for faster Android emulation on VT-enabled systems.
If you are developing on a machine with an Intel CPU that has VT capabilities, you can take advantage of HAXM
to greatly speed up the Android Emulator (if you're not sure whether your CPU supports VT, see Does My
Processor Supports Intel Virtualization Technology?).
NOTE
You can't run a VM-accelerated emulator inside another VM, such as a VM hosted by VirtualBox, VMWare, or Docker. You
must run the Android emulator directly on your system hardware.
Before using the Android Emulator for the first time, it's a good idea to verify that HAXM is installed and available
for the Android Emulator to use.
Verifying HAXM Installation
You can check to see if HAXM is available by viewing the Starting Android Emulator window while the
emulator starts. To start the Android Emulator, do the following:
Visual Studio
Visual Studio for Mac
1. Launch the Android Device Manager by clicking Tools > Android > Android Device Manager:
2. If you see a Performance Warning dialog similar to the following, then HAXM is not yet installed or
configured properly on your computer:
If a Performance Warning dialog like this is shown, see Performance Warnings to identify the cause and
resolve the underlying problem.
3. Select an x86 image (for example, VisualStudio_android-23_x86_phone) and click Start:
4. Watch for the Starting Android Emulator dialog window while the emulator starts up. If HAXM is
installed, you will see the message, HAX is working and emulator runs in fast virt mode as shown in
this screenshot:
If you do not see this message, then HAXM is probably not installed. For example, here is a screenshot of a
message you may see if HAXM is not available:
If HAXM is not available on your computer, use the steps in the next section to install HAXM.
Installing HAXM
If the emulator does not start, HAXM may have to be installed manually. HAXM install packages for both
Windows and macOS are available from the Intel Hardware Accelerated Execution Manager page. Use the
following steps to download and install HAXM manually:
Visual Studio
Visual Studio for Mac
1. From the Intel website, download the latest HAXM virtualization engine installer for Windows. The
advantage of downloading the HAXM installer directly from the Intel website is that you can be assured of
using the latest version.
Alternately, you can use the SDK Manager to download the HAXM installer (In the SDK Manager, click
Tools > Extras > Intel x86 Emulator Accelerator (HAXM installer)). The Android SDK normally
downloads the HAXM installer to the following location:
C:\Program Files (x86)\Android\android-
sdk\extras\intel\Hardware_Accelerated_Execution_Manager
Note that the SDK Manager does not install HAXM, it merely downloads the HAXM installer to the above
location; you still have to launch it manually.
2. Run intelhaxm -android.exe to start the HAXM installer. Accept the default values in the installer dialogs:
Hardware Acceleration and AMD CPUs
Because the Android emulator currently supports AMD hardware acceleration only on Linux, hardware
acceleration is not available for AMD -based computers running Windows.
Related Links
Run Apps on the Android Emulator
Managing Virtual Devices with the Android Device
Manager
6/25/2018 • 12 minutes to read • Edit Online
This article explains how to use the Android Device Manager to create and configure Android Virtual Devices
(AVDs) that emulate physical Android devices. You can use these virtual devices to run and test your app without
having to rely on a physical device.
Overview
After you have verified that hardware acceleration is enabled (as described in Hardware Acceleration for Emulator
Performance), the next step is to use the Android Device Manager (also referred to as the Xamarin Android
Device Manager) to create virtual devices that you can use to test and debug your app.
Visual Studio
Visual Studio for Mac
This article explains how to use the Android Device Manager to create, duplicate, customize, and launch Android
virtual devices.
You use the Android Device Manager to create and configure Android Virtual Devices (AVDs) that run in the
Android Emulator. Each AVD is an emulator configuration that simulates a physical Android device. This makes it
possible to run and test your app in a variety of configurations that simulate different physical Android devices.
Requirements
To use the Android Device Manager, you will need the following:
Visual Studio 2017 version 15.7 or later is required. Visual Studio Community, Professional, and Enterprise
editions are supported.
Visual Studio Tools for Xamarin version 4.9 or later.
The Android SDK must be installed (see Setting up the Android SDK for Xamarin.Android), and SDK tools
version 26.1.1 or later must be installed as explained in the next section. Be sure to install the Android SDK
at the following location (if it is not already installed): C:\Program Files (x86)\Android\android-sdk.
If you see the following error dialog on launch, see Android Emulator Troubleshooting for workaround
instructions:
Before you can use the Android Device Manager, you must install Android SDK tools version 26.1.1 or later. If
Android SDK tools 26.1.1 or later is not installed, you may see this error dialog on launch:
If you see this error dialog, click Open SDK Manager to open the Android SDK Manager. In the Android SDK
Manager, click the Tools tab and install the following:
Android SDK Tools 26.1.1 or later
Android SDK Platform -Tools 27.0.1 or later
Android SDK Build-Tools 27.0.3 or later
These packages should be shown with Installed status as seen in the following screenshot:
After these packages are installed, you can close the SDK Manager and re-launch the Android Device Manager.
Main Screen
When you first launch the Android Device Manager, it presents a screen that displays all currently-configured
virtual devices. For each device, the Name, Operating System (Android API Level), CPU, Memory size, and
screen resolution are displayed:
When you click a device in the list, the Start button appears on the right. You can click the Start button to launch
the emulator with this virtual device:
After the emulator starts with the selected virtual device, the Start button changes to a Stop button that you can
use to halt the emulator:
New Device
To create a new device, click the New button (located in the upper right-hand area of the screen):
2. Select a system image to use with this virtual device by clicking the System image pull-down menu. This
menu lists the installed system device manager images under Installed. The Download section lists
system device manager images that are currently unavailable on your development computer but can be
automatically installed:
3. Give the device a new name. In the following example, the new device is named Nexus 5 API 25:
4. Edit any properties that you need to modify. To make changes to properties, see Editing Android Virtual
Device Properties.
5. Add any additional properties that you need to explicitly set. The New Device screen lists only the most
commonly-modified properties, but you can click the Add Property pull-down menu (in the bottom left-
hand corner) to add additional properties. In the following example, the hw.lcd.backlight property is being
added:
6. Click the Create button (lower right-hand corner) to create the new device:
7. You might get a License Acceptance screen. Click Accept if you agree to the license terms:
8. The Android Device Manager adds the new device to the list of installed virtual devices while displaying a
Creating progress indicator during device creation:
9. When the creation process is complete, the new device is shown in the list of installed virtual devices with a
Start button, ready to launch:
Edit Device
To edit an existing virtual device, select the device and click the Edit button (located in the upper right-hand corner
of the screen):
Clicking Edit launches the Device Editor for the selected virtual device:
The Device Editor screen lists the properties of the virtual device in the first column, with the corresponding
values of each property in the second column. When you select a property, a detailed description of that property
is displayed on the right.
For example, in the following screenshot the hw.lcd.density property is being changed from 420 to 240:
After you have made the necessary configuration changes, click the Save button. For more information about
changing virtual device properties, see Editing Android Virtual Device Properties.
Additional Options
Additional options for working with devices are available from the … menu in the upper right-hand corner:
Factory Reset – Resets the selected device to its default settings, erasing any user changes made to the
internal state of the device while it was running (this also erases the current Quick Boot snapshot, if any).
This change does not alter modifications that you make to the virtual device during creation and editing. A
dialog box will appear with the reminder that this reset cannot be undone. Click Wipe user data to confirm
the reset.
Delete – Permanently deletes the selected virtual device. A dialog box will appear with the reminder that
deleting a device cannot be undone. Click Delete if you are certain that you want to delete the device.
Troubleshooting
The following sections explain how to diagnose and work around problems that may occur when using the
Android Device Manager to configure virtual devices.
Visual Studio
Visual Studio for Mac
Android SDK in Non-Standard Location
Typically, the Android SDK is installed at the following location:
C:\Program Files (x86)\Android\android-sdk
If the SDK is not installed at this location, you may get this error when you launch the Android Device Manager:
To work around this problem, do the following:
1. From the Windows desktop, navigate to
C:\Users\username\AppData\Roaming\XamarinDeviceManager:
2. Double-click to open one of the log files and locate the Config file path. For example:
After making this change to user.config, you should be able to launch the Android Device Manager.
Snapshot disables WiFi on Android Oreo
If you have an AVD configured for Android Oreo with simulated Wi-Fi access, restarting the AVD after a snapshot
may cause Wi-Fi access to become disabled.
To work around this problem,
1. Select the AVD in the Android Device Manager.
2. From the additional options menu, click Reveal in Explorer.
3. Navigate to snapshots > default_boot.
4. Delete the snapshot.pb file:
Summary
This guide introduced the Android Device Manager available in Visual Studio for Mac and Visual Studio Tools for
Xamarin. It explained essential features such as starting and stopping the Android emulator, selecting an Android
virtual device (AVD ) to run, creating new virtual devices, and how to edit a virtual device. It explained how to edit
profile hardware properties for further customization, and it provided troubleshooting tips for common problems.
Related Links
Changes to the Android SDK Tooling
Debugging on the Android Emulator
SDK Tools Release Notes (Google)
avdmanager
sdkmanager
Editing Android Virtual Device Properties
6/4/2018 • 15 minutes to read • Edit Online
This article explains how to use the Android Device Manager to edit the profile properties of an Android virtual
device.
Visual Studio
Visual Studio for Mac
The Android Device Manager supports the editing of individual Android virtual device profile properties. The
New Device and Device Edit screens list the properties of the virtual device in the first column, with the
corresponding values of each property in the second column (as seen in this example):
When you select a property, a detailed description of that property is displayed on the right. You can modify
hardware profile properties and AVD properties. Hardware profile properties (such as hw.ramSize and
hw.accelerometer ) describe the physical characteristics of the emulated device. These characteristics include
screen size, the amount of available RAM, whether or not an accelerometer is present. AVD properties specify the
operation of the AVD when it runs. For example, AVD properties can be configured to specify how the AVD uses
your development computer's graphics card for rendering.
You can change properties by using the following guidelines:
To change a boolean property, click the check mark to the right of the boolean property:
To change an enum (enumerated) property, click the down-arrow to the right of the property and choose a
new value.
To change a string or integer property, double-click the current string or integer setting in the value column
and enter a new value.
The following table provides a detailed explanation of the properties listed in the New Device and Device
Editor screens:
abi.type ABI type – Specifies the ABI x86, x86_64, armeabi-v7a, arm64-v8a
(application binary interface) type of
the emulated device. The x86 option is
for the instruction set commonly
referred to as "x86" or "IA-32." The
x86_64 option is for the 64-bit x86
instruction set. The armeabi-v7a
option is for the ARM instruction set
with v7-a ARM extensions. The arm64-
v8a option is for the ARM instruction
set that supports AArch64.
hw.gpu.mode GPU emulation mode – Determines auto, host, mesa, angle, swiftshader, off
how GPU emulation is implemented by
the emulator. If you select auto, the
emulator will choose hardware and
software acceleration based on your
development computer setup. If you
select host, the emulator will use your
development computer's graphics
processor to perform GPU emulation
for faster rendering. If your GPU is not
compatible with the emulator and you
are on Windows, you can try angle
instead of host. The angle mode uses
DirectX to provide performance similar
to host. If you select mesa, the
emulator will use the Mesa 3D software
library to render graphics. Select mesa
if you have problems rendering via
your development computer's graphics
processor. The swiftshader mode can be
used to render graphics in software
with slightly less performance than
using your computer's GPU. The off
option (disable graphics hardware
emulation) is a deprecated option that
can cause improper rendering for some
items and is therefore not
recommended.
PROPERTY DESCRIPTION OPTIONS
hw.lcd.density LCD density – The density of the 120, 160, 240, 213, 320
emulated LCD display, measured in
density-independent pixels, or dp (dp is
a virtual pixel unit). When the setting is
160 dp, each dp corresponds to one
physical pixel. At runtime, Android uses
this value to select and scale the
appropriate resources/assets for correct
display rendering.
PROPERTY DESCRIPTION OPTIONS
hw.screen Touch screen type – Defines the type touch, multi-touch, no-touch
of screen on the emulated device. A
multi-touch screen can track two or
more fingers on the touch interface. A
touch screen can detect only single-
finger touch events. A no-touch screen
does not detect touch events.
For more information about these properties, see Hardware Profile Properties.
Android Emulator Troubleshooting
7/17/2018 • 7 minutes to read • Edit Online
In this article, the most common warning messages and issues that occur while configuring and running the
Android Emulator are described, along with workarounds and tips.
Performance Warnings
Visual Studio
Visual Studio for Mac
Beginning with Visual Studio 2017 version 15.4, a performance warning dialog may be displayed when you first
deploy your app to the Android Emulator. These warning dialogs are explained below.
Computer Does Not Contain an Intel Procesor
When this dialog is displayed, your computer does not have an Intel processor, which is required for acceleration
of the Android SDK Emulator. If your computer does not have an Intel processor, we recommend using a physical
Android device for development.
Hyper-V Is Installed or Active
When this dialog is displayed, Hyper-V is installed or active and must be disabled. Disabling Hyper-V explains how
to resolve this issue.
HAXM is Not Installed
This dialog indicates that your computer has an Intel processor, Hyper-V is disabled, but HAXM is not installed.
Installing HAXM describes the steps for installing HAXM.
HAXM Process Not Running
This dialog is displayed if your computer has an Intel processor, Hyper-V is disabled, Intel HAXM is installed, but
the HAXM process is not running. To resolve this issue, open a Command Prompt window and enter the following
command:
sc query intelhaxm
If the HAXM process is running, you should see output similar to the following:
SERVICE_NAME: intelhaxm
TYPE : 1 KERNEL_DRIVER
STATE : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
If STATE is not set to RUNNING , see How to Use the Intel Hardware Accelerated Execution Manager to resolve the
problem.
Other Failures
This dialog is displayed if your computer has an Intel processor, Hyper-V is disabled, Intel HAXM is installed, the
HAXM process is running, but the emulator fails to start for some unknown reason. To help resolve this error, see
How to Use the Intel Hardware Accelerated Execution Manager.
Disabling Performance Warnings
If you would rather not see performance warnings, you can disable them. In Visual Studio, click Tools > Options
> Xamarin > Android Settings and disable the Warn if AVD acceleration is not supported (HAXM ) option:
Deployment Issues
If you get an error about a failure to install the APK on the emulator or a failure to run the Android Debug Bridge
(adb), verify that the Android SDK can connect to your emulator. To do this, use the following steps:
1. Launch the emulator from the Android Device Manager (select your virtual device and click Start).
2. Open a Command Prompt and go to the folder where adb is installed. For example, on Windows, this
might be at: C:\Program Files (x86)\Android\android-sdk\platform -tools\adb.exe.
3. Type the following command:
adb devices
4. If the emulator is accessible from the Android SDK, the emulator should appear in the list of attached
devices. For example:
5. If the emulator does not appear in this list, start the Android SDK Manager, apply all updates, then try
launching the emulator again.
HAXM Issues
Visual Studio
Visual Studio for Mac
If the Android Emulator does not start properly, this is often caused by problems with HAXM. HAXM issues are
often the result of conflicts with other virtualization technologies, incorrect settings, or an out of date HAXM driver.
HAXM Virtualization Conflicts
HAXM can conflict with other technologies that use virtualization, such as Hyper-V, Windows Device Guard, and
some antivirus software:
Hyper-V – If you are using a version of Windows before the Windows 10 April 2018 update (build
1803) and Hyper-V is enabled, follow the steps in Disabling Hyper-V.
Device Guard – Device Guard and Credential Guard can prevent Hyper-V from being disabled on
Windows machines. To disable Device Guard and Credential Guard, see Disabling Device Guard.
Antivirus Software – If you are running antivirus software that uses hardware-assisted virtualization (such
as Avast), disable or uninstall this software, reboot, and retry the Android SDK Emulator.
Incorrect BIOS Settings
If you are using HAXM on a Windows PC, HAXM will not work unless virtualization technology (Intel VT-x) is
enabled in the BIOS. If VT-x is disabled, you will get an error similiar to the following when you attempt to start
the Android Emulator:
This computer meets the requirements for HAXM, but Intel Virtualization Technology (VT-x) is not
turned on.
To correct this error, boot the computer into the BIOS, enable both VT-x and SL AT (Second Level Address
Translation), then restart the computer back into Windows.
Disabling Hyper-V
If you are using a version of Windows before the Windows 10 April 2018 Update (build 1803) and Hyper-V is
enabled, you must disable Hyper-V and reboot your computer to install and use HAXM. If you are using
Windows 10 April 2018 Update (build 1803) or later, Android Emulator version 27.2.7 or later can use Hyper-V
(instead of HAXM ) for hardware acceleration, so it is not necessary to disable Hyper-V.
You can disable Hyper-V from the Control Panel by following these steps:
1. In the Windows search box, enter Programs and then click the Programs and Features search result.
2. In the Control Panel Programs and Features dialog, click Turn Windows features on or off:
Intel HAXM and Microsoft Hyper-V cannot both be active at the same time. Unfortunately, there is no way to
switch between between Hyper-V and HAXM without restarting your computer.
In some cases, using the above steps will not succeed in disabling Hyper-V if Device Guard and Credential Guard
are enabled. If you are unable to disable Hyper-V (or it seems to be disabled but HAXM installation still fails), use
the steps in the next section to disable Device Guard and Credential Guard.
Disabling Device Guard
Device Guard and Credential Guard can prevent Hyper-V from being disabled on Windows machines. This is
often a problem for domain-joined machines that are configured and controlled by an owning organization. On
Windows 10, use the following steps to see if Device Guard is running:
1. In Windows Search, type System info to start the System Information app.
2. In the System Summary, look to see if Device Guard Virtualization based security is present and is in
the Running state:
4. Change Turn On Virtualization Based Security to Disabled (as shown above) and exit the Local Group
Policy Editor.
5. In the Windows Search Box, type cmd. When Command Prompt appears in the search results, right-click
Command Prompt and select Run as Administrator.
6. Copy and paste the following commands into the command prompt window (if drive Z: is in use, pick an
unused drive letter to use instead):
mountvol Z: /s
copy %WINDIR%\System32\SecConfig.efi Z:\EFI\Microsoft\Boot\SecConfig.efi /Y
bcdedit /create {0cb3b571-2f2e-4343-a879-d86a476d7215} /d "DebugTool" /application osloader
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} path "\EFI\Microsoft\Boot\SecConfig.efi"
bcdedit /set {bootmgr} bootsequence {0cb3b571-2f2e-4343-a879-d86a476d7215}
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} loadoptions DISABLE-LSA-ISO,DISABLE-VBS
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} device partition=Z:
mountvol Z: /d
7. Restart your computer. On the boot screen, you should see a prompt like the following:
Do you want to disable Credential Guard?
Press the indicated key to disable Credential Guard as prompted.
8. After the computer reboots, check again to ensure that Hyper-V is disabled (as described in the previous
steps).
If Hyper-V is still not disabled, the policies of your domain-joined computer may prevent you from disabling
Device Guard or Credential Guard. In this case, you can request an exemption from your domain adminstrator to
allow you to opt out of Credential Guard. Alternately, you can use a computer that is not domain-joined to use
HAXM.
Set Up Device for Development
6/25/2018 • 6 minutes to read • Edit Online
This article will discuss how to setup an Android device and connect it to a computer so that the device may be
used to run and debug Xamarin.Android applications.
By now, you've probably seen your great new application running on the Android emulator, and want to see it
running on your shiny Android device. Here are the steps involved with connecting a device to a computer for
debugging:
1. Enable Debugging on the Device - By default, it will not be possible to debug applications on a Android
device.
2. Install USB Drivers - This step is not necessary for OS X computers. Windows computers may require
the installation of USB drivers.
3. Connect the Device to the Computer - The final step involves connecting the device to the computer by
either USB or WiFi.
Each of these steps will be covered in more detail in the sections below.
Once the Developer Options tab is available under Settings > System, open it to reveal developer settings:
This is the place to enable developer options such as USB debugging and stay awake mode.
NOTE
These are the steps to set up a Google Nexus device and are provided as a reference. Steps for your specific device may
vary, but will follow a similar pattern. Search the internet for your device if you have trouble.
Run the android.bat application in the [Android SDK install path]\tools directory. By default, the
Xamarin.Android installer will put the Android SDK in following location on a Windows computer:
C:\Users\[username]\AppData\Local\Android\android-sdk
Check the Google USB Driver box, and click the Install button. The driver files are downloaded to the following
location:
C:\Users\[username]\AppData\Local\Android\android-sdk\extras\google\usb_driver
Installing the USB Driver
After the USB drivers are downloaded, it is necessary to install them. To install the drivers on Windows 7:
1. Connect your device to the computer with a USB cable.
2. Right-click on the Computer from your desktop or Windows Explorer, and select Manage .
3. Select Devices in the left pane.
4. Locate and expand Other Devices in the right pane.
5. Right-click the device name and select Update Driver Software . This will launch the Hardware Update
Wizard.
6. Select Browse my computer for driver software and click Next .
7. Click Browse and locate the USB driver folder (the Google USB driver is located in [Android SDK install
path]\extras\google\usb_driver).
8. Click Next to install the driver.
Installing Unverified Drivers in Windows 8
Extra steps may be required to install an unverified driver in Windows 8. The following steps describe how to
install the drivers for a Galaxy Nexus:
1. Access the Windows 8 Advanced Boot Options - This step involves rebooting the computer to access
the Advanced Boot Options. Start up a command line prompt and reboot the computer by using the
following command:
shutdown.exe /r /o
After this command is issued, your computer will not be able to listen to devices that are connected via
USB.
4. Disconnect the USB cable connecting your device to your computer.
5. Configure ADB so that it will connect to your Android device on the port that was specified in step 1
above:
Once this command finished the Android device is connected to the computer via WiFi.
When you're done debugging via WiFi, it is possible reset ADB back to USB mode with the following command:
adb usb
It is possible to ask ADB to list the devices that are connected to the computer. Regardless of how the devices are
connected, you can issue the following command at the command prompt to see what is connected:
adb devices
Summary
This article discussed how to configure an Android device for development by enabling debugging on the device.
It also covered how to connect the device to a computer using either USB or WiFi.
Related Links
Android Debug Bridge
Using Hardware Devices
Samsung Driver Downloads
OEM USB Drivers
Google USB Driver
XDA Developers : Windows 8 - ADB/fastboot driver problem solved
Microsoft's OpenJDK Distribution Preview
7/25/2018 • 2 minutes to read • Edit Online
This guide describes the steps for switching to the preview release of Microsoft's distribution of the OpenJDK.
Overview
Beginning with Visual Studio 15.9 and Visual Studio for Mac 7.7, Visual Studio Tools for Xamarin will move from
Oracle’s JDK to a lightweight version of the OpenJDK that is intended solely for Android development:
Download
To get started, download the correct build for your system:
Mac – https://dl.xamarin.com/OpenJDK/mac/microsoft-dist-openjdk-1.8.0.9.zip
Windows x86 – https://dl.xamarin.com/OpenJDK/win32/microsoft-dist-openjdk-1.8.0.9.zip
Windows x64 – https://dl.xamarin.com/OpenJDK/win64/microsoft-dist-openjdk-1.8.0.9.zip
Configure
Unzip to the correct location:
Mac – $HOME/Library/Developer/Xamarin/jdk/microsoft_dist_openjdk_1.8.0.9
Windows – C:\Program Files\Android\jdk\microsoft_dist_openjdk_1.8.0.9
IMPORTANT
This example uses build 1.8.0.9; however, the version you download may be newer.
Windows – Click Tools > Options > Xamarin > Android Settings and change the Java Development Kit
Location to the full path of the OpenJDK installation. In the following example, this path is set to C:\Program
Files\Android\jdk\microsoft_dist_openjdk_1.8.0.9:
Revert
To revert to the Oracle JDK, change the Java SDK location to the previously-used Oracle JDK path and rebuild the
solution. On Mac, you can revert to the Oracle JDK path by clicking Reset to Defaults.
If you have any problems with the Microsoft OpenJDK distribution, please report issues by using the feedback tool
in your IDE so that they can be tracked and corrected quickly.
Summary
In this article, you learned how to configure your IDE to use the preview release of Microsoft's OpenJDK
distribution, which is slated for stable release later in 2018.
Hello, Android
7/25/2018 • 2 minutes to read • Edit Online
In this two -part guide, you will build your first Xamarin.Android application using Visual Studio for Mac or Visual
Studio and develop an understanding of the fundamentals of Android application development with Xamarin.
Along the way, the tools, concepts, and steps required to build and deploy a Xamarin.Android application will be
introduced.
Part 1: Quickstart
In the first part of this guide you'll create an application that translates an alphanumeric phone number entered
by the user into a numeric phone number, and then calls that number.
Related Links
Android Getting Started
Debugging in Visual Studio
Visual Studio for Mac Recipes - Debugging
Hello, Android: Quickstart
7/20/2018 • 14 minutes to read • Edit Online
In this two -part guide, you will build your first Xamarin.Android application (using Visual Studio or Visual Studio
for Mac) and develop an understanding of the fundamentals of Android application development with Xamarin.
Along the way, you will be introduced to the tools, concepts, and steps required to build and deploy a
Xamarin.Android application.
Requirements
To follow along with this walkthrough, you will need the following:
Visual Studio
Visual Studio for Mac
Windows 7 or later.
Visual Studio 2015 Professional or later.
This walkthrough assumes that the latest version of Xamarin.Android is installed and running on your platform
of choice. For a guide to installing Xamarin.Android, refer to the Xamarin.Android Installation guides. Before you
get started, please download and unzip the Xamarin App Icons & Launch Screens set.
Configuring Emulators
If you are using the Android emulator, we recommend that you configure the emulator to use hardware
acceleration. Instructions for configuring hardware acceleration are available in Hardware Acceleration for
Emulator Performance.
Walkthrough
Visual Studio
Visual Studio for Mac
Start Visual Studio. Click File > New > Project to create a new project.
In the New Project dialog, click the Android App template. Name the new project Phoneword . Click OK:
In the New Android App dialog, click Blank App and click OK to create the new project:
Creating the Layout
After the new project is created, expand the Resources folder and then the layout folder in the Solution
Explorer. Double-click activity_main.axml to open it in the Android Designer. This is the layout file for the
app's screen:
From the Toolbox (the area on the left), enter text into the search field and drag a Text (Large) widget onto
the design surface (the area in the center):
With the Text (Large) control selected on the design surface, use the Properties pane to change the text
property of the Text (Large) widget to Enter a Phoneword: as shown here:
Drag a Plain Text widget from the Toolbox to the design surface and place it underneath the Text (Large)
widget:
With the Plain Text widget selected on the design surface, use the Properties pane to change the id property
of the Plain Text widget to @+id/PhoneNumberText and change the text property to 1-855-XAMARIN :
Drag a Button from the Toolbox to the design surface and place it underneath the Plain Text widget:
With the Button selected on the design surface, use the Properties pane to change the id property of the
Button to @+id/TranslateButton and change the text property to Translate :
Drag a TextView from the Toolbox to the design surface and place it under the Button widget. Set the id
property of the TextView to @+id/TranslatedPhoneWord and change the text to an empty string:
Save your work by pressing CTRL+S.
Writing Translation Code
The next step is to add some code to translate phone numbers from alphanumeric to numeric. Add a new file to
the project by right-clicking the Phoneword project in the Solution Explorer pane and choosing Add > New
Item... as shown below:
In the Add New Item dialog, select Visual C# > Code > Code File and name the new code file
PhoneTranslator.cs:
This creates a new empty C# class. Insert the following code into this file:
using System.Text;
using System;
namespace Core
{
public static class PhonewordTranslator
{
public static string ToNumber(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
return "";
else
raw = raw.ToUpperInvariant();
Save the changes to the PhoneTranslator.cs file by clicking File > Save (or by pressing CTRL+S ), then close
the file.
Wiring up the Interface
The next step is to add code to wire up the user interface by inserting backing code into the MainActivity class.
Begin by wiring up the Translate button. In the MainActivity class, find the OnCreate method. The next step is
to add the button code inside OnCreate , below the base.OnCreate(bundle) and
SetContentView (Resource.Layout.Main) calls. First, modify the template code so that the OnCreate method
resembles the following:
using System;
using Android.App;
using Android.Content;
using Android.Widget;
using Android.OS;
namespace Phoneword
{
[Activity (Label = "Phone Word", MainLauncher = true)]
public class MainActivity : Activity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
Get a reference to the controls that were created in the layout file via the Android Designer. Add the following
code inside the OnCreate method, after the call to SetContentView :
Add code that responds to user presses of the Translate button. Add the following code to the OnCreate method
(after the lines added in the previous step):
Save your work by selecting File > Save All (or by pressing CTRL -SHIFT-S ) and build the application by
selecting Build > Rebuild Solution (or by pressing CTRL -SHIFT-B ).
If there are errors, go through the previous steps and correct any mistakes until the application builds
successfully. If you get a build error such as, Resource does not exist in the current context, verify that the
namespace name in MainActivity.cs matches the project name ( Phoneword ) and then completely rebuild the
solution. If you still get build errors, verify that you have installed the latest Xamarin.Android updates.
Setting the Label and App Icon
You should now have a working application – it's time to add the finishing touches! In MainActivity.cs, edit the
Label for the MainActivity . The Label is what Android displays at the top of the screen to let users know
where they are in the application. At the top of the MainActivity class, change the Label to Phone Word as
shown here:
namespace Phoneword
{
[Activity (Label = "Phone Word", MainLauncher = true)]
public class MainActivity : Activity
{
...
}
}
Now it's time to set the application icon. By default, Visual Studio will provide a default icon for the project. Let's
delete these files from the solution, and replace them with a different icon. Expand the Resources folder in the
Solution Pad. Notice that there are five folders that are prefixed with mipmap-, and that each of these folders
contains a single Icon.png file:
It is necessary to delete each of these icon files from the project. Right click on each of Icon.png files, and select
Delete from the context menu:
Click on the Delete button in the dialog.
Next, download and unzip Xamarin App Icons set. This zip file holds the icons for the application. Each icon is
visually identical but at different resolutions it renders correctly on different devices with different screen
densities. The set of files must be copied into the Xamarin.Android project. In Visual Studio, in the Solution
Explorer, right-click the mipmap-hdpi folder and select Add > Existing Items:
From the selection dialog, navigate to the unzipped Xamarin AdApp Icons directory and open the mipmap-hdpi
folder. Select Icon.png and click Add.
Repeat these steps for each of the mipmap- folders until the contents of the mipmap- Xamarin App Icons
folders are copied to their counterpart mipmap- folders in the Phoneword project.
After all the icons are copied to the Xamarin.Android project, open the Project Options dialog by right clicking
on the project in the Solution Pad. Select Build > Android Application and select **@mipmap/icon** from
the Application icon combo box:
Congratulations on completing your first Xamarin.Android application! Now it's time to dissect the tools and
skills you have just learned. Next up is the Hello, Android Deep Dive.
Related Links
Xamarin Android App Icons (ZIP )
Phoneword (sample)
Hello, Android: Deep Dive
7/25/2018 • 17 minutes to read • Edit Online
In this two -part guide, you'll build your first Xamarin.Android application and develop an understanding of the
fundamentals of Android application development with Xamarin. Along the way, you will be introduced to the
tools, concepts, and steps required to build and deploy a Xamarin.Android application.
A Solution called Phoneword was created and the Android project Phoneword was placed inside of it.
Look at the items inside the Project to see each folder and its purpose:
Properties – Contains the AndroidManifest.xml file that describes all of the requirements for the
Xamarin.Android application, including name, version number, and permissions. The Properties folder also
houses AssemblyInfo.cs, a .NET assembly metadata file. It is a good practice to fill this file with some basic
information about your application.
References – Contains the assemblies required to build and run the application. If you expand the
References directory, you'll see references to .NET assemblies such as System, System.Core, and
System.Xml, as well as a reference to Xamarin's Mono.Android assembly.
Assets – Contains the files the application needs to run including fonts, local data files, and text files. Files
included here are accessible through the generated Assets class. For more information on Android Assets,
see the Xamarin Using Android Assets guide.
Resources – Contains application resources such as strings, images, and layouts. You can access these
resources in code through the generated Resource class. The Android Resources guide provides more
details about the Resources directory. The application template also includes a concise guide to Resources
in the AboutResources.txt file.
Resources
The Resources directory contains four folders named drawable, layout, mipmap and values, as well as a file
named Resource.designer.cs.
The items are summarized in the table below:
drawable – The drawable directories house drawable resources such as images and bitmaps.
mipmap – The mipmap directory holds drawable files for different launcher icon densities. In the default
template, the drawable directory houses the application icon file, Icon.png.
layout – The layout directory contains Android designer files (.axml) that define the user interface for each
screen or Activity. The template creates a default layout called Main.axml.
values – This directory houses XML files that store simple values such as strings, integers, and colors. The
template creates a file to store string values called Strings.xml.
Resource.designer.cs – Also known as the Resource class, this file is a partial class that holds the unique
IDs assigned to each resource. It is automatically created by the Xamarin.Android tools and is regenerated
as necessary. This file should not be manually edited, as Xamarin.Android will overwrite any manual
changes made to it.
Since there is no linear progression through an Android application (you can launch the application from several
points), Android has a unique way of keeping track of what classes and files make up an application. In the
Phoneword example, all the parts that make up the application are registered with a special XML file called the
Android Manifest. The role of the Android Manifest is to keep track of an application's contents, properties,
and permissions and to disclose them to the Android operating system. You can think of the Phoneword
application as a single Activity (screen) and a collection of resource and helper files tied together by the Android
Manifest file, as illustrated by the diagram below:
The next few sections explore the relationships between the various parts of the Phoneword application; this
should provide you with a better understanding of the diagram above. This exploration begins with the user
interface as it discusses the Android designer and layout files.
User Interface
Main.axml is the user interface layout file for the first screen in the application. The .axml indicates that this is an
Android designer file (AXML stands for Android XML). The name Main is arbitrary from Android's point of view –
the layout file could have been named something else. When you open Main.axml in the IDE, it brings up the
visual editor for Android layout files called the Android Designer:
Visual Studio
Visual Studio for Mac
In the Phoneword app, the TranslateButton's ID is set to @+id/TranslateButton :
Visual Studio
Visual Studio for Mac
When you set the id property of the TranslateButton, the Android Designer maps the TranslateButton control
to the Resource class and assigns it a resource ID of TranslateButton . This mapping of visual control to class
makes it possible to locate and use the TranslateButton and other controls in app code. This will be covered in
more detail when you break apart the code that powers the controls. All you need to know for now is that the code
representation of a control is linked to the visual representation of the control in the designer via the id property.
Source View
Everything defined on the design surface is translated into XML for Xamarin.Android to use. The Android
Designer provides a source view that contains the XML that was generated from the visual designer. You can view
this XML by switching to the Source panel in the lower left of the designer view, as illustrated by the screenshot
below:
Visual Studio
Visual Studio for Mac
This XML source code should contain the Text (Large), Plain Text, and the two Button elements. For a more in-
depth tour of the Android Designer, refer to the Xamarin Android Designer Overview guide.
The tools and concepts behind the visual part of the user interface have now been covered. Next, it's time to jump
into the code that powers the user interface as Activities and the Activity Lifecycle are explored.
The Activity Attribute registers the Activity with the Android Manifest; this lets Android know that this class is
part of the Phoneword application managed by this manifest. The Label property sets the text that will be
displayed at the top of the screen.
The MainLauncher property tells Android to display this Activity when the application starts up. This property
becomes important as you add more Activities (screens) to the application as explained in the Hello, Android
Multiscreen guide.
Now that the basics of MainActivity have been covered, it's time to dive deeper into the Activity code by
introducing the Activity Lifecycle.
Activity Lifecycle
In Android, Activities go through different stages of a lifecycle depending on their interactions with the user.
Activities can be created, started and paused, resumed and destroyed, and so on. The Activity class contains
methods that the system calls at certain points in the screen's lifecycle. The following diagram illustrates a typical
life of an Activity as well as some of the corresponding lifecycle methods:
By overriding Activity lifecycle methods, you can control how the Activity loads, how it reacts to the user, and
even what happens after it disappears from the device screen. For example, you can override the lifecycle methods
in the diagram above to perform some important tasks:
OnCreate – Creates views, initializes variables, and performs other prep work that must be done before the
user sees the Activity. This method is called only once when the Activity is loaded into memory.
OnResume – Performs any tasks that must happen every time the Activity returns to the device screen.
OnPause – Performs any tasks that must happen every time the Activity leaves the device screen.
When you add custom code to a lifecycle method in the Activity , you override that lifecycle method's base
implementation. You tap into the existing lifecycle method (which has some code already attached to it), and you
extend that method with your own code. You call the base implementation from inside your method to ensure that
the original code runs before your new code. An example of this is illustrated in the next section.
The Activity Lifecycle is an important and complex part of Android. If you'd like to learn more about Activities
after you finish the Getting Started series, read the Activity Lifecycle guide. In this guide, the next focus is the first
stage of the Activity Lifecycle, OnCreate .
OnCreate
Android calls the Activity 's OnCreate method when it creates the Activity (before the screen is presented to the
user). You can override the OnCreate lifecycle method to create views and prepare your Activity to meet the user:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
In the Phoneword app, the first thing to do in OnCreate is load the user interface created in the Android
Designer. To load the UI, call SetContentView and pass it the resource layout name for the layout file: Main.axml .
The layout is located at Resource.Layout.Main :
SetContentView (Resource.Layout.Main);
When MainActivity starts up, it creates a view that is based on the contents of the Main.axml file. Note that the
layout file name is matched to the Activity name – Main.axml is the layout for MainActivity. This isn't required
from Android's point of view, but as you begin to add more screens to the application, you'll find that this naming
convention makes it easier to match the code file to the layout file.
After the layout file is prepared, you can start looking up controls. To look up a control, call FindViewById and pass
in the resource ID of the control:
Now that you have references to the controls in the layout file, you can start programming them to respond to
user interaction.
Responding to User Interaction
In Android, the Click event listens for the user's touch. In this app, the Click event is handled with a lambda, but
a delegate or a named event handler could be used instead. The final TranslateButton code resembled the
following:
In this two -part guide, you expand the Phoneword application that you created in the Hello, Android guide to
handle a second screen. Along the way, this guide will introduce the basic Android Application Building Blocks and
dive deeper into Android architecture as you develop a better understanding of Android application structure and
functionality.
Part 1: Quickstart
In the first part of this guide, you'll add a second screen to the Phoneword application to keep track of the history
of numbers called from the app. The final app will display a second screen that lists the call history.
Related Links
Android Getting Started
Debugging in Visual Studio
Visual Studio for Mac Recipes - Debugging
Hello, Android Multiscreen: Quickstart
5/1/2018 • 6 minutes to read • Edit Online
This two -part guide expands the Phoneword application to handle a second screen. Along the way, basic Android
Application Building Blocks are introduced with a deeper dive into Android architecture.
The accompanying Deep Dive reviews what was built and discusses architecture, navigation, and other new
Android concepts encountered along the way.
Requirements
Because this guide picks up where Hello, Android leaves off, it requires completion of the Hello, Android
Quickstart. If you would like to jump directly into the walkthrough below, you can download the completed
version of Phoneword (from the Hello, Android Quickstart) and use it to start the walkthrough.
Walkthrough
In this walkthrough you'll add a Translation History screen to the Phoneword application.
Visual Studio
Visual Studio for Mac
Start by opening the Phoneword application in Visual Studio and editing the Main.axml file from the Solution
Explorer.
Updating the Layout
From the Toolbox, drag a Button onto the design surface and place it below the TranslatedPhoneWord
TextView. In the Properties pane, change the button Id to @+id/TranslationHistoryButton
Set the Text property of the button to @string/translationHistory . The Android Designer will interpret this
literally, but you're going to make a few changes so that the button's text shows up correctly:
Expand the values node under the Resources folder in the Solution Explorer and double-click the string
resources file, Strings.xml:
Add the translationHistory string name and value to the Strings.xml file and save it:
The Translation History button text should update to reflect the new string value:
With the Translation History button selected on the design surface, find the enabled setting in the Properties
pane and set its value to false to disable the button. This will cause the button to become darker on the design
surface:
Creating the Second Activity
Create a second Activity to power the second screen. In the Solution Explorer, right-click the Phoneword
project and choose Add > New Item...:
In the Add New Item dialog, choose Visual C# > Activity and name the Activity file
TranslationHistoryActivity.cs.
Replace the template code in TranslationHistoryActivity.cs with the following:
using System;
using System.Collections.Generic;
using Android.App;
using Android.OS;
using Android.Widget;
namespace Phoneword
{
[Activity(Label = "@string/translationHistory")]
public class TranslationHistoryActivity : ListActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Create your application here
var phoneNumbers = Intent.Extras.GetStringArrayList("phone_numbers") ?? new string[0];
this.ListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1,
phoneNumbers);
}
}
}
In this class, you're creating a ListActivity and populating it programmatically, so you don't need to create a new
layout file for this Activity. This is discussed in more detail in the Hello, Android Multiscreen Deep Dive.
Adding Translation History Code
This app collects phone numbers (that the user has translated on the first screen) and passes them to the second
screen. The phone numbers are stored as a list of strings. To support lists (and Intents, which are used later), add
the following using directives to the top of MainActivity.cs:
using System.Collections.Generic;
using Android.Content;
Next, create an empty list that can be filled with phone numbers. The MainActivity class will look like this:
In the MainActivity class, add the following code to register the Translation History button (place this line after
the translateButton declaration):
Add the following code to the end of the OnCreate method to wire up the Translation History button:
Update the Translate button to add the phone number to the list of phoneNumbers . The Click handler for the
TranslateHistoryButton should resemble the following code:
Save and build the application to make sure there are no errors.
Running the App
Deploy the application to an emulator or device. The following screenshots illustrate the running Phoneword
application:
Congratulations on completing your first multi-screen Xamarin.Android application! Now it's time to dissect the
tools and skills you just learned – next up is the Hello, Android Multiscreen Deep Dive.
Related Links
Xamarin App Icons & Launch Screens (ZIP )
Phoneword (sample)
PhonewordMultiscreen (sample)
Hello, Android Multiscreen: Deep Dive
4/12/2018 • 6 minutes to read • Edit Online
In this two -part guide, the basic Phoneword application (created in the Hello, Android guide) is expanded to
handle a second screen. Along the way, the basic Android Application Building Blocks are introduced. A deeper
dive into Android architecture is included to help you develop a better understanding of Android application
structure and functionality.
Android Navigation
Intents were used to navigate between screens. It's time to dive into this code to see how Intents work and
understand their role in Android navigation.
Launching a Second Activity with an Intent
In the Phoneword application, an Intent was used to launch a second screen (Activity). Start by creating an Intent,
passing in the current Context ( this , referring to the current Context) and the type of Application Block that
you're looking for ( TranslationHistoryActivity ):
The Context is an interface to global information about the application environment – it lets newly-created
objects know what's going on with the application. If you think of an Intent as a message, you are providing the
name of the message recipient ( TranslationHistoryActivity ) and the receiver's address ( Context ).
Android provides an option to attach simple data to an Intent (complex data is handled differently). In the
Phoneword example, PutStringArrayExtra is used to attach a list of phone numbers to the Intent and
StartActivity is called on the recipient of the Intent. The completed code looks like this:
For more information on string resources and other Android resources, refer to the Android Resources guide.
ListView and ArrayAdapter – A ListView is a UI component that provides a simple way to present a scrolling list
of rows. A ListView instance requires an Adapter to feed it with data contained in row views. The following line
of code was used to populate the user interface of TranslationHistoryActivity :
ListViews and Adapters are beyond the scope of this document, but they are covered in the very comprehensive
ListViews and Adapters guide. Populating a ListView With Data deals specifically with using built-in ListActivity
and ArrayAdapter classes to create and populate a ListView without defining a custom layout, as was done in the
Phoneword example.
Summary
Congratulations, you've completed your first multi-screen Android application! This guide introduced Android
Application Building Blocks and Intents and used them to build a multi-screened Android application. You now
have the solid foundation you need to start developing your own Xamarin.Android applications.
Next, you'll learn to build cross-platform applications with Xamarin in the Building Cross-Platform Applications
guides.
Xamarin for Java Developers
6/20/2018 • 24 minutes to read • Edit Online
If you are a Java developer, you are well on your way to leveraging your skills and existing code on the Xamarin
platform while reaping the code reuse benefits of C#. You will find that C# syntax is very similar to Java syntax,
and that both languages provide very similar features. In addition, you'll discover features unique to C# that will
make your development life easier.
Overview
This article provides an introduction to C# programming for Java developers, focusing primarily on the C#
language features that you will encounter while developing Xamarin.Android applications. Also, this article
explains how these features differ from their Java counterparts, and it introduces important C# features (relevant
to Xamarin.Android) that are not available in Java. Links to additional reference material are included, so you can
use this article as a "jumping off" point for further study of C# and .NET.
If you are familiar with Java, you will feel instantly at home with the syntax of C#. C# syntax is very similar to Java
syntax – C# is a "curly brace" language like Java, C, and C++. In many ways, C# syntax reads like a superset of Java
syntax, but with a few renamed and added keywords.
Many key characteristics of Java can be found in C#:
Class-based object-oriented programming
Strong typing
Support for interfaces
Generics
Garbage collection
Runtime compilation
Both Java and C# are compiled to an intermediate language that is run in a managed execution environment. Both
C# and Java are statically-typed, and both languages treat strings as immutable types. Both languages use a
single-rooted class hierarchy. Like Java, C# supports only single inheritance and does not allow for global
methods. In both languages, objects are created on the heap using the new keyword, and objects are garbage-
collected when they are no longer used. Both languages provide formal exception handling support with try /
catch semantics. Both provide thread management and synchronization support.
However, there are many differences between Java and C#. For example:
Java does not support implicitly-typed local variables (C# supports the var keyword).
In Java, you can pass parameters only by value, while in C# you can pass by reference as well as by value.
(C# provides the ref and out keywords for passing parameters by reference; there is no equivalent to
these in Java).
Java does not support preprocessor directives like #define .
Java does not support unsigned integer types, while C# provides unsigned integer types such as ulong ,
uint , ushort and byte .
Java does not support operator overloading; in C# you can overload operators and conversions.
In a Java switch statement, code can fall through into the next switch section, but in C# the end of every
switch section must terminate the switch (the end of each section must close with a break statement).
In Java, you specify the exceptions thrown by a method with the throws keyword, but C# has no concept of
checked exceptions – the throws keyword is not supported in C#.
C# supports Language-Integrated Query (LINQ ), which lets you use the reserved words from , select ,
and where to write queries against collections in a way that is similar to database queries.
Of course, there are many more differences between C# and Java than can be covered in this article. Also, both
Java and C# continue to evolve (for example, Java 8, which is not yet in the Android toolchain, supports C#-style
lambda expressions) so these differences will change over time. Only the most important differences currently
encountered by Java developers new to Xamarin.Android are outlined here.
Going from Java to C# Development provides an introduction to the fundamental differences between C#
and Java.
Object-Oriented Programming Features outlines the most important object-oriented feature differences
between the two languages.
Keyword Differences provides a table of useful keyword equivalents, C#-only keywords, and links to C#
keyword definitions.
C# brings many key features to Xamarin.Android that are not currently readily available to Java developers on
Android. These features can help you to write better code in less time:
Properties – With C#'s property system, you can access member variables safely and directly without
having to write setter and getter methods.
Lambda Expressionss – In C# you can use anonymous methods (also called lambdas) to express your
functionality more succinctly and more efficiently. You can avoid the overhead of having to write one-time-
use objects, and you can pass local state to a method without having to add parameters.
Event Handling – C# provides language-level support for event-driven programming, where an object can
register to be notified when an event of interest occurs. The event keyword defines a multicast broadcast
mechanism that a publisher class can use to notify event subscribers.
Asynchronous Programming – The asynchronous programming features of C# ( async / await ) keep apps
responsive. The language-level support of this feature makes async programming easy to implement and
less error-prone.
Finally, Xamarin allows you to leverage existing Java assets via a technology known as binding. You can call your
existing Java code, frameworks, and libraries from C# by making use of Xamarin's automatic binding generators.
To do this, you simply create a static library in Java and expose it to C# via a binding.
namespace WeatherApp
{
...
Importing Types
When you make use of types defined in external namespaces, you import these types with a using statement
(which is very similar to the Java import statement). In Java, you might import a single type with a statement like
the following:
import javax.swing.JButton
You might import an entire Java package with a statement like this:
import javax.swing.*
The C# using statement works in a very similar way, but it allows you to import an entire package without
specifying a wildcard. For example, you will often see a series of using statements at the beginning of
Xamarin.Android source files, as seen in this example:
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Net;
using System.IO;
using System.Json;
using System.Threading.Tasks;
These statements import functionality from the System , Android.App , Android.Content , etc. namespaces.
Generics
Both Java and C# support generics, which are placeholders that let you plug in different types at compile time.
However, generics work slightly differently in C#. In Java, type erasure makes type information available only at
compile time, but not at run time. By contrast, the .NET common language runtime (CLR ) provides explicit support
for generic types, which means that C# has access to type information at runtime. In day-to-day Xamarin.Android
development, the importantance of this distinction is not often apparent, but if you are using reflection, you will
depend on this feature to access type information at run time.
In Xamarin.Android, you will often see the generic method FindViewById used to get a reference to a layout
control. This method accepts a generic type parameter that specifies the type of control to look up. For example:
In this code example, FindViewById gets a reference to the TextView control that is defined in the layout as Label,
then returns it as a TextView type.
For more information about generics, see the MSDN Generics topic. Note that there are some limitations in
Xamarin.Android support for generic C# classes; for more information, see Limitations.
In this example, SensorsActivity inherits from Activity and implements the functionality declared in the
ISensorEventListener interface. Note that the list of interfaces must come after the base class (or you will get a
compile-time error). By convention, C# interface names are prepended with an upper-case "I"; this makes it
possible to determine which classes are interfaces without requiring an implements keyword.
When you want to prevent a class from being further subclassed in C#, you precede the class name with sealed –
in Java, you precede the class name with final .
For more about C# class definitions, see the MSDN Classes and Structs and Inheritance topics.
Properties
In Java, mutator methods (setters) and inspector methods (getters) are often used to control how changes are
made to class members while hiding and protecting these members from outside code. For example, the Android
TextView class provides getText and setText methods. C# provides a similar but more direct mechanism known
as properties. Users of a C# class can access a property in the same way as they would access a field, but each
access actually results in a method call that is transparent to the caller. This "under the covers" method can
implement side effects such as setting other values, performing conversions, or changing object state.
Properties are often used for accessing and modifying UI (user interface) object members. For example:
In this example, width and height values are read from the rulerView object by accessing its MeasuredWidth and
MeasuredHeight properties. When these properties are read, values from their associated (but hidden) field values
are fetched behind the scenes and returned to the caller. The rulerView object may store width and height values
in one unit of measurement (say, pixels) and convert these values on-the-fly to a different unit of measurement
(say, millimeters) when the MeasuredWidth and MeasuredHeight properties are accessed.
The rulerView object also has a property called DrawingCacheEnabled – the example code sets this property to
true to enable the drawing cache in rulerView . Behind the scenes, an associated hidden field is updated with the
new value, and possibly other aspects of rulerView state are modified. For example, when DrawingCacheEnabled is
set to false , rulerView may also erase any drawing cache information already accumulated in the object.
Access to properties can be read/write, read-only, or write-only. Also, you can use different access modifiers for
reading and writing. For example, you can define a property that has public read access but private write access.
For more information about C# properties, see the MSDN Properties topic.
Calling Base Class Methods
To call a base-class constructor in C#, you use a colon ( : ) followed by the base keyword and an initializer list;
this base constructor call is placed immediately after the derived constructor parameter list. The base-class
constructor is called on entry to the derived constructor; the compiler inserts the call to the base constructor at the
start of the method body. The following code fragment illustrates a base constructor called from a derived
constructor in a Xamarin.Android app:
public class PictureLayout : ViewGroup
{
...
public class PictureLayout (Context context)
: base (context)
{
...
}
...
}
In this example, the PictureLayout class is derived from the ViewGroup class. The PictureLayout constructor
shown in this example accepts a context argument and passes it to the ViewGroup constructor via the
base(context) call.
To call a base-class method in C#, use the base keyword. For example, Xamarin.Android apps often make calls to
base methods as shown here:
In this case, the OnCreate method defined by the derived class ( MainActivity ) calls the OnCreate method of the
base class ( Activity ).
Access Modifiers
Java and C# both support the public , private , and protected access modifiers. However, C# supports two
additional access modifiers:
internal – The class member is accessible only within the current assembly.
protected internal – The class member is accessible within the defining assembly, the defining class, and
derived classes (derived classes both inside and outside the assembly have access).
For more information about C# access modifiers, see the MSDN Access Modifiers topic.
Virtual and Override Methods
Both Java and C# support polymorphism, the ability to treat related objects in the same manner. In both
languages, you can use a base-class reference to refer to a derived-class object, and the methods of a derived class
can override the methods of its base classes. Both languages have the concept of a virtual method, a method in a
base class that is designed to be replaced by a method in a derived class. Like Java, C# supports abstract classes
and methods.
However, there are some differences between Java and C# in how you declare virtual methods and override them:
In C#, methods are non-virtual by default. Parent classes must explicitly label which methods are to be
overridden by using the virtual keyword. By contrast, all methods in Java are virtual methods by default.
To prevent a method from being overridden in C#, you simply leave off the virtual keyword. By contrast,
Java uses the final keyword to mark a method with "override is not allowed."
C# derived classes must use the override keyword to explicitly indicate that a virtual base-class method is
being overridden.
For more information about C#'s support for polymorphism, see the MSDN Polymorphism topic.
Lambda Expressions
C# makes it possible to create closures: inline, anonymous methods that can access the state of the method in
which they are enclosed. Using lambda expressions, you can write fewer lines of code to implement the same
functionality that you might have implemented in Java with many more lines of code.
Lambda expressions make it possible for you to skip the extra ceremony involved in creating a one-time-use class
or anonymous class as you would in Java – instead, you can just write the business logic of your method code
inline. Also, because lambdas have access to the variables in the surrounding method, you don't have to create a
long parameter list to pass state to your method code.
In C#, lambda expressions are created with the => operator as shown here:
In Xamarin.Android, lambda expressions are often used for defining event handlers. For example:
In this example, the lambda expression code (the code within the curly braces) increments a click count and
updates the button text to display the click count. This lambda expression is registered with the button object as
a click event handler to be called whenever the button is tapped. (Event handlers are explained in more detail
below.) In this simple example, the sender and args parameters are not used by the lambda expression code, but
they are required in the lambda expression to meet the method signature requirements for event registration.
Under the hood, the C# compiler translates the lambda expression into an anonymous method that is called
whenever button click events take place.
For more information about C# and lambda expressions, see the MSDN Lambda Expressions topic.
Event Handling
An event is a way for an object to notify registered subscribers when something interesting happens to that object.
Unlike in Java, where a subscriber typically implements a Listener interface that contains a callback method, C#
provides language-level support for event handling through delegates. A delegate is like an object-oriented type-
safe function pointer – it encapsulates an object reference and a method token. If a client object wants to subscribe
to an event, it creates a delegate and passes the delegate to the notifying object. When the event occurs, the
notifying object invokes the method represented by the delegate object, notifying the subscribing client object of
the event. In C#, event handlers are essentially nothing more than methods that are invoked through delegates.
For more information about delegates, see the MSDN Delegates topic.
In C#, events are multicast; that is, more than one listener can be notified when an event takes place. This
difference is observed when you consider the syntactical differences between Java and C# event registration. In
Java you call SetXXXListener to register for event notifications; in C# you use the += operator to register for
event notifications by "adding" your delegate to the list of event listeners. In Java, you call SetXXXListener to
unregister, while in C# you use the -= to "subtract" your delegate from the list of listeners.
In Xamarin.Android, events are often used for notifying objects when a user does something to a UI control.
Normally, a UI control will have members that are defined using the event keyword; you attach your delegates to
these members to subscribe to events from that UI control.
To subscribe to an event:
1. Create a delegate object that refers to the method that you want to be invoked when the event occurs.
2. Use the += operator to attach your delegate to the event you are subscribing to.
The following example defines a delegate (with an explicit use of the delegate keyword) to subscribe to button
clicks. This button-click handler starts a new activity:
startActivityButton.Click += delegate {
Intent intent = new Intent (this, typeof (MyActivity));
StartActivity (intent);
};
However, you also can use a lambda expression to register for events, skipping the delegate keyword altogether.
For example:
In this example, the startActivityButton object has an event that expects a delegate with a certain method
signature: one that accepts sender and event arguments and returns void. However, because we don't want to go to
the trouble to explicitly define such a delegate or its method, we declare the signature of the method with
(sender, e) and use a lambda expression to implement the body of the event handler. Note that we have to
declare this parameter list even though we aren't using the sender and e parameters.
It is important to remember that you can unsubscribe a delegate (via the -= operator), but you cannot
unsubscribe a lambda expression – attempting to do so can cause memory leaks. Use the lambda form of event
registration only when your handler will not unsubscribe from the event.
Typically, lambda expressions are used to declare event handlers in Xamarin.Android code. This shorthand way to
declare event handlers may seem cryptic at first, but it saves an enormous amount of time when you are writing
and reading code. With increasing familiarity, you become accustomed to recognizing this pattern (which occurs
frequently in Xamarin.Android code), and you spend more time thinking about the business logic of your
application and less time wading through syntactical overhead.
Asynchronous Programming
Asynchronous programming is a way to improve the overall responsiveness of your application. Asynchronous
programming features make it possible for the rest of your app code to continue running while some part of your
app is blocked by a lengthy operation. Accessing the web, processing images, and reading/writing files are
examples of operations that can cause an entire app to appear to freeze up if it is not written asynchronously.
C# includes language-level support for asynchronous programming via the async and await keywords. These
language features make it very easy to write code that performs long-running tasks without blocking the main
thread of your application. Briefly, you use the async keyword on a method to indicate that the code in the
method is to run asynchronously and not block the caller's thread. You use the await keyword when you call
methods that are marked with async . The compiler interprets the await as the point where your method
execution is to be moved to a background thread (a task is returned to the caller). When this task completes,
execution of the code resumes on the caller's thread at the await point in your code, returning the results of the
async call. By convention, methods that run asynchronously have Async suffixed to their names.
In Xamarin.Android applications, async and await are typically used to free up the UI thread so that it can
respond to user input (such as the tapping of a Cancel button) while a long-running operation takes place in a
background task.
In the following example, a button click event handler causes an asynchronous operation to download an image
from the web:
downloadButton.Click += downloadAsync;
...
async void downloadAsync(object sender, System.EventArgs e)
{
webClient = new WebClient ();
var url = new Uri ("http://photojournal.jpl.nasa.gov/jpeg/PIA15416.jpg");
byte[] bytes = null;
In this example, when the user clicks the downloadButton control, the downloadAsync event handler creates a
WebClient object and a Uri object to fetch an image from the specifed URL. Next, it calls the WebClient object's
DownloadDataTaskAsync method with this URL to retrieve the image.
Notice that the method declaration of downloadAsync is prefaced by the async keyword to indicate that it will run
asynchronously and return a task. Also note that the call to DownloadDataTaskAsync is preceded by the await
keyword. The app moves the execution of the event handler (starting at the point where await appears) to a
background thread until DownloadDataTaskAsync completes and returns. Meanwhile, the app's UI thread can still
respond to user input and fire event handlers for the other controls. When DownloadDataTaskAsync completes
(which may take several seconds), execution resumes where the bytes variable is set to the result of the call to
DownloadDataTaskAsync , and the remainder of the event handler code displays the downloaded image on the
caller's (UI) thread.
For an introduction to async / await in C#, see the MSDN Asynchronous Programming with Async and Await
topic. For more information about Xamarin support of asynchronous programming features, see Async Support
Overview.
Keyword Differences
Many language keywords used in Java are also used in C#. There are also a number of Java keywords that have an
equivalent but differently-named counterpart in C#, as listed in this table:
JAVA C# DESCRIPTION
Also, there are many keywords that are unique to C# and have no counterpart in Java. Xamarin.Android code
often makes use of the following C# keywords (this table is useful to refer to when you are reading through
Xamarin.Android sample code):
C# DESCRIPTION
Summary
This article provided an introduction to the Xamarin.Android C# programming environment from a Java
developer's perspective. It pointed out the similarities between C# and Java while explaining their practical
differences. It introduced assemblies and namespaces, explained how to import external types, and provided an
overview of the differences in access modifiers, generics, class derivation, calling base-class methods, method
overriding, and event handling. It introduced C# features that are not available in Java, such as properties, async /
await asynchronous programming, lambdas, C# delegates, and the C# event handling system. It included tables
of important C# keywords, explained how to interoperate with existing Java libraries, and provided links to related
documentation for further study.
Related Links
Java Integration Overview
C# Programming Guide
C# Reference
Moving to C# and the .NET Framework, for Java Developers
Xamarin.Android Application Fundamentals
5/2/2018 • 3 minutes to read • Edit Online
This section provides a guide on some of the more common things tasks or concepts that developers need to be
aware of when developing Android applications.
Accessibility
This page describes how to use the Android Accessibility APIs to build apps according to the accessibility checklist.
Resources in Android
This article introduces the concept of Android resources in Xamarin.Android and documents how to use them. It
covers how to use resources in your Android application to support application localization, and multiple devices
including varying screen sizes and densities.
Activity Lifecycle
Activities are a fundamental building block of Android Applications and they can exist in a number of different
states. The activity lifecycle begins with instantiation and ends with destruction, and includes many states in
between. When an activity changes state, the appropriate lifecycle event method is called, notifying the activity of
the impending state change and allowing it to execute code to adapt to that change. This article examines the
lifecycle of activities and explains the responsibility that an activity has during each of these state changes to be
part of a well-behaved, reliable application.
Localization
This article explains how to localize a Xamarin.Android into other languages by translating strings and providing
alternate images.
Services
This article covers Android services, which are Android components that allow work to be done in the background.
It explains the different scenarios that services are suited for and shows how to implement them both for
performing long-running background tasks as well as to provide an interface for remote procedure calls.
Broadcast Receivers
This guide covers how to create and use broadcast receivers, an Android component that responds to system-wide
broadcasts, in Xamarin.Android.
Permissions
You can use the tooling support built into Visual Studio for Mac or Visual Studio to create and add permissions to
the Android Manifest. This document describes how to add permissions in Visual Studio and Xamarin Studio.
CPU Architectures
Xamarin.Android supports several CPU architectures, including 32-bit and 64-bit devices. This article explains how
to target an app to one or more Android-supported CPU architectures.
Handling Rotation
This article describes how to handle device orientation changes in Xamarin.Android. It covers how to work with the
Android resource system to automatically load resources for a particular device orientation as well as how to
programmatically handle orientation changes. Then it describes techniques for maintaining state when a device is
rotated.
Android Audio
The Android OS provides extensive support for multimedia, encompassing both audio and video. This guide
focuses on audio in Android and covers playing and recording audio using the built-in audio player and recorder
classes, as well as the low -level audio API. It also covers working with Audio events broadcast by other
applications, so that developers can build well-behaved applications.
Notifications
This section explains how to implement local and remote notifications in Xamarin.Android. It describes the various
UI elements of an Android notification and discusses the API's involved with creating and displaying a notification.
For remote notifications, both Google Cloud Messaging and Firebase Cloud Messaging are explained. Step-by-
step walkthroughs and code samples are included.
Touch
This section explains the concepts and details of implementing touch gestures on Android. Touch APIs are
introduced and explained followed by an exploration of gesture recognizers.
This page describes how to use the Android Accessibility APIs to build apps according to the accessibility checklist.
Refer to the iOS accessibility and OS X accessibility pages for other platform APIs.
Describing UI Elements
Android provides a ContentDescription property that is used by screen reading APIs to provide an accessible
description of the control's purpose.
The content description can be set in either C# or in the AXML layout file.
C#
The description can be set in code to any string (or a string resource):
AXML layout
In XML layouts use the android:contentDescription attribute:
<ImageButton
android:id=@+id/saveButton"
android:src="@drawable/save_image"
android:contentDescription="Save data" />
someText.Hint = "Enter some text"; // displays (and is "read") when control is empty
AXML layout
In XML layout files use the android:hint attribute:
<EditText
android:id="@+id/someText"
android:hint="Enter some text" />
AXML layout
In layout XML use the android:labelFor property to reference another control's identifier:
<TextView
android:id="@+id/labelFirstName"
android:hint="Enter some text"
android:labelFor="@+id/editFirstName" />
<EditText
android:id="@+id/editFirstName"
android:hint="Enter some text" />
button.Click += delegate {
button.Text = string.Format ("{0} clicks!", count++);
button.AnnounceForAccessibility (button.Text);
};
label.Focusable = false;
AXML layout
In layout XML files set the android:focusable attribute:
<android:focusable="false" />
You can also control focus order with the nextFocusDown , nextFocusLeft , nextFocusRight , nextFocusUp attributes,
typically set in the layout AXML. Use these attributes to ensure the user can navigate easily through the controls
on the screen.
Accessibility and Localization
In the examples above the hint and content description are set directly to the display value. It is preferable to use
values in a Strings.xml file, such as this:
Using text from a strings file is shown below in C# and AXML layout files:
C#
Instead of using string literals in code, look up translated values from strings files with Resources.GetText :
AXML
In layout XML accessibility attributes like hint and contentDescription can be set to a string identifier:
<TextView
android:id="@+id/someText"
android:hint="@string/enter_info" />
<ImageButton
android:id=@+id/saveButton"
android:src="@drawable/save_image"
android:contentDescription="@string/save_info" />
The benefit of storing text in a separate file is multiple language translations of the file can be provided in your app.
See the Android localization guide to learn how add localized string files to an application project.
Testing Accessibility
Follow these steps to enable TalkBack and Explore by Touch to test accessibility on Android devices.
You may need to install TalkBack from Google Play if it does not appear in Settings > Accessibility.
Related Links
Cross-platform Accessibility
Android Accessibility APIs
Understanding Android API Levels
7/3/2018 • 18 minutes to read • Edit Online
Xamarin.Android has several Android API level settings that determine your app's compatibility with multiple
versions of Android. This guide explains what these settings mean, how to configure them, and what effect they
have on your app at run time.
Quick Start
Xamarin.Android exposes three Android API level project settings:
Target Framework – Specifies which framework to use in building your application. This API level is used
at compile time by Xamarin.Android.
Minimum Android Version – Specifies the oldest Android version that you want your app to support.
This API level is used at run time by Android.
Target Android Version – Specifies the version of Android that your app is intended to run on. This API
level is used at run time by Android.
Before you can configure an API level for your project, you must install the SDK platform components for that
API level. For more information about downloading and installing Android SDK components, see Android SDK
Setup.
NOTE
Beginning in August 2018, the Google Play Console will require that new apps target API level 26 (Android 8.0) or higher.
Existing apps will be required to target API level 26 or higher beginning in November 2018. For more information, see
Improving app security and performance on Google Play for years to come.
Visual Studio
Visual Studio for Mac
Normally, all three Xamarin.Android API levels are set to the same value. On the Application page, set
Compile using Android version (Target Framework) to the latest stable API version (or, at a minimum, to
the Android version that has all of the features you need). In the following screenshot, the Target Framework is
set to Android 7.1 (API Level 25 - Nougat):
On the Android Manifest page, set the Minimum Android version to Use Compile using SDK version and
set the Target Android version to the same value as the Target Framework version (in the following screenshot,
the Target Android Framework is set to Android 7.1 (Nougat)):
If you want to maintain backward compatibility with an earlier version of Android, set Minimum Android
version to target to the oldest version of Android that you want your app to support. (Note that API Level 14
is the minimum API level required for Google Play services and Firebase support.) The following example
configuration supports Android versions from API Level 14 thru API level 25:
If your app supports multiple Android versions, your code must include runtime checks to ensure that your app
works with the Minimum Android version setting (see Runtime Checks for Android Versions below for details).
If you are consuming or creating a library, see API Levels and Libraries below for best practices in configuring
API level settings for libraries.
API 26 (Android 8.0) – Oreo, released August 2017. Build version code Android.OS.BuildVersionCodes.O
API 25 (Android 7.1) – Nougat, released December 2016. Build version code
Android.OS.BuildVersionCodes.NMr1
API 24 (Android 7.0) – Nougat, released August 2016. Build version code
Android.OS.BuildVersionCodes.N
API 23 (Android 6.0) – Marshmallow, released August 2015. Build version code
Android.OS.BuildVersionCodes.M
API 22 (Android 5.1) – Lollipop, released March 2015. Build version code
Android.OS.BuildVersionCodes.LollipopMr1
API 21 (Android 5.0) – Lollipop, released November 2014. Build version code
Android.OS.BuildVersionCodes.Lollipop
API 20 (Android 4.4W ) – Kitkat Watch, released June 2014. Build version code
Android.OS.BuildVersionCodes.KitKatWatch
API 19 (Android 4.4) – Kitkat, released October 2013. Build version code
Android.OS.BuildVersionCodes.KitKat
API 18 (Android 4.3) – Jelly Bean, released July 2013. Build version code
Android.OS.BuildVersionCodes.JellyBeanMr2
API 17 (Android 4.2-4.2.2) – Jelly Bean, released November 2012. Build version code
Android.OS.BuildVersionCodes.JellyBeanMr1
API 16 (Android 4.1-4.1.1) – Jelly Bean, released June 2012. Build version code
Android.OS.BuildVersionCodes.JellyBean
API 15 (Android 4.0.3-4.0.4) – Ice Cream Sandwich, released December 2011. Build version code
Android.OS.BuildVersionCodes.IceCreamSandwichMr1
API 14 (Android 4.0-4.0.2) – Ice Cream Sandwich, released October 2011. Build version code
Android.OS.BuildVersionCodes.IceCreamSandwich
API 13 (Android 3.2) – Honeycomb, released June 2011. Build version code
Android.OS.BuildVersionCodes.HoneyCombMr2
API 12 (Android 3.1.x) – Honeycomb, released May 2011. Build version code
Android.OS.BuildVersionCodes.HoneyCombMr1
API 11 (Android 3.0.x) – Honeycomb, released February 2011. Build version code
Android.OS.BuildVersionCodes.HoneyComb
API 10 (Android 2.3.3-2.3.4) – Gingerbread, released February 2011. Build version code
Android.OS.BuildVersionCodes.GingerBreadMr1
API 9 (Android 2.3-2.3.2) – Gingerbread, released November 2010. Build version code
Android.OS.BuildVersionCodes.GingerBread
API 8 (Android 2.2.x) – Froyo, released June 2010. Build version code
Android.OS.BuildVersionCodes.Froyo
API 7 (Android 2.1.x) – Eclair, released January 2010. Build version code
Android.OS.BuildVersionCodes.EclairMr1
API 6 (Android 2.0.1) – Eclair, released December 2009. Build version code
Android.OS.BuildVersionCodes.Eclair01
API 5 (Android 2.0) – Eclair, released November 2009. Build version code
Android.OS.BuildVersionCodes.Eclair
API 4 (Android 1.6) – Donut, released September 2009. Build version code
Android.OS.BuildVersionCodes.Donut
API 3 (Android 1.5) – Cupcake, released May 2009. Build version code
Android.OS.BuildVersionCodes.Cupcake
API 2 (Android 1.1) – Base, released February 2009. Build version code
Android.OS.BuildVersionCodes.Base11
API 1 (Android 1.0) – Base, released October 2008. Build version code
Android.OS.BuildVersionCodes.Base
As this list indicates, new Android versions are released frequently – sometimes several releases per year. As a
result, the universe of Android devices that might run your app includes of a wide variety of older and newer
Android versions. How can you guarantee that your app will run consistently and reliably on so many different
versions of Android? Android's API levels can help you manage this problem.
Android API Levels
Each Android device runs at exactly one API level – this API level is guaranteed to be unique per Android
platform version. The API level precisely identifies the version of the API set that your app can call into; it
identifies the combination of manifest elements, permissions, etc. that you code against as a developer.
Android's system of API levels helps Android determine whether an application is compatible with an Android
system image prior to installing the application on a device.
When an application is built, it contains the following API level information:
The target API level of Android that the app is built to run on.
The minimum Android API level that an Android device must have to run your app.
These settings are used to ensure that the functionality needed to run the app correctly is available on the
Android device at installation time. If not, the app is blocked from running on that device. For example, if the API
level of an Android device is lower than the minimum API level that you specify for your app, the Android
device will prevent the user from installing your app.
Set the Target Framework by selecting an API level in the drop-down menu under Compile using Android
version as shown above.
Minimum Android Version
The Minimum Android version (also known as minSdkVersion ) is the oldest version of the Android OS (i.e., the
lowest API level) that can install and run your application. By default, an app can only be installed on devices
matching the Target Framework setting or higher; if the Minimum Android version setting is lower than the
Target Framework setting, your app can also run on earlier versions of Android. For example, if you set the
Target Framework to Android 7.1 (Nougat) and set the Minimum Android version to Android 4.0.3 (Ice
Cream Sandwich), your app can be installed on any platform from API level 15 to API level 25, inclusive.
Although your app may successfully build and install on this range of platforms, this does not guarantee that it
will successfully run on all of these platforms. For example, if your app is installed on Android 5.0 (Lollipop)
and your code calls an API that is available only in Android 7.1 (Nougat) and newer, your app will get a
runtime error and possibly crash. Therefore, your code must ensure – at runtime – that it calls only those APIs
that are supported by the Android device that it is running on. In other words, your code must include explicit
runtime checks to ensure that your app uses newer APIs only on devices that are recent enough to support
them. Runtime Checks for Android Versions, later in this guide, explains how to add these runtime checks to
your code.
Visual Studio
Visual Studio for Mac
To access the Minimum Android version setting in Visual Studio, open the project properties in Solution
Explorer and select the Android Manifest page. In the drop-down menu under Minimum Android version
you can select the Minimum Android version for your application:
If you select Use Compile using SDK version, the Minimum Android version will be the same as the Target
Framework setting.
Target Android Version
The Target Android Version (also known as targetSdkVersion ) is the API level of the Android device where the
app expects to run. Android uses this setting to determine whether to enable any compatibility behaviors – this
ensures that your app continues to work the way you expect. Android uses the Target Android version setting of
your app to figure out which behavior changes can be applied to your app without breaking it (this is how
Android provides forward compatibility).
The Target Framework and the Target Android version, while having very similar names, are not the same thing.
The Target Framework setting communicates target API level information to Xamarin.Android for use at
compile time, while the Target Android version communicates target API level information to Android for use at
run time (when the app is installed and running on a device).
Visual Studio
Visual Studio for Mac
To access this setting in Visual Studio, open the project properties in Solution Explorer and select the Android
Manifest page. In the drop-down menu under Target Android version you can select the Target Android
version for your application:
We recommend that you explicitly set the Target Android version to the latest version of Android that you use to
test your app. Ideally, it should be set to the latest Android SDK version – this allows you to use new APIs prior
to working through the behavior changes. For most developers, we do not recommend setting the Target
Android version to Use Compile using SDK version.
In general, the Target Android Version should be bounded by the Minimum Android Version and the Target
Framework. That is:
Minimum Android Version <= Target Android Version <= Target Framework
For more information about SDK levels, see the Android Developer uses-sdk documentation.
In this example, our app's Target Framework is set to Android 5.0 (API Level 21) and its Minimum Android
version is set to Android 4.1 (API Level 16). Because SetCategory is available in API level
Android.OS.BuildVersionCodes.Lollipop and later, this example code will call SetCategory only when it is actually
available – it will not attempt to call SetCategory when the API level is 16, 17, 18, 19, or 20. The functionality is
reduced on these earlier Android versions only to the extent that notifications are not sorted properly (because
they are not categorized by type), yet the notifications are still published to alert the user. Our app still works,
but its functionality is slightly diminished.
In general, the build version check helps your code decide at runtime between doing something the new way
versus the old way. For example:
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
{
// Do things the Lollipop way
}
else
{
// Do things the pre-Lollipop way
}
There's no fast and simple rule that explains how to reduce or modify your app's functionality when it runs on
older Android versions that are lacking one or more APIs. In some cases (such as in the SetCategory example
above), it's sufficient to simply omit the API call when it's not available. However, in other cases, you may need
to implement alternate functionality for when Android.OS.Build.VERSION.SdkInt is detected to be less than the
API level that your app needs to present its optimum experience.
The Minimum Android version and Target Android version settings are not available because the resulting
library is not a stand-alone app – the library could be run on any Android version, depending on the app that it
is packaged with. You can specify how the library is to be compiled, but you can't predict which platform API
level the library will be run on. With this in mind, the following best practices should be observed when
consuming or creating libraries:
When consuming an Android library – If you are consuming an Android library in your application,
be sure to set your app's Target Framework setting to an API level that is at least as high as the Target
Framework setting of the library.
When creating an Android library – If you are creating an Android library for use by other
applications, be sure to set its Target Framework setting to the minimum API level that it needs in order
to compile.
These best practices are recommended to help prevent the situation where a library attempts to call an API that
is not available at runtime (which can cause the app to crash). If you are a library developer, you should strive to
restrict your usage of API calls to a small and well-established subset of the total API surface area. Doing so
helps to ensure that your library can be used safely across a wider range of Android versions.
Summary
This guide explained how Android API levels are used to manage app compatibility across different versions of
Android. It provided detailed steps for configuring the Xamarin.Android Target Framework, Minimum Android
version, and Target Android version project settings. It provided instructions for using the Android SDK
Manager to install SDK packages, included examples of how to write code to deal with different API levels at
runtime, and explained how to manage API levels when creating or consuming Android libraries. It also
provided a comprehensive list that relates API levels to Android version numbers (such as Android 4.4),
Android version names (such as Kitkat), and Xamarin.Android build version codes.
Related Links
Android SDK Setup
SDK CLI Tooling Changes
Picking your compileSdkVersion, minSdkVersion, and targetSdkVersion
What is API Level?
Codenames, Tags, and Build Numbers
Android Resources
4/12/2018 • 2 minutes to read • Edit Online
This article introduces the concept of Android resources in Xamarin.Android and will document how to use them.
It covers how to use resources in your Android application to support application localization, and multiple
devices including varying screen sizes and densities.
Overview
An Android application is seldom just source code. There are often many other files that make up an application:
video, images, fonts, and audio files just to name a few. Collectively, these non-source code files are referred to as
resources and are compiled (along with the source code) during the build process and packaged as an APK for
distribution and installation onto devices:
This article will take a comprehensive look at using resources and cover the following topics:
Android Resource Basics – Using default resources programmatically and declaratively, adding resource
types such as images and fonts to an application.
Device Specific Configurations – Supporting the different screen resolutions and densities in an
application.
Localization – Using resources to support the different regions an application may be used.
Related Links
Using Android Assets
Application Fundamentals
Application Resources
Supporting Multiple Screens
Android Resource Basics
7/25/2018 • 4 minutes to read • Edit Online
Almost all Android applications will have some sort of resources in them; at a minimum they often have the user
interface layouts in the form of XML files. When a Xamarin.Android application is first created, default resources
are setup by the Xamarin.Android project template:
Visual Studio
Visual Studio for Mac
The five files that make up the default resources were created in the Resources folder:
Icon.png – The default icon for the application
Main.axml – The default user interface layout file for an application. Note that while Android uses the .xml
file extension, Xamarin.Android uses the .axml file extension.
Strings.xml – A string table to help with localization of the application
AboutResources.txt – This is not necessary and may safely be deleted. It just provides a high level
overview of the Resources folder and the files in it.
Resource.designer.cs – This file is automatically generated and maintained by Xamarin.Android and holds
the unique ID's assigned to each resource. This is very similar and identical in purpose to the R.java file that
an Android application written in Java would have. It is automatically created by the Xamarin.Android tools
and will be regenerated from time to time.
Each resource ID is contained inside a nested class that corresponds to the resource type. For example, when the
file Icon.png was added to the project, Xamarin.Android updated the Resource class, creating a nested class called
Drawable with a constant inside named Icon . This allows the file Icon.png to be referred to in code as
Resource.Drawable.Icon . The Resource class should not be manually edited, as any changes that are made to it will
be overwritten by Xamarin.Android.
When referencing resources programmatically (in code), they can be accessed via the Resources class hierarchy
which uses the following syntax:
@[<PackageName>.]Resource.<ResourceType>.<ResourceName>
PackageName – The package which is providing the resource and is only required when resources from
other packages are being used.
ResourceType – This is the nested resource type that is within the Resource class described above.
Resource Name – this is the filename of the resource (without the extension) or the value of the
android:name attribute for resources that are in an XML element.
@[<PackageName>:]<ResourceType>/<ResourceName>.
PackageName – the package which is providing the resource and is only required when resources from
other packages are being used.
ResourceType – This is the nested resource type that is within the Resource class.
Resource Name – this is the filename of the resource (without the file type extension) or the value of the
android:name attribute for resources that are in an XML element.
This example has an ImageView that requires a drawable resource named flag. The ImageView has its src
attribute set to **@drawable/flag**. When the activity starts, Android will look inside the directory
Resource/Drawable for a file named flag.png (the file extension could be another image format, like flag.jpg)
and load that file and display it in the ImageView . When this application is run, it would look something like the
following image:
Default Resources
4/12/2018 • 4 minutes to read • Edit Online
Default resources are items that are not specific to any particular device or form factor, and therefore are the
default choice by the Android OS if no more specific resources can be found. As such, they're the most common
type of resource to create. They're organized into sub-directories of the Resources directory according to their
resource type:
Visual Studio
Visual Studio for Mac
In the image above, the project has default values for drawable resources, layouts, and values (XML files that
contain simple values).
A complete list of resource types is provided below:
animator – XML files that describe property animations. Property animations were introduced in API level
11 (Android 3.0) and provides for the animation of properties on an object. Property animations are a more
flexible and powerful way to describe animations on any type of object.
anim – XML files that describe tween animations. Tween animations are a series of animation instructions
to perform transformations on the contents of a View object, or example, rotation an image or growing the
size of text. Tween animations are limited to only View objects.
color – XML files that describe a state list of colors. To understand color state lists, consider a UI widget such
as a Button. It may have different states such as pressed or disabled, and the button may change color with
each change in state. The list is expressed in a state list.
drawable – Drawable resources are a general concept for graphics that can be compiled into the application
and then accessed by API calls or referenced by other XML resources. Some examples of drawables are
bitmap files (.png, .gif, .jpg), special resizable bitmaps known as Nine-Patches, state lists, generic shapes
defined in XML, etc.
layout – XML files that describe a user interface layout, such as an activity or a row in a list.
menu – XML files that describe application menus such as Options Menus, Context Menus, and submenus.
For an example of menus, see the Popup Menu Demo or the Standard Controls sample.
raw – Arbitrary files that are saved in their raw, binary form. These files are compiled into an Android
application in a binary format.
values – XML files that contain simple values. An XML file in the values directory does not define a single
resource, but instead can define multiple resources. For example one XML file may hold a list of string
values, while another XML file may hold a list of color values.
xml – XML files that are similar in function to the .NET configuration files. These are arbitrary XML that can
be read at run time by the application
Alternate Resources
4/12/2018 • 8 minutes to read • Edit Online
Alternate resources are those resources that target a specific device or run-time configuration such as the current
language, particular screen size, or pixel density. If Android can match a resource that is more specific for a
particular device or configuration than the default resource, then that resource will be used instead. If it does not
find an alternate resource that matches the current configuration, then the default resources will be loaded. How
Android decides what resources will be used by an application will be covered in more detail below, in the section
Resource Location
Alternate resources are organized as a sub-directory inside the Resources folder according to the resource type,
just like default resources. The name of the alternate resource subdirectory is in the form: ResourceType-Qualifier
Qualifier is a name that identifies a specific device configuration. There may be more than one qualifier in a name,
each of them separated by a dash. For example, the screenshot below shows a simple project that has alternate
resources for various configurations such as locale, screen density, screen size, and orientation:
Visual Studio
Visual Studio for Mac
Screen Aspect – This is based on the aspect ratio, not the screen orientation. A long screen is wider. Added
in API level 4 (Android 1.6). Possible values are long and notlong.
Screen Orientation – Portrait or landscape screen orientation. This can change during the lifetime of an
application. Possible values are port and land .
Dock Mode – For devices in a car dock or a desk dock. Added in API level 8 (Android 2.2.x). Possible values
are car and desk .
Night Mode – Whether or not the application is running at night or in the day. This may change during the
lifetime of an application and is meant to give developers an opportunity to use darker versions of an
interface at night. Added in API level 8 (Android 2.2.x). Possible values are night and notnight .
Screen Pixel Density (dpi) – The number of pixels in a given area on the physical screen. Typically
expressed as dots per inch (dpi). Possible values are:
ldpi – Low density screens.
mdpi – Medium density screens
hdpi – High density screens
xhdpi – Extra high density screens
nodpi – Resources that are not to be scaled
tvdpi – Introduced in API level 13 (Android 3.2) for screens between mdpi and hdpi.
Touchscreen Type – Specifies the type of touchscreen a device may have. Possible values are notouch (no
touch screen), stylus (a resistive touchscreen suitable for a stylus), and finger (a touchscreen).
Keyboard Availability – Specifies what kind of keyboard is available. This may change during the lifetime
of an application – for example when a user opens a hardware keyboard. Possible values are:
keysexposed – The device has a keyboard available. If there is no software keyboard enabled, then
this is only used when the hardware keyboard is opened.
keyshidden – The device does have a hardware keyboard but it is hidden and no software keyboard
is enabled.
keyssoft – the device has a software keyboard enabled.
Primary Text Input Method – Use to specify what kinds of hardware keys are available for input. Possible
values are:
nokeys – There are no hardware keys for input.
qwerty – There is a qwerty keyboard available.
12key – There is a 12-key hardware keyboard
Navigation Key Availability – For when 5-way or d-pad (directional-pad) navigation is available. This can
change during the lifetime of your application. Possible values are:
navexposed – the navigational keys are available to the user
navhidden – the navigational keys are not available.
Primary Non-Touch Navigation Method – The kind of navigation available on the device. Possible
values are:
nonav – the only navigation facility available is the touch screen
dpad – a d-pad (directional-pad) is available for navigation
trackball – the device has a trackball for navigation
wheel – the uncommon scenario where there are one or more directional wheels available
Platform Version (API level) – The API level supported by the device in the format vN, where N is the
API level that is being targeted. For example, v11 will target an API level 11 (Android 3.0) device.
For more complete information about resource qualifiers see Providing Resources on the Android Developers
website.
When the system is looking for density-specific resources and cannot find them, it will attempt to locate other
density specific resources and scale them. Android may not necessarily use the default resources. For example,
when looking for a low -density resource and it is not available, Android may select high-density version of the
resource over the default or medium-density resources. It does this because the high-density resource can be
scaled down by a factor of 0.5, which will result in fewer visibility issues than scaling down a medium-density
resource which would require a factor of 0.75.
As an example, consider an application that has the following drawable resource directories:
drawable
drawable-en
drawable-fr-rCA
drawable-en-port
drawable-en-notouch-12key
drawable-en-port-ldpi
drawable-port-ldpi
drawable-port-notouch-12key
And now the application is run on a device with the following configuration:
Locale – en-GB
Orientation – port
Screen density – hdpi
Touchscreen type – notouch
Primary input method – 12key
To begin with, the French resources are eliminated as they conflict with the locale of en-GB , leaving us with:
drawable
drawable-en
drawable-en-port
drawable-en-notouch-12key
drawable-en-port-ldpi
drawable-port-ldpi
drawable-port-notouch-12key
Next, the first qualifier is selected from the qualifiers table above: MCC and MNC. There are no resource
directories that contain this qualifier so the MCC/MNC code is ignored.
The next qualifier is selected, which is Language. There are resources that match the language code. All resource
directories that do not match the language code of en are rejected, so that the list of resources is now:
drawable-en-port
drawable-en-notouch-12key
drawable-en-port-ldpi
The next qualifier that is present is for screen orientation, so all resource directories that do not match the screen
orientation of port are eliminated:
drawable-en-port
drawable-en-port-ldpi
Next is the qualifier for screen density, ldpi , which results in the exclusion of one more resource directory:
drawable-en-port-ldpi
As a result of this process, Android will use the drawable resources in the resource directory
drawable-en-port-ldpi for the device.
NOTE
The screen size qualifiers provide one exception to this selection process. It is possible for Android to select resources that are
designed for a smaller screen than what the current device provides. For example, a large screen device may use the
resources provide for a normal sized screen. However the reverse of this is not true: the same large screen device will not use
the resources provided for an xlarge screen. If Android cannot find a resource set that matches a given screen size, the
application will crash.
Creating Resources for Varying Screens
4/12/2018 • 7 minutes to read • Edit Online
Android itself runs on many different devices, each having a wide variety of resolutions, screen sizes, and screen
densities. Android will perform scaling and resizing to make your application work on these devices, but this may
result in a sub-optimal user experience. For example, images may appear blurry, images may occupy too much (or
not enough) screen space which causes the position of UI elements in the layout will overlap or be too far apart.
Concepts
A few terms and concepts are important to understand to support multiple screens.
Screen Size – The amount of physical space for displaying your application
Screen Density – The number of pixels in any given area on the screen. The typical unit of measure is dots
per inch (dpi).
Resolution – The total number of pixels on the screen. When developing applications, resolution is not as
important as screen size and density.
Density-independent pixel (dp) – This is a virtual unit of measure to allow layouts to be designed
independent of density. To convert dp into screen pixels the following formula is used:
px = dp × dpi ÷ 160
Orientation – The screen's orientation is considered to be landscape when it is wider than it is tall. In
contrast, portrait orientation is when the screen is taller than it is wide. The orientation can change during
the lifetime of an application as the user rotates the device.
Notice that the first three of these concepts are inter-related – increasing the resolution without increasing the
density will increase the screen size. However if both the density and resolution are increased then the screen size
can remain unchanged. This relationship between screen size, density and resolution complicate screen support
very quickly.
To help deal with this complexity, the Android framework prefers to use density-independent pixels (dp ) for screen
layouts. By using density independent pixels, UI elements will appear to the user to have the same physical size on
screens with different densities.
AndroidManifest.xml is added to the Properties directory. The file is then edited to include supports-screens:
The following is a comparison of how the older pre-API Level 13 screen size qualifiers compare to density-
independent pixels:
426dp x 320dp is small
470dp x 320dp is normal
640dp x 480dp is large
960dp x 720dp is xlarge
The newer screen size qualifiers in API level 13 and up have a higher precedence than the older screen qualifiers
of API levels 12 and lower. For applications that will span the old and the new API levels, it may be necessary to
create alternate resources using both sets of qualifiers as shown in the following screen shot:
Visual Studio
Visual Studio for Mac
This website will help with creation of bitmaps that target the four common screen densities by providing one
image. Android Asset Studio will then create the bitmaps with some customizations and then allow them to be
downloaded as a zip file.
Application localization is the act of providing alternate resources to target a specific region or locale. For example,
you might provide localized language strings for various countries, or you might change colors or layout to match
particular cultures. Android will load and use the resources appropriate for the device's locale at runtime time
without any changes to the source code.
For example, the image below shows the same application running in three different device locales, but the text
displayed in each button is specific to the locale that each device is set to:
In this example, the contents of a layout file, Main.axml looks something like this:
In the example above, the string for the button was loaded from the resources by providing the resource ID for the
string:
Visual Studio
Visual Studio for Mac
Localizing Android Apps
Read the Introduction to Localization for tips and guidance on localizing mobile apps.
The Localizing Android Apps guide contains more specific examples on how to translate strings and localize
images using Xamarin.Android.
Related Links
Localizing Android Apps
Cross-Platform Localization Overview
Using Android Assets
4/12/2018 • 2 minutes to read • Edit Online
Assets provide a way to include arbitrary files like text, xml, fonts, music, and video in your application. If you try to
include these files as "resources", Android will process them into its resource system and you will not be able to
get the raw data. If you want to access data untouched, Assets are one way to do it.
Assets added to your project will show up just like a file system that can read from by your application using
AssetManager. In this simple demo, we are going to add a text file asset to our project, read it using AssetManager ,
and display it in a TextView.
Selecting the correct BuildAction ensures that the file will be packaged into the APK at compile time.
Reading Assets
Assets are read using an AssetManager. An instance of the AssetManager is available by accessing the Assets
property on an Android.Content.Context , such as an Activity. In the following code, we open our read_asset.txt
asset, read the contents, and display it using a TextView.
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
Related Links
AssetManager
Context
Fonts
4/13/2018 • 11 minutes to read • Edit Online
Overview
Beginning with API level 26, the Android SDK allows fonts to be treated as resources, just like a layouts or
drawables. The Android Support Library 26 NuGet will backport the new font API's to those apps that target API
level 14 or higher.
After targetting API 26 or installing the Android Support Library v26, there are two ways to use fonts in an
Android application:
1. Package the font as an Android resource – this ensures that the font is always available to the application,
but will increase the size of the APK.
2. Download the fonts – Android also supports downloading a font from a font provider. The font provider
checks if the font is already on the device. If necessary, the font will be downloaded and cached on the device.
This font can be shared between multiple applications.
Similar fonts (or a font that may have several different styles) may be grouped into font families. This allows
developers to specify certain attributes of the font, such as it's weight, and Android will automatically select the
appropriate font from the font family.
The Android Support Library v26 will backport support for fonts to API level 26. When targeting the older API
levels, it is necessary to declare the app XML namespace and to name the various font attributes using the
android: namespace and the app: namespace. If only the android: namespace is used, then the fonts will not be
displayed devices running API level 25 or less. For example, this XML snippet declares a new font family resource
that will work in API level 14 and higher:
<font android:font="@font/sourcesanspro_regular"
android:fontStyle="normal"
android:fontWeight="400"
app:font="@font/sourcesanspro_regular"
app:fontStyle="normal"
app:fontWeight="400" />
</font-family>
As long as fonts are provided to an Android application in a proper way, they can be applied to a UI widget by
setting the fontFamily attribute. For example, the following snippet demonstrates how to display a font in a
TextView:
<TextView
android:text="The quick brown fox jumped over the lazy dog."
android:fontFamily="@font/sourcesanspro_regular"
app:fontFamily="@font/sourcesanspro_regular"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
This guide will first discuss how to use fonts as an Android resource, and then move on to discuss how to
download fonts at runtime.
Fonts as a Resource
Packaging a font into an Android APK ensures that it is always available to the application. A font file (either a .TTF
or a .OTF file) is added to a Xamarin.Android application just like any other resource, by copying files to a
subdirectory in the Resources folder of a Xamarin.Android project. Fonts resources are kept in a font sub-
directory of the Resources folder of the project.
NOTE
The fonts should have a Build Action of AndroidResource or they will not be packaged into the final APK. The build action
should be automatically set by the IDE.
When there are many similar font files (for example, the same font with different weights or styles) it is possible to
group them into a font family.
Font Families
A font family is a set of fonts that have different weights and styles. For example, there might be separate font files
for bold or italic fonts. The font family is defined by font elements in an XML file that is kept in the
Resources/font directory. Each font family should have it's own XML file.
To create a a font family, first add all the fonts to the Resources/font folder. Then create a new XML file in the font
folder for the font family. The name of the XML file has no affinity or relationship to the fonts being referenced; the
resource file can be any legal Android resource file name. This XML file will have a root font-family element that
contains one or more font elements. Each font element declares the attributes of a font.
The following XML is an example of a font family for the Sources Sans Pro font that defines many different font
weights. This is saved as file in the Resources/font folder named sourcesanspro.xml:
<TextView
android:text="Sans Source Pro semi-bold italic, 600 weight, italic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/sourcesanspro"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center_horizontal"
android:fontWeight="600"
android:textStyle="italic"
/>
The GetFont method will automatically load the the first font within a font family. To load a font that matches a
specific style, use the Typeface.Create method. This method will try to load a font that matches the specified style.
As an example, this snippet will try to load a bold Typeface object from a font family that is defined in
Resources/fonts:
Downloading Fonts
Instead of packaging fonts as an application resource, Android can download fonts from a remote source. This will
have the desirable effect of reducing the size of the APK.
Fonts are downloaded with the assistance of a font provider. This is a specialized content provider that manages
the downloading and caching of fonts to all applications on the device. Android 8.0 includes a font provider to
download fonts from the Google Font Repository. This default font provider is backported to API level 14 with the
Android Support Library v26.
When an app makes a request for a font, the font provider will first check to see if the font is already on the device.
If not, it will then attempt to download the font. If the font cannot be downloaded, then Android will use the default
system font. Once the font has been downloaded, it is available to all applications on the device, not just the app
that made the initial request.
When a request is made to download a font, the app does not directly query the font provider. Instead, apps will
use an instance of the FontsContract API (or the FontsContractCompat if the Support Library 26 is being used).
Android 8.0 supports downloading fonts in two different ways:
1. Declare Downloadable Fonts as a Resource – An app may declare downloadable fonts to Android via XML
resource files. These files will contain all of the meta-data that Android needs to asynchronously download the
fonts when the app starts and cache them on the device.
2. Programmatically – APIs in Android API level 26 allow an application to download the fonts
programmatically, while the application is running. Apps will create a FontRequest object for a given font, and
pass this object to the FontsContract class. The FontsContract takes the FontRequest and retrieves the font
from a font provider. Android will synchronously download the font. An example of creating a FontRequest will
be shown later in this guide.
Regardless of which approach is used, resources files that must be added to the Xamarin.Android application
before fonts can be downloaded. First, the font(s) must be declared in an XML file in the Resources/font directory
as part of a font family. This snippet is an example of how to download fonts from the Google Fonts Open Source
collection using the default font provider that comes with Android 8.0 (or Support Library v26):
The font-family element contains the following attributes, declaring the information that Android requires to
download the fonts:
1. fontProviderAuthority – The authority of the Font Provider to be used for the request.
2. fontPackage – The package for the Font Provider to be used for the request. This is used to verify the identity
of the provider.
3. fontQuery – This is a string that will help the font provider locate the requested font. Details on the font query
are specific to the font provider. The QueryBuilder class in the Downloadable Fonts sample app provides some
information on the query format for fonts from the Google Fonts Open Source Collection.
4. fontProviderCerts – A resource array with the list of sets of hashes for the certificates that the provider should
be signed with.
Once the fonts are defined, it may be necessary to provide information about the font certificates involved with the
download.
Font Certificates
If the font provider is not preinstalled on the device, or if the app is using the Xamarin.Android.Support.Compat
library, Android requires the security certificates of the font provider. These certificates will be listed in an array
resource file that is kept in Resources/values directory.
For example, the following XML is named Resources/values/fonts_cert.xml and stores the certificates for the
Google font provider:
MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1U
EBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQ
EJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ
2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5k
cm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdG
Ns8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6
t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr2
2ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOj
gfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQs
wCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECx
MHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFM
AMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEB
ahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtA
WPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8n
fBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
</item>
</string-array>
<string-array name="com_google_android_gms_fonts_certs_prod">
<item>
MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQ
HEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4Mj
EyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3M
RQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCC
AQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRcz
fey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs
1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYX
tqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r
45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29
vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBA
UAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+
a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1Mvcy
UTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3W
fMBEmh/9iFBDAaTCK
</item>
</string-array>
</resources>
With these resource files in place, the app is capable of downloading the fonts.
Declaring Downloadable Fonts as Resources
By listing the downloadable fonts in the AndroidManifest.XML, Android will asynchronously download the fonts
when the app first starts. The font's themselves are listed in an array resource file, similar to this one:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="downloadable_fonts" translatable="false">
<item>@font/vt323</item>
</array>
</resources>
To download these fonts, they have to be declared in AndroidManifest.XML by adding meta-data as a child of
the application element. For example, if the downloadable fonts are declared in a resource file at
Resources/values/downloadable_fonts.xml, then this snippet would have to be added to the manifest:
In the previous snippet FontToDownload is a query that will help the font from the Google Fonts Open Source
collection.
Before passing the FontRequest to the FontContractCompat.RequestFont method, there are two objects that must be
created:
FontsContractCompat.FontRequestCallback – This is an abstract class which must be extended. It is a callback that
will be invoked when RequestFont is finished. A Xamarin.Android app must subclass
FontsContractCompat.FontRequestCallback and override the OnTypefaceRequestFailed and OnTypefaceRetrieved ,
providing the actions to be taken when the download fails or succeeds respectively.
Handler – This is a Handler which will be used by RequestFont to download the font on a thread, if necessary.
Fonts should not be downloaded on the UI thread.
This snippet is an example of a C# class that will asynchronously download a font from Google Fonts Open Source
collection. It implements the FontRequestCallback interface, and raises a C# event when FontRequest has finished.
public class FontDownloadHelper : FontsContractCompat.FontRequestCallback
{
// A very simple font query; replace as necessary
public static readonly String FontToDownload = "Courgette";
Handler GetHandlerThreadHandler()
{
if (Handler == null)
{
HandlerThread handlerThread = new HandlerThread("fonts");
handlerThread.Start();
Handler = new Handler(handlerThread.Looper);
}
return Handler;
}
}
To use this helper, a new FontDownloadHelper is created, and an event handler is assigned:
var fontHelper = new FontDownloadHelper();
Summary
This guide discussed the new APIs in Android 8.0 to support downloadable fonts and fonts as resources. It
discussed how to embed existing fonts in an APK and to use them in a layout. It also discussed how Android 8.0
supports downloading fonts from a font provider, either programmatically or by declaring the font meta-data in
resource files.
Related Links
fontFamily
FontConfig
FontRequest
FontsContractCompat
Resources.GetFont
Typeface
Android Support Library 26 NuGet
Using Fonts in Android
CSS font weight specification
Google Fonts Open Source collection
Source Sans Pro
Activity Lifecycle
4/12/2018 • 17 minutes to read • Edit Online
Activities are a fundamental building block of Android applications and they can exist in a number of different
states. The activity lifecycle begins with instantiation and ends with destruction, and includes many states in
between. When an activity changes state, the appropriate lifecycle event method is called, notifying the activity of
the impending state change and allowing it to execute code to adapt to that change. This article examines the
lifecycle of activities and explains the responsibility that an activity has during each of these state changes to be
part of a well-behaved, reliable application.
Activity Lifecycle
The Android activity lifecycle comprises a collection of methods exposed within the Activity class that provide the
developer with a resource management framework. This framework allows developers to meet the unique state
management requirements of each activity within an application and properly handle resource management.
Activity States
The Android OS arbitrates Activities based on their state. This helps Android identify activities that are no longer
in use, allowing the OS to reclaim memory and resources. The following diagram illustrates the states an Activity
can go through during its lifetime:
These states can be broken into 4 main groups as follows:
1. Active or Running – Activities are considered active or running if they are in the foreground, also known as
the top of the activity stack. This is considered the highest priority activity in Android, and as such will only
be killed by the OS in extreme situations, such as if the activity tries to use more memory than is available
on the device as this could cause the UI to become unresponsive.
2. Paused – When the device goes to sleep, or an activity is still visible but partially hidden by a new, non-
full-sized or transparent activity, the activity is considered paused. Paused activities are still alive, that is,
they maintain all state and member information, and remain attached to the window manager. This is
considered to be the second highest priority activity in Android and, as such, will only be killed by the OS if
killing this activity will satisfy the resource requirements needed to keep the Active/Running Activity stable
and responsive.
3. Stopped/Backgrounded – Activities that are completely obscured by another activity are considered
stopped or in the background. Stopped activities still try to retain their state and member information for
as long as possible, but stopped activities are considered to be the lowest priority of the three states and,
as such, the OS will kill activities in this state first to satisfy the resource requirements of higher priority
activities.
4. Restarted – It is possible for an activity that is anywhere from paused to stopped in the lifecycle to be
removed from memory by Android. If the user navigates back to the activity it must be restarted, restored
to its previously saved state, and then displayed to the user.
Activity Re -Creation in Response to Configuration Changes
To make matters more complicated, Android throws one more wrench in the mix called Configuration Changes.
Configuration changes are rapid activity destruction/re-creation cycles that occur when the configuration of an
activity changes, such as when the device is rotated (and the activity needs to get re-built in landscape or portrait
mode), when the keyboard is displayed (and the activity is presented with an opportunity to resize itself ), or when
the device is placed in a dock, among others.
Configuration changes still cause the same Activity State changes that would occur during stopping and
restarting an activity. However, in order to make sure that an application feels responsive and performs well
during configuration changes, it's important that they be handled as quickly as possible. Because of this, Android
has a specific API that can be used to persist state during configuration changes. We'll cover this later in the
Managing State Throughout the Lifecycle section.
Activity Lifecycle Methods
The Android SDK and, by extension, the Xamarin.Android framework provide a powerful model for managing
the state of activities within an application. When an activity's state is changing, the activity is notified by the OS,
which calls specific methods on that activity. The following diagram illustrates these methods in relationship to
the Activity Lifecycle:
As a developer, you can handle state changes by overriding these methods within an activity. It's important to
note, however, that all lifecycle methods are called on the UI thread and will block the OS from performing the
next piece of UI work, such as hiding the current activity, displaying a new activity, etc. As such, code in these
methods should be as brief as possible to make an application feel well performing. Any long-running tasks
should be executed on a background thread.
Let's examine each of these lifecycle methods and their use:
OnCreate
OnCreate is the first method to be called when an activity is created. OnCreate is always overridden to perform
any startup initializations that may be required by an Activity such as:
Creating views
Initializing variables
Binding static data to lists
OnCreate takes a Bundle parameter, which is a dictionary for storing and passing state information and objects
between activities If the bundle is not null, this indicates the activity is restarting and it should restore its state
from the previous instance. The following code illustrates how to retrieve values from the bundle:
string intentString;
bool intentBool;
if (bundle != null)
{
intentString = bundle.GetString("myString");
intentBool = bundle.GetBoolean("myBool");
}
if (_camera==null)
{
// Do camera initializations here
}
}
OnResume is important because any operation that is done in OnPause should be un-done in OnResume , since it's
the only lifecycle method that is guaranteed to execute after OnPause when bringing the activity back to life.
OnPause
OnPause is called when the system is about to put the activity into the background or when the activity becomes
partially obscured. Activities should override this method if they need to:
Commit unsaved changes to persistent data
Destroy or clean up other objects consuming resources
Ramp down frame rates and pausing animations
Unregister external event handlers or notification handlers (i.e. those that are tied to a service). This must
be done to prevent Activity memory leaks.
Likewise, if the Activity has displayed any dialogs or alerts, they must be cleaned up with the .Dismiss()
method.
As an example, the following code snippet will release the camera, as the Activity cannot make use of it while
paused:
There are two possible lifecycle methods that will be called after OnPause :
1. OnResume will be called if the Activity is to be returned to the foreground.
2. OnStop will be called if the Activity is being placed in the background.
OnStop
OnStop is called when the activity is no longer visible to the user. This happens when one of the following occurs:
A new activity is being started and is covering up this activity.
An existing activity is being brought to the foreground.
The activity is being destroyed.
OnStop may not always be called in low -memory situations, such as when Android is starved for resources and
cannot properly background the Activity. For this reason, it is best not to rely on OnStop getting called when
preparing an Activity for destruction. The next lifecycle methods that may be called after this one will be
OnDestroy if the Activity is going away, or OnRestart if the Activity is coming back to interact with the user.
OnDestroy
OnDestroy is the final method that is called on an Activity instance before it's destroyed and completely removed
from memory. In extreme situations Android may kill the application process that is hosting the Activity, which
will result in OnDestroy not being invoked. Most Activities will not implement this method because most clean up
and shut down has been done in the OnPause and OnStop methods. The OnDestroy method is typically
overridden to clean up long running resources that might leak resources. An example of this might be
background threads that were started in OnCreate .
There will be no lifecycle methods called after the Activity has been destroyed.
OnRestart
OnRestart is called after your activity has been stopped, prior to it being started again. A good example of this
would be when the user presses the home button while on an activity in the application. When this happens
OnPause and then OnStop methods are called, and the Activity is moved to the background but is not destroyed.
If the user were then to restore the application by using the task manager or a similar application, Android will
call the OnRestart method of the activity.
There are no general guidelines for what kind of logic should be implemented in OnRestart . This is because
OnStart is always invoked regardless of whether the Activity is being created or being restarted, so any
resources required by the Activity should be initialized in OnStart , rather than OnRestart .
The next lifecycle method called after OnRestart will be OnStart .
Back vs. Home
Many Android devices have two distinct buttons: a "Back" button and a "Home" button. An example of this can be
seen in the following screenshot of Android 4.0.3:
There is a subtle difference between the two buttons, even though they appear to have the same effect of putting
an application in the background. When a user clicks the Back button, they are telling Android that they are done
with the activity. Android will destroy the Activity. In contrast, when the user clicks the Home button the activity is
merely placed into the background – Android will not kill the activity.
int c;
this.SetContentView (Resource.Layout.SimpleStateView);
if (bundle != null) {
c = bundle.GetInt ("counter", -1);
} else {
c = -1;
}
The code above increments an integer named c when a button named incrementCounter is clicked, displaying
the result in a TextView named output . When a configuration change happens - for example, when the device is
rotated - the above code would lose the value of c because the bundle would be null , as shown in the figure
below:
To preserve the value of c in this example, the Activity can override OnSaveInstanceState , saving the value in the
bundle as shown below:
Now when the device is rotated to a new orientation, the integer is saved in the bundle and is retrieved with the
line:
NOTE
It is important to always call the base implementation of OnSaveInstanceState so that the state of the view hierarchy can
also be saved.
Vi e w St a t e
Overriding OnSaveInstanceState is an appropriate mechanism for saving transient data in an Activity across
orientation changes, such as the counter in the above example. However, the default implementation of
OnSaveInstanceState will take care of saving transient data in the UI for every view, so long as each view has an
ID assigned. For example, say an application has an EditText element defined in XML as follows:
<EditText android:id="@+id/myText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
Since the EditText control has an id assigned, when the user enters some data and rotates the device, the data
is still displayed, as shown below:
OnRestoreInstanceState
OnRestoreInstanceState will be called after OnStart . It provides an activity the opportunity to restore any state
that was previously saved to a Bundle during the previous OnSaveInstanceState . This is the same bundle that is
provided to OnCreate , however.
The following code demonstrates how state can be restored in OnRestoreInstanceState :
This method exists to provide some flexibility around when state should be restored. Sometimes it is more
appropriate to wait until all initializations are done before restoring instance state. Additionally, a subclass of an
existing Activity may only want to restore certain values from the instance state. In many cases, it's not necessary
to override OnRestoreInstanceState , since most activities can restore state using the bundle provided to
OnCreate .
For an example of saving state using a Bundle , refer to the Walkthrough - Saving the Activity state.
Bundle Limitations
Although OnSaveInstanceState makes it easy to save transient data, it has some limitations:
It is not called in all cases. For example, pressing Home or Back to exit an Activity will not result in
OnSaveInstanceState being called.
The bundle passed into OnSaveInstanceState is not designed for large objects, such as images. In the case
of large objects, saving the object from OnRetainNonConfigurationInstance is preferable, as discussed
below.
Data saved by using the bundle is serialized, which can lead to delays.
Bundle state is useful for simple data that doesn't use much memory, whereas non-configuration instance data is
useful for more complex data, or data that is expensive to retrieve, such as from a web service call or a
complicated database query. Non-configuration instance data gets saved in an object as needed. The next section
introduces OnRetainNonConfigurationInstance as a way of preserving more complex data types through
configuration changes.
Persisting Complex Data
In addition to persisting data in the bundle, Android also supports saving data by overriding
OnRetainNonConfigurationInstance and returning an instance of a Java.Lang.Object that contains the data to
persist. There are two primary benefits of using OnRetainNonConfigurationInstance to save state:
The object returned from OnRetainNonConfigurationInstance performs well with larger, more complex data
types because memory retains this object.
The OnRetainNonConfigurationInstance method is called on demand, and only when needed. This is more
economical than using a manual cache.
Using OnRetainNonConfigurationInstance is suitable for scenarios where it is expensive to retrieve the data
multiple times, such as in web service calls. For example, consider the following code that searches Twitter:
var results = (from result in (JsonArray)j ["results"] let jResult = result as JsonObject select jResult
["text"].ToString ()).ToArray ();
This code retrieves results from the web formatted as JSON, parses them, and then presents the results in a list,
as shown in the following screenshot:
When a configuration change occurs - for example, when a device is rotated - the code repeats the process. To
reuse the originally retrieved results and not cause needless, redundant network calls, we can use
OnRetainNonconfigurationInstance to save the results, as shown below:
if (tweetsWrapper != null) {
PopulateTweetList (tweetsWrapper.Tweets);
} else {
SearchTwitter ("xamarin");
}
...
Now when the device is rotated, the original results are retrieved from the LastNonConfiguartionInstance
property. In this example, the results consist of a string[] containing tweets. Since
OnRetainNonConfigurationInstance requires that a Java.Lang.Object be returned, the string[] is wrapped in a
class that subclasses Java.Lang.Object , as shown below:
For example, attempting to use a TextView as the object returned from OnRetainNonConfigurationInstance will
leak the Activity, as illustrated by the code below:
TextView _textView;
if(tv != null) {
_textView = tv;
var parent = _textView.Parent as FrameLayout;
parent.RemoveView(_textView);
} else {
_textView = new TextView (this);
_textView.Text = "This will leak.";
}
SetContentView (_textView);
}
In this section, we learned how to preserve simple state data with the Bundle , and persist more complex data
types with OnRetainNonConfigurationInstance .
Summary
The Android activity lifecycle provides a powerful framework for state management of activities within an
application but it can be tricky to understand and implement. This chapter introduced the different states that an
activity may go through during its lifetime, as well as the lifecycle methods that are associated with those states.
Next, guidance was provided as to what kind of logic should be performed in each of these methods.
Related Links
Handling Rotation
Android Activity
Walkthrough - Saving the Activity state
4/12/2018 • 4 minutes to read • Edit Online
We have covered the theory behind saving state in the Activity Lifecycle guide; now, let's walk through an example.
When we click the Start Activity B button, we see Activity A pause and stop while Activity B goes through its
state changes:
[ActivityLifecycle.MainActivity] Activity A - OnPause
[ActivityLifecycle.SecondActivity] Activity B - OnCreate
[ActivityLifecycle.SecondActivity] Activity B - OnStart
[ActivityLifecycle.SecondActivity] Activity B - OnResume
[ActivityLifecycle.MainActivity] Activity A - OnStop
When we click the Back button, Activity B is destroyed and Activity A is resumed:
int _counter = 0;
Next, let's edit the Resource/layout/Main.axml layout file and add a new clickButton that displays the number
of times the user has clicked the button. The resulting Main.axml should resemble the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/myButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/mybutton_text" />
<Button
android:id="@+id/clickButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/counterbutton_text" />
</LinearLayout>
Let's add the following code to the end of the OnCreate method in MainActivity – this code handles click events
from the clickButton :
When we build and run the app again, a new button appears that increments and displays the value of _counter
on each click:
But when we rotate the device to landscape mode, this count is lost:
Examining the application output, we see that Activity A was paused, stopped, destroyed, recreated, restarted, then
resumed during the rotation from portrait to landscape mode:
Because Activity A is destroyed and recreated again when the device is rotated, its instance state is lost. Next, we
will add code to save and restore the instance state.
Adding Code to Preserve Instance State
Let's add a method to MainActivity to save the instance state. Before Activity A is destroyed, Android
automatically calls OnSaveInstanceState and passes in a Bundle that we can use to store our instance state. Let's
use it to save our click count as an integer value:
When Activity A is recreated and resumed, Android passes this Bundle back into our OnCreate method. Let's add
code to OnCreate to restore the _counter value from the passed-in Bundle . Add the following code just before
the line where clickbutton is defined:
if (bundle != null)
{
_counter = bundle.GetInt ("click_count", 0);
Log.Debug(GetType().FullName, "Activity A - Recovered instance state");
}
Build and run the app again, then click the second button a few times. When we rotate the device to landscape
mode, the count is preserved!
Before the OnStop method was called, our new OnSaveInstanceState method was called to save the _counter
value in a Bundle . Android passed this Bundle back to us when it called our OnCreate method, and we were able
to used it to restore the _counter value to where we left off.
Summary
In this walkthough, we have used our knowledge of the Activity Lifecycle to preserve state data.
Related Links
ActivityLifecycle (sample)
Activity Lifecycle
Android Activity
Creating Android Services
6/7/2018 • 9 minutes to read • Edit Online
This guide discusses Xamarin.Android services, which are Android components that allow work to be done without
an active user interface. Services are very commonly used for tasks that are performed in the background, such as
time consuming calculations, downloading files, playing music, and so on. It explains the different scenarios that
services are suited for and shows how to implement them both for performing long -running background tasks as
well as for providing an interface for remote procedure calls.
This is a potential memory leak – the thread created by the first instance of the Activity will still be running. If the
thread has a reference to the first instance of the Activity, this will prevent Android from garbage collecting the
object. However, the second instance of the Activity is still created (which in turn might create a new thread).
Rotating the device several times in rapid succession may exhaust all the RAM and force Android to terminate the
entire application to reclaim memory.
As a rule of thumb, if the work to be performed should outlive an Activity, then a service should be created to
perform that work. However, if the work is only applicable in the context of an Activity, then creating a thread to
perform the work might be more appropriate. For example, creating a thumbnail for a photo that was just added
to a photo gallery app should probably occur in a service. However, a thread might be more appropriate to play
some music that should only be heard while an Activity is in the foreground.
Background work can be broken down into two broad classifications:
1. Long Running Task – This is work that is ongoing until explicitly stopped. An example of a long running task
is an app that streams music or that must monitor data collected from a sensor. These tasks must run even
though the application has no visible user interface.
2. Periodic Tasks – (sometimes referred to as a job) A periodic task is one that is of relatively short in duration
(several seconds) and is run on a schedule (i.e. once a day for a week or perhaps just once in the next 60
seconds). An example of this is downloading a file from the internet or generating a thumbnail for an image.
There are four different types of Android services:
Bound Service – A bound service is a service that has some other component (typically an Activity) bound
to it. A bound service provides an interface that allows the bound component and the service to interact
with each other. Once there are no more clients bound to the service, Android will shut the service down.
IntentService – An IntentService is a specialized subclass of the Service class that simplifies service
creation and usage. An IntentService is meant to handle individual autonomous calls. Unlike a service,
which can concurrently handle multiple calls, an IntentService is more like a work queue processor – work
is queued up and an IntentService processes each job one at a time on a single worker thread. Typically,
an IntentService is not bound to an Activity or a Fragment.
Started Service – A started service is a service that has been started by some other Android component
(such as an Activity) and is run continously in the background until something explicitly tells the service to
stop. Unlike a bound service, a started service does not have any clients directly bound to it. For this reason,
it is important to design started services so that they may be gracefully restarted as necessary.
Hybrid Service – A hybrid service is a service that has the characteristics of a started service and a bound
service. A hybrid service can be started by when a component binds to it or it may be started by some
event. A client component may or may not be bound to the hybrid service. A hybrid service will keep
running until it is explicitly told to stop, or until there are no more clients bound to it.
Which type of service to use is very dependent on application requirements. As a rule of thumb, an IntentService
or a bound service are sufficient for most tasks that an Android application must perform, so preference should be
given to one of those two types of services. An IntentService is a good choice for "one-shot" tasks, such as
downloading a file, while a bound service would be suitable when frequent interactions with an Activity/Fragment
is required.
While most services run in the background, there is a special sub-category known as a foreground service. This is
a service that is given a higher priority (compared to a normal service) to perform some work for the user (such as
playing music).
It is also possible to run a service in it's own process on the same device, this is sometimes referred to as a remote
service or as an out-of-process service. This does require more effort to create, but can be useful for when an
application needs to share functionality with other applications, and can, in some cases, improve the user
experience of an application.
Background Execution Limits in Android 8.0
Starting in Android 8.0 (API level 26), an Android application no longer have the ability to run freely in the
background. When in the foreground, an app can start and run services without restriction. When an application
moves into the background, Android will grant the app a certain amount of time to start and use services. Once
that time has elapsed, the app can no longer start any services and any services that were started will be
terminated. At this point is is not possible for the app to perform any work. Android considers an application to be
in the foreground if one of the following conditions are met:
There is a visible activity (either started or paused).
The app has started a foreground service.
Another app is in the foreground and is using components from an app that would be otherwise in the
background. An example of this is if Application A, which is in the foreground, is bound to a service provided
by Application B. Application B would then also be considered in the foreground, and not terminated by
Android for being in the background.
There are some situations where, even though an app is in the background, Android will wake up the app and
relax these restrictions for a few minutes, allowing the app to perform some work:
A high priority Firebase Cloud Message is received by the app.
The app receives a broadcast, such as
The application receives an executes a PendingIntent in response to a Notification.
Existing Xamarin.Android applications may have to change how they perform background work to avoid any
issues that might arise on Android 8.0. Here are some practical alterantives to an Android service:
Schedule work to run in the background using the Android Job Scheduler or the Firebase Job
Dispatcher – These two libraries provide a framework for applications to segregate background work in to
jobs, a discrete unit of work. Apps can then schedule the job with the operating system along with some criteria
about when the job can run.
Start the service in the foreground – a foreground service is useful for when the app must perform some
task in the background and the user may need to periodically interact with that task. The foreground service
will display a persistent notification so that the user is aware that the app is running a background task and also
provides a way to monitor or interact with the task. An example of this would be a podcasting app that is
playing back a podcast to the user or perhaps downloading a podcast episode so that it can be enjoyed later.
Use a high priority Firebase Cloud Message (FCM ) – When Android receives a high priority FCM for an
app, it will allow that app to run services in the background for a short period of time. This would be a good
alternative to having a background service that polls an app in the background.
Defer work for when the app comes into the foreground – If none of the previous solutions are viable,
then apps must develop their own way to pause and resume work when the app comes to the foreground.
Related Links
Android Oreo Background Execution Limits
Creating a Service
5/7/2018 • 4 minutes to read • Edit Online
[Service]
public class DemoService : Service
{
// Magical code that makes the service do wonderful things.
}
At compile time, Xamarin.Android will register the service by injecting the following XML element into
AndroidManifest.xml (notice that Xamarin.Android generated a random name for the service):
It is possible to share a service with other Android applications by exporting it. This is accomplished by setting the
Exported property on the ServiceAttribute . When exporting a service, the ServiceAttribute.Name property
should also be set to provide a meaningful public name for the service. This snippet demonstrates how to export
and name a service:
[Service(Exported=true, Name="com.xamarin.example.DemoService")]
public class DemoService : Service
{
// Magical code that makes the service do wonderful things.
}
The AndroidManifest.xml element for this service will then look something like:
Services have their own lifecycle with callback methods that are invoked as the service is created. Exactly which
methods are invoked depends on the type of service. A started service must implement different lifecycle methods
than a bound service, while a hybrid service must implement the callback methods for both a started service and a
bound service. These methods are all members of the Service class; how the service is started will determine
what lifecycle methods will be invoked. These lifecycle methods will be discussed in more detail later.
By default, a service will start in the same process as an Android application. It is possible to start a service in its
own process by setting the ServiceAttribute.IsolatedProcess property to true:
[Service(IsolatedProcess=true)]
public class DemoService : Service
{
// Magical code that makes the service do wonderful things, in it's own process!
}
The next step is to examine how to start a service and then move on to examine how to implement the three
different types of services.
NOTE
A service runs on the UI thread, so if any work is to be performed which blocks the UI, the service must use threads to
perform the work.
Starting A Service
The most basic way to start a service in Android is to dispatch an Intent which contains meta-data to help identify
which service should be started. There are two different styles of Intents that can be used to start a service:
Explicit Intent – An explicit Intent will identify exactly what service should be used to complete a given
action. An explicit Intent can be thought of as a letter that has a specific address; Android will route the intent
to the service that is explicitly identified. This snippet is one example of using an explicit Intent to start a
service called DownloadService :
Implicit Intent – This type of Intent loosely identifies the of action that the user wishes to perform, but the
exact service to complete that action is unknown. An implicit Intent can be thought of as a letter that is
addressed "To Whom It May Concern...". Android will examine the contents of the Intent, and determine if
there is an existing service which matches the intent.
An intent filter is used to help match the implicit intent with a registered service. An intent filter is an XML
element that is added to AndroidManifest.xml which contains the necessary meta-data to help match a
Service with an implicit intent.
If Android has more than one possible match for an implicit intent, then it may ask the user to select the
component to handle the action:
IMPORTANT
Starting in Android 5.0 (AP level 21) an implicit intent cannot be used to start a service.
Where possible, applications should use explicit Intents to start a service. An implicit Intent does not ask for a
specific service to start – it is a request for some service installed on the device to handle the request. This
ambiguous request can result in the wrong service handling the request or another app needlessly starting (which
increases the pressure for resources on the device).
How the Intent is dispatched depends on the type of service and will be discussed in more detail later in the guides
specific to each type of service.
Creating an Intent Filter for Implicit Intents
To associate a service with a implicit Intent, an Android app must provide some meta-data to identify the
capabilities of the service. This meta-data is provided by intent filters. Intent filters contain some information, such
as an action or a type of data, that must be present in an Intent to start a service. In Xamarin.Android, the intent
filter is registered in AndroidManifest.xml by decorating a service with the IntentFilterAttribute . For example,
the following code adds an intent filter with an associated action of com.xamarin.DemoService :
[Service]
[IntentFilter(new String[]{"com.xamarin.DemoService"})]
public class DemoService : Service
{
}
This results in an entry being included in the AndroidManifest.xml file – an entry that is packaged with the
application in a way analogous to the following example:
<service android:name="demoservice.DemoService">
<intent-filter>
<action android:name="com.xamarin.DemoService" />
</intent-filter>
</service>
With the basics of a Xamarin.Android service out of the way, let's examine the the different subtypes of services in
more detail.
Related Links
Android.App.Service
Android.App.ServiceAttribute
Android.App.Intent
Android.App.IntentFilterAttribute
Bound Services in Xamarin.Android
5/7/2018 • 11 minutes to read • Edit Online
Bound services are Android services that provide a client-server interface that a client (such as an Android Activity )
can interact with. This guide will discuss the key components involved with creating a bound service and how to
use it in a Xamarin.Android application.
namespace BoundServiceDemo
{
[Service(Name="com.xamarin.ServicesDemo1")]
public class TimestampService : Service, IGetTimestamp
{
static readonly string TAG = typeof(TimestampService).FullName;
IGetTimestamp timestamper;
/// <summary>
/// This method will return a formatted timestamp to the client.
/// </summary>
/// <returns>A string that details what time the service started and how long it has been running.
</returns>
public string GetFormattedTimestamp()
{
return timestamper?.GetFormattedTimestamp();
}
}
}
In the sample, the OnCreate method initializes an object that holds the logic for retrieving and formatting a
timestamp that would be requested by a client. When the first client tries to bind to the service, Android will invoke
the OnBind method. This service will instantiate a TimestampServiceBinder object that will allow the clients to
access this instance of the running service. The TimestampServiceBinder class is discussed in the next section.
Implementing IBinder
As mentioned, an IBinder object provides the communication channel between a client and a service. Android
applications should not implement the IBinder interface, the Android.OS.Binder should be extended. The Binder
class provides much of the necessary infrastructure which is necessary marshal the binder object from the service
(which may be running in a separate process) to the client. In most cases, the Binder subclass is only a few lines of
code and wraps a reference to the service. In this example, TimestampBinder has a property that exposes the
TimestampService to the client:
This Binder makes it possible to invoke the public methods on the service; for example:
Once Binder has been extended, it is necessary to implement IServiceConnection to connect everything together.
Creating the Service Connection
The IServiceConnection will present|introduce|expose|connect the Binder object to the client. In addition to
implementing the IServiceConnection interface, the class must extend Java.Lang.Object . The service connection
should also provide some way that the client can access the Binder (and therefore communicate with the bound
service).
This code is from the accompanying sample project is one possible way to implement IServiceConnection :
using Android.Util;
using Android.OS;
using Android.Content;
namespace BoundServiceDemo
{
public class TimestampServiceConnection : Java.Lang.Object, IServiceConnection, IGetTimestamp
{
static readonly string TAG = typeof(TimestampServiceConnection).FullName;
MainActivity mainActivity;
public TimestampServiceConnection(MainActivity activity)
{
IsConnected = false;
Binder = null;
mainActivity = activity;
}
if (IsConnected)
{
message = message + " bound to service " + name.ClassName;
mainActivity.UpdateUiForBoundService();
}
else
{
message = message + " not bound to service " + name.ClassName;
mainActivity.UpdateUiForUnboundService();
}
Log.Info(TAG, message);
mainActivity.timestampMessageTextView.Text = message;
return Binder?.GetFormattedTimestamp();
}
}
}
As a part of the binding process, Android will invoke the OnServiceConnected method, providing the name of the
service that is being bound and the binder that holds a reference to the service itself. In this example, the service
connection has two properties, one that holds a reference to the Binder and a boolean flag for if the client is
connected to the service or not.
The OnServiceDisconnected method is only invoked when the connection between a client and a service is
unexpectedly lost or broken. This method allows the client a chance to respond to the interruption in service.
if (serviceConnection == null)
{
this.serviceConnection = new TimestampServiceConnection(this);
}
IMPORTANT
Starting with Android 5.0 (API level 21) it is only possible to bind to a service with an explicit intent.
This particular example allow an activity to invoke methods on the service itself:
// In this example the Activity is only talking to a friend, i.e. the IGetTimestamp interface provided by the
Binder.
string currentTimestamp = serviceConnection.Binder.GetFormattedTimestamp()
Related Links
Android.App.Service
Android.Content.Bind
Android.Content.Context
Android.Content.IServiceConnection
Android.OS.Binder
Android.OS.IBinder
BoundServiceDemo (sample)
Intent Services in Xamarin.Android
4/12/2018 • 2 minutes to read • Edit Online
[Service]
public class DemoIntentService: IntentService
{
public DemoIntentService () : base("DemoIntentService")
{
}
Work is sent to an IntentService by instantiating an Intent and then calling the StartService method with that
Intent as a parameter. The Intent will be passed to the service as a parameter in the OnHandleIntent method. This
code snippet is an example of sending a work request to an Intent:
// This code might be called from within an Activity, for example in an event
// handler for a button click.
Intent downloadIntent = new Intent(this, typeof(DemoIntentService));
// This is just one example of passing some values to an IntentService via the Intent:
downloadIntent.Put
("file_to_download", "http://www.somewhere.com/file/to/download.zip");
StartService(downloadIntent);
The IntentService can extract the values from the Intent, as demonstrated in this code snippet:
Related Links
IntentService
StartService
Started Services with Xamarin.Android
4/12/2018 • 5 minutes to read • Edit Online
The first parameter is an Intent object containing the meta-data about the work to perform. The second
parameter contains a StartCommandFlags value that provides some information about the method call. This
parameter has one of two possible values:
StartCommandFlag.Redelivery – This means that the Intent is a re-delivery of a previous Intent . This value is
provided when the service had returned StartCommandResult.RedeliverIntent but was stopped before it could be
properly shut down.
StartCommandFlag.Retry - This value is received when a previous OnStartCommand call failed and Android is
trying to start the service again with the same intent as the previous failed attempt.
Finally, the third parameter is an integer value that is unique to the application that identifies the request. It is
possible that multiple callers may invoke the same service object. This value is used to associate a request to stop a
service with a given request to start a service. It will be discussed in more detail in the section Stopping the Service.
The value StartCommandResult is returned by the service as a suggestion to Android on what to do if the service is
killed due to resource constraints. There are three possible values for StartCommandResult :
StartCommandResult.NotSticky – This value tells Android that it is not necessary to restart the service that it
has killed. As an example of this, consider a service that generates thumbnails for a gallery in an app. If the
service is killed, it isn't crucial to recreate the thumbnail immediately – the thumbnail can be recreated the next
time the app is run.
StartCommandResult.Sticky – This tells Android to restart the Service, but not to deliver the last Intent that
started the Service. If there are no pending Intents to handle, then a null will be provided for the Intent
parameter. An example of this might be a music player app; the service will restart ready to play music, but it
will play the last song.
StartCommandResult.RedeliverIntent – This value is will tell Android to restart the service and re-deliver the
last Intent . An example of this is a service that downloads a data file for an app. If the service is killed, the data
file still needs to be downloaded. By returning StartCommandResult.RedeliverIntent , when Android restarts the
service it will also provide the Intent (which holds the URL of the file to download) to the service. This will
enable the download to either restart or resume (depending on the exact implementation of the code).
There is a fourth value for StartCommandResult – StartCommandResult.ContinuationMask . This value is returned by
OnStartCommand and it describes how Android will continue the service it has killed. This value isn't typically used to
start a service.
The key lifecycle events of a started service are shown in this diagram:
Stopping the Service
A started service will keep running indefinitely; Android will keep the service running as long as there are sufficient
system resources. Either the client must stop the service, or the service may stop itself when it is done its work.
There are two ways to stop a service:
Android.Content.Context.StopService() – A client (such as an Activity) can request a service stop by
calling the StopService method:
Related Links
StartedServicesDemo (sample)
Android.App.Service
Android.App.StartCommandFlags
Android.App.StartCommandResult
Android.Content.BroadcastReceiver
Android.Content.Intent
Android.OS.Handler
Android.Widget.Toast
Status Bar Icons
Foreground Services
7/11/2018 • 3 minutes to read • Edit Online
A foreground service is a special type of a bound service or a started service. Occasionally services will perform
tasks that users must be actively aware of, these services are known as foreground services. An example of a
foreground service is an app that is providing the user with directions while driving or walking. Even if the app is in
the background, it is still important that the service has sufficient resources to work properly and that the user has
a quick and handy way to access the app. For an Android app, this means that a foreground service should receive
higher priority than a "regular" service and a foreground service must provide a Notification that Android will
display as long as the service is running.
To start a foreground service, the app must dispatch an Intent that tells Android to start the service. Then the
service must register itself as a foreground service with Android. Apps that are running on Android 8.0 (or higher)
should use the Context.StartForegroundService method to start the service, while apps that are running on devices
with an older version of Android should use Context.StartService
This C# extension method is an example of how to start a foreground service. On Android 8.0 and higher it will use
the StartForegroundService method, otherwise the older StartService method will be used.
public static void StartForegroundServiceComapt<T>(this Context context, Bundle args = null) where T : Service
{
var intent = new Intent(context, typeof(T));
if (args != null)
{
intent.PutExtras(args);
}
The previous notification will display a status bar notification that that is similar to the following:
This screenshot shows the expanded notification in the notification tray with two actions that allow the user to
control the service:
More information about notifications is available in the Local Notifications section of the Android Notifications
guide.
StopForeground(true);
If the service is halted with a call to StopSelf or StopService , the status bar notification will be removed.
Related Links
Android.App.Service
Android.App.Service.StartForeground
Local Notifications
ForegroundServiceDemo (sample)
Running Android Services in Remote Processes
4/12/2018 • 26 minutes to read • Edit Online
Generally, all components in an Android application will run in the same process. Android services are a notable
exception to this in that they can be configured to run in their own processes and shared with other applications,
including those from other Android developers. This guide will discuss how to create and use an Android remote
service using Xamarin.
This guide will discuss the details of implementing an out-of-process service. It will discuss how to implement a
service that is meant to run in its own process and how a client may communicate with that service using the
Messenger framework. It will also briefly discuss two-way communication: the client sending a message to a
service and the service sending a message back to the client. Because services can be shared between different
applications, this guide will also discuss one technique for limiting client access to the service by using Android
permissions.
IMPORTANT
Bugzilla 51940 - Services with isolated processes and custom Application class fail to resolve overloads properly reports that
a Xamarin.Android service will not start up properly when the IsolatedProcess is set to true . This guide is provided for a
reference. A Xamarin.Android application should still be able to communicate with an out-of-process service that is written in
Java.
Requirements
This guide assumes familiarity with creating services.
Although it is possible to use implicit intents with apps that target older Android APIs, this guide will focus
exclusively on the use of explicit intents. Apps targeting Android 5.0 (API level 21) or higher must use an explicit
intent to bind with a service; this is the technique that will be demonstrated in this guide..
[Service(Name = "com.xamarin.TimestampService",
Process=":timestampservice_process",
Exported=true)]
Global Process – A service that is run in a global process is accessible to all applications running on the
device. A global process must be a fully qualified class name that starts with a lower case character. (Unless
steps are taken to secure the service, other applications may bind and interact with it. Securing the service
against unauthorized use will be discussed later in this guide.)
[Service(Name = "com.xamarin.TimestampService",
Process="com.xamarin.xample.messengerservice.timestampservice_process",
Exported=true)]
Isolated Process – An isolated process is a process that runs in its own sandbox, isolated from the rest of
the system and with no special permissions of its own. To run a service in an isolated process, the
IsolatedProcess property of the ServiceAttribute is set to true as shown in this code snippet:
[Service(Name = "com.xamarin.TimestampService",
IsolatedProcess= true,
Process="com.xamarin.xample.messengerservice.timestampservice_process",
Exported=true)]
IMPORTANT
See Bugzilla 51940 - Services with isolated processes and custom Application class fail to resolve overloads properly
An isolated service is a simple way to secure an application and the device against untrusted code. For example, an
app may download and execute a script from a website. In this case, performing this in an isolated process provides
an additional layer of security against untrusted code compromising the Android device.
IMPORTANT
Once a service has been exported, the name of the service should not change. Changing the name of the service may break
other applications that are using the service.
To see the effect that the Process property has, the following screenshot shows a service running in its own
private process:
switch (messageType)
{
case Constants.SAY_HELLO_TO_TIMESTAMP_SERVICE:
// The client as sent a simple Hello, say in the Android Log.
break;
case Constants.GET_UTC_TIMESTAMP:
// Call methods on the service to retrive a timestamp message.
break;
default:
Log.Warn(TAG, $"Unknown messageType, ignoring the value {messageType}.");
base.HandleMessage(msg);
break;
}
}
}
It is also possible to package parameters for the service in the Message . This will be discussed later in this guide.
The next topic to consider is creating the Messenger object to process the incoming Message s.
Instantiating the Messenger
As previously discussed, deserializing the Message object and invoking Handler.HandleMessage is the responsibilty
of the Messenger object. The Messenger class also provides an IBinder object that the client will use to send
messages to the service.
When the service starts, it will instantiate the Messenger and inject the Handler . A good place to perform this
initialization is on the OnCreate method of the service. This code snippet is one example of a service that initializes
its own Handler and Messenger :
At this point, the final step is for the Service to override OnBind .
Implementing Service.OnBind
All bound services, whether they run in their own process or not, must implement the OnBind method. The return
value of this method is some object that the client can use to interact with the service. Exactly what that object is
depends whether the service is a local service or a remote service. While a local service will return a custom
IBinder implementation, a remote service will return the IBinder that is encapsulated but the Messenger that
was created in the previous section:
public override IBinder OnBind(Intent intent)
{
Log.Debug(TAG, "OnBind");
return messenger.Binder;
}
Once these three steps are accomplished, the remote service can be considered complete.
// This is the package name of the APK, set in the Android manifest
const string REMOTE_SERVICE_COMPONENT_NAME = "com.xamarin.TimestampService";
// This is the name of the service, according the value of ServiceAttribute.Name
const string REMOTE_SERVICE_PACKAGE_NAME = "com.xamarin.xample.messengerservice";
// Provide the package name and the name of the service with a ComponentName object.
ComponentName cn = new ComponentName(REMOTE_SERVICE_PACKAGE_NAME, REMOTE_SERVICE_COMPONENT_NAME);
Intent serviceToStart = new Intent();
serviceToStart.SetComponent(cn);
When the service is bound, the IServiceConnection.OnServiceConnected method is invoked and provides an
IBinder to a client. However, the client will not directly use the IBinder . Instead, it will instantiate a Messenger
object from that IBinder . This is the Messenger that the client will use to interact with the remote service.
The following is an example of a very basic IServiceConnection implementation that demonstrates how a client
would handle connecting to and disconnecting from a service. Notice that the OnServiceConnected method receives
and IBinder , and the client creates a Messenger from that IBinder :
public class TimestampServiceConnection : Java.Lang.Object, IServiceConnection
{
static readonly string TAG = typeof(TimestampServiceConnection).FullName;
MainActivity mainActivity;
Messenger messenger;
if (IsConnected)
{
// things to do when the connection is successful. perhaps notify the client? enable UI features?
}
else
{
// things to do when the connection isn't successful.
}
}
// Things to do when the service disconnects. perhaps notify the client? disable UI features?
}
}
Once the service connection and the intent are created, it is possible for the client to call BindService and initiate
the binding process:
After the client has successfully bound to the service and the Messenger is available, it is possible for the client to
send Messages to the service.
There are several different forms of the Message.Obtain method. The previous example uses the
Message.Obtain(Handler h, Int32 what) . Because this is an asynchronous request to an out-of-process service; there
will be no response from the service, so the Handler is set to null . The second parameter, Int32 what , will be
stored in the .What property of the Message object. The .What property is used by code in the service process to
invoke methods on the service.
The Message class also exposes two additional properties that may be of use to the recipent: Arg1 and Arg2 .
These two properties are integer values that may have some special agreed upon values that have meaning
between the client and the service. For example, Arg1 may hold a customer ID and Arg2 may hold a purchase
order number for that customer. The Method.Obtain(Handler h, Int32 what, Int32 arg1, Int32 arg2) can be used to
set the two properties when the Message is created. Another way to populate these two values is to set the .Arg
and .Arg2 properties directly on the Message object after it has been created.
Passing Additional Values to the Service
It is possible to pass more complex data to the service by using a Bundle . In this case, extra values can be placed in
a Bundle and sent along with the Message by setting the .Data property property before sending.
messenger.Send(msg);
NOTE
In general, a Message should not have a payload larger than 1MB. The size limit may vary according the version of Android
and on any proprietary changes the vendor might have made to their implementation of the Android Open Source Project
(AOSP) that is bundled with the device.
This sample code demonstrates how the client will instantiate the Message and package a Messenger that the
service should use for its response:
try
{
serviceConnection.Messenger.Send(msg);
}
catch (RemoteException ex)
{
Log.Error(TAG, ex, "There was a problem sending the message.");
}
The service must make some changes to its own Handler to extract the Messenger and use that to send replies to
the client. This code snippet is an example of how the service's Handler would create a Message and send it back
to the client:
// This is the message that the service will send to the client.
Message responseMessage = Message.Obtain(null, Constants.RESPONSE_TO_SERVICE);
Bundle dataToReturn = new Bundle();
dataToReturn.PutString(Constants.RESPONSE_MESSAGE_KEY, "This is the result from the service.");
responseMessage.Data = dataToReturn;
// The msg object here is the message that was received by the service. The service will not instantiate a
client,
// It will use the client that is encapsulated by the message from the client.
Messenger clientMessenger = msg.ReplyTo;
if (clientMessenger!= null)
{
try
{
clientMessenger.Send(responseMessage);
}
catch (Exception ex)
{
Log.Error(TAG, ex, "There was a problem sending the message.");
}
}
Note that in the code samples above, the Messenger instance that is created by the client is not the same object that
is received by the service. These are two different Messenger objects running in two separate processes that
represent the communication channel.
[Service(Name = "com.xamarin.TimestampService",
Process="com.xamarin.TimestampService.timestampservice_process",
Permission="signature")]
public class TimestampService : Service
{
}
2. Create a custom permission – It is possible for the developer of the service to create a custom permission
for the service. This is best for when a developer wants to share their service with applications from other
developers. A custom permission requires a bit more effort to implement and will be covered below.
A simplified example of creating a custom normal permission will be described in the next section. For more
information about Android permissions, please consult Google's documentation for Best Practices & Security. For
more information about Android permissions, see the Permissions section of the Android documentation for the
application manifest for more information about Android permissions.
NOTE
In general, Google discourages the use of custom permissions as they may prove confusing to users.
<permission android:name="com.xamarin.xample.messengerservice.REQUEST_TIMESTAMP"
android:protectionLevel="signature"
android:label="@string/permission_label"
android:description="@string/permission_description"
/>
<application android:allowBackup="true"
android:icon="@mipmap/icon"
android:label="@string/app_name"
android:theme="@style/AppTheme">
</application>
</manifest>
Then, the AndroidManifest.xml of the client APK must explicitly request this new permission. This is done by
adding the users-permission attribute to the AndroidManifest.xml:
<application
android:allowBackup="true"
android:icon="@mipmap/icon"
android:label="@string/app_name"
android:theme="@style/AppTheme">
</application>
</manifest>
Related Links
Handler
Message
Messenger
ServiceAttribute
The Exported attribute
Services with isolated processes and custom Application class fail to resolve overloads properly
Processes and Threads
Android Manifest - Permissions
Security Tips
MessengerServiceDemo (sample)
Service Notifications
4/12/2018 • 2 minutes to read • Edit Online
This guide discusses how an Android service may use local notifications to dispatch information to a user.
[Service]
public class MyService: Service
{
// A notification requires an id that is unique to the application.
const int NOTIFICATION_ID = 9000;
// Work has finished, now dispatch anotification to let the user know.
Notification.Builder notificationBuilder = new Notification.Builder(this)
.SetSmallIcon(Resource.Drawable.ic_notification_small_icon)
.SetContentTitle(Resources.GetString(Resource.String.notification_content_title))
.SetContentText(Resources.GetString(Resource.String.notification_content_text));
When the user slides down the notification screen from the top, the full notification is displayed:
Updating A Notification
To update a notification, the service will republish the notification using the same notification ID. Android will
display or update the notification in the status bar as necessary.
void UpdateNotification(string content)
{
var notification = GetNotification(content, pendingIntent);
NotificationManager notificationManager =
(NotificationManager)GetSystemService(Context.NotificationService);
notificationManager.Notify(NOTIFICATION_ID, notification);
}
More information about notifications is available in the Local Notifications section of the Android Notifications
guide.
Related Links
Local Notifications in Android
Broadcast Receivers in Xamarin.Android
6/25/2018 • 8 minutes to read • Edit Online
When Xamarin.Android compiles the class, it will also update the AndroidManifest with the necessary meta-data
to register the receiver. For a statically-registered broadcast receiver, the Enabled properly must be set to true ,
otherwise Android will not be able to create an instance of the receiver.
The Exported property controls whether the broadcast receiver can receive messages from outside the
application. If the property is not explicitly set, the default value of the property is determined by Android based on
if there are any intent-filters associated with the broadcast receiver. If there is at least one intent-filter for the
broadcast receiver then Android will assume that the Exported property is true . If there are no intent-filters
associated with the broadcast receiver, then Android will assume that the value is false .
The OnReceive method receives a reference to the Intent that was dispatched to the broadcast receiver. This
makes is possible for the sender of the intent to pass values to the broadcast receiver.
Statically registering a Broadcast Receiver with an Intent Filter
When a BroadcastReceiver is decorated with the IntentFilterAttribute , Xamarin.Android will add the necessary
<intent-filter> element to the Android manifest at compile time. The following snippet is an example of a
broadcast receiver that will run when a device has finished booting (if the appropriate Android permissions were
granted by the user):
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class MyBootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
// Work that should be done when the device boots.
}
}
It is also possible to create an intent filter that will respond to custom intents. Consider the following example:
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { "com.xamarin.example.TEST" })]
public class MySampleBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
// Do stuff here
}
}
Apps that target Android 8.0 (API level 26) or higher may not statically register for an implicit broadcast. Apps
may still statically register for an explicit broadcast. There is a small list of of implicit broadcasts that are exempt
from this restriction. These exceptions are described in the Implicit Broadcast Exceptions guide in the Android
documentation. Apps that are interested in implicit broadcasts must do so dynamically using the RegisterReceiver
method. This is described next.
Context-Registering a Broadcast Receiver
Context-registration (also referred to as dynamic registration) of a receiver is performed by invoking the
RegisterReceiver method, and the broadcast receiver must be unregistered with a call to the UnregisterReceiver
method. To prevent leaking resources, it is important to unregister the receiver when it is no longer relevant for the
context (the Activity or service). For example, a service may broadcast an intent to inform an Activity that updates
are available to be displayed to the user. When the Activity starts, it would register for those Intents. When the
Activity is moved into the background and no longer visible to the user, it should unregister the receiver because
the UI for displaying the updates is no longer visible. The following code snippet is an example of how to register
and unregister a broadcast receiver in the context of an Activity:
In the previous example, when the Activity comes into the foreground, it will register a broadcast receiver that will
listen for a custom intent by using the OnResume lifecycle method. As the Activity moves into the background, the
OnPause() method will unregister the receiver.
Publishing a Broadcast
A broadcast may be published to all apps installed on the device creating an Intent object and dispatching it with
the SendBroadcast or the SendOrderedBroadcast method.
1. Context.SendBroadcast methods – There are several implementations of this method. These methods
will broadcast the intent to the entire system. Broadcast receivers thatwill receive the intent in an
indeterminate order. This provides a great deal of flexibility but means that it is possible for other
applications to register and receive the intent. This can pose a potential security risk. Applications may need
to implement addition security to prevent unauthorized access. One possible solution is to use the
LocalBroadcastManager which will only dispatch messages within the private space of the app. This code
snippet is one example of how to dispatch an intent using one of the SendBroadcast methods:
This snippet is another example of sending a broadcast by using the Intent.SetAction method to identify
the action:
Other apps on the device cannot receive the messages that are published with the LocalBroadcastManager . This
code snippet shows how to dispatch an Intent using the LocalBroadcastManager :
Related Links
BroadcastReceiver
Context.RegisterReceiver
Context.SendBroadcast
Context.UnregisterReceiver
Intent
IntentFilter
LocalBroadcastManager
Local Notifications in Android
Android Support Library v4
Android Localization
5/7/2018 • 6 minutes to read • Edit Online
This document introduces the localization features of the Android SDK and how to access them with Xamarin.
This value will be a locale identifier that contains both a language code and a locale code, separated by an
underscore. For reference, here is a list of Java locales and Android-supported locales via StackOverflow.
Common examples include:
en_US for English (United Statees)
es_ES for Spanish (Spain)
ja_JP for Japanese (Japan)
zh_CN for Chinese (China)
zh_TW for Chinese (Taiwan)
pt_PT for Portuguese (Portugal)
pt_BR for Portuguese (Brazil)
LOCALE_CHANGED
Android generates android.intent.action.LOCALE_CHANGED when the user changes their language selection.
Activities can opt to handle this by setting the android:configChanges attribute on the activity, like this:
NOTE
When specifying a top-level language like es only two characters are required; however when specifying a full locale, the
directory name format requires a dash and lowercase r to separate the two parts, for example pt-rBR or zh-rCN. Compare
this to the value returned in code, which has an underscore (eg. pt_BR ). Both of these are different to the value .NET
CultureInfo class uses, which has a dash only (eg. pt-BR ). Keep these differences in mind when working across Xamarin
platforms.
<string name="app_name">TaskyL10n</string>
You need to escape according to normal XML rules, and the name must be a valid Android resource ID (no spaces
or dashes). Here is an example of the default (English) strings file for the example:
values/Strings.xml
<resources>
<string name="app_name">TaskyL10n</string>
<string name="taskadd">Add Task</string>
<string name="taskname">Name</string>
<string name="tasknotes">Notes</string>
<string name="taskdone">Done</string>
<string name="taskcancel">Cancel</string>
</resources>
The Spanish directory values-es contains a file with the same name (Strings.xml) that contains the translations:
values-es/Strings.xml
With the strings files set-up, the translated values can be referenced in both layouts and code.
AXML Layout Files
To reference localized strings in layout files, use the @string/id syntax. This XML snippet from the sample shows
text properties being set with localized resource IDs (some other attributes have been omitted):
<TextView
android:id="@+id/NameLabel"
android:text="@string/taskname"
... />
<CheckBox
android:id="@+id/chkDone"
android:text="@string/taskdone"
... />
GetText Method
To retrieve translated strings in code, use the GetText method and pass the resource ID:
Quantity Strings
Android string resources also let you create quantity strings which allow translators to provide different
translations for different quantities, such as:
"There is 1 task left."
"There are 2 tasks still to do."
(rather than a generic "There are n task(s) left").
In the Strings.xml
<plurals name="numberOfTasks">
<!--
As a developer, you should always supply "one" and "other"
strings. Your translators will know which strings are actually
needed for their language.
-->
<item quantity="one">There is %d task left.</item>
<item quantity="other">There are %d tasks still to do.</item>
</plurals>
To render the complete string use the GetQuantityString method, passing the resource ID and the value to be
displayed (which is passed twice). The second parameter is used by Android to determine which quantity string
to use, the third parameter is the value actually substituted into the string (both are required).
Testing
Make sure to thoroughly test the default locale. Your application will crash if the default resources cannot be
loaded for some reason (i.e. they are missing).
Emulator Testing
Refer to Google's Testing on an Android Emulator section for instructions on how to set an emulator to a specific
locale using the ADB shell.
Device Testing
To test on a device, change the language in the Settings app. Tip: Make a note of the icons and location of the
menu items so that you can revert the language to the original setting.
Summary
This article covers the basics of localizing Android applications using the built-in resource handling. You can learn
more about i18n and L10n for iOS, Android and cross-platform (including Xamarin.Forms) apps in this cross-
platform guide.
Related Links
Tasky (localized in code) (sample)
Android Localizing with Resources
Cross-Platform Localization Overview
Xamarin.Forms Localization
iOS Localization
Permissions In Xamarin.Android
7/25/2018 • 9 minutes to read • Edit Online
Overview
Android applications run in their own sandbox and for security reasons do not have access to certain system
resources or hardware on the device. The user must explicitly grant permission to the app before it may use these
resources. For example, an application cannot access the GPS on a device without explicit permission from the
user. Android will throw a Java.Lang.SecurityException if an app tries to access a protected resource without
permission.
Permissions are declared in the AndroidManifest.xml by the application developer when the app is developed.
Android has two different workflows for obtaining the user's consent for those permissions:
For apps that targeted Android 5.1 (API level 22) or lower, the permission request occurred when the app was
installed. If the user did not grant the permissions, then the app would not be installed. Once the app is
installed, there is no way to revoke the permissions except by uninstalling the app.
Starting in Android 6.0 (API level 23), users were given more control over permissions; they can grant or
revoke permissions as long as the app is installed on the device. This screenshot shows the permission settings
for the Google Contacts app. It lists the various permissions and allows the user to enable or disable
permissions:
Android apps must check at run-time to see if they have permission to access a protected resource. If the app does
not have permission, then it must make requests using the new APIs provided by the Android SDK for the user to
grant the permissions. Permissions are divided into two categories:
Normal Permissions – These are permissions which pose little security risk to the user's security or privacy.
Android 6.0 will automatically grant normal permissions at the time of installation. Please consult the Android
documentation for a complete list of normal permissions.
Dangerous Permissions – In contrast to normal permissions, dangerous permissions are those that protect
the user's security or privacy. These must be explictly granted by the user. Sending or receiving an SMS
message is an example of an action requiring a dangerous permission.
IMPORTANT
The category that a permission belongs to may change over time. It is possible that a permission which was categorized as a
"normal" permission may be elevated in future API levels to a dangerous permission.
Dangerous permissions are further sub-divided into permission groups. A permission group will hold permissions
that are logically related. When the user grants permission to one member of a permission group, Android
automatically grants permission to all members of that group. For example, the STORAGE permission group holds
both the WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE permissions. If the user grants permission to
READ_EXTERNAL_STORAGE , then the WRITE_EXTERNAL_STORAGE permission is automatically granted at the same time.
Before requesting one or more permissions, it is a best practice to provide a rationale as to why the app requires
the permission before requesting the permission. Once the user understands the rationale, the app can request
permission from the user. By understanding the rationale, the user can make an informed decision if they wish to
grant the permission and understand the repercussions if they do not.
The whole workflow of checking and requesting permissions is known as a run-time permissions check, and can
be summarized in the following diagram:
The Android Support Library backports some of the new APIs for permissions to older versions of Android.
These backported APIs will automatically check the version of Android on the device so it is not necessary to
perform an API level check each time.
This document will discuss how to add permissions to a Xamarin.Android application and how apps that target
Android 6.0 (API level 23) or higher should perform a run-time permission check.
NOTE
It is possible that permissions for hardware may affect how the app is filtered by Google Play. For example, if the app
requires permission for the camera, then Google Play will not show the app in the Google Play Store on a device that does
not have a camera installed.
Requirements
It is strongly recommended that Xamarin.Android projects include the Xamarin.Android.Support.Compat NuGet
package. This package will backport permission specific APIs to older versions of Android, providing one common
interface without the need to constantly check the version of Android that the app is running on.
NOTE
Applications should only request the permissions that they require.
Visual Studio
Visual Studio for Mac
It is possible to declare the permissions using the tool support built into Visual Studio:
1. Double-click Properties in the Solution Explorer and select the Android Manifest tab in the Properties
window:
2. If the application does not already have an AndroidManifest.xml, click No AndroidManifest.xml found.
Click to add one as shown below:
3. Select any permissions your application needs from the Required permissions list and save:
Xamarin.Android will automatically add some permissions at build time to Debug builds. This will make
debugging the application easier. In particular, two notable permissions are INTERNET and READ_EXTERNAL_STORAGE .
These automatically-set permissions will not appear to be enabled in the Required permissions list. Release
builds, however, use only the permissions that are explicitly set in the Required permissions list.
For apps that target Android 5.1(API level 22) or lower, there is nothing more that needs to be done. Apps that will
run on Android 6.0 (API 23 level 23) or higher should proceed on to the next section on how to perform run time
permission checks.
Runtime Permission Checks in Android 6.0
The ContextCompat.CheckSelfPermission method (available with the Android Support Library) is used to check if a
specific permission has been granted. This method will return a Android.Content.PM.Permission enum which has
one of two values:
Permission.Granted – The specified permission has been granted.
Permission.Denied – The specified permission has not been granted.
This code snippet is an example of how to check for the Camera permission in an Activity:
It is a best practice to inform the user as to why a permission is necessary for an application so that an informed
decision can be made to grant the permission. An example of this would be an app that takes photos and geo-tags
them. It is clear to the user that the camera permission is necessary, but it might not be clear why the app also
needs the location of the device. The rationale should display a message to help the user understand why the
location permission is desirable and that the camera permission is required.
The ActivityCompat.ShouldShowRequestPermissionRational method is used to determine if the rationale should be
shown to the user. This method will return true if the rationale for a given permission should be displayed. This
screenshot shows an example of a Snackbar displayed by an application that explains why the app needs to know
the location of the device:
This code snippet is an example of the two methods that were discussed. First, a check is made to determine if the
permission rationale should be shown. If the rationale is to be shown, then a Snackbar is displayed with the
rationale. If the user clicks OK in the Snackbar, then the app will request the permissions. If the user does not
accept the rationale, then the app should not proceed to request permissions. If the rationale is not shown, then
the Activity will request the permission:
if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.AccessFineLocation))
{
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// For example if the user has previously denied the permission.
Log.Info(TAG, "Displaying camera permission rationale to provide additional context.");
RequestPermission can be called even if the user has already granted permission. Subsequent calls are not
necessary, but they provide the user with the opportunity to confirm (or revoke) the permission. When
RequestPermission is called, control is handed off to the operating system, which will display a UI for accepting the
permissions:
After the user is finished, Android will return the results to the Activity via a callback method,
OnRequestPermissionResult . This method is a part of the interface
ActivityCompat.IOnRequestPermissionsResultCallback which must be implemented by the Activity. This interface
has a single method, OnRequestPermissionsResult , which will be invoked by Android to inform the Activity of the
user's choices. If the user has granted the permission, then the app can go ahead and use the protected resource.
An example of how to implement OnRequestPermissionResult is shown below:
Summary
This guide discussed how to add and check for permissions in an Android device. The differences in how
permissions work between old Android apps (API level < 23) and new Android apps (API level > 22). It discussed
how to perform run-time permission checks in Android 6.0.
Related Links
List of Normal Permissions
Runtime Permissions Sample App
Handling Permissions in Xamarin.Android
Graphics and Animation
4/12/2018 • 17 minutes to read • Edit Online
Android provides a very rich and diverse framework for supporting 2D graphics and animations. This topic
introduces these frameworks and discusses how to create custom graphics and animations for use in a
Xamarin.Android application.
Overview
Despite running on devices that are traditionally of limited power, the highest rated mobile applications often have
a sophisticated User Experience (UX), complete with high quality graphics and animations that provide an intuitive,
responsive, dynamic feel. As mobile applications get more and more sophisticated, users have begun to expect
more and more from applications.
Luckily for us, modern mobile platforms have very powerful frameworks for creating sophisticated animations and
custom graphics while retaining ease of use. This enables developers to add rich interactivity with very little effort.
UI API frameworks in Android can roughly be split into two categories: Graphics and Animation.
Graphics are further split into different approaches for doing 2D and 3D graphics. 3D graphics are available via a
number of built in frameworks such as OpenGL ES (a mobile specific version of OpenGL ), and third-party
frameworks such as MonoGame (a cross platform toolkit compatible with the XNA toolkit). Although 3D graphics
are not within the scope of this article, we will examine the built-in 2D drawing techniques.
Android provides two different API's for creating 2D graphics. One is a high level declarative approach and the
other a programmatic low -level API:
Drawable Resources – These are used to create custom graphics either programmatically or (more
typically) by embedding drawing instructions in XML files. Drawable resources are typically defined as XML
files that contain instructions or actions for Android to render a 2D graphic.
Canvas – this is a low level API that involves drawing directly on an underlying bitmap. It provides very
fine-grained control over what is displayed.
In addition to these 2D graphics techniques, Android also provides several different ways to create animations:
Drawable Animations – Android also supports frame-by-frame animations known as Drawable
Animation. This is the simplest animation API. Android sequentially loads and displays Drawable resources
in sequence (much like a cartoon).
View Animations – View Animations are the original animation API's in Android and are available in all
versions of Android. This API is limited in that it will only work with View objects and can only perform
simple transformations on those Views. View animations are typically defined in XML files found in the
/Resources/anim folder.
Property Animations – Android 3.0 introduced a new set of animation API's known as Property
Animations. These new API's introduced an extensible and flexible system that can be used to animate the
properties of any object, not just View objects. This flexibility allows animations to be encapsulated in
distinct classes that will make code sharing easier.
View Animations are more suitable for applications that must support the older pre-Android 3.0 API's (API level
11). Otherwise applications should use the newer Property Animation API's for the reasons that were mentioned
above.
All of these frameworks are viable options, however where possible, preference should be given to Property
Animations, as it is a more flexible API to work with. Property Animations allow for animation logic to be
encapsulated in distinct classes that makes code sharing easier and simplifies code maintenance.
Accessibility
Graphics and animations help to make Android apps attractive and fun to use; however, it is important to
remember that some interactions occur via screenreaders, alternate input devices, or with assisted zoom. Also,
some interactions may occur without audio capabilities.
Apps are more usable in these situations if they have been designed with accessibility in mind: providing hints and
navigation assistance in the user-interface, and ensuring there is text-content or descriptions for pictorial elements
of the UI.
Refer to Google's Accessibility Guide for more information on how to utilize Android's accessibility APIs.
2D Graphics
Drawable Resources are a popular technique in Android applications. As with other resources, Drawable Resources
are declarative – they're defined in XML files. This approach allows for a clean separation of code from resources.
This can simplify development and maintenance because it is not necessary to change code to update or change
the graphics in an Android application. However, while Drawable Resources are useful for many simple and
common graphic requirements, they lack the power and control of the Canvas API.
The other technique, using the Canvas object, is very similar to other traditional API frameworks such as
System.Drawing or iOS's Core Drawing. Using the Canvas object provides the most control of how 2D graphics
are created. It is appropriate for situations where a Drawable Resource will not work or will be difficult to work
with. For example, it may be necessary to draw a custom slider control whose appearance will change based on
calculations related to the value of the slider.
Let's examine Drawable Resources first. They are simpler and cover the most common custom drawing cases.
Drawable Resources
Drawable Resources are defined in an XML file in the directory /Resources/drawable . Unlike embedding PNG or
JPEG's, it is not necessary to provide density-specific versions of Drawable Resources. At runtime, an Android
application will load these resources and use the instructions contained in these XML files to create 2D graphics.
Android defines several different types of Drawable Resources:
ShapeDrawable – This is a Drawable object that draws a primitive geometric shape and applies a limited set
of graphical effects on that shape. They are very useful for things such as customizing Buttons or setting the
background of TextViews. We will see an example of how to use a ShapeDrawable later in this article.
StateListDrawable – This is a Drawable Resource that will change appearance based on the state of a
widget/control. For example, a button may change its appearance depending on whether it is pressed or not.
LayerDrawable – This Drawable Resource that will stack several other drawables one on top of another. An
example of a LayerDrawable is shown in the following screenshot:
<padding android:left="5dp"
android:right="5dp"
android:top="5dp"
android:bottom="5dp" />
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp" />
</shape>
We can reference this Drawable Resource declaratively in a Layout or other Drawable as shown in the following
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#33000000">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/shape_rounded_blue_rect"
android:text="@string/message_shapedrawable" />
</RelativeLayout>
Drawable Resources can also be applied programmatically. The following code snippet shows how to
programmatically set the background of a TextView:
TextView tv = FindViewById<TextView>(Resource.Id.shapeDrawableTextView);
tv.SetBackgroundResource(Resource.Drawable.shape_rounded_blue_rect);
To see what this would look like, run the AnimationsDemo project and select the Shape Drawable item from the
main menu. We should see something similar to the following screenshot:
For more details about the XML elements and syntax of Drawable Resources, consult Google's documentation.
Using the Canvas Drawing API
Drawables are powerful but have their limitations. Certain things are either not possible or very complex (for
example: applying a filter to a picture that was taken by a camera on the device). It would be very difficult to apply
red-eye reduction by using a Drawable Resource. Instead, the Canvas API allows an application to have very fine-
grained control to selectively change colors in a specific part of the picture.
One class that is commonly used with the Canvas is the Paint class. This class holds colour and style information
about how to draw. It is used to provide things such a color and transparency.
The Canvas API uses the painter's model to draw 2D graphics. Operations are applied in successive layers on top
of each other. Each operation will cover some area of the underlying bitmap. When the area overlaps a previously
painted area, the new paint will partially or completely obscure the old. This is the same way that many other
drawing APIs such as System.Drawing and iOS's Core Graphics work.
There are two ways to obtain a Canvas object. The first way involves defining a Bitmap object, and then
instantiating a Canvas object with it. For example, the following code snippet creates a new canvas with an
underlying bitmap:
The other way to obtain a Canvas object is by the OnDraw callback method that is provided the View base class.
Android calls this method when it decides a View needs to draw itself and passes in a Canvas object for the View
to work with.
The Canvas class exposes methods to programmatically provide the draw instructions. For example:
Canvas.DrawPaint – Fills the entire canvas's bitmap with the specified paint.
Canvas.DrawPath – Draws the specified geometric shape using the specified paint.
Canvas.DrawText – Draws the text on the canvas with the specified colour. The text is drawn at location x,y
.
Drawing with the Canvas API
Let's see an example of the Canvas API in action. The following code snippet shows how to draw a view:
public class MyView : View
{
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
Paint green = new Paint {
AntiAlias = true,
Color = Color.Rgb(0x99, 0xcc, 0),
};
green.SetStyle(Paint.Style.FillAndStroke);
This code above first creates a red paint and a green paint object. It fills the content of the canvas with red, and
then instructs the canvas to draw a green rectangle that is 25% of the width of the canvas. An example of this can
be seen by in AnimationsDemo project that is included with the source code for this article. By starting up the
application and selecting the Drawing item from the main menu, we should a screen similar to the following:
Animation
Users like things that move in their applications. Animations are a great way to improve the user experience of an
application and help it stand out. The best animations are the ones that users don't notice because they feel natural.
Android provides the following three API's for animations:
View Animation – This is the original API. These animations are tied to a specific View and can perform
simple transformations on the contents of the View. Because of it's simplicity, this API still useful for things
like alpha animations, rotations, and so forth.
Property Animation – Property animations were introduced in Android 3.0. They enable an application to
animate almost anything. Property animations can be used to change any property of any object, even if
that object is not visible on the screen.
Drawable Animation – This a special Drawable resource that is used to apply a very simple animation
effect to layouts.
In general, property animation is the preferred system to use as it is more flexible and offers more features.
View Animations
View animations are limited to Views and can only perform animations on values such as start and end points,
size, rotation, and transparency. These types of animations are typically referred to as tween animations. View
animations can be defined two ways – programmatically in code or by using XML files. XML files are the preferred
way to declare view animations, as they are more readable and easier to maintain.
The animation XML files will be stored in the /Resources/anim directory of a Xamarin.Android project. This file
must have one of the following elements as the root element :
alpha – A fade-in or fade-out animation.
rotate – A rotation animation.
scale – A resizing animation.
translate – A horizontal and/or vertical motion.
set – A container that may hold one or more of the other animation elements.
By default, all animations in an XML file will be applied simultaneously. To make animations occur sequentially, set
the android:startOffset attribute on one of the elements defined above.
It is possible to affect the rate of change in an animation by using an interpolator. An interpolator makes it possible
for animation effects to be accelerated, repeated, or decelerated. The Android framework provides several
interpolators out of the box, such as (but not limited to):
AccelerateInterpolator / DecelerateInterpolator – these interpolators increase or decrease the rate of
change in an animation.
BounceInterpolator – the change bounces at the end.
LinearInterpolator – the rate of changes is constant.
The following XML shows an example of an animation file that combines some of these elements:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android=http://schemas.android.com/apk/res/android
android:shareInterpolator="false">
<scale android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillEnabled="true"
android:fillAfter="false"
android:duration="700" />
<set android:interpolator="@android:anim/accelerate_interpolator">
<scale android:fromXScale="1.4"
android:toXScale="0.0"
android:fromYScale="0.6"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:fillEnabled="true"
android:fillBefore="false"
android:fillAfter="true"
android:startOffset="700"
android:duration="400" />
<rotate android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:fillEnabled="true"
android:fillBefore="false"
android:fillAfter="true"
android:startOffset="700"
android:duration="400" />
</set>
</set>
This animation will perform all of the animations simultaneously. The first scale animation will stretch the image
horizontally and shrink it vertically, and then the image will simultaneously be rotated 45 degrees counter-
clockwise and shrink, disappearing from the screen.
The animation can be programmatically applied to a View by inflating the animation and then applying it to a View.
Android provides the helper class Android.Views.Animations.AnimationUtils that will inflate an animation resource
and return an instance of Android.Views.Animations.Animation . This object is applied to a View by calling
StartAnimation and passing the Animation object. The following code snippet shows an example of this:
Now that we have a fundamental understanding of how View Animations work, lets move to Property Animations.
Property Animations
Property animators are a new API that was introduced in Android 3.0. They provide a more extensible API that can
be used to animate any property on any object.
All property animations are created by instances of the Animator subclass. Applications do not directly use this
class, instead they use one of it's subclasses:
ValueAnimator – This class is the most important class in the entire property animation API. It calculates the
values of properties that need to be changed. The ViewAnimator does not directly update those values;
instead, it raises events that can be used to update animated objects.
ObjectAnimator – This class is a subclass of ValueAnimator . It is meant to simplify the process of animating
objects by accepting a target object and property to update.
AnimationSet – This class is responsible for orchestrating how animations run in relation to one another.
Animations may run simultaneously, sequentially, or with a specified delay between them.
Evaluators are special classes that are used by animators to calculate the new values during an animation. Out of
the box, Android provides the following evaluators:
IntEvaluator – Calculates values for integer properties.
FloatEvaluator – Calculates values for float properties.
ArgbEvaluator – Calculates values for colour properties.
If the property that is being animated is not a float , int or colour, applications may create their own evaluator
by implementing the ITypeEvaluator interface. (Implementing custom evaluators is beyond the scope of this
topic.)
Using the ValueAnimator
There are two parts to any animation: calculating animated values and then setting those values on properties on
some object. ValueAnimator will only calculate the values, but it will not operate on objects directly. Instead, objects
will be updated inside event handlers that will be invoked during the animation lifespan. This design allows several
properties to be updated from one animated value.
You obtain an instance of ValueAnimator by calling one of the following factory methods:
ValueAnimator.OfInt
ValueAnimator.OfFloat
ValueAnimator.OfObject
Once that is done, the ValueAnimator instance must have its duration set, and then it can be started. The following
example shows how to animate a value from 0 to 1 over the span of 1000 milliseconds:
But itself, the code snippet above is not very useful – the animator will run but there is no target for the updated
value. The Animator class will raise the Update event when it decides that it is necessary to inform listeners of a
new value. Applications may provide an event handler to respond to this event as shown in the following code
snippet:
As you can see from the previous code snippet, ObjectAnimator can reduce and simplify the code that is necessary
to animate an object.
Drawable Animations
The final animation API is the Drawable Animation API. Drawable animations load a series of Drawable resources
one after the other and display them sequentially, similar to a flip-it cartoon.
Drawable resources are defined in an XML file that has an <animation-list> element as the root element and a
series of <item> elements that define each frame in the animation. This XML file is stored in the
/Resource/drawable folder of the application. The following XML is an example of a drawable animation:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/asteroid01" android:duration="100" />
<item android:drawable="@drawable/asteroid02" android:duration="100" />
<item android:drawable="@drawable/asteroid03" android:duration="100" />
<item android:drawable="@drawable/asteroid04" android:duration="100" />
<item android:drawable="@drawable/asteroid05" android:duration="100" />
<item android:drawable="@drawable/asteroid06" android:duration="100" />
</animation-list>
This animation will run through six frames. The android:duration attribute declares how long each frame will be
displayed. The next code snippet shows an example of creating a Drawable animation and starting it when the user
clicks a button on the screen:
AnimationDrawable _asteroidDrawable;
_asteroidDrawable = (Android.Graphics.Drawables.AnimationDrawable)
Resources.GetDrawable(Resource.Drawable.spinning_asteroid);
At this point we have covered the foundations of the animation APIs available in an Android application.
Summary
This article introduced a lot of new concepts and API's to help add some graphics to an Android application. First it
discussed the various 2D graphics API's and demonstrated how Android allows applications to draw directly to the
screen using a Canvas object. We also saw some alternate techniques that allow graphics to be declaratively
created using XML files. Then we went on to discuss the old and new API's for creating animations in Android.
Related Links
Animation Demo (sample)
Animation and Graphics
Using Animations to Bring your Mobile Apps to Life
AnimationDrawable
Canvas
Object Animator
Value Animator
CPU Architectures
5/18/2018 • 3 minutes to read • Edit Online
Xamarin.Android supports several CPU architectures, including 32 -bit and 64 -bit devices. This article explains how
to target an app to one or more Android -supported CPU architectures.
NOTE
64-bit runtime support is currently an experimental feature. Remember that 64-bit runtimes are not required to run your
app on 64-bit devices.
Additional Information
In some situations, you may need to create a separate APK for each architecture (to reduce the size of your APK,
or because your app has shared libraries that are specific to a particular CPU architecture). For more information
about this approach, see Build ABI-Specific APKs.
Handling Rotation
4/12/2018 • 8 minutes to read • Edit Online
This topic describes how to handle device orientation changes in Xamarin.Android. It covers how to work with the
Android resource system to automatically load resources for a particular device orientation as well as how to
programmatically handle orientation changes.
Overview
Because mobile devices are easily rotated, built-in rotation is a standard feature in mobile OSes. Android provides
a sophisticated framework for dealing with rotation within applications, whether the user interface is created
declaratively in XML or programmatically in code. When automatically handling declarative layout changes on a
rotated device, an application can benefit from the tight integration with the Android resource system. For
programmatic layout, changes must be handled manually. This allows finer control at runtime, but at the expense
of more work for the developer. An application can also choose to opt out of the Activity restart and take manual
control of orientation changes.
This guide examines the following orientation topics:
Declarative Layout Rotation – How to use the Android resource system to build orientation-aware
applications, including how to load both layouts and drawables for particular orientations.
Programmatic Layout Rotation – How to add controls programmatically as well as how to handle
orientation changes manually.
If the device is rotated to landscape orientation, the Activity's OnCreate method is called again and the same
Main.axml file is inflated, as shown in the screenshot below:
Orientation-Specific Layouts
In addition to the layout folder (which defaults to portrait and can also be explicitly named layout-port by
including a folder named layout-land ), an application can define the views it needs when in landscape without
any code changes.
Suppose the Main.axml file contained the following XML:
If a folder named layout-land that contains an additional Main.axml file is added to the project, inflating the
layout when in landscape will now result in Android loading the newly added Main.axml. Consider the landscape
version of the Main.axml file that contains the following code (for simplicity, this XML is similar to the default
portrait version of the code, but uses a different string in the TextView ):
Running this code and rotating the device from portrait to landscape demonstrates the new XML loading, as
shown below:
Drawable Resources
During rotation, Android treats drawable resources similarly to layout resources. In this case, the system gets the
drawables from the Resources/drawable and Resources/drawable-land folders, respectively.
For example, say the project includes an image named Monkey.png in the Resources/drawable folder, where the
drawable is referenced from an ImageView in XML like this:
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/monkey"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
Let's further assume that a different version of Monkey.png is included under Resources/drawable-land. Just
like with the layout files, when the device is rotated, the drawable changes for the given orientation, as shown
below:
Handling Rotation Programmatically
Sometimes we define layouts in code. This can happen for a variety of reasons, including technical limitations,
developer preference, etc. When we add controls programmatically, an application must manually account for
device orientation, which is handled automatically when we use XML resources.
Adding Controls in Code
To add controls programmatically, an application needs to perform the following steps:
Create a layout.
Set layout parameters.
Create controls.
Set control layout parameters.
Add controls to the layout.
Set the layout as the content view.
For example, consider a user interface consisting of a single TextView control added to a RelativeLayout , as
shown in the following code.
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// create a layout
var rl = new RelativeLayout (this);
This code creates an instance of a RelativeLayout class and sets its LayoutParameters property. The LayoutParams
class is Android's way of encapsulating how controls are positioned in a reusable way. Once an instance of a
layout is created, controls can be created and added to it. Controls also have LayoutParameters , such as the
TextView in this example. After the TextView is created, adding it to the RelativeLayout and setting the
RelativeLayout as the content view results in the application displaying the TextView as shown:
// create a layout
var rl = new RelativeLayout (this);
This code sets the TextView to be positioned 100 pixels from the top left of the screen, automatically animating to
the new layout, when rotated to landscape, as shown here:
Preventing Activity Restart
In addition to handling everything in OnCreate , an application can also prevent an Activity from being restarted
when the orientation changes by setting ConfigurationChanges in the ActivityAttribute as follows:
Now when the device is rotated, the Activity is not restarted. In order to manually handle the orientation change in
this case, an Activity can override the OnConfigurationChanged method and determine the orientation from the
Configuration object that is passed in, as in the new implementation of the Activity below:
if (newConfig.Orientation == Android.Content.Res.Orientation.Portrait) {
_tv.LayoutParameters = _layoutParamsPortrait;
_tv.Text = "Changed to portrait";
} else if (newConfig.Orientation == Android.Content.Res.Orientation.Landscape) {
_tv.LayoutParameters = _layoutParamsLandscape;
_tv.Text = "Changed to landscape";
}
}
}
Here the TextView's layout parameters are initialized for both landscape and portrait. Class variables hold the
parameters, along with the TextView itself, since the Activity will not be re-created when orientation changes. The
code still uses the surfaceOrientartion in OnCreate to set the initial layout for the TextView . After that,
OnConfigurationChanged handles all subsequent layout changes.
When we run the application, Android loads the user interface changes as device rotation occurs, and does not
restart the Activity.
Summary
This article covered how to use Android's built-in capabilities to work with rotation. First, it explained how to use
the Android resource system to create orientation aware applications. Then it presented how to add controls in
code as well as how to handle orientation changes manually.
Related Links
Rotation Demo (sample)
Activity Lifecycle
Handling Runtime Changes
Fast Screen Orientation Change
Android Audio
4/12/2018 • 10 minutes to read • Edit Online
The Android OS provides extensive support for multimedia, encompassing both audio and video. This guide
focuses on audio in Android and covers playing and recording audio using the built-in audio player and recorder
classes, as well as the low -level audio API. It also covers working with Audio events broadcast by other
applications, so that developers can build well-behaved applications.
Overview
Modern mobile devices have adopted functionality that formerly would have required dedicated pieces of
equipment – cameras, music players and video recorders. Because of this, multimedia frameworks have become a
first-class feature in mobile APIs.
Android provides extensive support for multimedia. This article examines working with audio in Android, and
covers the following topics
1. Playing Audio with MediaPlayer – Using the built-in MediaPlayer class to play audio, including local
audio files and streamed audio files with the AudioTrack class.
2. Recording Audio – Using the built-in MediaRecorder class to record audio.
3. Working with Audio Notifications – Using audio notifications to create well-behaved applications that
respond correctly to events (such as incoming phone calls) by suspending or canceling their audio outputs.
4. Working with Low-Level Audio – Playing audio using the AudioTrack class by writing directly to
memory buffers. Recording audio using the AudioRecord class and reading directly from memory buffers.
Requirements
This guide requires Android 2.0 (API level 5) or higher. Please note that debugging audio on Android must be
done on a device.
It is necessary to request the RECORD_AUDIO permissions in AndroidManifest.XML:
Playing Audio with the MediaPlayer Class
The simplest way to play audio in Android is with the built-in MediaPlayer class. MediaPlayer can play either local
or remote files by passing in the file path. However, MediaPlayer is very state-sensitive and calling one of its
methods in the wrong state will cause an exception to be thrown. It's important to interact with MediaPlayer in the
order described below to avoid errors.
Initializing and Playing
Playing audio with MediaPlayer requires the following sequence:
1. Instantiate a new MediaPlayer object.
2. Configure the file to play via the SetDataSource method.
3. Call the Prepare method to initialize the player.
4. Call the Start method to start the audio playing.
The code sample below illustrates this usage:
protected MediaPlayer player;
public void StartPlayer(String filePath)
{
if (player == null) {
player = new MediaPlayer();
} else {
player.Reset();
player.SetDataSource(filePath);
player.Prepare();
player.Start();
}
}
player.Pause();
To resume paused playback, call the Start method. This will resume from the paused location in the playback:
player.Start();
player.Stop();
When the player is no longer needed, the resources must be released by calling the Release method:
player.Release();
Stopping recording
To stop the recording, call the Stop method on the MediaRecorder :
recorder.Stop();
Cleaning up
Once the MediaRecorder has been stopped, call the Reset method to put it back into its idle state:
recorder.Reset();
When the MediaRecorder is no longer needed, its resources must be released by calling the Release method:
recorder.Release();
audioTrack.Play();
audioTrack.Write(audioBuffer, 0, audioBuffer.Length);
}
audioTrack.Pause();
audioTrack.Stop();
Cleanup
When the AudioTrack is no longer needed, its resources must be released by calling Release:
audioTrack.Release();
audRecorder.Stop();
Cleanup
When the AudioRecord object is no longer needed, calling its Release method releases all resources associated
with it:
audRecorder.Release();
Summary
The Android OS provides a powerful framework for playing, recording and managing audio. This article covered
how to play and record audio using the high-level MediaPlayer and MediaRecorder classes. Next, it explored how
to use audio notifications to share the audio resources of the device between different applications. Finally, it dealt
with how to playback and record audio using the low -level APIs, which interface directly with memory buffers.
Related Links
Working With Audio (sample)
Media Player
Media Recorder
Audio Manager
Audio Track
Audio Recorder
Notifications in Xamarin.Android
4/12/2018 • 2 minutes to read • Edit Online
Overview
This section explains how to implement notifications in Xamarin.Android. It describes the various UI elements of
an Android notification and discusses the API's involved with creating and displaying a notification.
Sections
Local Notifications In Android
This section explains how to implement local notifications in Xamarin.Android. It describes the various UI
elements of an Android notification and discuss the API's involved with creating and displaying a notification.
Walkthrough - Using Local Notifications in Xamarin.Android
This walkthrough covers how to use local notifications in a Xamarin.Android application. It demonstrates the
basics of creating and publishing a notification. When the user clicks on the notification in the notification drawer
it starts up a second Activity.
Related Links
Local Notifications (sample)
Remote Notifications (sample)
Local Notifications
7/25/2018 • 30 minutes to read • Edit Online
This section shows how to implement local notifications in Xamarin.Android. It explains the various UI elements
of an Android notification and discusses the API's involved with creating and displaying a notification.
To obtain details about the notification, the user can open the notification drawer (which expands each
notification icon to reveal notification content) and perform any actions associated with the notifications. The
following screen shot shows a notification drawer that corresponds to the notification area displayed above:
Base layouts are limited to 64 density-independent pixels (dp) in height. Android creates this basic notification
style by default.
Optionally, notifications can display a large icon that represents the application or the sender's photo. When a
large icon is used in a notification in Android 5.0 and later, the small notification icon is displayed as a badge over
the large icon:
Beginning with Android 5.0, notifications can also appear on the lockscreen:
The user can double-tap the lockscreen notification to unlock the device and jump to the app that originated that
notification, or swipe to dismiss the notification. Apps can set the visibility level of a notification to control what is
shown on the lockscreen, and users can choose whether to allow sensitive content to be shown in lockscreen
notifications.
Android 5.0 introduced a high-priority notification presentation format called Heads-up. Heads-up notifications
slide down from the top of the screen for a few seconds and then retreat back up to the notification area:
Heads-up notifications make it possible for the system UI to put important information in front of the user
without disrupting the state of the currently running activity.
Android includes support for notification metadata so that notifications can be sorted and displayed intelligently.
Notification metadata also controls how notifications are presented on the lockscreen and in Heads-up format.
Applications can set the following types of notification metadata:
Priority – The priority level determines how and when notifications are presented. For example, In
Android 5.0, high-priority notifications are displayed as Heads-up notifications.
Visibility – Specifies how much notification content is to be displayed when the notification appears on
the lockscreen.
Category – Informs the system how to handle the notification in various circumstances, such as when the
device is in Do not Disturb mode.
Note: Visibility and Category were introduced in Android 5.0 and are not available in earlier versions of
Android. Beginning with Android 8.0, notification channels are used to control how notifications are presented to
the user.
Expanded Layouts
Beginning with Android 4.1, notifications can be configured with expanded layout styles that allow the user to
expand the height of the notification to view more content. For example, the following example illustrates an
expanded layout notification in contracted mode:
Notification Creation
To create a notification in Android, you use the Notification.Builder class. Notification.Builder was introduced
in Android 3.0 to simplify the creation of notification objects. To create notifications that are compatible with
older versions of Android, you can use the NotificationCompat.Builder class instead of Notification.Builder
(see Compatibility later in this topic for more information about using NotificationCompat.Builder ).
Notification.Builder provides methods for setting the various options in a notification, such as:
The content, including the title, the message text, and the notification icon.
The style of the notification, such as Big Text, Inbox, or Image style.
The priority of the notification: minimum, low, default, high, or maximum.
The visibility of the notification on the lockscreen: public, private, or secret.
Category metadata that helps Android classify and filter the notification.
An optional intent that indicates an activity to launch when the notification is tapped.
After you set these options in the builder, you generate a notification object that contains the settings. To publish
the notification, you pass this notification object to the Notification Manager. Android provides the
NotificationManager class, which is responsible for publishing notifications and displaying them to the user. A
reference to this class can be obtained from any context, such as an activity or a service.
How to Generate a Notification
To generate a notification in Android, follow these steps:
1. Instantiate a Notification.Builder object.
2. Call various methods on the Notification.Builder object to set notification options.
3. Call the Build method of the Notification.Builder object to instantiate a notification object.
4. Call the Notify method of the notification manager to publish the notification.
You must provide at least the following information for each notification:
A small icon (24x24 dp in size)
A short title
The text of the notification
The following code example illustrates how to use Notification.Builder to generate a basic notification. Notice
that Notification.Builder methods support method chaining; that is, each method returns the builder object so
you can use the result of the last method call to invoke the next method call:
In this example, a new Notification.Builder object called builder is instantiated, the title and text of the
notification are set, and the notification icon is loaded from Resources/drawable/ic_notification.png. The call
to the notification builder's Build method creates a notification object with these settings. The next step is to call
the Notify method of the notification manager. To locate the notification manager, you call GetSystemService , as
shown above.
The Notify method accepts two parameters: the notification identifier and the notification object. The
notification identifier is a unique integer that identifies the notification to your application. In this example, the
notification identifier is set to zero (0); however, in a production application, you will want to give each
notification a unique identifier. Reusing the previous identifier value in a call to Notify causes the last
notification to be overwritten.
When this code runs on an Android 5.0 device, it generates a notification that looks like the following example:
The notification icon is displayed on the left hand side of the notification – this image of a circled “i” has an alpha
channel so that Android can draw a gray circular background behind it. You can also supply an icon without an
alpha channel. To display a photographic image as an icon, see Large Icon Format later in this topic.
The timestamp is set automatically, but you can override this setting by calling the SetWhen method of the
notification builder. For example, the following code example sets the timestamp to the current time:
builder.SetWhen (Java.Lang.JavaSystem.CurrentTimeMillis());
This call to SetDefaults will cause the device to play a sound when the notification is published. If you want the
device to vibrate rather than play a sound, you can pass NotificationDefaults.Vibrate to SetDefaults. If you
want the device to play a sound and vibrate the device, you can pass both flags to SetDefaults :
If you enable sound without specifying a sound to play, Android uses the default system notification sound.
However, you can change the sound that will be played by calling the notification builder's SetSound method.
For example, to play the alarm sound with your notification (instead of the default notification sound), you can
get the URI for the alarm sound from the RingtoneManager and pass it to SetSound :
builder.SetSound (RingtoneManager.GetDefaultUri(RingtoneType.Alarm));
Alternatively, you can use the system default ringtone sound for your notification:
builder.SetSound (RingtoneManager.GetDefaultUri(RingtoneType.Ringtone));
After you create a notification object, it's possible to set notification properties on the notification object (rather
than configure them in advance through Notification.Builder methods). For example, instead of calling the
SetDefaults method to enable vibration on a notification, you can directly modify the bit flag of the notification's
Defaults property:
// Turn on vibrate:
notification.Defaults |= NotificationDefaults.Vibrate;
This example causes the device to vibrate when the notification is published.
Updating a Notification
If you want to update the content of a notification after it has been published, you can reuse the existing
Notification.Builder object to create a new notification object and publish this notification with the identifier of
the last notification. For example:
In this example, the existing Notification.Builder object is used to create a new notification object with a
different title and message. The new notification object is published using the identifier of the previous
notification, and this updates the content of the previously-published notification:
The body of the previous notification is reused – only the title and the text of the notification changes while the
notification is displayed in the notification drawer. The title text changes from "Sample Notification" to "Updated
Notification" and the message text changes from "Hello World! This is my first notification!" to "Changed to this
message."
A notification remains visible until one of three things happens:
The user dismisses the notification (or taps Clear All).
The application makes a call to NotificationManager.Cancel , passing in the unique notification ID that was
assigned when the notification was published.
The application calls NotificationManager.CancelAll .
For more about updating Android notifications, see Modify a Notification.
Starting an Activity from a Notification
In Android, it's common for a notification to be associated with an action – an activity that's launched when the
user taps the notification. This activity can reside in another application or even in another task. To add an action
to a notification, you create a PendingIntent object and associate the PendingIntent with the notification. A
PendingIntent is a special type of intent that allows the recipient application to run a predefined piece of code
with the permissions of the sending application. When the user taps the notification, Android starts up the
activity specified by the PendingIntent .
The following code snippet illustrates how to create a notification with a PendingIntent that will launch the
activity of the originating app, MainActivity :
// Instantiate the builder and set notification elements, including pending intent:
Notification.Builder builder = new Notification.Builder(this)
.SetContentIntent (pendingIntent)
.SetContentTitle ("Sample Notification")
.SetContentText ("Hello World! This is my first action notification!")
.SetSmallIcon (Resource.Drawable.ic_notification);
Tapping this notification takes the user back to the originating activity.
In a production app, your app must handle the back stack when the user presses the Back button within the
notification activity (if you are not familiar with Android tasks and the back stack, see Tasks and Back Stack). In
most cases, navigating backward out of the notification activity should return the user out of the app and back to
Home screen. To manage the back stack, your app uses the TaskStackBuilder class to create a PendingIntent
with a back stack.
Another real-world consideration is that the originating activity may need to send data to the notification activity.
For example, the notification may indicate that a text message has arrived, and the notification activity (a
message viewing screen), requires the ID of the message to display the message to the user. The activity that
creates the PendingIntent can use the Intent.PutExtra method to add data (for example, a string) to the intent so
that this data is passed to the notification activity.
The following code sample illustrates how to use TaskStackBuilder to manage the back stack, and it includes an
example of how to send a single message string to a notification activity called SecondActivity :
// Setup an intent for SecondActivity:
Intent secondIntent = new Intent (this, typeof(SecondActivity));