Following multiple forums and sites telling the same thing on how to discover Bluetooth devices (paired or unpaired) I wrote down this piece of code.
class MainActivity: Activity
{
BluetoothAdapter btAdapter;
static ArrayAdapter<string> newDevicesArrayAdapter;
public static List<string> mDeviceList = new List<string>();
DeviceDiscoveredReceiver receiver;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
receiver = new DeviceDiscoveredReceiver(this);
IntentFilter filter = new IntentFilter(BluetoothDevice.ActionFound);
RegisterReceiver(receiver, filter);
btAdapter = BluetoothAdapter.DefaultAdapter;
}
class DeviceDiscoveredReceiver : BroadcastReceiver
{
Activity mainActivity;
public DeviceDiscoveredReceiver(Activity activity)
{
this.mainActivity = activity;
}
public override void OnReceive(Context context, Intent intent)
{
String action = intent.Action;
if (BluetoothDevice.ActionFound.Equals(action))
{
BluetoothDevice device = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
mDeviceList.Add(device.Name + ";" + device.Address);
var path = Android.OS.Environment.ExternalStorageDirectory + Java.IO.File.Separator + "Download";
string filename = Path.Combine(path, "myfile.txt");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
using (StreamWriter objStreamWriter = new StreamWriter(filename, true))
{
objStreamWriter.WriteLine(mDeviceList.Last());
objStreamWriter.Close();
}
}
}
}
}
Here, the Activity class has a BroadcastReceiver class where any discovered Bluetooth device's Name with MAC address gets written down to a .txt file. I am very new to Xamarin and new to android and here are the things I am confused with:
I am wondering how can I get a list containing all the Bluetooth
devices?
How can I start the "get Bluetooth devices" event?
Am I missing something in the codes? because nothing happens when I
launch it inside my android smartphone.
My main goal here is to just start discovering the Bluetooth devices but how?
Ok, it was easy but as I was new, it took some time to get it around my head. I missed the SetContentView(Resources.Layout.Main) inside the OnCreate method so simply change the OnCreate method to this:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resources.Layout.Main); //add this line
receiver = new DeviceDiscoveredReceiver(this);
IntentFilter filter = new IntentFilter(BluetoothDevice.ActionFound);
RegisterReceiver(receiver, filter);
btAdapter = BluetoothAdapter.DefaultAdapter;
}
Related
Is there any possibility to open Contacts App in Xamarin IOS,
For android the below code worked for me.
var activity = Forms.Context as Activity;
var intent = new Intent(Intent.ActionInsert);
intent.SetType(ContactsContract.Contacts.ContentType);
activity.StartActivity(intent);
Where as for IOS I have't find any code can any one have solution for this.
Apple has released two new frameworks, Contacts and ContactsUI, that replace the existing Address Book and Address Book UI frameworks used by iOS 8 and earlier.
You could use these two frameworks to deal with all situation which involve contacts.
To make it clear, I create a simple app to show how to display contact app in ios.
you can open the contacts app with code like:
public override void ViewDidLoad()
{
base.ViewDidLoad();
picker1.TouchDown += Picker1_TouchDown;
}
private void Picker1_TouchDown(object sender, EventArgs e)
{ //create a picker
var picker = new CNContactPickerViewController();
//set the delegate
picker.Delegate = new ContactPickerDelegate();
//display picker
PresentViewController(picker, true, null);
}
The ContactPickerDelegate is what you need to create and used to respond to the user's interaction with the picker.
The code is like:
public class ContactPickerDelegate: CNContactPickerDelegate
{
#region Constructors
public ContactPickerDelegate ()
{
}
public ContactPickerDelegate (IntPtr handle) : base (handle)
{
}
#endregion
#region Override Methods
public override void ContactPickerDidCancel (CNContactPickerViewController picker)
{
Console.WriteLine ("User canceled picker");
}
public override void DidSelectContact (CNContactPickerViewController picker, CNContact contact)
{
Console.WriteLine ("Selected: {0}", contact);
}
public override void DidSelectContactProperty (CNContactPickerViewController picker, CNContactProperty contactProperty)
{
Console.WriteLine ("Selected Property: {0}", contactProperty);
}
#endregion
}
Screenshots:
For more information, you can refer to https://learn.microsoft.com/en-us/xamarin/ios/platform/contacts
The project is done in Visual Studio with Xamarin and targeted for Android.
In my simple project I have 1 activity (MainActivity). Here I create an instance of a Scanner object that will sit in background and listen for iBeacons. Once the scanner has been created I call a Start method on the scanner object.
In the constructor of the Scanner object, there will be setup an instance of a Listener object. This instance is called when ever a beacon is detected.
Cut short – my main activity makes an instance of a scanner object. On creation of the scanner object a listener object is created. This listener object will be activated when a beacon is detected.
In my MainActivity I have a multiline TextView. I want it to show the beacons found in the listener object.
What is the best way to pass this beacon ID (string) to the TextView in the main activity?
I’m new to programming in Android, so all the different concepts with blocks, intents and what have you, are a bit confusing. I would have thought it was straight forward passing data from a listener event to the TextView but this has proven more difficult then expected.
I don’t mind going slow – so please feel free to elaborate and consider me the novice I am :-D
UPDATE:
I have edited the code to make it as short as possible, and pasted it below. Hope this gives an idea.
[Activity(Label = "DeviceScanSample", MainLauncher = true, Icon = "#mipmap/icon")]
public class MainActivity : Activity
{
KontaktScanner scanner;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
// Initialize Scanner
scanner = new KontaktScanner(this);
// Button actions
startScanButton.Click += delegate
{
if (CheckPermission(Manifest.Permission.AccessCoarseLocation))
{
// Start devices scan
scanner.Start();
}
else
{
// Ask for permissions if needed
...
}
};
}
}
public class KontaktScanner : Java.Lang.Object, IOnServiceReadyListener
{
IProximityManager proximityManager;
public KontaktScanner(Context context)
{
// Set Space listener
proximityManager.SetSpaceListener(new KontaktSimpleSpaceListener());
}
public void Start()
{
proximityManager.Connect(this);
}
}
class KontaktSimpleSpaceListener : SimpleSpaceListener
{
public void OnRegionEntered(IBeaconRegion beaconRegion)
{
Log.Info(TAG, string.Format("Entered {0} region", beaconRegion.Identifier));
}
public void OnRegionAbandoned(IBeaconRegion beaconRegion)
{
Log.Info(TAG, string.Format("Abandoned {0} region", beaconRegion.Identifier));
}
}
Try something like this:
Pass the context here:
public KontaktScanner(Activity activity)
{
// Set Space listener
proximityManager.SetSpaceListener(new KontaktSimpleSpaceListener(activity));
}
Then:
class KontaktSimpleSpaceListener : SimpleSpaceListener
{
Activity context
public KontaktSimpleSpaceListener(Activity activity)
{
this.context = activity;
}
public void OnRegionEntered(IBeaconRegion beaconRegion)
{
Log.Info(TAG, string.Format("Entered {0} region", beaconRegion.Identifier));
MainActivity myActivity = (MainActivity) context;
myActivity.updateTextView("My Data");// pass the string here.
}
public void OnRegionAbandoned(IBeaconRegion beaconRegion)
{
Log.Info(TAG, string.Format("Abandoned {0} region", beaconRegion.Identifier));
MainActivity myActivity = (MainActivity) context;
myActivity.updateTextView("My another data");// pass the string here.
}
}
Then create method in MainActivity:
public void updateTextView(string s)
{
RunOnUiThread(() =>
{
yourTextView.Text = s;//set your TextView here
});
}
I have not checked the syntax but something like this should work.
I've just started looking into Xamarin and just can not to wrap around my head how to make multiple Activities have a reference same instance of service.
I am starting KeyPressedReceiver from MainActivity and start listening for power button being pressed.
When three click are being made, I am calling service method InitCancelActivity, which starts playing mp3 file and opens CancelActivity.
In CancelActivity there is a text field and a button. And when user press this button, I want the value from text field to be passes to the GeneralService method KillAlert.
The question is how to reference instance of GeneralService (which is already created) from CancelActivity, so I could call KillAlert?
And this part
if (_service == null)
_service = new GeneralService();
looks absolutely wrong. Should I instantiate it in MainActivity and pass to a KeyPressedReceiver constructor?
[Activity(Label = "TTTT", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
KeyPressedReceiver receiver;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
receiver = new KeyPressedReceiver();
RegisterReceiver(receiver, new IntentFilter(Intent.ActionScreenOn));
}
}
[BroadcastReceiver(Enabled = true)]
public class KeyPressedReceiver : BroadcastReceiver
{
private GeneralService _service;
private int _clicks = 0;
public override void OnReceive(Context context, Intent intent)
{
if (_service == null)
_service = new GeneralService();
_clicks++;
if (_clicks > 5)
{
_service.InitCancelActivity();
}
}
}
[Service(Name = "com.ff.GeneralService")]
public class GeneralService : Service {
private readonly Android.Media.MediaPlayer _player;
public GeneralService()
{
_player = new Android.Media.MediaPlayer();
}
public void RaiseAlert()
{
// start playing .mp3 file
}
public void KillAlert(string pass)
{
// stop playing .mp3 file
}
public void InitCancelActivity()
{
this.RaiseAlert();
var i = new Intent(this, typeof(CancelActivity));
i.SetFlags(ActivityFlags.NewTask);
this.StartActivity(i);
}
}
[Activity(Label = "CancelActivity")]
public class CancelActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.cancel);
this.FindViewById(Resource.Id.cancelButtonYes).Click += delegate
{
var password = this.FindViewById(Resource.Id.cancelPassword);
// call KillAlert method from GeneralServic
};
}
}
Create static GeneralService instance and use in Cancel Activity.
for example
[Service(Name = "com.ff.GeneralService")]
public class GeneralService : Service {
private readonly Android.Media.MediaPlayer _player;
public static generalService;
public GeneralService()
{
_player = new Android.Media.MediaPlayer();
generalService=this
}
public void RaiseAlert()
{
// start playing .mp3 file
}
public void KillAlert(string pass)
{
// stop playing .mp3 file
}
public void InitCancelActivity()
{
this.RaiseAlert();
var i = new Intent(this, typeof(CancelActivity));
i.SetFlags(ActivityFlags.NewTask);
this.StartActivity(i);
}
}
and use in CancelActivity like below example
[Activity(Label = "CancelActivity")]
public class CancelActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.cancel);
this.FindViewById(Resource.Id.cancelButtonYes).Click += delegate
{
var password = this.FindViewById(Resource.Id.cancelPassword);
// call KillAlert method from GeneralServic
GeneralService.generalService.KillAlert(password.TEXT);
};
}
}
today i started developing with C# and i tried to scan for a beacon.
This is how far i came..
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
BluetoothAdapter oBluetoothAdapter = BluetoothAdapter.DefaultAdapter;
BluetoothLeScanner oScanner = oBluetoothAdapter.BluetoothLeScanner;
ScanCallback oCallback;
if(!oBluetoothAdapter.IsEnabled)
{
StartActivity(new Intent(BluetoothAdapter.ActionRequestEnable));
}
else
{
oScanner.StartScan(oCallback);
}
}
The Problem is that i dont know how to use the Callback Parameter of the StartScan function. Can sombody please tell me how to use the callback right ?
On android the implementation would be something like this:
_Manager = (BluetoothManager)appContext.GetSystemService("bluetooth");
_Adapter = _Manager.Adapter;
_LeScanner = _Adapter.BluetoothLeScanner;
_BluetoothScanCallback = new BluetoothScanCallback();
Then when you start your scan it would be something like this:
_LeScanner.StartScan(_BluetoothScanCallback);
where BluetoothScanCallback would be implemented using something like:
public class BluetoothScanCallback : ScanCallback
{
public override void OnScanResult([GeneratedEnum] ScanCallbackType callbackType, ScanResult result)
{
base.OnScanResult(callbackType, result);
}
}
I am trying to create a simple app to get user coordinates on an Android phone using VS 2010 and Mono for Android. All samples seem to be in java which, as I'm not a java developer, is confusing. If anyone has some sample code using only C# it would be much appreciated.
You can create a listener by implementing the ILocationListener interface. This is a sample for an activity that also acts as a location listener (though it can be a separate class if you want too):
[Activity(Label = "Location Demo")]
public class LocationActivity : Activity, ILocationListener
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
var locationManager = (LocationManager)GetSystemService(LocationService);
var criteria = new Criteria { Accuracy = Accuracy.NoRequirement };
string bestProvider = locationManager.GetBestProvider(criteria, true);
locationManager.RequestLocationUpdates(bestProvider, 5000, 2, this);
}
public void OnLocationChanged(Location location)
{
}
public void OnProviderDisabled(string provider)
{
}
public void OnProviderEnabled(string provider)
{
}
public void OnStatusChanged(string provider, Availability status, Bundle extras)
{
}
}
I have a similar sample up here that reads in the coordinates and prints them to the screen.