質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Android Widget

ホームスクリーンウィジェット、またはAndroidアプリケーションのスクリーン上で使用される一般的なユーザインタフェース要素に関連することを指します。

Q&A

解決済

1回答

3764閲覧

[xamarin.android]AppWidgetアプリをアップデートしたタイミングで処理を行いたい

mika33532

総合スコア27

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Android Widget

ホームスクリーンウィジェット、またはAndroidアプリケーションのスクリーン上で使用される一般的なユーザインタフェース要素に関連することを指します。

0グッド

0クリップ

投稿2017/04/26 06:55

編集2017/04/26 06:57

開発環境

・VisualStudio2017 C# xamarin.android
・Windows7
・Android 7.1.2(Nexus5X)

アプリ概要

1秒おきに表示更新するシンプルな時計ウィジェットアプリを制作しています。

AppWidgetProviderとServiceの派生クラスを作成し、
Intent.ActionTimeTick("android.intent.action.TIME_TICK")を
1分おきに受信して1秒間隔タイマーを起動し表示更新しています。
タイマーは60秒で終了し、次のIntent.ActionTimeTickでまたタイマーを起動して繰り返します。
この処理はServiceで行っています。

質問内容

現在は開発中でVS2017からデバッグ実行してNexus5X上で実行しています。
初期インストール時は問題ないのですが、
ウィジェットを配置し動作させた状態でVisualStudioからデバッグ実行して
アプリ更新するとウィジェットの1秒毎の表示更新が停止してしまいます。

アプリを更新するとServiceやIntent.ActionTimeTickの通知が停止してしまうようなので
再起動する処理を実装したいのですがそのタイミングが取れません。
Service#OnCreate(),OnDestroy(),OnStartCommand()や
Application派生クラスを実装してApplication#OnCreate()などに
デバッグログ出力コードを入れてみたのですが、いずれも実行されていないようでした。
あとバージョン番号をあげて試してみましたが同様でした。

たぶん、Google Playでアプリを更新するときにも
同じ問題が発生するような気がするので対処が必要だと思っています。

以前Eclipse環境で同じようなアプリを制作したときにはこのような症状は無かったと思うのですが、、、
数年前のことなのでSDKの違いもあるのかもしれませんが。。

再起動する処理を実装する方法を教えていただけませんでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ウィジェットを作ったことがないので見当違いなことを言っているかもしれませんが、
BroadcastReceiverではだめでしょうか?

アプリ更新時
android.intent.action.MY_PACKAGE_REPLACED
もしくは
android.intent.action.PACKAGE_REMOVED
android.intent.action.PACKAGE_ADDED
android.intent.action.PACKAGE_REPLACED

端末が再起動したときも考慮して、android.intent.action.BOOT_COMPLETEDも見るとよいかと思います

サンプルコード

using Android.App; using Android.Content; namespace MyApp.Droid { [BroadcastReceiver] [IntentFilter(new[] { "android.intent.action.BOOT_COMPLETED" , "android.intent.action.MY_PACKAGE_REPLACED" })] public class MyBroadcastReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { var myIntent = new Intent(context, typeof(MyService)); context.StartService(myIntent); } } }

投稿2017/04/26 09:43

編集2017/04/26 09:47
yamataka3

総合スコア145

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mika33532

2017/04/26 10:47 編集

ご回答ありがとうございました!(^^) MY_PACKAGE_REPLACEDは知りませんでした。 これを受信すればできそうですね。 実際に組み込んでやってみたのですが、受信できるところまで確認できませんでした。 他にも問題がありそうな気がしますので、もっと単純なテストアプリを作成して 確認してみようと思います。
mika33532

2017/04/26 19:24

いろいろやってみたんですが、MY_PACKAGE_REPLACEDを受信できませんでした。 Receiverはこのようにコーディングしてます。(確認用にIntentFilterのActionをたくさん入れてます) 他のアプリを消したときにPACKAGE_REMOVEDは受信できているので問題は無さそうな気がします。。 ```C# [BroadcastReceiver(Name = "com.domain.appname.AppReceiver")] [IntentFilter(new[] { Intent.ActionPackageAdded, Intent.ActionPackageChanged, Intent.ActionPackageRemoved, Intent.ActionPackageReplaced, Intent.ActionMyPackageReplaced }, DataScheme ="package")] public class AppReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { Android.Util.Log.Debug(TAG, "action:" + intent.Action); } } ``` 確認手順はこのように行っています。 1.新規でAppWidgetアプリをNexus5Xへインストール。(VSの「デバッグの開始 F5」で実行) 2.ウィジェットを貼り付ける。Serviceが起動して時計が動く。(アプリはSTART状態になる) 3.VSで「デバッグの開始 F5」を再度行い、アプリを更新する。 ※この段階でMY_PACKAGE_REPLACEDが受信できると想定しているのですが、デバイスログにログが出力されませんでした。 また、手順3の前にバージョン番号をあげてから実行すると 配置していたウィジェットが消されてしまいました。 デバイスログをみるとパッケージが削除されてからインストールされるようなので、 パッケージが一時的に無くなったために削除されてしまうようです。 (AppWidgetHostView Package name com.domain.appname not found というログが出力されてました) Eclipseで製作した別のアプリ(Google Playに公開してバージョンアップもしています)では バージョンアップでウィジェットが消えてしまうようなことも 時計がフリーズしてしまうことも無かったので同じようにしたいと思っています。 コーディングや確認手順等に問題がありそうでしたら、ご指摘いただけると助かります。 よろしくお願いいたします。
yamataka3

2017/04/27 03:01

AppWidgetについて少し調べてみました。 AppWidgetProviderがBroadcastReceiverを継承しているらしいので、 別途BroadcastReceiverを作成しなくても、AppWidgetProviderを継承したクラスの OnReceiveで同様の処理ができるみたいです。そちらでIntentを受信できないか確認してみてもらってもよいでしょうか。 その他のアプローチとして、デバッグ時に毎回通る初期化メソッドなどあれば、 そこでサービスの開始処理を記述してみる サービスのOnTaskRemovedやOnDestroyでサービスを再起動する処理を仕込んでみるなどどうでしょうか ``` public override void OnTaskRemoved(Intent rootIntent) { base.OnTaskRemoved(rootIntent); var intent = new Intent(this, typeof(MyService)); // ちょっと時間おいてから再起動 ((AlarmManager)GetSystemService(Context.AlarmService)) .Set(AlarmType.Rtc, Java.Lang.JavaSystem.CurrentTimeMillis() + 1000, PendingIntent.GetService(this, 11, intent, 0)); } ```
mika33532

2017/04/27 11:05

yamataka3 様、何度もご回答いただきありがとうございます。 BroadcastReceiverの処理をAppWidgetProviderの派生クラスに実装してみましたが、 状況変わりませんでした。 APPWIDGET_UPDATEやPACKAGE_ADDなどはきちんと受信できましたが、 MY_PACKAGE_REPLACEDは受信できませんでした。 あとアプリ更新時に、OnTaskRemovedやOnDestroyが呼び出されるか ログ出力コードを入れて確認してみましたが、デバイスログに出力されませんでした。 うーん。。 AndroidStudioで同じようなコードを書いてみて動くかどうかをやってみようと思います。 動いたら差分を確認してみようと思います。
mika33532

2017/04/27 17:50

AndroidStudioでサンプルアプリを作って試してみましたが、 2回ほどMY_PACKAGE_REPLACEDが受信できました。 しかしどんな状態のときに発信されるのかよく分からないので 試行錯誤してみたいと思います。 あとAlarmManagerを利用したサービス再起動処理を延々と続ける処理を入れたら うまくいくかやってみようと思います。 (Service#onDestoy()やonTaskRemoved()が実行されたら正常終了とみなして停止しますが) 解決するまで至りませんでしたが、 いろいろ教えていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問