Sdílet prostřednictvím


Přijímače všesměrových vysílání v Xamarin.Androidu

Tato část popisuje, jak používat přijímač vysílání.

Přehled přijímače vysílání

Přijímač vysílání je komponenta androidu, která aplikaci umožňuje reagovat na zprávy (AndroidIntent), které jsou vysílány operačním systémem Android nebo aplikací. Vysílání se řídí modelem publikování a odběru – událost způsobí publikování a přijetí vysílání komponentami, které mají zájem o událost.

Android identifikuje dva typy vysílání:

  • Explicitní vysílání – tyto typy všesměrových vysílání cílí na konkrétní aplikaci. Nejběžnějším použitím explicitního vysílání je spuštění aktivity. Příklad explicitního vysílání, když aplikace potřebuje vytočit telefonní číslo; Odešle záměr, který cílí na aplikaci Telefon v Androidu a předá telefonní číslo, které se má vytočit. Android pak bude směrovat záměr do aplikace Telefon.
  • Implicitní vysílání – Tato vysílání se odesílají do všech aplikací na zařízení. Příkladem implicitního vysílání je ACTION_POWER_CONNECTED záměr. Tento záměr se publikuje pokaždé, když Android zjistí, že se baterie na zařízení nabíjí. Android tento záměr přesměruje na všechny aplikace, které se k této události zaregistrovaly.

Přijímač všesměrového vysílání je podtřídou BroadcastReceiver typu a musí přepsat metodu OnReceive . Android se spustí OnReceive v hlavním vlákně, takže tato metoda by měla být navržena tak, aby se spustila rychle. Při vytváření vláken v OnReceive systému android je potřeba věnovat pozornost tomu, že po dokončení metody může proces ukončit. Pokud přijímač všesměrového vysílání musí provádět dlouhou práci, doporučuje se naplánovat úlohu pomocí JobSchedulerdispečeru úlohy Firebase. Plánování práce s úlohou bude popsáno v samostatné příručce.

Filtr záměru slouží k registraci příjemce vysílání, aby Android mohl správně směrovat zprávy. Filtr záměru lze zadat za běhu (někdy se označuje jako příjemce zaregistrovaný v kontextu nebo jako dynamická registrace) nebo může být staticky definován v manifestu Androidu (příjemce zaregistrovaný manifestem). Xamarin.Android poskytuje atribut jazyka C#, IntentFilterAttributekterý staticky zaregistruje filtr záměru (podrobněji se probereme dále v této příručce). Počínaje Androidem 8.0 není možné, aby aplikace staticky zaregistrovala implicitní vysílání.

Primární rozdíl mezi příjemcem registrovaným manifestem a příjemcem registrovaným kontextem spočívá v tom, že příjemce zaregistrovaný v kontextu bude reagovat pouze na vysílání v době, kdy aplikace běží, zatímco příjemce zaregistrovaný manifestem může reagovat na všesměrové vysílání, i když aplikace nemusí být spuštěná.

Existují dvě sady rozhraní API pro správu přijímače všesměrového vysílání a odesílání vysílání:

  1. Context – Třídu Android.Content.Context lze použít k registraci přijímače vysílání, který bude reagovat na události na úrovni celého systému. Slouží Context také k publikování všesměrových vysílání pro celý systém.
  2. LocalBroadcastManager – Toto je rozhraní API, které je k dispozici prostřednictvím balíčku NuGet knihovny podpory Xamarin v4. Tato třída se používá k zachování všesměrových a všesměrových přijímačů izolovaných v kontextu aplikace, která je používá. Tato třída může být užitečná pro zabránění jiným aplikacím v reakci na vysílání pouze aplikace nebo odesílání zpráv soukromým příjemcům.

Přijímač vysílání nemusí zobrazovat dialogy a důrazně se nedoporučuje zahajovat aktivitu v rámci přijímače vysílání. Pokud příjemce vysílání musí uživatele upozornit, měl by publikovat oznámení.

Není možné svázat nebo spustit službu z přijímače vysílání.

Tento průvodce popisuje, jak vytvořit přijímač vysílání a jak ho zaregistrovat, aby mohl přijímat vysílání.

Vytvoření přijímače všesměrového vysílání

Pokud chcete vytvořit přijímač vysílání v Xamarin.Android, aplikace by měla podtřídu třídy BroadcastReceiver , doplnit ji pomocí BroadcastReceiverAttributea přepsat metodu OnReceive :

[BroadcastReceiver(Enabled = true, Exported = false)]
public class SampleReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Do stuff here.

        String value = intent.GetStringExtra("key");
    }
}

Když Xamarin.Android zkompiluje třídu, aktualizuje také AndroidManifest potřebnými meta-daty pro registraci příjemce. Pro staticky zaregistrovaný přijímač vysílání musí Enabled být správně nastaven na true, jinak Android nebude moci vytvořit instanci příjemce.

Vlastnost Exported určuje, zda příjemce vysílání může přijímat zprávy z mimo aplikaci. Pokud vlastnost není explicitně nastavena, výchozí hodnota vlastnosti je určena Androidem na základě toho, jestli jsou k příjemci vysílání přidružené nějaké filtry záměru. Pokud pro příjemce vysílání existuje alespoň jeden filtr záměru, Android předpokládá, že Exported vlastnost je true. Pokud nejsou žádné filtry záměru spojené s příjemcem vysílání, Android předpokládá, že hodnota je false.

Metoda OnReceive obdrží odkaz na Intent to, který byl odeslán do přijímače vysílání. To umožňuje odesílateli záměru předat hodnoty příjemci vysílání.

Staticky registrace přijímače všesměrového vysílání s filtrem záměru

BroadcastReceiver Při dekorování IntentFilterAttributepomocí xamarin.Android přidá potřebný <intent-filter> prvek do manifestu Androidu v době kompilace. Následující fragment kódu je příkladem přijímače všesměrového vysílání, který se spustí po dokončení spouštění zařízení (pokud uživatel udělil příslušná oprávnění Androidu):

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class MyBootReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Work that should be done when the device boots.     
    }
}

Poznámka:

V Androidu 8.0 (ROZHRANÍ API 26 a novějších) společnost Google umístila omezení, která aplikace můžou dělat, zatímco uživatelé s nimi přímo nekomuagují. Tato omezení mají vliv na služby na pozadí a implicitní přijímače vysílání, například Android.Content.Intent.ActionBootCompleted. Z těchto omezení může být obtížné zaregistrovat Boot Completed přijímač vysílání v novějších verzích Androidu. Pokud se jedná o tento případ, mějte na paměti, že tato omezení se nevztahují na služby na popředí, které lze volat z vašeho přijímače vysílání.

Je také možné vytvořit filtr záměru, který bude reagovat na vlastní záměry. Představte si následující příklad:

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { "com.xamarin.example.TEST" })]
public class MySampleBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Do stuff here
    }
}

Aplikace, které cílí na Android 8.0 (úroveň rozhraní API 26) nebo vyšší, nemusí staticky registrovat pro implicitní vysílání. Aplikace se můžou staticky registrovat k explicitnímu vysílání. Existuje malý seznam implicitních vysílání, které jsou z tohoto omezení vyloučené. Tyto výjimky jsou popsány v průvodci výjimkami implicitního vysílání v dokumentaci k Androidu. Aplikace, které mají zájem o implicitní vysílání, to musí provést dynamicky pomocí RegisterReceiver metody. Toto je popsáno dále.

Registrace přijímače všesměrového vysílání v kontextu

Kontextová registrace (označovaná také jako dynamická registrace) přijímače se provádí vyvoláním RegisterReceiver metody a příjemce vysílání musí být odregistrován voláním metody UnregisterReceiver . Pokud chcete zabránit úniku prostředků, je důležité zrušit registraci příjemce, pokud už není relevantní pro kontext (aktivita nebo služba). Například služba může vysílat záměr informovat aktivitu, že aktualizace jsou k dispozici k zobrazení uživateli. Když se aktivita spustí, zaregistruje se pro tyto záměry. Když se aktivita přesune na pozadí a uživateli se už nezobrazí, měla by zrušit registraci příjemce, protože uživatelské rozhraní pro zobrazení aktualizací už není viditelné. Následující fragment kódu je příkladem registrace a zrušení registrace příjemce vysílání v kontextu aktivity:

[Activity(Label = "MainActivity", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity: Activity
{
    MySampleBroadcastReceiver receiver;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        receiver = new MySampleBroadcastReceiver();

        // Code omitted for clarity
    }

    protected override void OnResume()
    {
        base.OnResume();
        RegisterReceiver(receiver, new IntentFilter("com.xamarin.example.TEST"));
        // Code omitted for clarity
    }

    protected override void OnPause()
    {
        UnregisterReceiver(receiver);
        // Code omitted for clarity
        base.OnPause();
    }
}

V předchozím příkladu, když aktivita přichází do popředí, zaregistruje příjemce vysílání, který bude naslouchat vlastnímu záměru pomocí OnResume metody životního cyklu. Když se aktivita přesune na pozadí, OnPause() metoda zruší registraci příjemce.

Publikování vysílání

Všesměrové vysílání může být publikováno do všech aplikací nainstalovaných na zařízení, které vytváří objekt záměru a odesílá ho pomocí SendBroadcast metody nebo metody SendOrderedBroadcast .

  1. Context.SendBroadcast metody – Existuje několik implementací této metody. Tyto metody budou vysílat záměr do celého systému. Přijímače vysílání, které obdrží záměr v nedeterminátu pořadí. To poskytuje velkou flexibilitu, ale znamená to, že je možné, aby se ostatní aplikace zaregistrovaly a přijímaly záměr. To může představovat potenciální bezpečnostní riziko. Aplikace můžou potřebovat implementovat další zabezpečení, aby se zabránilo neoprávněnému přístupu. Jedním z možnýchřešeních LocalBroadcastManager Tento fragment kódu je jedním z příkladů odeslání záměru SendBroadcast pomocí jedné z metod:

    Intent message = new Intent("com.xamarin.example.TEST");
    // If desired, pass some values to the broadcast receiver.
    message.PutExtra("key", "value");
    SendBroadcast(message);
    

    Tento fragment kódu je dalším příkladem odeslání všesměrového vysílání pomocí Intent.SetAction metody k identifikaci akce:

    Intent intent = new Intent();
    intent.SetAction("com.xamarin.example.TEST");
    intent.PutExtra("key", "value");
    SendBroadcast(intent);
    
  2. Context.SendOrderedBroadcast – Tato metoda je velmi podobná Context.SendBroadcast, s rozdílem, že záměr bude publikován jeden po druhém příjemcům v pořadí, v jakém byli příjemci zaregistrováni.

LocalBroadcastManager

Xamarin Support Library v4 poskytuje pomocnou třídu s názvem LocalBroadcastManager. Je LocalBroadcastManager určen pro aplikace, které nechtějí odesílat ani přijímat vysílání z jiných aplikací na zařízení. Zprávy LocalBroadcastManager budou publikovány pouze v kontextu aplikace a pouze pro ty příjemce vysílání, které jsou registrovány v LocalBroadcastManageraplikaci . Tento fragment kódu je příkladem registrace přijímače LocalBroadcastManagervysílání v:

Android.Support.V4.Content.LocalBroadcastManager.GetInstance(this). RegisterReceiver(receiver, new IntentFilter("com.xamarin.example.TEST"));

Jiné aplikace na zařízení nemůžou přijímat zprávy, které jsou publikovány LocalBroadcastManagerpomocí nástroje . Tento fragment kódu ukazuje, jak odeslat záměr pomocí :LocalBroadcastManager

Intent message = new Intent("com.xamarin.example.TEST");
// If desired, pass some values to the broadcast receiver.
message.PutExtra("key", "value");
Android.Support.V4.Content.LocalBroadcastManager.GetInstance(this).SendBroadcast(message);