BroadcastReceiverでToastを表示すると即消えてしまう

1,427 views
Skip to first unread message

KS

unread,
Nov 14, 2011, 11:00:06 PM11/14/11
to 日本Androidの会
お世話になっております。
主題の件ですが、どなたか分かる方ご教示ください。

・AlarmManagerで、指定時刻にBroadcastReceiverをキックする。
・BroadcastReceiverでは、特定の処理をしてから結果をToastに出す。

というアプリを作っているのですが、Toast.LENGTH_LONGを指定しているにも
関わらず、あっという間に表示が消えてしまい、悩んでいます。

どうも、Receiverのインスタンスが消滅するのと同時に、Toastも
道連れで消えているような。。

public class HogeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String msg = (何らかの処理);
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}

どなたか、原因 or 有効な回避策が分かる方、ご教示いただければ。。

元木

unread,
Nov 14, 2011, 11:20:34 PM11/14/11
to android-g...@googlegroups.com
こんにちは、元木です。

どのようなアプリを作成されているのか存じ上げないので
的外れな意見になってしまうかも
and ご質問の回答になっていませんが、、

処理結果の表示には、ToastでなくNotificationを
利用されてはいかがでしょうか?

Toastだと、(ご質問の現象が解決したとしても)何秒後かには
消えてしまうため、そのときユーザが画面を見ていなければ、
処理結果を知ることができなくなりそうな気がします。

awwa

unread,
Nov 15, 2011, 2:00:20 AM11/15/11
to android-g...@googlegroups.com
あわと申します。

気になって試してみました。

結果、onReceive()の中にsleep()をいれるとToast表示開始のタイミングが遅れてあっという間に消えるような動作になります。
sleep()を取り除くと、通常の表示時間は変わりませんでした。
LENGTH_LONGで3秒くらいではないかと思います。

恐らく、onReceive()内の「何らかの処理」に時間がかかっているのではないかと思います。
何らかの処理をコメントアウトしてみると問題を切り分けられるかと思います。
ちなみに、onReceive()内にsleep(4000)をいれるとToastは表示されませんでした。

onReceive()で重たい処理は避けるのが前提ということで。

ではでは。

2011年11月15日13:00 KS <mail.ks...@gmail.com>:

> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>
>

--
awwa <aww...@gmail.com>
Twitter http://twitter.com/awwa500
Blog http://awwa500.blogspot.com/

KS

unread,
Nov 15, 2011, 10:06:33 AM11/15/11
to 日本Androidの会
ご返信ありがとうございます。用途としては2つ考えているのですが、特にやりたいのは「端末をいじっている最中に届いたSMSを即プレビューしたい」と
いうものです。

自分の使っている端末は、届いたSMSの中身を開くのに画面を数回タップする必要があり、その都度、いまやっている作業を一度中断して、「意識的に見に
行く」という動作をはさむ必要があります。これが非常に煩雑で面倒くさいのです。。

Notificationも1タップで中身が読めるので、選択肢としては十分ありなのですが、いっそのことなら、メインの作業を中断することなく、片目
でSMSの内容も確認できるようにしたい、という半ばヨコシマな思いがモチベーションとなり、ちょっとずつ開発を進めておりました。

このため、実現したいことは非常にシンプルで、

 ・SMSの内容が「読み終えられるだけの短時間」だけ、ぽこっと画面に表示される。
 ・画面OFF中に届いたSMSは、作業前に開いて読む、と割り切る。
  (Toastには残らないがあきらめる)

のみなのですが、作ってみると意外に難航し、四苦八苦していた次第です。

KS

unread,
Nov 15, 2011, 10:13:40 AM11/15/11
to 日本Androidの会
ご返信いただきありがとうございます。わざわざ検証までしていただいたようで恐縮です。
Toast出す処理だけならLONGでもいけますか。。

やっていることは、届いたSMSの内容を横取りして表示するくらいの軽さなのですが、自分の端末(IS12SH)ですとToastが短時間で消えてしま
います。
あわさんにご紹介いただいた「sleepを挟んだ場合」の動きを自分の環境でも試してみたところ、確かにToastの表示時間が目で追えないほどに短く
なりました。

onReceiveは、用途に多少なり限りがある、と割り切ったほうが良いのかもしれませんね。
良い機会なので、どんなことができて、どんなことはできないか、実践+Web調べで調査をしてみようかと思います。

awwa

unread,
Nov 16, 2011, 9:21:33 AM11/16/11
to android-g...@googlegroups.com
あわです。
どれくらい軽い処理なのかよくわかりませんが、とりあえず、今回の目的を達成するためにはAsyncTaskか何かを使って別スレッドに処理させて、完了後Toastすると期待通りの動作になると思います。たぶん、こんな雰囲気です。ただ、リファレンスにもあるようにBroadcastReceiverは処理を待てないので、http://developer.android.com/intl/ja/reference/android/content/BroadcastReceiver.html今回のように処理をやりっ放しでいい場合にのみ使えると思います。もし、処理を待って他に色々とやりたければServiceを、ユーザからの入力が必要なのであればActivityを、それぞれonReceive()で起動してあげるのが一般的かと思います。
public class ToastReceiver extends BroadcastReceiver {
private Context context; @Override public void onReceive(Context
context, Intent intent) { this.context = context; ToastTask tt = new
ToastTask(); Integer[] params = null; tt.execute(params); } private
class ToastTask extends AsyncTask<Integer, Integer, Integer> {
@Override protected Integer doInBackground(Integer... params)
{ try { // 何か処理 Thread.sleep(5000); } catch
(InterruptedException e) { e.printStackTrace(); } //
onPostExecute()へ結果を渡す return 0; } protected void
onPostExecute(Integer result) { Toast.makeText(context, "終わったよ",
Toast.LENGTH_LONG).show(); } }
}
ではでは。

2011年11月16日0:13 KS <mail.ks...@gmail.com>:

KS

unread,
Nov 19, 2011, 11:50:29 AM11/19/11
to 日本Androidの会
あわさん、たびたびのご回答ありがとうございます。
(仕事が立て込んだりで、返信が遅れてしまいました。。)

いただいたコードですが、自分の環境ですとやっぱりToast即消えになってしまいました。
(端末によってAndroidのパラメータが微調整されていたりするのかも・・・?)

その後、自分もいろいろと調べ物をしたところ、

・そもそも、BroadcastReceiverは短時間(10秒)くらいの処理をひっそり
 やるためのもの。重いこと、目立つことはさせるべきでない。

というような情報にたどり着きました。
自分の使い方がそもそも悪かったと諦めるしかなさそうです。

----

↑の調べ物と平行して、ご紹介いただいたServiceについても勉強してみました。
で、さっそく処理をServiceにて実装しなおしたところ、今度は一発解決!
無事に長時間Toastが実現できました。

いやー、長かった、、そのぶん喜びもひとしおです。

まだまだひよっこですが、今回の教訓を経て、実現したい機能と実装への落とし込み方について
少なからず理解が深まってきたように思います。

いろいろとご教示いただき、本当にありがとうございました。

Reply all
Reply to author
Forward
0 new messages