2017-10-28 39 views
2

我使用依存服务DependencyService.Get<ISetAlarm>().SetAlarm(hour,min,"Diabetics App","Hello i remind you to take medicine");,它连接到我的AlarmReceiverAlarmImplementation类, 问题是:发出通知环时应用推出与否(Xamarin.Forms)

当我把依赖服务代码在任何形式的通知 只有当我启动该表格时,当我把onStart,onSleep 方法的通知只有在这种状态,如何ca ñ我使 的应用程序,使其通知像一个真正的报警,当它是 推出或不?

ADDITIONALLLY:

AlarmReceiver类

using System; 
using Android.App; 
using Android.Content; 
using Android.Media; 
using Android.Support.V4.App; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Diagnostics; 
using System.Globalization; 
using Android.Widget; 
using Diabetes.localDB; 
using Xamarin.Forms; 

namespace Diabetes.Droid 
{ 
    [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) 
     { 
      if (intent.Action.Equals("android.intent.action.BOOT_COMPLETED")) 
      { 
      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); 
     } 
     } 
    } 

    [BroadcastReceiver] 
    [IntentFilter(new string[] { "ARCHIVE", "REPLY" })] 
    public class CustomActionReceiver : BroadcastReceiver 
    { 
     public override void OnReceive(Context context, Intent intent) 
     { 

      switch (intent.Action) 
      { 
       case "ARCHIVE": 
        try 
        { 
         MedicationDatabase db = new MedicationDatabase(); 
         db.addtracktaken("true"); 
         Toast.MakeText(context, "DOSAGE TAKEN", ToastLength.Short).Show(); 
        } 
        catch (Exception e) 
        { 
         Debug.WriteLine(e.StackTrace); 
        } 
        break; 
       case "REPLY": 
        try 
        { 
         Toast.MakeText(context, "ARCHIVE", ToastLength.Short).Show(); 
         MedicationDatabase db = new MedicationDatabase(); 
         db.addtrackmissed("true"); 
         Toast.MakeText(context, "DOSAGE MISSED", ToastLength.Short).Show(); 
        } 
        catch (Exception e) 
        { 
         Debug.WriteLine(e.StackTrace); 
        } 
        break; 
      } 

      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); 
       } 
      } 
     } 
    } 
} 

AlarmImplementation类

[assembly: Xamarin.Forms.Dependency(typeof(SetAlarmImplementation))] 
namespace Diabetes.Droid 
{ 
    public class SetAlarmImplementation : ISetAlarm 
    { 

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

      MedicationDatabase db = new MedicationDatabase(); 
      var alarm_list = db.GetAlarmList(); 
      //Debug.WriteLine(" Time -- : "+ m.ToString()); 




      Intent myintent = new Intent(Xamarin.Forms.Forms.Context, typeof(AlarmReceiver)); 
      myintent.PutExtra("message", message); 
      myintent.PutExtra("title", title); 
      PendingIntent pendingintent = PendingIntent.GetBroadcast(Xamarin.Forms.Forms.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); 
      // PendingIntent pendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent, PendingIntentFlags.UpdateCurrent); 
      AlarmManager alarmManager = Xamarin.Forms.Forms.Context.GetSystemService(Android.Content.Context.AlarmService) as AlarmManager; 
      alarmManager.Set(AlarmType.RtcWakeup, cal.TimeInMillis, pendingintent); 
     } 
    } 
} 

编辑:

这是我的新更新

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using Android.App; 
using Android.Content; 
using Android.OS; 
using Android.Runtime; 
using Android.Views; 
using Android.Widget; 
using Diabetes.localDB; 
using Diabetes.Main; 

namespace Diabetes.Droid 
{ 
    [Activity(Label = "MainApplication")] 
    public class MainApplication : Activity 
    { 
     ISetAlarm alarmService; 
     MedicationDatabase db = new MedicationDatabase(); 

     public MainApplication(){ 

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

     protected override void OnCreate(Bundle savedInstanceState) 
     { 
      base.OnCreate(savedInstanceState); 
      alarmService = new SetAlarmImplementation(); 
      //Get list of stored time from Sqlite 
      var alarm_list = db.GetAlarmList(); 
      //Debug.WriteLine(" Time -- : "+ m.ToString()); 
      var message = "Hello Its I remind you to take insulin"; 
      var title = "Diabetics App"; 
      foreach (var list in alarm_list) 
      { 
       var hour = Int32.Parse(list.Substring(0, 2)); 
       var minute = Int32.Parse(list.Substring(3, 2)); 
       alarmService.SetAlarm(hour, minute, title,message); 
       // Create your application here 
      } 
     } 
    } 
} 

这是我做了什么,但现在当我设置任何通知到来时,就好像有不知何故,我必须使它触发。

我认为接近答案,我需要一些更多的指导,谢谢。

编辑2:

看看我的sqlite的DB类:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using SQLite.Net; 
using Xamarin.Forms; 

namespace Diabetes.localDB 
{ 
    public class MedicationDatabase 
    { 
     private SQLiteConnection _connection; 

     public MedicationDatabase() 
     { 

      _connection = DependencyService.Get<ISQLite>().GetConnection(); 
      _connection.CreateTable<Medication>(); 
      _connection.CreateTable<SetReminder>(); 
      // _connection.CreateTable<Track>(); 
      _connection.CreateTable<TrackMissed>(); 
      _connection.CreateTable<TrackTaken>(); 
      _connection.CreateTable<LoginModel>(); 


     } 
     public void AddDetails(string username, string alarm_time, string units, string insulin_type, string unique_id, string status) 
     { 

      _connection.Query<Medication>("Insert into [Medication] (username, alarm_time, units,insulin_type,unique_id,status) values" + 
              "('" + username + "','" + alarm_time + "','" + units + "','" + insulin_type + "','" + unique_id + "','" + status + "')"); 

     } 


     public void AddReminder(string username, string alarm_time, 
          string units, string insulin_type, string count_times) 
     { 

      _connection.Query<SetReminder>("Insert into [SetReminder] (username, alarm_time, units,insulin_type,count_times) values" + 
              "('" + username + "','" + alarm_time + "','" + units 
              + "','" + insulin_type + "','" + count_times + "')"); 
     } 

     public IEnumerable<Medication> AllMedicationResults() 
     { 
      return (from t in _connection.Table<Medication>() 
        select t).ToList(); 
     } 

     public IEnumerable<SetReminder> AllReminders() 
     { 
      return (from t in _connection.Table<SetReminder>() 
        select t).ToList(); 
     } 

     public IEnumerable<string> GetAlarmList() 
     { 
      return (from t in _connection.Table<Medication>() 
        select t.alarm_time).ToList(); 
     } 


     /* public string AlarmSample(){ 
      return (_connection.Table<SetReminder>().Select(r => r.) 
      .AsEnumerable() 
         .Select(r => r.Substring(1, r.Length - 2).Split(','))).ToList().ToString() 
                      ;  }*/ 

     public IEnumerable<string> GetUnitsList() 
     { 
      return (from t in _connection.Table<Medication>() 
        select t.units).ToList(); 
     } 

     public void DeleteAlarm() 
     { 
      _connection.DeleteAll<SetReminder>(); 
     } 


     public void DeleteTime(int id) 
     { 

      _connection.Delete<Medication>(id); 
     } 

     public void DeleteAllTime() 
     { 
      _connection.DeleteAll<Medication>(); 
     } 

     // Tracking table 
     public void addtracktaken(string taken) 
     { 

      _connection.Query<TrackTaken>("Insert into [TrackTaken] (taken) values" + 
              "('" + taken + "')"); 
     } 

     public void addtrackmissed(string missed) 
     { 

      _connection.Query<TrackMissed>("Insert into [TrackMissed] (missed) values" + 
              "('" + missed + "')"); 
     } 

     public int GetTracksTakenNos() 
     { 
      return (from t in _connection.Table<TrackTaken>() 
        select t.taken).Count(); 
     } 

     public int GetTracksMissedNo() 
     { 
      return (from t in _connection.Table<TrackMissed>() 
        select t.missed).Count(); 
     } 

     //Loging in 
     public void addUser(string username, string logged) 
     { 

      _connection.Query<LoginModel>("Insert into [LoginModel] (username,LoggedIn) values" + 
              "('" + username + "', '" + logged + "')"); 
     } 

     public void DeleteUsers() 
     { 
      _connection.DeleteAll<LoginModel>(); 
     } 

     public string LoggedInStatus() 
     { 
      List<LoginModel> list = _connection.Query<LoginModel>("Select LoggedIn From [LoginModel] where ID=1"); 
      return list[0].LoggedIn; 

     } 

     public string GetUserName() 
     { 
      List<LoginModel> list = _connection.Query<LoginModel>("Select username From [LoginModel] where ID=1"); 
      return list[0].username; 

     } 

    } 
} 

和接口:

namespace Diabetes.localDB 
{ 
    public interface ISQLite 
    { 
     SQLiteConnection GetConnection(); 
    } 
} 
+0

你尝试用这个插件: https://www.nuget.org/packages/Xam.Plugins.Notifier/? 它已经为您处理AlarmManager并提供PCL实现。 –

+0

是@RodrigoE。,我尝试过,但它错过了很多功能,这就是为什么我最终使用了依赖服务 –

+0

@IdrisStack你是说当你调用'.SetAlarm'时立即触发通知? – SushiHangover

回答

1

首先,因为依赖的不使用DependencyService Xamarin形式初始化,所以它只会在应用程序打开时工作。当应用程序关闭时,您不能执行任何与Xamarin Forms相关的调用,因为MainActivity在此时不可用,并且Xamarin Forms会继续调用它。

会建议,而不是执行以下操作:

1,创建一个Android应用程序类

2.创建你的报警服务存在的实例。

3。设置闹钟

[Application] 
public class MainApplication : Application 
{ 
    ISetAlarm alarmService; 
    public MainApplication(IntPtr handle, JniHandleOwnership transer) :base(handle, transer) 
    { 
    } 

    public override void OnCreate() 
    { 
     base.OnCreate(); 
     alarmService = new SetAlarmImplementation(); 
     alarmService.SetAlarm(hour,min,"Diabetics App","Hello i remind you to take medicine"); 

    } 
} 
+0

非常感谢回复@Rendy,我编辑我的帖子,但现在我没有收到任何通知 –

+0

当母鸡申请关闭或打开时,您没有收到任何通知? –

+0

顺便说一句,你修改的代码是错误的,你继续使用一个Activity来初始化你的报警,你只需将它重命名为MainApppication。 –

1

您的应用程序类的OnCreate方法启动粘滞服务,这样做,即使在应用程序关闭,该服务将保持应用程序活着,你仍然可以得到通知。

[Application] 
public class MainApplication : Application 
{ 
    public static Context AppContext; 
    public MainApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) 
    { 
    } 

    public override void OnCreate() 
    { 
     base.OnCreate(); 
     AppContext = this.ApplicationContext; 

     StartService(); 
    } 

    public static 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); 
      alarm.Cancel(pintent); 
     } 
    } 

    public static void StopService() 
    { 
     AppContext.StopService(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); 
      alarm.Cancel(pintent); 
     } 
    } 

} 

创建一个粘服务类:

[Service] 
public class AppStickyService : Service 
{ 
    public override void OnCreate() 
    { 
     base.OnCreate(); 

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

    public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId) 
    { 
     System.Diagnostics.Debug.WriteLine("Sticky Service - Started"); 
     return StartCommandResult.Sticky; 
    } 

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

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

一个注意你不应该在调试时关闭应用程序。您可以停止该应用程序,然后重新打开并再次关闭。但是在调试过程中不要关闭它,因为Android不能很好地处理这种情况。 –

+0

我试过这段代码,我第一次放置了'alarmService.SetAlarm(小时,分钟,“糖尿病应用程序”,“你好,我提醒你吃药”); '然后'StartService()'它在设置的时间到达时崩溃了,而且我以相反的方式做了什么,我是否应该将所有的警报实现代码放入** StartService()**方法中? –

+0

请接受我在Facebook上的朋友请求我的名字是** Lutaaya Huzaifah Idris ** –