LoginSignup
0
0

More than 1 year has passed since last update.

Xamarin.FormsでBroadcastReceiverを使う場合は覚悟する

Last updated at Posted at 2022-06-21

はじめに

Xamarinは、C#でアプリ作りたい人は良いかもしれません。
特にXamarin.Formsを使い、Androidアプリでローカル通知も考えている人向きの記事になります。

BroadcastReceiver

Xamarin.Formsは、DependencyService.Get 経由でOSネイティブの処理をDI的に呼び出すことができます。

Androidネイティブ処理と同様にプログラミングするとローカル通知などでネイティブ処理と同様に処理できるのですが、ここでは詳しいことは省略します。

[BroadcastReceiver(DirectBootAware = true)]
public class AlarmReceiver : BroadcastReceiver
{

    public override void OnReceive(Context context, Intent intent)

などとするとブロードキャストを受け取れます。

OSネイティブからXamarin.Formsの処理も呼び出せる

さてここで、依存プロジェクトを設定するとOSネイティブから Xamarin.Forms側に書いた処理も呼び出せます。

ログや次の通知などの処理も共通処理として呼び出すことができます。

アプリがメモリ上から消えていた場合の罠

大抵は
OSネイティブ -> Xamarin.Forms
側の処理を呼び出しても問題ないのですが、

長時間アプリが使われてない場合やタスクキルされた場合、
アプリがメモリ上から消えていた場合、DependencyService.Get で例外が発生する可能性があります。

You MUST call Xamarin.Forms.Init(); prior to using it

DependencyService.GetXamarin.Formsの初期化が必要だったのです。

タスクキルされるとその初期化の状態も失います。

しかもバックグラウンドなのでアプリが落ちたという表示もありません。

OnReceive から global::Xamarin.Forms.Forms.Init(this, bundle);
を呼び出せばよいが初期化に時間がかかってバックグラウンドでの制限時間オーバーのため打ち切られてしまう可能性もある。

つまりできることは、
OSネイティブ -> Xamarin.Forms
で呼び出す処理すべてから DependencyService.Get を取り除かないといけないことになります。

しかも一旦書いてしまったものから取り除くのは大変で、ライブラリの中で書かれていたりすると大変です..

もう投げ出したくなります。

ローカル通知のテスト

OnReceive で次の通知を設定しようとしているなら、テストがさらに大変です。

直近のローカル通知はおそらく何も問題がないのですが、そのOnReceiveを受け取った段階ではXamarin.Forms が生きてない可能性があるため、
直近のローカル通知を受け取る前にタスクキルや端末再起動などを行って、メモリ上から消えている状態にして
logcatとにらめっこすることや、adbコマンドなどで通知の存在を確認することになります。

adb shell dumpsys alarm

このコマンドの存在を知らなかったらだいぶきつい。

これをちゃんと確認しないと、「テスト段階では通知来たので大丈夫と思ったのに、本番だと通知が来ない。」
という羽目になります。

まとめ

DependencyService.Get くらいXamarin.Formsの初期化なしで使わせてほしい。

そもそもXamarinを

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0