Xamarin forms. The app crashes in the background.

Ilim Gusseinov 81 Reputation points
2022-05-04T07:07:56.77+00:00

Hi everybody. I have a problem with my program, it uses Essentials: Accelerometer to count the number of device tilts.But the problem is that sometimes it doesn't work, and sometimes it works, but not stably, when the phone is in the background or when the screen is locked.The program also uses Essentials: Vibration, which also does not work or is unstable in the background or in a locked screen mode.I also tried to use the services to work in the background, but they did not bring results, or maybe I implemented them incorrectly??? Please help me find a solution for this situation, that's also my github // https://github.com/Ilim-Hussein/MyMobilProject // I put together a test code sample there having such a problem. Thanks !

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,289 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 67,781 Reputation points Microsoft Vendor
    2022-05-05T07:18:41.427+00:00

    Hello,​

    I test your demo, I find you create DoLongRunningOperationThings method in DataSource.cs, but this method is empty. Please move your Accelerometer.ReadingChanged += Accelerometer_ReadingChanged; code to DoLongRunningOperationThings method and move related code from AboutPage.cs to DataSource.cs.

    When I click the start button, make the application in background and lock the screen. When I get counter meet the If condition, I get the Vibtate normally. My test device is
    android 9.0 and android 1.0.

    ===========
    Update=============

    If you want to transfer data from DataSource.cs to MainPage.xaml.cs

    For example, I transfer result data from Accelerometer_ReadingChanged method of DataSource.cs like following code.

       void Accelerometer_ReadingChanged(object sender, AccelerometerChangedEventArgs e)  
                {  
                    var data = e.Reading;  
                    result = counter / 2;  
       //add transfer code here  
                   MessagingCenter.Send<Object, string>(this, "TestMessage", result.ToString());  
               }  
    

    Then, you can get result in MainPage.xaml.cs , for testing, I set the text for Rakaat_1.Text

       public MainPage()  
               {  
                   InitializeComponent();  
         
                   MessagingCenter.Subscribe<Object, string>(this, "TestMessage", (sender, arg) =>  
                   {  
                       string message = arg;  
                       Rakaat_1.Text = message;  
                   });  
                    
               }  
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


1 additional answer

Sort by: Most helpful
  1. Ilim Gusseinov 81 Reputation points
    2022-05-18T16:08:13.313+00:00
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Xamarin.Forms;
    using Xamarin.Essentials;
    namespace AlgoritmForegraundPR
    {
        public partial class MainPage : ContentPage
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            //Here, at the click of the button, we must accept the message and the message variable must be initialized to our Rakaat_1.Text
            public void Click_Start(object sender, System.EventArgs e) //Start button
            {
                DependencyService.Get<IAndroidService>().StartService();
                DependencyService.Get<IAccelerometrST>().StartAccelerometer();
               // Checking the activation of the Accelerometer.
                if (Accelerometer.IsMonitoring) { Rakaat_1.Text = "1"; }
            }
    
    
            public void Click_Stop (object sender, System.EventArgs e) //Stop button
            {
                DependencyService.Get<IAndroidService>().StopService();
                DependencyService.Get<IAccelerometrST>().StopAccelerometer();
               // Check turning off the Accelerometer.
                if (Accelerometer.IsMonitoring == false) { Rakaat_1.Text = "Start counter";}
            }
    
    
        }
    }
    
    
    
    
    
    using Android.App;
    using Android.Content;
    using Android.OS;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Xamarin.Forms;
    using Xamarin.Essentials;
    using System.Threading.Tasks;
    
    
    [assembly: Xamarin.Forms.Dependency(typeof(AlgoritmForegraundPR.Droid.DataSource))]
    
    namespace AlgoritmForegraundPR.Droid
    {
        [Service]
        public class DataSource : Service , IAccelerometrST
        {
            MainPage aboutPage = new MainPage();
            public override IBinder OnBind(Intent intent)
            {
                return null;
            }
            public const int ServiceRunningNotifID = 9000;
    
    
            public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
            {
                Notification notif = DependencyService.Get<INotification>().ReturnNotif();
                StartForeground(ServiceRunningNotifID, notif);
    
                _ = DoLongRunningOperationThings();
    
                return StartCommandResult.Sticky;
            }
            public object DoLongRunningOperationThings()
            {
                Accelerometer.ReadingChanged += Accelerometer_ReadingChanged;
    
                return null;
            }
    
    
            public override void OnDestroy()
            {
                base.OnDestroy();
            }
    
            public override bool StopService(Intent name)
            {
                return base.StopService(name);
            }
    
    
    
    
            public float num1 = 0.8f;
            public float num2 = 0.9f;
            public float num3 = 0.2f;
            public float num4 = 0.1f;
    
            public float Aceler_dataX = 0.0f;
            public float Aceler_dataY = 0.0f;
            public float Aceler_dataZ = 0.0f;
    
            public bool c;
            public bool d;
    
            public int counter;
            public int result;
    
            //The value of this variable must be sent to the MainPage class
            string message = "Hello";
            // Or The value of this variable must be sent to the MainPage class
            int message_num = 123;
    
    
            void Accelerometer_ReadingChanged(object sender, AccelerometerChangedEventArgs e)
             {
                 var data = e.Reading;
                 result = counter / 2;
                 Aceler_dataX = data.Acceleration.X;
                 Aceler_dataY = data.Acceleration.Y;
                 Aceler_dataZ = data.Acceleration.Z;
                 Result_Condition();
    
                aboutPage.Rakaat_1.Text = Convert.ToString(result);
    
                 if (counter / 2 == 3)
                 {
                     Vibtate_Controll(1);
                 }
    
                 else if (counter / 2 == 6)
                 {
                     Vibtate_Controll(2);
                 }
    
                 else if (counter / 2 == 9)
                 {
                     Vibtate_Controll(3);
                 }
    
             }
    
            public bool ResultCounter_Y_1(bool condition) // checking the condition Y 1 - 0.8 to 0.9
            {
                if (Aceler_dataY >= num1 && Aceler_dataY <= num2)
                {
                    condition = true;
                }
                else
                {
                    condition = false;
                }
                return condition;
            }
    
            public bool ResultCounter_Y_2(bool condition) // checking the condition Y 2 - 0.2 to 0.1
            {
                if (Aceler_dataY <= num3 && Aceler_dataY >= num4)
                {
                    condition = true;
                }
                else
                {
                    condition = false;
                }
                return condition;
            }
    
            public void Result_Condition() //  Checking the fulfillment of conditions with Accelerometers and output counter +1 in the case of true true
            {
    
                if (ResultCounter_Y_1(false) == true) { c = true; }
                if (ResultCounter_Y_2(false) == true) { d = true; }
    
                if (c == true && d == true)
                {
                    c = false;
                    d = false;
                    counter += 1;
                }
            }
    
    
            {
                Accelerometer.Start(SensorSpeed.UI);
                DependencyService.Get<IAndroidService>().StartService();
            }
    
    
            public void Click_Stop(object sender, System.EventArgs e) //Stop button
            {
                Accelerometer.Stop();
                DependencyService.Get<IAndroidService>().StopService();
                counter = 0;
                aboutPage.Rakaat_1.Text = "Start counter";
            }
    
            */
    
            public async void Vibtate_Controll(int count_vibr) //Vibration control
            {
                var durition = TimeSpan.FromSeconds(0.3);
    
                for (int i = 0; i < count_vibr; i++)
                {
                    Vibration.Vibrate(durition);
                    await Task.Delay(700);
                }
            }
    
    
            public void StartAccelerometer()
            {
                Accelerometer.Start(SensorSpeed.UI);
            }
    
            public void StopAccelerometer()
            {
                Accelerometer.Stop();
            }
        }
    }