2012-03-31 20 views
2

私はシステムアラーム(RTC_WAKEUP)でデバイスを起動し、私のアプリを開くタイマーのアプリケーションがあります。何千もの成功した警報の後、それはちょうど起こった、設定された警報が完全に成功しなかったこと。それはonReceive()の間に死んで、私のアプリを起動しなかったし、システム通知を発しませんでした。androidアラームがonReceive中に死んだ

アラームがトリガされた
public void onReceive(Context context, Intent intent) { 
    Log.i("timer", "timer's end broadcast received at: " + (System.currentTimeMillis()/1000)); 
    m_Context = context; 

    Bundle extras = intent.getExtras(); 
    final int id = extras.getInt("timer_id"); 

    Intent activityIntent = new Intent(m_Context, TinyTimerActivity.class); 
    activityIntent.putExtra("timer_id", id); 
    activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    m_Context.startActivity(activityIntent); 

    m_SharedPrefs = PreferenceManager.getDefaultSharedPreferences(m_Context); 

    // start the alarm sound 
    final AudioManager localAudioManager = (AudioManager)m_Context.getSystemService("audio"); 
    final int ringerMode = localAudioManager.getRingerMode(); 
    final boolean audibleInSilentMode = m_SharedPrefs.getBoolean("audible_in_silent_mode", true); 
    final boolean silentAlarm = m_SharedPrefs.getBoolean("silent_alarm", false); 

    // and now load the alarm sound and play it for the desired time 
    showFinishedNotification(!silentAlarm && (ringerMode != AudioManager.RINGER_MODE_SILENT || audibleInSilentMode)); 

    // cancel the alarm after some time 
    final int duration = Integer.parseInt(m_SharedPrefs.getString("alarm_length", "-1")); 
    if (duration > 0) { 
     (new Handler()).postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       ((NotificationManager)m_Context.getSystemService(Context.NOTIFICATION_SERVICE)).cancel(NOTIFICATION_TIMER_FINISED_ID); 
      } 
     }, duration * 1000); 
    } 
} 

、私はgReaderアプリを使用していました。ここにBroadcastReceiverのonReceive()メソッドです。ここでlogcatは(私のアプリがsk.martinflorek.TinyTimerである)である:

I( 146) Start proc sk.martinflorek.TinyTimer for broadcast sk.martinflorek.TinyTimer/.timers.TimerReceiver: pid=18307 uid=10070 gids={3003} (ActivityManager) 
I(18307) Pub sk.martinflorek.TinyTimer.providers.TimersProvider: sk.martinflorek.TinyTimer.providers.TimersProvider (ActivityThread) 
I(18307) timer's end broadcast received at: 1333208420 (timer) 
I( 146) Starting: Intent { flg=0x30000000 cmp=sk.martinflorek.TinyTimer/.TinyTimerActivity (has extras) } from pid 18307 (ActivityManager) 
D(18198) couldn't save which view has focus because the focused view [email protected] has no id. (PhoneWindow) 
I( 146) No longer want android.process.media (pid 17918): hidden #16 (ActivityManager) 
I( 146) Sending signal. PID: 18307 SIG: 9 (Process) 
I( 146) Kill sk.martinflorek.TinyTimer (pid 18307): provider com.android.providers.media.MediaProvider in dying process android.process.media (ActivityManager) 
I( 146) Process sk.martinflorek.TinyTimer (pid 18307) has died. (ActivityManager) 

はなぜandroid.process.mediaは私のアプリを殺さなかったし、これを防止するために、どのように?それは一度だけ起こります...

+0

あなたのアプリがコンテンツプロバイダ用の開いたCursorオブジェクトを保持している場合に、この問題が発生する可能性があります。 MediaProviderはあなたのアプリケーションのクラッシュに関わっていたので、cursor.close()がどこかで呼び出されなかった可能性があります。 – acj

+0

@acj BroadcastReceiverはカーソルを開かず(アプリケーション自体がいくつかのカーソルを起動時に開きます)、私の知識アプリには複数のカーソルが同時に開くことがあります。これはまだ問題ではありますか? – shelll

+0

可能です。私が考えているシナリオでは、しばらくの間、アプリケーションを使用して、いくつかのカーソルを開いて、他のアプリケーションに移動します。あなたのアプリは停止されていますが、メモリに残ります。ある時点(おそらくあなたのBroadcastReceiverが実行されている)で、MediaProviderが殺されることがあります。あなたはまだカーソルを開いているので、あなたのアプリも殺されます。カーソルを閉じる_この問題を回避する必要があります。 – acj

答えて

0

BroadcastReceiverは長時間の操作では意味がありません。 BroadcastReceiverは非常に短命であると考えられています。私は他の人からBroadcastReceiverが最大50 ms持続するべきであることを読みました。それ以上の場合は、Serviceを開始してください。

だからあなたはどちらかだけのServiceを開始するか、BroadcastReceiver内からServiceを開始し、Serviceに(例えばHandler.postDelayed()など)のコードを消費する任意の時間を移動するために、アラームを設定する必要があります。

+0

postDelayed()の部分がその状況で使用されていませんでした。レシーバのコードが十分速かったので、アクティビティを開始して通知を表示する必要がありました。 – shelll

+0

さて、あなたがしたことがすべて 'startActivity'であり、通知を表示すれば、なぜそれが死ぬのか説明できない理由はありません。場合によっては、問題の原因となるAndroidのエラーがあります。他に何もしておらず、毎回起こっているのであれば、あなたのコードに誤りがあるかもしれません。しかし、これが一度だけ起こったら、それを肩をすくめて、再び起こらないことを願ってください。 – Jakar

関連する問題