2016-09-02 3 views
1

Я надеюсь, что кто-то может помочь мне в этом вопросе. Я пытаюсь использовать AltBeaconOrg, оболочку iBeacon с открытым исходным кодом, созданную для Xamarin.Использование AltBeacon в Xamarin

Проблема, с которой я сталкиваюсь, заключается в том, что слушатель реализован в сервисе следующим образом, он отлично работает.

[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() 
    { 

    } 
} 

Я получаю следующее сообщение об ошибке производства:

Не удалось активировать JNI ручки 0x7fefabe700 (key_handle 0x11c1ff5) из Java type 'md53c8887b34fc5ad8a1fb3519f652d3fea/DroidSensorService' как управляемый тип '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] в/Пользователи/строитель/данных/дорожки/3540/1cf254db/источник/monodroid/src/Mono.Android/src/Java.Interop/TypeManager.cs: 176 at (динамический метод-оболочка) System.Object: ac4a9174-05aa-4926-9a80-8a8455916649 (intptr, intptr, intptr, intptr, intptr , intptr)

Внутреннее исключение - это нечто вроде строк «Попытка вызвать виртуальный метод» android.content.Context ... »(Xamarin Studio отключает его).

Если я перемещаю строку, создающую экземпляр MyBeaconClass над вызовом Start(), приложение на телефоне падает без каких-либо исключений, возникающих в Xamarin Studio.

Я ценю, что этот код предназначался для работы непосредственно в классе Activity или Service, но было бы намного опереться, если бы я смог достичь этого, так как я бы поделился этой службой другими функциями.

Примечание: Я попытался использовать контекст, который был введен непосредственно, и Android.App.Application.Context напрямую.

Большое спасибо за чтение, Ричард

ответ

0

Ваш MyBeaconClass должен наследоваться от Java.Lang.Object, чтобы для JNI обертка должна быть создана Xamarin.Android поэтому вызовы Java маршалируются на C#. Помните, что вы имеете дело с двумя виртуальными машинами, которые должны быть соединены между собой:

public class MyBeaconClass : Java.Lang.Object, IRangeNotifier, IBeaconConsumer 
{ 
    ~~~ 
} 
0

Благодарим вас за ответ SushiHangover. К сожалению, ваше предложение не было ответом в этом случае, или, по крайней мере, не только. В итоге я реализовал решение в классе сервиса и назвал новую услугу с первой.

Спасибо,

Ричард

Смежные вопросы