Skip to content
Shiny .NET v4.1 BETA - Linux, MacOS, & Blazor Support! TONS of new features and improvements across the board. Check It Out

Motion Activity

Frameworks
.NET MAUI
Operating Systems
Android
iOS

Shiny provides cross-platform motion activity recognition, allowing your app to detect whether the user is walking, running, cycling, driving, or stationary.

  • On iOS, this uses CMMotionActivityManager from the CoreMotion framework.
  • On Android, this uses Google Play Services Activity Recognition API.

Register motion activity recognition in MauiProgram.cs:

// Without a background delegate
services.AddMotionActivity();
// With a background delegate for processing activity changes in the background
services.AddMotionActivity<MyMotionActivityDelegate>();

iOS: Add to Info.plist:

<key>NSMotionUsageDescription</key>
<string>This app uses motion activity to detect your movement type</string>

Android: The ACTIVITY_RECOGNITION permission is required and will be requested automatically via RequestAccess().

Use WhenReading() to observe activity changes in the UI:

public class MyViewModel : IDisposable
{
readonly IMotionActivityManager activityManager;
IDisposable? sub;
public MyViewModel(IMotionActivityManager activityManager)
{
this.activityManager = activityManager;
}
public async Task Start()
{
var access = await this.activityManager.RequestAccess();
if (access != AccessState.Available)
return;
await this.activityManager.StartListener();
this.sub = this.activityManager
.WhenReading()
.Subscribe(reading =>
{
// reading.Activity → MotionActivityType (Walking, Running, Cycling, etc.)
// reading.Confidence → MotionActivityConfidence (Low, Medium, High)
// reading.Timestamp → DateTimeOffset
});
}
public async Task Stop()
{
this.sub?.Dispose();
await this.activityManager.StopListener();
}
public void Dispose() => this.sub?.Dispose();
}

Implement IMotionActivityDelegate for processing activity changes even when the app is backgrounded:

public class MyMotionActivityDelegate : IMotionActivityDelegate
{
readonly ILogger<MyMotionActivityDelegate> logger;
public MyMotionActivityDelegate(ILogger<MyMotionActivityDelegate> logger)
{
this.logger = logger;
}
public Task OnReading(MotionActivityReading reading)
{
this.logger.LogInformation(
"Activity: {Activity}, Confidence: {Confidence}",
reading.Activity,
reading.Confidence
);
return Task.CompletedTask;
}
}

Register the delegate:

services.AddMotionActivity<MyMotionActivityDelegate>();
MemberReturn TypeDescription
IsListeningboolWhether the manager is currently listening
GetCurrentStatus()AccessStateGet current permission status without prompting
RequestAccess()Task<AccessState>Request permission to use motion activity
GetLastReading()IObservable<MotionActivityReading?>Get the last known reading
WhenReading()IObservable<MotionActivityReading>Observable stream of activity changes
StartListener()TaskStart listening for activity changes
StopListener()TaskStop listening for activity changes
ValueDescription
UnknownActivity could not be determined
StationaryDevice is not moving
WalkingUser is walking
RunningUser is running
CyclingUser is cycling
AutomotiveUser is in a vehicle
ValueDescription
LowLow confidence in the detected activity
MediumMedium confidence
HighHigh confidence
claude plugin marketplace add shinyorg/skills
claude plugin install shiny-client@shiny
copilot plugin marketplace add https://github.com/shinyorg/skills
copilot plugin install shiny-client@shiny
View shiny-client Plugin