Forum Xamarin Xamarin.Android

How to keep my broadcastreceiver alive when I close the app?

Hello folks, I've been researching this topic since yesterday and I couldn't find anything that works for my case. I guess it has something to do with my Manifest however I'm really not sure why.

Here's my Manifest:

<receiver
    android:name=".BirthdayReceiver"> 
    android:process=":remote"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
      <action android:name="android.intent.action.BOOT_COMPLETED" />
      <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
  </receiver>

And here's my Broadcast receiver:

    namespace HappyBirthdayApp_v2
    {
        [BroadcastReceiver]
        [IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
        public class BirthdayReceiver : BroadcastReceiver
        {
            public override void OnReceive(Context context, Intent intent)
            {
                Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
        }
         }
    }

On my MainActivity, I have the code that instantiates the broadcastreceiver:

                    AlarmManager manager = (AlarmManager)GetSystemService(Context.AlarmService);
                                Intent myIntent;
                                PendingIntent pendingIntent;
                                DateTime birthdayChecker = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 13, 0, 0);
                                myIntent = new Intent(this, typeof(BirthdayReceiver));
                                pendingIntent = PendingIntent.GetBroadcast(this, 0, myIntent, 0);
                                manager.SetRepeating(AlarmType.RtcWakeup, SystemClock.ElapsedRealtime() + 3000, 5 * 1000, pendingIntent);

Anything I missed in my simple code?

Best Answer

  • duffthebluffduffthebluff PHMember ✭✭
    Accepted Answer

    @Simonagi, yes I was able to solve this. Here's my code:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="TestApp_v2.TestApp_v2" android:versionCode="1" android:versionName="1.1" android:installLocation="auto">
      <uses-sdk android:minSdkVersion="17" />
      <uses-permission android:name="android.permission.READ_CONTACTS" />
      <uses-permission android:name="android.permission.WRITE_CONTACTS" />
      <application android:allowBackup="true" android:label="@string/app_name" android:theme="@style/Theme.AppCompat.Light.NoActionBar" android:screenOrientation="portrait" android:icon="@drawable/icon">
        <receiver android:name=".AlertReceiver" android:enabled="true" android:exported="true" />
      </application>
    

    Here's my receiver:

    namespace TestApp_v2
    {
        [BroadcastReceiver(Enabled = true)]
        class AlertReceiver : BroadcastReceiver
        {
            public override void OnReceive(Context context, Intent intent)
                Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
        }
    }
    

    I used this for my reference:

Answers

  • SimonagiSimonagi USMember

    Hi,

    I have the same problem. Did you fix the problem?
    Can you help me?
    Thank you.

  • duffthebluffduffthebluff PHMember ✭✭
    Accepted Answer

    @Simonagi, yes I was able to solve this. Here's my code:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="TestApp_v2.TestApp_v2" android:versionCode="1" android:versionName="1.1" android:installLocation="auto">
      <uses-sdk android:minSdkVersion="17" />
      <uses-permission android:name="android.permission.READ_CONTACTS" />
      <uses-permission android:name="android.permission.WRITE_CONTACTS" />
      <application android:allowBackup="true" android:label="@string/app_name" android:theme="@style/Theme.AppCompat.Light.NoActionBar" android:screenOrientation="portrait" android:icon="@drawable/icon">
        <receiver android:name=".AlertReceiver" android:enabled="true" android:exported="true" />
      </application>
    

    Here's my receiver:

    namespace TestApp_v2
    {
        [BroadcastReceiver(Enabled = true)]
        class AlertReceiver : BroadcastReceiver
        {
            public override void OnReceive(Context context, Intent intent)
                Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
        }
    }
    

    I used this for my reference:

  • jackrajjackraj USMember ✭✭

    @duffthebluff said:
    @Simonagi, yes I was able to solve this. Here's my code:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="TestApp_v2.TestApp_v2" android:versionCode="1" android:versionName="1.1" android:installLocation="auto">
      <uses-sdk android:minSdkVersion="17" />
      <uses-permission android:name="android.permission.READ_CONTACTS" />
      <uses-permission android:name="android.permission.WRITE_CONTACTS" />
      <application android:allowBackup="true" android:label="@string/app_name" android:theme="@style/Theme.AppCompat.Light.NoActionBar" android:screenOrientation="portrait" android:icon="@drawable/icon">
        <receiver android:name=".AlertReceiver" android:enabled="true" android:exported="true" />
      </application>
    

    Here's my receiver:

    namespace TestApp_v2
    {
        [BroadcastReceiver(Enabled = true)]
        class AlertReceiver : BroadcastReceiver
        {
            public override void OnReceive(Context context, Intent intent)
              Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
        }
    }
    

    I used this for my reference:

    Here my code button click but not working How to keep my broadcastreceiver alive when I close the app?

    private void Btn_Submit_Click(object sender, System.EventArgs e)
    {
    try
    {
    if (!string.IsNullOrEmpty(edt_Time.Text) && !string.IsNullOrEmpty(edt_Second.Text) && !string.IsNullOrEmpty(edt_mobile.Text))
    {
    if (Convert.ToInt32(edt_Second.Text) > 59)
    {
    return;
    }
    try
    {
    string Mobilenumber = edt_prefix.Text + edt_mobile.Text;
    }
    catch (Exception ex)
    {
    Toast.MakeText(this, "SharedPreferences in Mainactivity" + ex.Message, ToastLength.Long).Show();
    }

                    Intent alarm = new Intent(this, typeof(ServicesCallBroadcastReceiver));                    
                    bool alarmRunning = (PendingIntent.GetBroadcast(this, 0, alarm, PendingIntentFlags.NoCreate) != null);
                    if (alarmRunning == false)
                    {
    
                        //PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
                        PendingIntent pendingIntent = PendingIntent.GetBroadcast(this, 0, alarm, 0);
                        //INITIALIZE ALARM MANAGER
                        AlarmManager alarmManager = (AlarmManager)GetSystemService(AlarmService);
    
                        Java.Util.Calendar firingCal = Java.Util.Calendar.GetInstance(Java.Util.TimeZone.Default);
                        Java.Util.Calendar currentCal = Java.Util.Calendar.GetInstance(Java.Util.TimeZone.Default);
                        int time = Convert.ToInt32(edt_Time.Text);
                        int sec = Convert.ToInt32(edt_Second.Text);
                        firingCal.Set(Java.Util.Calendar.Hour, time); // At the hour you wanna fire
                        firingCal.Set(Java.Util.Calendar.Minute, sec); // Particular minute
                        firingCal.Set(Java.Util.Calendar.Second, 0); // particular second
    
                        long intendedTime = firingCal.TimeInMillis;
                        long currentTime = currentCal.TimeInMillis;
    
                        if (intendedTime >= currentTime)
                        {
                            //SET THE ALARM
                            alarmManager.SetExact(AlarmType.RtcWakeup, intendedTime, pendingIntent);
                        }
                        else
                        {
                            // set from next day
                            // you might consider using calendar.add() for adding one day to the current day
                            firingCal.Add(Java.Util.Calendar.DayOfMonth, 1);
                            intendedTime = firingCal.TimeInMillis;
                            PellucidLog.Logfile.WriteEventLog("Class:MainActivity", "Method:MainActivity ", 0, "Next time set OnCreate method Called", System.Diagnostics.TraceEventType.Information);
    
                            alarmManager.SetExact(AlarmType.RtcWakeup, intendedTime, pendingIntent);
                        }
    
    
                    }
                    else
                    {
                        Toast.MakeText(this, "You alread set alarm", ToastLength.Long).Show();
                    }
                }
            }
            catch (Exception ex)
            {
                Toast.MakeText(this, "Exception occurred in Btn_Submit_Click:" + ex.Message, ToastLength.Long).Show();
            }
        }
    }
    

    Broadcast class

    [BroadcastReceiver(Enabled = true)]
    public class ServicesCallBroadcastReceiver : BroadcastReceiver
    {
    public override void OnReceive(Context context, Intent intent)
    {
    try
    {
    if (intent.Action != null)
    {
    if (intent.Action.Equals(Intent.ActionBootCompleted))
    {

                        Toast.MakeText(context, "ServicesCallBroadcastReceiver Received intent second called!", ToastLength.Short).Show();
                        Log.Info("Received intent!", "Received second");
                        PellucidLog.Logfile.WriteEventLog("Class:ServicesCallBroadcastReceiver", "Method:OnReceive First", 0, "OnReceive method Called", System.Diagnostics.TraceEventType.Information);
                        context.StartService(new Intent(context, typeof(BackupServicesCall)));
                    }
                }
                else
                {
                    Toast.MakeText(context, "ServicesCallBroadcastReceiver Received intent second called!", ToastLength.Short).Show();
                    Log.Info("Received intent!", "Received second");                    
                    context.StartService(new Intent(context, typeof(BackupServicesCall)));
                }
            }
            catch(Exception ex)
            {
                Toast.MakeText(Application.Context, "Exception occurred in OnReceive method of ServicesCallBroadcastReceiver:" + ex.Message, ToastLength.Long).Show();
            }               
        }
    }
    

  • duffthebluffduffthebluff PHMember ✭✭

    @jackraj have you tried to run this deployed on a device?

  • jackrajjackraj USMember ✭✭

    @duffthebluff said:
    @jackraj have you tried to run this deployed on a device?

    Yes,I have tried till now also

  • duffthebluffduffthebluff PHMember ✭✭

    Hmmm what I can suggest is try this with a small scale approach. Start with a clean solution, without anything and do the steps EXACTLY as what the video has shown. Just display a toast if the simple code is fired. Let's see if a short simple code would definitely fire the broadcast receiver in the first place. From my experience running the broadcaster is tricky because it depends on a lot of factors such as OS version, manufacturer's own algorithm (some manufacturers implements disposal of broadcast receivers once your app is closed), etc.

Sign In or Register to comment.