Xamarin.Forms开发:如何从Xamarin.Droid向ViewModel传递数据
Hey there! Let's walk through the next steps to get your WiFi monitoring research app fully functional with Xamarin.Forms. You've already got a solid foundation laid out, so let's build on that:
Since you already have code to access WiFi networks, the next step is to set up continuous scanning and real-time result capture:
- First, register a broadcast receiver to listen for scan results updates. Here's a sample implementation:
[BroadcastReceiver(Enabled = true)] [IntentFilter(new[] { WifiManager.ScanResultsAvailableAction })] public class WifiScanReceiver : BroadcastReceiver { private readonly WifiManager _wifiManager; private readonly IWifiDataService _dataService; public WifiScanReceiver(WifiManager wifiManager, IWifiDataService dataService) { _wifiManager = wifiManager; _dataService = dataService; } public override void OnReceive(Context context, Intent intent) { if (intent.Action != WifiManager.ScanResultsAvailableAction) return; var scanResults = _wifiManager.ScanResults; foreach (var result in scanResults) { var wifiRecord = new WifiResearchModel { Ssid = result.Ssid, Bssid = result.Bssid, SignalStrength = ConvertSignalStrength(result.Level), Frequency = result.Frequency, // Add your custom research fields here ScanTimestamp = DateTime.UtcNow, DeviceId = Android.OS.Build.Serial, ResearchNotes = "Initial scan" // Example custom field }; _dataService.SaveWifiRecord(wifiRecord); } } // Convert raw signal level to a more readable percentage private int ConvertSignalStrength(int rawLevel) { return Math.Max(0, Math.Min(100, (rawLevel + 100) * 2)); } }
- Don't forget to add critical permissions to your
AndroidManifest.xml(and handle dynamic permissions for Android 6.0+):
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Note: Android requires location permissions to retrieve WiFi scan results, even if you don't need location data for your research.
For a lightweight, cross-platform solution, use SQLite.NET to store your WiFi data (including custom research fields):
- Install the
sqlite-net-pclNuGet package in your shared project. - Create a data model that includes both WiFi details and your custom fields:
public class WifiResearchModel { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Ssid { get; set; } public string Bssid { get; set; } public int SignalStrength { get; set; } public int Frequency { get; set; } // Custom research fields public DateTime ScanTimestamp { get; set; } public string DeviceId { get; set; } public string ResearchNotes { get; set; } public string StudyTag { get; set; } }
- Build a cross-platform data service interface and Android implementation:
// Shared interface public interface IWifiDataService { Task SaveWifiRecord(WifiResearchModel record); Task<List<WifiResearchModel>> GetAllRecords(); } // Android implementation public class WifiDataService : IWifiDataService { private readonly SQLiteConnection _dbConnection; public WifiDataService() { var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "wifi_research.db3"); _dbConnection = new SQLiteConnection(dbPath); _dbConnection.CreateTable<WifiResearchModel>(); } public Task SaveWifiRecord(WifiResearchModel record) { _dbConnection.InsertOrReplace(record); return Task.CompletedTask; } public Task<List<WifiResearchModel>> GetAllRecords() { return Task.FromResult(_dbConnection.Table<WifiResearchModel>().ToList()); } }
Connect your scanning logic to your existing ViewModel to let users start/stop scans and view data:
- Add scan control commands to your ViewModel:
public class MainViewModel : INotifyPropertyChanged { private readonly IWifiDataService _dataService; private readonly IWifiScanner _wifiScanner; public ICommand StartScanCommand { get; } public ICommand StopScanCommand { get; } public MainViewModel(IWifiDataService dataService, IWifiScanner wifiScanner) { _dataService = dataService; _wifiScanner = wifiScanner; StartScanCommand = new Command(InitiateScanning); StopScanCommand = new Command(HaltScanning); } private void InitiateScanning() { _wifiScanner.StartContinuousScan(); IsScanning = true; } private void HaltScanning() { _wifiScanner.StopContinuousScan(); IsScanning = false; } private bool _isScanning; public bool IsScanning { get => _isScanning; set { _isScanning = value; OnPropertyChanged(); } } // Implement INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
- Create a
IWifiScannerinterface (shared) and Android implementation to manage scanning intervals and receiver registration:
// Shared interface public interface IWifiScanner { void StartContinuousScan(); void StopContinuousScan(); } // Android implementation public class WifiScanner : IWifiScanner { private readonly WifiManager _wifiManager; private readonly WifiScanReceiver _scanReceiver; private Timer _scanTimer; public WifiScanner(WifiManager wifiManager, WifiScanReceiver scanReceiver) { _wifiManager = wifiManager; _scanReceiver = scanReceiver; } public void StartContinuousScan() { Application.Context.RegisterReceiver(_scanReceiver, new IntentFilter(WifiManager.ScanResultsAvailableAction)); // Trigger scan every 10 seconds (adjust as needed for your research) _scanTimer = new Timer(_ => _wifiManager.StartScan(), null, 0, 10000); } public void StopContinuousScan() { _scanTimer?.Dispose(); Application.Context.UnregisterReceiver(_scanReceiver); } }
- Verify permission flow on Android 6.0+ devices to ensure location permissions are granted before scanning starts.
- Optimize database performance: if scanning frequently, batch insert records instead of writing one at a time.
- Add a UI component (like a
CollectionView) to bind and display stored WiFi records for quick research validation.
内容的提问来源于stack exchange,提问作者Rui Silva

