android - Hacer un timbre de notificación cuando la aplicación se inicie o no(Xamarin.Forms)
notifications (2)
En primer lugar, no use un DependencyService porque depende de la inicialización de Xamarin Forms, por lo que solo funcionará cuando se abra la aplicación. No se puede ejecutar ninguna llamada relacionada con Formularios Xamarin cuando se cierra la aplicación, ya que MainActivity no está disponible en ese punto y Xamarin Forms se retransmite en él.
En cambio, sugerirá hacer lo siguiente:
1. Crea una clase de aplicación de Android
2. Cree la instancia de su servicio de alarma allí.
3. Configurar la alarma
[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");
}
}
Estoy usando la dependencia Service DependencyService.Get<ISetAlarm>().SetAlarm(hour,min,"Diabetics App","Hello i remind you to take medicine");
, que se conecta a mi clase AlarmReceiver
y AlarmImplementation
, el problema es:
Cuando coloco el código del Servicio de Dependencia en cualquier forma, la Notificación solo aparece cuando la
onStart,onSleep
, cuando pongo enonStart,onSleep
métodos enonStart,onSleep
la notificación viene solo en dichos estados, ¿cómo puedo hacer que la aplicación haga notificaciones como una alarma real , cuando o bien se lanzó o no ?.
ADICIONALMENTE:
Clase 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);
}
}
}
}
}
Clase 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);
}
}
}
EDITAR:
Esta es mi nueva actualización
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
}
}
}
}
Esto es lo que he hecho, pero ahora, cuando configuro el momento en que no llega ninguna notificación, es como si de algún modo tuviera que hacer que se disparara.
Creo que estoy cerca de la respuesta, necesito más orientación gracias.
EDICION 2:
Echa un vistazo a mi clase de DB Sqlite:
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;
}
}
}
Y la interfaz:
namespace Diabetes.localDB
{
public interface ISQLite
{
SQLiteConnection GetConnection();
}
}
Inicie un servicio fijo en el método OnCreate de su clase de aplicación para que, incluso si la aplicación se cierra, el servicio mantendrá la aplicación activa y todavía puede recibir notificaciones.
[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);
}
}
}
Crea una clase de servicio adhesiva:
[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();
}
}