Open-source project
dotnet/android-samples avatar
dotnet/android-samples

dotnet/android-samples, and the contribution contract behind a sample gallery

A collection of .NET for Android sample projects

2,214 stars3,913 forksC#MIT

At a glance

What is it?
This repository holds fourteen small applications that demonstrate individual Android API bindings from C#, and almost all of its README is not about the samples but about the rules for adding one: a screenshots folder, a YAML header with seven required keys, and a buildable project. Its release list, which is a feed of gallery entries from May 2020 rather than a release history, is the most revealing thing in the repository.
Who is it for?
Use this repository as a reference for how specific Android APIs surface through the .NET bindings, and take the contribution contract as a template if you maintain a sample gallery of your own, because the YAML front matter and the build requirement together are what stop a gallery rotting. Do not expect it to be a learning path or a set of current examples, since the sample list is a small hand-picked set and the last gallery entry was published in May 2020.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 20 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Fourteen samples, chosen for the APIs that are hard to find

The repository description is minimal, a collection of .NET for Android sample projects, and the README adds that they show usage of various Android API wrappers from C#, with individual samples downloadable from a sample gallery. So this is a reference set rather than a course, and the selection of what to include is the interesting design decision.

The top-level directories are the list: AIDLDemo, AccelerometerPlay, ActivityLifecycle, BackdropEffects, Button, HpkeEncryption, HttpRequestTimingInspector, LocalNotifications, PdfAnnotator, Phoneword, PopupMenuDemo, SwitchDemo, TextSwitcher and UpdateUsersProfile. Fourteen projects.

Read as a set, they are not a set of applications. There is no weather app and no to-do list. What there is, is the platform surface where a C# developer would not guess how the binding looks. AIDL is Android's interface description language for talking between processes, and its binding shape is not obvious. ActivityLifecycle is the callback sequence every Android developer already knows from Java and now has to recognise in C#. BackdropEffects is the window backdrop API, which is a specific platform feature with a specific shape. LocalNotifications and PopupMenuDemo and TextSwitcher and SwitchDemo are the widget and notification corners where the mapping from Android views to managed types is least obvious. PdfAnnotator is document annotation rather than document display.

One entry stands out and deserves its own note. HpkeEncryption is a sample for Hybrid Public Key Encryption, the scheme that underpins key establishment in modern TLS and exists precisely to allow a transition to post-quantum algorithms. Its presence tells you the binding set covers current cryptographic primitives, not just the historical ones, and it is a much better signal about the state of the platform layer than a hello-world application would be.

A few of the names also date the repository. Phoneword and Button are among the oldest names in the sample lineage, from the era when a sample set had a phone-number-to-word converter and a button. They are still here, which tells you the set was curated by keeping what existed rather than by designing afresh.

There is also a top-level `Screenshots/` directory, which is separate from the per-sample requirement discussed below and is presumably for this README rather than for any one project.

The release list is a gallery feed from May 2020, not a release history

The three most recent releases in this repository are numbered 147894, 147893 and 147497, and they are titled Xamarin.Android - SynchronizedNotifications, Xamarin.Android - TvLeanback and Xamarin.Android - Notepad Sample with Mono.Sqlite. They were all published in May 2020.

Read that carefully, because it is not a software release history and interpreting it as one leads to wrong conclusions. These are sequential identifiers, roughly 147,000 of them, generated when a sample is published to the gallery. The number is an identifier in Microsoft's sample infrastructure, not a version of anything in this repository.

What the list tells you is when samples were last fed into the gallery, which is May 2020. That is over six years before the last push to the repository, which was on 2026-09-09. So the repository is being touched while the gallery feed is not being updated, and the two facts point in different directions.

The titles point somewhere else again. All three say Xamarin.Android, using the product's former name, in a repository whose samples are for .NET for Android. The naming convention in the contribution contract reinforces it, requiring every sample's name to begin with a specific string. So a reader arriving through the gallery sees Xamarin branding on samples that target the current product, and the inconsistency has persisted long enough that the README's own examples still use it.

None of this means the samples are broken. A sample that demonstrates a stable platform API is as correct in 2026 as it was in 2020, and several of the APIs here, activity lifecycle and notification handling among them, are among the most stable in the Android SDK. What it does mean is that this repository's visible activity is not a reliable signal of currency, and that anyone using the gallery as a discovery mechanism is looking at a feed that stopped in 2020.

The repository's own last push is the better freshness signal, and it is recent. Treat the samples as maintained and the gallery as frozen.

The YAML front matter, and why a name field has to start with a fixed string

The largest section of this README is the sample requirements, and the second of the three requirements is the one that reveals the whole design.

Each sample needs a `README.md` that begins with a YAML header delimited by three dashes, carrying seven pieces of metadata. The names are given with constraints, and the example is provided in full:

yaml
---
name: .NET for Android - Android P Mini Demo
description: "Demonstrates new display cutout and image notification features (Android Pie)"
page_type: sample
languages:
- csharp
products:
- dotnet-android
urlFragment: android-p-androidpminidemo
---

The constraints are: the name must begin with a fixed prefix, the description must be brief, under 150 characters, and appears in the sample code browser search, `page_type` must be the literal string `sample`, `languages` lists the languages used, `products` should be the project's own identifier for every sample in this repository, and `urlFragment` should be an all-lowercase path with directory separators replaced by dashes and no other punctuation. There is also a note that the header must be valid YAML, so characters in the name or description will require the whole string to be quoted.

Why would a sample need a name that starts with a fixed string? Because the sample galleries are powered by the GitHub sample repositories, as the README says. The front matter is the only thing the gallery's indexer sees, and the prefix is how a product claims its samples inside a shared catalogue that also contains other products' samples. This is why a separate MAUI gallery link exists in the same README: same infrastructure, different product identifier.

That architecture explains the whole contribution contract. A gallery that indexes repository files is a gallery that goes stale the moment a repository stops conforming, so the contract is unusually strict. The `urlFragment` rule exists because the gallery builds a URL from the path and any punctuation produces a broken link. The `description` length limit exists because the field renders in a search result. The `page_type` literal exists because the indexer probably switches on it. The YAML validity note exists because a contributor will hit a parse error rather than a validation error.

This is unglamorous and it is exactly right. The alternative, a sample list maintained in a documentation site, requires somebody to remember to update it.

Screenshots as a build requirement, and a two-line-per-sample cost

The other two requirements are as concrete. A sample needs a folder called `Screenshots` containing at least one screenshot of the sample on each platform, with a preference for one per page or per major piece of functionality. And it needs a buildable solution and project file, with the requirement stated in the imperative that the project must build and have the appropriate project scaffolding.

The screenshots requirement is the unusual one, and it is not decoration. A gallery entry is a card with a picture, and a card with no picture does not get clicked. So the screenshots are not documentation for the sample, they are the sample's entry in an index. That reframing explains the preference for one per page: a sample with five screens should contribute five images, because each image is a separate thing a browser can show someone deciding whether to click.

It also explains why the requirement is stated as a build requirement rather than a documentation one. The project must build, and it must have the solution and project files, which is what makes it cloneable and runnable by whoever clicks. A sample that does not compile is worse than no sample, because it occupies an index slot and produces a bug report instead of a working reference.

So the full cost of adding a sample is roughly: write the application, make it build, add a screenshots folder, write a README with a precisely shaped YAML header, and open an issue proposing it before you do any of that. The README says submissions should start by creating an issue with a proposal, which means the maintainers want to steer what gets added rather than accept a directory and review it afterwards. For a curated set of fourteen, that is the right process.

What a reader gets for that cost is fourteen curated, buildable, illustrated references for the awkward parts of the platform surface, each indexed in a search that people actually use to find samples. It is a small amount of content doing a disproportionate amount of work.

The seven migration steps, and why removing manifest attributes is step three

Two sections of the README, one under a heading about tips for migration and one about porting, contain almost the same seven-step list, with the second noting that it was copied from a branch of the same repository. That duplication is a small editorial artefact and it tells you the list has been stable long enough to be copied around inside one file.

The goal is stated as fully modernising the template for .NET and C# 11, and the method is to compare against a freshly generated template of the same name from `dotnet new android`. Then seven steps, and the order matters less than the content.

If the root namespace does not match the project name, the existing code may not compile without setting it explicitly, in the .csproj, with a line like this:

xml
<RootNamespace>Xamarin.AidlDemo</RootNamespace>

Then update dependencies and packages. Then, and this is the step with the most bite, remove `android:versionCode`, `android:versionName`, the `package` attribute, the `uses-sdk` element, and the application label attribute, because all of those are now defined in the .csproj file. That is the structural heart of the migration: in the classic Xamarin layout those facts lived in the Android manifest, and in the .NET layout they live in the project file, so leaving them in place produces a file with two sources of truth.

Then remove unused using statements, since implicit usings are enabled. Then convert namespace declarations to C# 10 file-scoped namespaces, which is a mechanical change that a tool does better than a person. Then build, fix the nullable reference type warnings that appear because nullable is enabled. Then run the app and confirm the sample still works, which is the step everybody skips and the one the README does not.

The list is short enough to memorise and specific enough to follow, and it points at a second, longer collection of migration tips on the legacy Xamarin wiki for cases it does not cover.

git mv before you port, which is the most useful thing in this README

The porting section contains a procedure that has nothing to do with .NET and everything to do with not destroying a decade of history, and it is the part of this README most worth copying regardless of platform.

The problem it solves is specific. Many legacy samples have their project, source and resource files sitting in the same directory as the README, the screenshots folder and other files not directly related to the sample code. .NET defaults to importing every file in the project directory as if it were part of the project, so porting in place immediately turns the README and the screenshots into project content.

The naive fix is to move the code into a subdirectory. The README's instruction is more careful than that, and the sequence is the whole point.

Create the new subdirectory first, named after the solution file without its extension. Then move the relevant files and directories into it, which the README lists as source code, project files, the `Properties` and `Resources` directories, using `git mv`. Then modify the solution file to update the project paths. Then commit those changes, and the README is emphatic that this ensures further changes will preserve commit history.

Why the ordering matters is the point. If you move files and change the project file in one commit, Git treats it as a rewrite: the history of every moved file is severed, and blame on a ten-year-old sample becomes impossible. If you move and commit, then change the project file and commit again, Git follows the rename, and every subsequent commit is attributed to the original author and the original line. The second commit is the one that does the real work, and it is only possible because the first one was kept separate.

The rest of the procedure follows. After the move, create a new project file with `dotnet new android -n SampleName` in a separate directory, copy the necessary package and project references from the old project, update them as needed, and only then replace the old project file with the new one. The sequence is move, commit, generate, copy references, replace.

This is a general technique. Any migration that changes a project's file layout should do the layout change as its own commit before doing anything else, and the cost of remembering that is a single extra commit.

Licence, code of conduct, and what this repository is not

The licence is the MIT License, and the README states it in a slightly unusual way that is worth reading accurately: .NET, including the android-samples repository, is licensed under the MIT licence. So the grant is stated at the level of the whole .NET project rather than this repository alone, which is a reminder that the samples are part of a larger product with its own terms rather than an independent body of work.

The code of conduct is the Contributor Covenant, adopted with a pointer to the .NET Foundation's version of it. That is boilerplate in the best sense: a repository with a public contribution process documents the expected behaviour rather than leaving it to inference.

What this repository is not is worth being clear about, because the name suggests otherwise. It is not a tutorial. There is no progression, no difficulty ordering and no narrative connecting one sample to the next. It is not a set of current examples either, since the gallery feed stopped in 2020 and the most recent release entries are from May of that year. And it is not a MAUI sample set, despite the MAUI installation link and the separate MAUI gallery in the README, because the product identifier required in every sample's front matter is specific to this project.

It is a curated reference set with a machine-readable index contract, which is a different and more durable thing. The samples are small on purpose, because a sample exists to demonstrate one API surface, and the curation principle visible in the list is that the awkward APIs get samples and the obvious ones do not.

For a reader, the practical guidance is short. If you are looking for how a specific Android API surfaces in C#, check whether it has a sample here and read that project. If you are porting an old Xamarin application, the seven-step list and the file-move procedure are both directly applicable and both short. If you maintain a sample gallery of your own, the front matter schema and the build requirement are the two things that keep one indexed correctly, and they are the parts of this README that generalise beyond .NET.

Editorial conclusion

Use this repository as a reference for how specific Android APIs surface through the .NET bindings, and take the contribution contract as a template if you maintain a sample gallery of your own, because the YAML front matter and the build requirement together are what stop a gallery rotting. Do not expect it to be a learning path or a set of current examples, since the sample list is a small hand-picked set and the last gallery entry was published in May 2020. Verify first by opening a sample directory and building it against the workload you have installed, checking that the sample list at the top level still reflects what the repository contains, and reading the migration tips before porting anything, since the procedure assumes a legacy Xamarin layout with mixed content directories.

Frequently asked questions

What is in the dotnet/android-samples repository?

A collection of .NET for Android sample projects showing usage of various Android API wrappers from C#. The top level has fourteen sample directories: AIDLDemo, AccelerometerPlay, ActivityLifecycle, BackdropEffects, Button, HpkeEncryption, HttpRequestTimingInspector, LocalNotifications, PdfAnnotator, Phoneword, PopupMenuDemo, SwitchDemo, TextSwitcher and UpdateUsersProfile.

What does a sample have to include to be accepted?

Three things. A Screenshots folder with at least one screenshot per platform, a README.md beginning with a YAML header carrying name, description, page_type, languages, products and urlFragment, and a buildable solution with a .csproj file. Submissions should start by creating an issue with a proposal rather than opening a pull request directly.

Why does each sample's README need a YAML header?

Because the sample galleries are powered by the GitHub sample repositories, so the front matter is what the gallery indexer reads. That is why the name field must begin with a fixed prefix, why page_type must be the literal string sample, why description is capped at 150 characters, and why the urlFragment must be an all-lowercase path with dashes and no other punctuation.

What are the steps for modernising an old Xamarin sample for .NET?

Compare against a dotnet new android template of the same name, set the root namespace in the .csproj if it does not match the project name, update dependencies, remove the manifest attributes now defined in the project file such as versionCode, versionName, package, uses-sdk and the application label, remove unused usings because implicit usings are enabled, convert to C# 10 file-scoped namespaces, then build with nullable enabled and run the app.

How do I preserve git history when porting a sample?

Create a subdirectory named after the solution file without its extension, move the code, project files, Properties and Resources directories into it with git mv, update the solution file's project paths, and commit that move on its own. Only then create the new project file with dotnet new android and copy the references across, so that the rename is recorded before the project file changes.

When was the last entry added to the dotnet/android-samples release list?

The three most recent are 147894, 147893 and 147497, all published in May 2020 and all titled with an Xamarin.Android prefix. Those are sequential gallery identifiers for published samples rather than software versions, so the list is a feed of gallery entries and it stopped in 2020, while the repository's own last push was on 2026-09-09.

Official sources

  1. dotnet/android-samples on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dotnet-android-samples.svg)](https://hysenlabs.com/projects/dotnet-android-samples)