question

Ilim-9822 avatar image
0 Votes"
Ilim-9822 asked LeonLu-MSFT edited

Xamarin forms. The app crashes in the background.

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 !

dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

LeonLu-MSFT avatar image
0 Votes"
LeonLu-MSFT answered LeonLu-MSFT edited

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.


· 13
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Oh, thank you so much for your reply. Could you send your solution in the form of a code ? I would be very grateful to you )

0 Votes 0 ·

I updated my answer, you can check it.

1 Vote 1 ·

When I implement DoLongRunningOperationThings() in DataSource.sc , then the method +=Accelerometer_ReadingChanged asks for the implementation of functions in DataSource.sc, how can this be circumvented so that the implementation of the method remains in AboutPage.sc? or is there another solution ?



0 Votes 0 ·

I cannot find a way to avoid it.

Because Xamarin do not have a API to keep application always running in the background or keep alive(due to the native platform limitation), we have to create a android native foreground services to keep app alive, then if you want to send information from DoLongRunningOperationThings method to AboutPage.sc, you can use Message Center or callback method to send information from dependence service to AboutPage.


1 Vote 1 ·

Hello. Thank you for your reply. I implemented the code on your recommendation, but now an error is coming out

XFC0002 EventHandler "Click_Start" with correct signature not found in type "AlgoritmForegraundPR.MainPage". AlgoritmForegraundPR D:\XamarinProject\AlgoritmForegraundPR\AlgoritmForegraundPR\MainPage.xaml 14, that is, the "Click_Start" button requires implementation in the "MainPage" class, but the implementation of the button in the "MainPage" class does not give results. Here is my test code, I rewrote the project and made it a little easier https://github.com/Ilim-Hussein/AlgoritmForegraundPR . Thanks !

0 Votes 0 ·
Show more comments

@Ilim-9822 I have not heard from you for a couple of days. Please let me know if there is anything that I can help here.

0 Votes 0 ·
Ilim-9822 avatar image
0 Votes"
Ilim-9822 answered LeonLu-MSFT commented
 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();
         }
     }
 }
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I updated my answer, please check it.

1 Vote 1 ·