在Xamarin中使用AltBeacon
本文关键字:AltBeacon Xamarin | 更新日期: 2023-09-27 18:05:10
我希望有人能指导我这个问题。我正在尝试使用AltBeaconOrg,一个为Xamarin创建的开源Android iBeacon包装器。
我面临的问题是,当侦听器在服务中实现时,它工作得很好。
[Service]
[IntentFilter(new [] {"com.testapp.SensorService"})]
public class DroidSensorService : Service, IRangeNotifier, IBeaconConsumer
{
static readonly string Tag = typeof(DroidSensorService).Name;
private IBinder binder;
private Region _region;
private BeaconManager _beaconManager;
public DroidSensorService()
{
}
public override void OnCreate()
{
base.OnCreate();
Log.Debug(Tag, "OnCreate called in the Service");
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
Log.Debug(Tag, "Service started");
_beaconManager = BeaconManager.GetInstanceForApplication(ApplicationContext);
_beaconManager.Bind(this);
return StartCommandResult.Sticky;
}
public override IBinder OnBind(Intent intent)
{
binder = new DroidSensorServiceBinder(this);
return binder;
}
public override void OnDestroy()
{
base.OnDestroy();
Log.Debug(Tag, "Service has been terminated");
}
public void OnBeaconServiceConnect()
{
_beaconManager.SetForegroundBetweenScanPeriod(5000);
_beaconManager.SetRangeNotifier(this);
_region = new AltBeaconOrg.BoundBeacon.Region("Region", null, null, null);
_beaconManager.StartRangingBeaconsInRegion(_region);
}
public void DidRangeBeaconsInRegion(ICollection<Beacon> beacons, Region region)
{
}
}
当发现新的信标时,会引发DidRangeBeacons事件。
如果我使用一个类来包装信标代码来实现解决方案,例如:
[Service]
[IntentFilter(new [] {"com.testapp.SensorService"})]
public class DroidSensorService : Service, ISensorService
{
static readonly string Tag = typeof(DroidSensorService).Name;
private IBinder binder;
private MyBeaconClass _myBeaconClass;
public DroidSensorService()
{
_myBeaconClass = new MyBeaconClass(this);
}
public override void OnCreate()
{
base.OnCreate();
Log.Debug(Tag, "OnCreate called in the Service");
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
Log.Debug(Tag, "Service started");
_myBeaconClass.Start();
return StartCommandResult.Sticky;
}
public override IBinder OnBind(Intent intent)
{
binder = new DroidSensorServiceBinder(this);
return binder;
}
public override void OnDestroy()
{
base.OnDestroy();
Log.Debug(Tag, "Sensor Service has been terminated");
}
}
public class MyBeaconClass : IRangeNotifier, IBeaconConsumer
{
private Context _context;
private Region _region;
private BeaconManager _beaconManager;
public MyBeaconClass(Context context)
{
_context = context;
}
public Context ApplicationContext
{
get
{
return _context.ApplicationContext;
}
}
public IntPtr Handle
{
get
{
return _context.Handle;
}
}
public void Start()
{
_beaconManager = BeaconManager.GetInstanceForApplication(_context.ApplicationContext);
_beaconManager.Bind(this);
}
public void OnBeaconServiceConnect()
{
_beaconManager.SetForegroundBetweenScanPeriod(5000);
_beaconManager.SetRangeNotifier(this);
_region = new AltBeaconOrg.BoundBeacon.Region("Region", null, null, null);
_beaconManager.StartRangingBeaconsInRegion(_region);
}
public void DidRangeBeaconsInRegion(ICollection<Beacon> beacons, Region region)
{
}
public bool BindService(Intent intent, IServiceConnection serviceConnection, [GeneratedEnum] Bind flags)
{
return _context.BindService(intent, serviceConnection, flags);
}
public void UnbindService(IServiceConnection serviceConnection)
{
_context.UnbindService(serviceConnection);
}
public void Dispose()
{
}
}
我得到以下错误:
无法激活Java类型'md53c8887b34fc5ad8a1fb3519f652d3fea/DroidSensorService'的JNI Handle 0x7fefabe700 (key_handle 0x11c1ff5)作为托管类型'Sensors.Droid.Classes.DroidSensorService'.
在Java.Interop.TypeManager。n_Activate (IntPtr jnienv, IntPtr jclass, IntPtr typename_ptr, IntPtr signature_ptr, IntPtr jobject, IntPtr parameters_ptr) [0x00180] in/Users/builder/data/lanes/3540/1cf254db/source/monodroid/src/Mono.Android/src/Java.Interop/TypeManager.cs:176at(包装器动态方法)系统。对象:ac4a9174 - 05 - aa - 4926 - 9 - a80 - 8 a8455916649 (intptr、intptr intptr, intptr, intptr, intptr)
内部异常类似于"尝试调用虚拟方法'android.content.Context…"(Xamarin Studio把它剪掉了)
如果我把实例化MyBeaconClass的行移到Start()调用的上面,手机上的应用程序就会崩溃,Xamarin Studio也不会引发异常。
我很欣赏这段代码的目的是直接在Activity或Service类中工作,但如果我能够实现这一点,那将会整洁得多,因为我将与其他功能共享这个服务。
注意:我已经尝试使用直接注入的上下文和Android.App.Application.Context。
非常感谢您的阅读。理查德。
您的MyBeaconClass
必须从Java.Lang.Object
继承,以便由Xamarin.Android
创建JNI包装器,以便Java调用被封送到c#。请记住,您正在处理两个必须桥接的vm:
public class MyBeaconClass : Java.Lang.Object, IRangeNotifier, IBeaconConsumer
{
~~~
}
谢谢你的回答SushiHangover。遗憾的是,你的建议不是这个问题的答案,至少不是唯一的答案。最后,我在一个服务类中实现了解决方案,并从第一个服务类中调用新服务。
谢谢,理查德