Широковещательный приемник OnReceive не вызывается в Xamarin Android

Обычно я не задаю вопросы на таких форумах, как этот, но сегодня мое разочарование достигло неба.

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

В настоящее время я пытаюсь запустить широковещательный приемник, который запускается методом SetRepeating в AlarmManager. Мой код для основного действия + Receiver + Manifest выглядит следующим образом:

Основной метод (просто блок кода с запуском будильника):

    var lvarManager = (AlarmManager)GetSystemService (Context.AlarmService);

    Intent lvarCurrencyIntent = new Intent (this, typeof(CurrencyUpdateService));

    var lvarPendingIntent = PendingIntent.GetBroadcast (this, 0, lvarCurrencyIntent, PendingIntentFlags.CancelCurrent);
    lvarManager.SetRepeating (AlarmType.Rtc, 1000, 5000, lvarPendingIntent);

Получатель:

    public class CurrencyUpdateService : BroadcastReceiver
{       
    public override void OnReceive (Context context, Intent intent)
    {
        Toast.MakeText (context, "Running", ToastLength.Short).Show ();
    }
}

Манифест:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="SplitTheBill.SplitTheBill" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="16" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application android:label="SplitTheBill" android:icon="@drawable/groups"></application>
<receiver android:process=":remote" android:name=".CurrencyUpdateService"/>
<provider android:name="mono.MonoRuntimeProvider" android:exported="false" android:initOrder="2147483647" android:authorities="StockService.StockService.mono.MonoRuntimeProvider.__mono_init__" />

I want to state that I'm a somewhat new user of Xamarin and as it quite succesfully makes shure that you don't touch Manifest files, I only added the line:

<receiver android:process=":remote" android:name=".CurrencyUpdateService"/>

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

Не стесняйтесь предлагать свои собственные решения и смеяться мне в лицо за очевидные вопросы;)


person Marcin Bator    schedule 22.05.2016    source источник


Ответы (2)


1-й) Пометьте свой класс широковещательного приемника атрибутом BroadcastReceiver, чтобы соответствующий тег генерировался в вашем AndroidManifest.xml во время компиляции:

[BroadcastReceiver]
public class CurrencyUpdateService : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        Toast.MakeText(context, "Running", ToastLength.Short).Show();
    }
}

Теперь ваш приемник будет запускать тосты каждые 5 секунд.

Примечание. Xamarin автоматически создает идентификаторы имен классов Android, поэтому, если вы не жестко запрограммируете имя для своего класса, вы не сможете вручную отредактировать манифест, чтобы добавить этот элемент.

AndroidManifest.xml из приведенного выше кода генерирует (для меня):

<receiver android:name="md57db81284125fca721c48509d8e9cea0b.CurrencyUpdateService" />

Теперь, если вы вручную добавите Name к Attribute, вы сможете управлять тем, что генерируется. Это необходимо в тех случаях, когда другим приложениям Android необходимо позвонить вам и для этого требуется предопределенное (статическое) имя.

[BroadcastReceiver(Name = "com.sushihangover.alarmso.Foobar")]
public class CurrencyUpdateService : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        Toast.MakeText(context, "Running", ToastLength.Short).Show();
    }
}

Примечание: не используйте точечное имя в стиле Android, используйте полное имя, которое включает ваш имя пакета, см. ссылку для деталей

AndroidManifest.xml теперь содержит:

<receiver android:name="com.sushihangover.alarmso.Foobar" />

2nd) Что касается того, почему вы пытаетесь запустить новый процесс, помните, что BroadcastReceiver не является Android Service... Вы можете удалить тег :process в своем манифесте, поскольку он не нужен для того, что вы делаете.

Если вы действительно хотите создать и запустить локальную или фоновую службу, вам следует проверить:

person SushiHangover    schedule 22.05.2016

Спасибо за ответ.

В конце концов я заставил его работать, добавив атрибут фильтра намерений в класс CurrencyUpdateService, но я понял, что мне действительно нужен липкий сервис, который будет работать, даже если приложение будет закрыто.

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

Единственное, что нужно помнить, это не верить AlarmManager, когда речь идет о тестировании на коротких интервалах (‹ 10 минут), так как иногда он срабатывает не вовремя.

person Marcin Bator    schedule 28.05.2016