반응형
* Android 28이상 31이하
1. 스캐너 SPP 모드 설정, 스캐너와 블루투스 페어링
2.AndroidManifest.xml 권한
<!-- AndroidManifest.xml Bluetooth 권한 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
3. MainActivity 권한 획득
private void CheckBluetoothPermissions()
{
if (CheckSelfPermission(Android.Manifest.Permission.Bluetooth) != Android.Content.PM.Permission.Granted ||
CheckSelfPermission(Android.Manifest.Permission.BluetoothAdmin) != Android.Content.PM.Permission.Granted ||
CheckSelfPermission(Android.Manifest.Permission.BluetoothConnect) != Android.Content.PM.Permission.Granted ||
CheckSelfPermission(Android.Manifest.Permission.BluetoothScan) != Android.Content.PM.Permission.Granted)
{
RequestPermissions(new string[]
{
Android.Manifest.Permission.Bluetooth,
Android.Manifest.Permission.BluetoothAdmin,
Android.Manifest.Permission.BluetoothConnect,
Android.Manifest.Permission.BluetoothScan
}, RequestBluetoothPermissionsId);
}
}
4. ContentPage 구현 샘플
private BluetoothAdapter _bluetoothAdapter;
private BluetoothSocket _bluetoothSocket;
private Stream _inputStream;
private Stream _outputStream;
private static readonly UUID _sppUUID = UUID.FromString("00001101-0000-1000-8000-00805F9B34FB");
private async void ContentPage_Loaded(object sender, EventArgs e)
{
//string userID = SessionHelper.LoadSavedUsername();
//ID.Text = userID;
//chkRemember.IsChecked = !string.IsNullOrEmpty(userID);
_bluetoothAdapter = BluetoothAdapter.DefaultAdapter;
if (_bluetoothAdapter == null)
{
await DisplayAlert("Error", "Bluetooth is not supported on this device.", "OK");
return;
}
await ConnectToDeviceAsync("EY-017P");
// Start a background task to continuously read data
StartReadingData();
}
private async void StartReadingData()
{
// Background task to continuously read data from the input stream
while (true)
{
try
{
if (_inputStream == null) break;
byte[] buffer = new byte[1024];
int bytes = await _inputStream.ReadAsync(buffer, 0, buffer.Length);
if (bytes > 0)
{
string data = Encoding.ASCII.GetString(buffer, 0, bytes);
// Handle the received data (e.g., update UI)
// For example, display the data in a label
// You might need to invoke this on the main thread if updating UI
await MainThread.InvokeOnMainThreadAsync(() =>
{
// Assume there's a Label named DataLabel to display the data
ID.Text = $"{data}";
//DisplayAlert("Data", data, "OK");
});
}
}
catch (Exception ex)
{
// Handle exception
await DisplayAlert("Error", $"Read failed: {ex.Message}", "OK");
}
}
}
private async Task ConnectToDeviceAsync(string deviceName)
{
var device = _bluetoothAdapter.BondedDevices.FirstOrDefault(d => d.Name == deviceName);
if (device == null)
{
await DisplayAlert("Error", "Device not found", "OK");
return;
}
try
{
_bluetoothSocket = device.CreateRfcommSocketToServiceRecord(_sppUUID);
// Ensure the socket is not already connected
if (_bluetoothSocket.IsConnected)
{
await DisplayAlert("Info", "Already connected", "OK");
return;
}
// Attempt to connect with a timeout
var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(10)); // 10 seconds timeout
try
{
await Task.Run(async () =>
{
await _bluetoothSocket.ConnectAsync();
}, cancellationTokenSource.Token);
_inputStream = _bluetoothSocket.InputStream;
_outputStream = _bluetoothSocket.OutputStream;
await DisplayAlert("Success", "Connected", "OK");
}
catch (OperationCanceledException)
{
await DisplayAlert("Error", "Connection attempt timed out.", "OK");
}
catch (Exception ex)
{
await DisplayAlert("Error", $"Connection failed: {ex.Message}", "OK");
}
}
catch (Exception ex)
{
await DisplayAlert("Error", $"Error during connection: {ex.Message}", "OK");
}
}