AltBeacon DidEnterRegion не сработал - PullRequest
0 голосов
/ 18 марта 2020

В моем приложении xamarin android AltBeacon DidEnterRegion не срабатывает, если для атрибута MainLauncher установлено значение false для MainActivity. Поскольку у меня есть SplashActivity для отображения экрана spla sh, я должен сделать SplashActivity своим MainLauncher. Я использую службу переднего плана для обнаружения iBeacon.

Код класса моего приложения:

 namespace AltBeaconLibrarySample.Droid
 {
 #if DEBUG
     [Application(Debuggable = true)]
 #else
     [Application(Debuggable = false)]
 #endif
     public class MainApplication : Application, IBootstrapNotifier
     {
         private RegionBootstrap regionBootstrap;
         private BackgroundPowerSaver backgroundPowerSaver;
         Region _generalRegion;
         public bool IsStartedRanging { get; set; }
         string foregroundServiceChannelId = "foregroundService";
         string channelName = "ForegroundService";
         int pendingIntentId = 1;

         public MainApplication(IntPtr handle, JniHandleOwnership transer)
           : base(handle, transer)
         {
         }

         public void DidDetermineStateForRegion(int p0, Region p1)
         {
         }

         public void DidEnterRegion(Region p0)
         {
             var beaconService = Xamarin.Forms.DependencyService.Get<IAltBeaconService>();
             if (!IsStartedRanging)
             {
                 beaconService.StartRanging();
                 IsStartedRanging = true;
             }
         }

         public void DidExitRegion(Region p0)
         {
             var beaconService = Xamarin.Forms.DependencyService.Get<IAltBeaconService>();
             if (IsStartedRanging)
             {
                 beaconService.StopRanging();
                 IsStartedRanging = false;
             }
             beaconService.DidExitRegion();
         }

         public override void OnCreate()
         {
             base.OnCreate();
             CrossCurrentActivity.Current.Init(this);

             BeaconManager bm = BeaconManager.GetInstanceForApplication(this);
             CreateNotificationChannel();
             bm.EnableForegroundServiceScanning(GetForegroundServiceNotification(), 456);
             bm.SetEnableScheduledScanJobs(false);

             _generalRegion = new Org.Altbeacon.Beacon.Region/* AltBeaconOrg.BoundBeacon.Region*/("myEmptyBeaconId", Identifier.Parse("23A01AF0-232A-4518-9C0E-323FB773F5EF"), null, null);
             regionBootstrap = new RegionBootstrap(this, _generalRegion);

             backgroundPowerSaver = new BackgroundPowerSaver(this);
         }

         void CreateNotificationChannel()
         {
             if (Build.VERSION.SdkInt < BuildVersionCodes.O)
             {
                 // Notification channels are new in API 26 (and not a part of the
                 // support library). There is no need to create a notification
                 // channel on older versions of Android.
                 return;
             }
             var channelDescription = "Foreground Sertrvice";
             var channel = new NotificationChannel(foregroundServiceChannelId, channelName, NotificationImportance.High)
             {
                 Description = channelDescription
             };

             var notificationManager = (NotificationManager)GetSystemService(NotificationService);
             notificationManager.CreateNotificationChannel(channel);
         }

         public Notification GetForegroundServiceNotification()
         {
             NotificationCompat.Builder builder = new NotificationCompat.Builder(this, foregroundServiceChannelId);
             builder.SetSmallIcon(Resource.Drawable.xamagonBlue);
             builder.SetContentTitle("Scanning for Beacons");
             Intent intent = new Intent(this, typeof(MainActivity));
             PendingIntent pendingIntent = PendingIntent.GetActivity(this, pendingIntentId, intent, PendingIntentFlags.UpdateCurrent);
             builder.SetContentIntent(pendingIntent);

             return builder.Build();
         }
     }
 }

Код класса SplashActivity:

namespace AltBeaconLibrarySample.Droid
{
    [Activity(Label = "AltBeaconLibrarySample.Droid",
        Icon = "@mipmap/icon",
        Theme = "@style/MainTheme",
        MainLauncher = true,
        NoHistory = true,
        LaunchMode = Android.Content.PM.LaunchMode.SingleInstance,
        ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]

    public class SplashActivity : Activity
    {
        static readonly string TAG = "X:" + typeof(SplashActivity).Name;

        public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
        {
            base.OnCreate(savedInstanceState, persistentState);
        }

        // Launches the startup task
        protected override void OnResume()
        {
            base.OnResume();
            Task startupWork = new Task(() => { SimulateStartup(); });
            startupWork.Start();
        }

        // Simulates background work that happens behind the splash screen
        async void SimulateStartup()
        {
            Log.Debug(TAG, "Performing some startup work that takes a bit of time.");
            await Task.Delay(50); // Simulate a bit of startup work.
            Log.Debug(TAG, "Startup work is finished - starting MainActivity.");
            StartActivity(new Intent(Application.Context, typeof(MainActivity)));
        }
    }
}

Android манифест:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.AltBeaconLibrarySample" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <application android:label="AltBeaconLibrarySample.Android">
        <service android:enabled="true" android:exported="false" android:isolatedProcess="false" android:label="Beacon" android:name="org.altbeacon.beacon.service.BeaconService"></service>
        <service android:enabled="true" android:exported="false" android:name="org.altbeacon.beacon.BeaconIntentProcessor"></service>
        <receiver android:name="org.altbeacon.beacon.startup.StartupBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

Код класса MainActivity:

namespace AltBeaconLibrarySample.Droid
{
    [Activity(Label = "AltBeaconLibrarySample.Droid", 
              Icon = "@mipmap/icon", 
              Theme = "@style/MainTheme",
              MainLauncher = false, 
              LaunchMode = Android.Content.PM.LaunchMode.SingleInstance,
              ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IBeaconConsumer
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
            CrossCurrentActivity.Current.Init(this, savedInstanceState);

            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

            LoadApplication(new App());
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

        #region IBeaconConsumer Implementation
        public void OnBeaconServiceConnect()
        {
        }
        #endregion
        protected override void OnDestroy()
        {
            base.OnDestroy();
            DependencyService.Get<IAltBeaconService>().OnDestroy();
        }

        protected override void OnResume()
        {
            base.OnResume();
        }

        protected override void OnPause()
        {
            base.OnPause();
        }
    }
}

Фрагмент кода BeaconManager:

BeaconManager bm = BeaconManager.GetInstanceForApplication(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity);

var iBeaconParser = new BeaconParser();
//  Estimote > 2013
iBeaconParser.SetBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
bm.BeaconParsers.Add(iBeaconParser);

bm.BackgroundMode = false;
bm.Bind((IBeaconConsumer)Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...