简体   繁体   English

带有Android服务和BroadcastReceiver的闹钟通知

[英]Alarm clock Notification with an Android Service and BroadcastReceiver

Am new in android broadcast receiver and services , currently am dealing with an alarm clock based application , i want my application to be having a sticky service as in when the Application is Idle or sleeping it makes a notification. 这是android 广播接收器服务中的新功能 ,当前正在处理基于闹钟的应用程序 ,我希望我的应用程序具有粘性服务,例如当应用程序处于空闲或休眠状态时会发出通知。

Currently the App makes a notification but it doesn't when the app is idle , i read somewhere that i have to use Sticky Services to implement this but i don't know how to connect it. 目前,应用程序会发出通知,但当应用程序处于空闲状态时不会发出通知,我读到某个地方必须使用Sticky Services来实现此功能,但我不知道如何连接它。

I will be very grateful for this help. 我将非常感谢您的帮助。

My current codes are below: 我当前的代码如下:

This is MainApplication.class it extends Application 这是MainApplication.class它扩展了Application

namespace Diabetes.Droid
{
    [Application]
    public class MainApplication : Application
    {
        ISetAlarm alarmService;
        public static Context AppContext;

        public MainApplication()
        {

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


        public override void OnCreate()
        {

            base.OnCreate();
            AppContext = this.ApplicationContext;
            alarmService = new SetAlarmImplementation();
            alarmService.SetAlarm(13,58,"hello","great work ");
        }



        public void SetAlarm(int hour, int minute, string title, string message)
        {

            AppContext.StartService(new Intent(AppContext, typeof(AppStickyService)));
            Intent myintent = new Intent(Android.App.Application.Context, typeof(AppStickyService));
            myintent.PutExtra("message", message);
            myintent.PutExtra("title", title);
            //PendingIntent pendingintent = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, myintent, PendingIntentFlags.UpdateCurrent);
            PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext, typeof(AppStickyService)), 0);

            Java.Util.Date date = new Java.Util.Date();
            Java.Util.Calendar cal = Java.Util.Calendar.Instance;
            cal.TimeInMillis = Java.Lang.JavaSystem.CurrentTimeMillis();
            cal.Set(Java.Util.CalendarField.HourOfDay, hour);
            cal.Set(Java.Util.CalendarField.Minute, minute);
            cal.Set(Java.Util.CalendarField.Second, 0);
            AlarmManager alarmManager = Android.App.Application.Context.GetSystemService(Android.Content.Context.AlarmService) as AlarmManager;
            alarmManager.Set(AlarmType.RtcWakeup, cal.TimeInMillis, pintent);
            // alarmManager.Cancel(pintent);

        }





        public void StartService()
        {

            AppContext.StartService(new Intent(AppContext, typeof(AppStickyService)));
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
            {

                PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext, typeof(AppStickyService)), 0);
                //AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(Context.AlarmService);
                Toast.MakeText(this, "Service started", ToastLength.Long).Show();
                //alarm.Cancel(pintent);
            }
        }

        public static void StopService()
        {
            AppContext.StopService(new Intent(AppContext, typeof(AppStickyService)));
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
            {
                // Toast.MakeText(this,"Service started", ToastLength.Long).Show();

                //PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext, typeof(AppStickyService)), 0);
                // AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(Context.AlarmService);
                //alarm.Cancel(pintent);
            }
        }
    }

This is AlarmImplementation.class 这是AlarmImplementation.class

public class SetAlarmImplementation : ISetAlarm
    {

        public SetAlarmImplementation(){}


        public void SetAlarm(int hour, int minute, string title, string message)
        {


            Intent myintent = new Intent(Android.App.Application.Context, typeof(AlarmReceiver));
            myintent.PutExtra("message", message);
            myintent.PutExtra("title", title);
            PendingIntent pendingintent = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, myintent, PendingIntentFlags.UpdateCurrent);

            Java.Util.Date date = new Java.Util.Date();
            Java.Util.Calendar cal = Java.Util.Calendar.Instance;
            cal.TimeInMillis = Java.Lang.JavaSystem.CurrentTimeMillis();
            cal.Set(Java.Util.CalendarField.HourOfDay, hour);
            cal.Set(Java.Util.CalendarField.Minute, minute);
            cal.Set(Java.Util.CalendarField.Second, 0);

            AlarmManager alarmManager = Android.App.Application.Context.GetSystemService(Android.Content.Context.AlarmService) as AlarmManager;
            alarmManager.Set(AlarmType.RtcWakeup, cal.TimeInMillis, pendingintent);
        }
    }

This is my BroadcastReceiver class 这是我的BroadcastReceiver类

[BroadcastReceiver]
    [IntentFilter(new string[] { "android.intent.action.BOOT_COMPLETED" }, Priority = (int)IntentFilterPriority.LowPriority)]
    public class AlarmReceiver : BroadcastReceiver
    {

        public override void OnReceive(Context context, Intent intent)
        {

            var message = intent.GetStringExtra("message");
            var title = intent.GetStringExtra("title");

            //Show toast here
            //Toast.MakeText(context, "Hello it's me ", ToastLength.Short).Show();
            var extras = intent.Extras;

            if (extras != null && !extras.IsEmpty)
            {
                NotificationManager manager_ = context.GetSystemService(Context.NotificationService) as NotificationManager;
                var notificationId = extras.GetInt("NotificationIdKey", -1);
                if (notificationId != -1)
                {
                    manager_.Cancel(notificationId);
                }
            }

            //Create intent for action 1 (TAKE)
            var actionIntent1 = new Intent();
            actionIntent1.SetAction("ARCHIVE");
            var pIntent1 = PendingIntent.GetBroadcast(context, 0, actionIntent1, PendingIntentFlags.CancelCurrent);

            //Create intent for action 2 (REPLY)
            var actionIntent2 = new Intent();
            actionIntent2.SetAction("REPLY");
            var pIntent2 = PendingIntent.GetBroadcast(context, 0, actionIntent2, PendingIntentFlags.CancelCurrent);

            Intent resultIntent = context.PackageManager.GetLaunchIntentForPackage(context.PackageName);

            var contentIntent = PendingIntent.GetActivity(context, 0, resultIntent, PendingIntentFlags.CancelCurrent);

            var pending = PendingIntent.GetActivity(context, 0,
                resultIntent,
                PendingIntentFlags.CancelCurrent);
            //seting an alarm
            MedicationDatabase db = new MedicationDatabase();
            var alarm_list = db.GetAlarmList();
            //Debug.WriteLine(" Time -- : "+ m.ToString());


            // Instantiate the Big Text style:
            Notification.BigTextStyle textStyle = new Notification.BigTextStyle();


            var builder =
                new Notification.Builder(context)
                                .AddAction(Resource.Drawable.tick_notify, "ARCHIVE", pIntent1)
                                .AddAction(Resource.Drawable.cancel_notify, "REPLY", pIntent2)
                                .SetSmallIcon(Resource.Drawable.ic_launcher)
                                .SetContentTitle("Diabetics Reminder")
                                .SetDefaults(NotificationDefaults.Sound)
                                .SetStyle(new Notification
                                .BigTextStyle()
                                .SetSummaryText("")
                                .SetBigContentTitle(title)
                                .BigText(message)
             ).SetDefaults(NotificationDefaults.All);

            builder.SetContentIntent(pending);

            var notification = builder.Build();


            var manager = NotificationManager.FromContext(context);
            manager.Notify(10010, notification);

        }
    }

And finally this is my Service Class, which i need more help to attach it to the Application so that the Alarm works when the Application isn't launched , like other Alarm Applications. 最后,这是我的Service类,我需要更多帮助将其附加到应用程序,以便在启动该应用程序时像其他警报应用程序一样启动警报。

[Service]
    public class AppStickyService : Service
    {

        public override void OnCreate()
        {
            base.OnCreate();

           // Toast.MakeText(this, "Service started Habiibi", ToastLength.Long).Show();
            //WireAlarm();
            System.Diagnostics.Debug.WriteLine("Sticky Service - Created");
        }

        public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
        {
            SetAlarm(12,39,"Try","Start Service");

            return StartCommandResult.Sticky;
        }

        public override Android.OS.IBinder OnBind(Android.Content.Intent intent)
        {
            System.Diagnostics.Debug.WriteLine("Sticky Service - Binded");
            //WireAlarm();
            return null;
        }

        public override void OnDestroy()
        {
            System.Diagnostics.Debug.WriteLine("Sticky Service - Destroyed");
            base.OnDestroy();
            WireAlarm();
        }

Try calling your service inside a Broadcast Receiver and like this . 尝试像这样在广播接收器中调用服务。

[BroadcastReceiver]
    [IntentFilter(new string[] { "android.intent.action.BOOT_COMPLETED" }, Priority = (int)IntentFilterPriority.LowPriority)]
    public class AlarmReceiver : BroadcastReceiver 
    {



        public override void OnReceive(Context context, Intent intent)
        {


            var message = intent.GetStringExtra("message");
            var title = intent.GetStringExtra("title");
            Intent i = new Intent(context, typeof(AppStickyService));
            i.PutExtra("message",message);
            i.PutExtra("title", title);
            context.StartService(i);

        }
    }

And then change your Service class to this : 然后将您的Service类更改为:

[Service(Exported = true, Name = "com.diabetics.Diabetes.AppStickyService")]
    public class AppStickyService : IntentService
    {

        public override void OnCreate()
        {
            base.OnCreate();
            //Toast.MakeText(this, "Service started", ToastLength.Long).Show();

            System.Diagnostics.Debug.WriteLine("Sticky Service - Created");
        }

        public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
        {

            WireAlarm(intent);

            return StartCommandResult.Sticky;
        }

        public override Android.OS.IBinder OnBind(Android.Content.Intent intent)
        {
            System.Diagnostics.Debug.WriteLine("Sticky Service - Binded");
            Toast.MakeText(this, "Service started", ToastLength.Long).Show();

            return null;
        }

        public override void OnDestroy()
        {
            try
            {
                base.OnDestroy();

            }
            catch (Java.Lang.IllegalStateException ex)
            {
                //Log.Debug("MainActivity.OnDestroy", ex, "The activity was destroyed twice");
                System.Diagnostics.Debug.WriteLine("Sticky Service error "+ ex);
            }



        }
public void WireAlarm(Intent intent)
        {
            //Show toast here
            //Toast.MakeText(context, "Hello it's me ", ToastLength.Short).Show();
            var message = intent.GetStringExtra("message");
            var title = intent.GetStringExtra("title");

            //Create intent for action 1 (TAKE)
            var actionIntent1 = new Intent();
            actionIntent1.SetAction("TAKE");
            var pIntent1 = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, actionIntent1, PendingIntentFlags.CancelCurrent);

            //Create intent for action 2 (REPLY)
            var actionIntent2 = new Intent();
            actionIntent2.SetAction("SKIP");
            var pIntent2 = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, actionIntent2, PendingIntentFlags.CancelCurrent);

            Intent resultIntent = Android.App.Application.Context.PackageManager.GetLaunchIntentForPackage(Android.App.Application.Context.PackageName);

            var contentIntent = PendingIntent.GetActivity(Android.App.Application.Context, 0, resultIntent, PendingIntentFlags.CancelCurrent);

            var pending = PendingIntent.GetActivity(Android.App.Application.Context, 0,
                resultIntent,
                PendingIntentFlags.CancelCurrent);

            //Debug.WriteLine(" Time -- : "+ m.ToString());


            // Instantiate the Big Text style:
            Notification.BigTextStyle textStyle = new Notification.BigTextStyle();


            var builder =
                new Notification.Builder(Android.App.Application.Context)
                                .AddAction(Resource.Drawable.tick_notify, "TAKE", pIntent1)
                                .AddAction(Resource.Drawable.cancel_notify, "SKIP", pIntent2)
                                .SetSmallIcon(Resource.Drawable.ic_launcher)
                                .SetContentTitle("Diabetics Reminder")
                                .SetDefaults(NotificationDefaults.Sound)
                                .SetStyle(new Notification
                                .BigTextStyle()
                                .SetSummaryText("")
                                .SetBigContentTitle(title)
                                .BigText(message)
             ).SetDefaults(NotificationDefaults.All);

            builder.SetContentIntent(pending);

            var notification = builder.Build();


            var manager = NotificationManager.FromContext(Android.App.Application.Context);
            manager.Notify(10010, notification);
        }

This might help you give it a try. 这可能会帮助您尝试一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM