Xamarin.Forms неожиданный сигнал тревоги в процессе backgroud в Android - PullRequest
0 голосов
/ 24 апреля 2020

Я просто пытаюсь получить несколько счетчиков обратного отсчета, когда он достигает индивидуального значения до 0, я хочу подать сигнал тревоги (без какого-либо взаимодействия пользователя между одним и следующим).

Обратный отсчет запрограммировано, например, на 5, 4 и 7 минут. Если это секунды, и приложение работает с включенным экраном, или только секунды, то проблем нет, но как только наступают минуты, экран выключается и телефон переходит в режим ожидания (я думаю), в результате получаем: 5, 6: 26 и 9:58 (вместо 5,4 и 7).

Я читал много пользовательских решений, которые обсуждались здесь, но у меня это не работает. Телефон работает Android v10.

Код для программирования сигнала тревоги с SetExactAndAllowWhileIdle:

public void ProgAlarm(int nIntervalo) {
    var alarmIntent = new Intent(MainActivity.Instance, typeof(AlarmReceiver));
    alarmIntent.PutExtra("Contador", nIntervalo);
    var pending = PendingIntent.GetBroadcast(MainActivity.Instance, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);

    MainActivity.alarM.SetExactAndAllowWhileIdle(AlarmType.ElapsedRealtimeWakeup,
        SystemClock.ElapsedRealtime()+tiempos[nIntervalo]*1000, pending);
}

И событие, инициированное для перепрограммирования сигнала тревоги:

[BroadcastReceiver]
public class AlarmReceiver: BroadcastReceiver {
   public override void OnReceive(Context context, Intent intent) {
       DependencyService.Get<IVarios>().Beep();
       int actual=intent.GetIntExtra("Contador",-1);
       if (actual!=-1) DependencyService.Get<IVarios>().ProgAlarm(++actual);
    }
}

До тревоги я пытался с PowerManager:

PowerManager pM = (PowerManager)GetSystemService(PowerService);
wakeLock=pM.NewWakeLock(WakeLockFlags.Partial, "CronoMultiple");
[...]
wakeLock.Acquire();
[...]
wakeLock.Release();

и с флагом: WakeLockFlags.AcquireCausesWakeup

Но это работает, только когда экран всегда был включен, с флагом .Partial, экран поворачивается выкл и приложение останавливается и счетчик не работает В эмуляторе P C он работает (даже с командами adb), но не на телефоне.

Любое решение без использования Сервиса? (Я новичок в Xamarin.forms).

1 Ответ

0 голосов
/ 27 апреля 2020

Вот простой пример, он будет срабатывать каждые 1 минуту:

интерфейс IVar ios

public interface IVarios
{
    void ProgAlarm(int minute);
} 

in MainActivity Позвольте ему реализовать IVar ios:

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity,IVarios
{
   public void ProgAlarm(int minute)
    {
        Intent intent = new Intent(MainActivity.Instance, typeof(LongRunningService));
        intent.PutExtra("Contador", minute);
        MainActivity.Instance.StartService(intent);
    }
}

в Android проекте, создать LongRunningService :

[Service]
class LongRunningService : Service
{

    int minutes;
    public override IBinder OnBind(Intent intent)
    {
        return null;
    }
    public override void OnCreate()
    {
        base.OnCreate();
    }

    [return: GeneratedEnum]
    public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
    {
       Android.Util.Log.Error("LongRunningService", "executed");
        AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
        int min = intent.GetIntExtra("Contador", -1);
        minutes = min != -1 ? min : minutes;
        int anHour = minutes * 60 * 1000;   // Number of milliseconds

        long triggerAtTime = SystemClock.ElapsedRealtime() + anHour; 

        Intent i = new Intent(this, typeof(AlarmReceiver));
        PendingIntent pi = PendingIntent.GetBroadcast(this, 0, i, PendingIntentFlags.UpdateCurrent);

        manager.SetExactAndAllowWhileIdle(AlarmType.ElapsedRealtimeWakeup, triggerAtTime, pi);
        return StartCommandResult.Sticky;
    }
}

in Android проект, создать AlarmReceiver :

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
class AlarmReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        Intent i = new Intent(context, typeof(LongRunningService));
        context.StartService(i);
    }
}

Тогда вы можете вызвать его на своей странице, например:

 DependencyService.Get<IVarios>().ProgAlarm(1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...