native-android-csharp/DemoAndroid/Activities/WakeOnLanActivity.cs

128 lines
3.7 KiB
C#
Raw Permalink Normal View History

2024-06-19 14:16:38 +00:00
using System.Net;
using System.Net.Sockets;
2024-06-19 17:02:44 +00:00
using Android.Content;
using Android.Hardware.Biometrics;
using Android.OS;
using Java.Lang;
2024-06-19 14:16:38 +00:00
namespace DemoAndroid;
2024-06-19 17:24:15 +00:00
[Activity(Label = "@string/app_name", MainLauncher = true, Theme = "@style/Default")]
2024-06-19 14:16:38 +00:00
public class WakeOnLanActivity : Activity
{
2024-06-19 17:02:44 +00:00
private const int BiometricStrong = 0x0000000f;
private const int BiometricWeak = 0x000000ff;
private const int DeviceCredential = 0x00008000;
private bool _authenticated = false;
2024-06-19 14:16:38 +00:00
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
SetContentView(Resource.Layout.activity_wakeonlan);
var button = FindViewById<Button>(Resource.Id.btnWakeOnLan);
button.Click += (sender, args) =>
{
2024-06-19 17:20:50 +00:00
OnlyAuthenticated(WakePc);
2024-06-19 14:16:38 +00:00
};
}
2024-06-19 17:20:50 +00:00
private void OnlyAuthenticated(Action action)
2024-06-19 17:02:44 +00:00
{
2024-06-19 17:20:50 +00:00
if (!_authenticated)
{
var callback = new BiometricCallback(this, () =>
{
_authenticated = true;
action();
});
var prompt = new BiometricPrompt.Builder(this)
.SetNegativeButton("Annuleren", MainExecutor, callback)
.SetTitle("Bewijs jezelf met je vingerafdruk")
.SetSubtitle("We willen zeker weten dat je niet Colinde bent")
.SetAllowedAuthenticators(BiometricStrong)
.Build();
2024-06-19 17:02:44 +00:00
2024-06-19 17:20:50 +00:00
var cancellation = new CancellationSignal();
2024-06-19 17:02:44 +00:00
2024-06-19 17:20:50 +00:00
prompt.Authenticate(cancellation, MainExecutor, callback);
return;
}
2024-06-19 17:02:44 +00:00
2024-06-19 17:20:50 +00:00
action();
2024-06-19 17:02:44 +00:00
}
2024-06-19 14:16:38 +00:00
private void WakePc()
{
2024-06-19 17:02:44 +00:00
byte[] macAddress = [0x2c, 0x4d, 0x54, 0x4d, 0x10, 0x0f];
var magicPacket = new byte[102];
2024-06-19 14:16:38 +00:00
// Fill first 6 bytes with 0xFF
2024-06-19 17:02:44 +00:00
for (var i = 0; i < 6; i++)
2024-06-19 14:16:38 +00:00
{
magicPacket[i] = 0xFF;
}
// Repeat MAC address 16 times
2024-06-19 17:02:44 +00:00
for (var i = 1; i <= 16; i++)
2024-06-19 14:16:38 +00:00
{
2024-06-19 17:02:44 +00:00
for (var j = 0; j < 6; j++)
2024-06-19 14:16:38 +00:00
{
magicPacket[i * 6 + j] = macAddress[j];
}
}
using var client = new UdpClient();
client.EnableBroadcast = true;
var endpoint = new IPEndPoint(IPAddress.Broadcast, 9); // 255.255.255.255 port 9
2024-06-19 17:02:44 +00:00
for (var i = 0; i < 5; i++)
2024-06-19 14:16:38 +00:00
{
// Try 5 times
client.Send(magicPacket, magicPacket.Length, endpoint);
}
2024-06-19 17:02:44 +00:00
2024-06-19 17:20:50 +00:00
Toast.MakeText(this, "Computer started!", ToastLength.Long)!.Show();
}
}
/// <summary>
/// Biometric authentication callbacks
/// https://developer.android.com/identity/sign-in/biometric-auth#java
/// </summary>
class BiometricCallback : BiometricPrompt.AuthenticationCallback, IDialogInterfaceOnClickListener
{
private Context _context;
private readonly Action _onSuccess;
public BiometricCallback(Context context, Action onSuccess)
{
_context = context;
_onSuccess = onSuccess;
}
public override void OnAuthenticationError(BiometricErrorCode errorCode, ICharSequence? errString)
{
Toast.MakeText(_context, $"Authenticatie mislukt: {errorCode}, {errString?.ToString()}", ToastLength.Long)!.Show();
}
public override void OnAuthenticationSucceeded(BiometricPrompt.AuthenticationResult? result)
{
Toast.MakeText(_context, "Authentication succeeded!", ToastLength.Short)!.Show();
_onSuccess();
}
public override void OnAuthenticationFailed()
{
Toast.MakeText(_context, "Authenticatie mislukt!", ToastLength.Long)!.Show();
}
public void OnClick(IDialogInterface? dialog, int which)
{
Toast.MakeText(_context, "Geannuleerd!", ToastLength.Long)!.Show();
2024-06-19 14:16:38 +00:00
}
}