1

即使應用程序關閉,我也想使鬧鐘運行, 當應用程序未關閉時,一切正常, 但當觸發時間並關閉應用程序時,時間到了應用程序崩潰的時候。 我嘗試了一些解決方案,但他們沒有幫助。當應用程序關閉時廣播接收器

這裏是我的代碼:

public class MainActivity extends Activity { 

//used for register alarm manager 
PendingIntent pendingIntent; 
//used to store running alarmmanager instance 
AlarmManager alarmManager; 
//Callback function for Alarmmanager event 
BroadcastReceiver mReceiver; 

TimePicker tp; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    //Register AlarmManager Broadcast receive. 
    RegisterAlarmBroadcast(); 

    tp = (TimePicker)findViewById(R.id.timePicker1); 
    tp.setIs24HourView(true); 

    Calendar cal=Calendar.getInstance(); 
    tp.setCurrentHour(cal.get(Calendar.HOUR_OF_DAY)); 
    tp.setCurrentMinute(cal.get(Calendar.MINUTE)); 

} 

public void onClickSetAlarm(View v) 
{ 
    //Get the current time and set alarm after 10 seconds from current time 
    // so here we get 
    Calendar time = Calendar.getInstance(); 
    time.set(Calendar.HOUR_OF_DAY, tp.getCurrentHour()); 
    time.set(Calendar.MINUTE, tp.getCurrentMinute()); 
    time.set(Calendar.SECOND, 0); 

    alarmManager.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent); 
    tp.setEnabled(false); 
// alarmManager.set(AlarmManager.RTC_WAKEUP, 
//   System.currentTimeMillis() + Integer.parseInt(time.getText().toString()) * 1000 , pendingIntent); 
} 

private void RegisterAlarmBroadcast() 
{ 
    // Log.i("Alarm Example:RegisterAlarmBroadcast()", "Going to register Intent.RegisterAlramBroadcast"); 

    //This is the call back function(BroadcastReceiver) which will be call when your 
    //alarm time will reached. 
    mReceiver = new BroadcastReceiver() 
    { 
     private static final String TAG = "Alarm Example Receiver"; 
     @Override 
     public void onReceive(Context context, Intent intent) 
     { 
      //Log.i(TAG,"BroadcastReceiver::OnReceive() >>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); 
      Toast.makeText(context, "Congrats!. Your Alarm time has been reached", Toast.LENGTH_LONG).show(); 
      tp.setEnabled(true); 

      // define sound URI, the sound to be played when there's a notification 
      Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 

      // intent triggered, you can add other intent for other actions 

      PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this, 0, new Intent("MY_ALARM_NOTIFICATION").setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0); 

      // this is it, we'll build the notification! 
      // in the addAction method, if you don't want any icon, just set the first param to 0 
      Notification mNotification = new Notification.Builder(MainActivity.this) 

       .setContentTitle("New Post!") 
       .setContentText("Here's an awesome update for you!") 
       .setSmallIcon(R.drawable.ic_launcher) 
       .setContentIntent(pIntent) 
       .setSound(soundUri) 

       // .addAction(R.drawable.ninja, "View", pIntent) 
       .addAction(0, "Remind", pIntent) 
       .build(); 

      NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 

      // If you want to hide the notification after it was selected, do the code below 
      // myNotification.flags |= Notification.FLAG_AUTO_CANCEL; 

      notificationManager.notify(0, mNotification); 
     } 
    }; 

    // register the alarm broadcast here 
    registerReceiver(mReceiver, new IntentFilter("MY_ALARM_NOTIFICATION")); 
    pendingIntent = PendingIntent.getBroadcast(this, 123456789, new Intent("MY_ALARM_NOTIFICATION").setFlags(Intent.FLAG_ACTIVITY_NEW_TASK),0); 
    alarmManager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE)); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
    } 
} 
private void UnregisterAlarmBroadcast() 
{ 
    alarmManager.cancel(pendingIntent); 
    getBaseContext().unregisterReceiver(mReceiver); 
} 
@Override 
protected void onDestroy() { 
    unregisterReceiver(mReceiver); 
    super.onDestroy(); 
    } 
} 

任何形式的幫助,將不勝感激。

這裏是我的manifest.xml:

<receiver android:name=".MainActivity" > 

     <intent-filter> 
      <action android:name="MY_ALARM_NOTIFICATION" /> 
     </intent-filter> 

    </receiver> 
+0

它究竟如何崩潰?請發佈logcat轉儲。 – 2014-10-20 20:22:59

回答

1

您已將清單中的Activity定義爲<receiver>。這是行不通的。

這裏有幾個問題。

  1. 您的BroadcastReceiver必須在清單中聲明爲<receiver>標記。這意味着您用作BroadcastReceiver的課程必須是公開的。
  2. 在您的代碼中,您已將BroadcastReceiver聲明爲匿名類。一般來說,這將起作用,但如果BroadcastReceiver需要從應用程序之外的組件調用,則這不起作用。 AlarmMnager在您的應用程序之外運行(實際上,它甚至會在應用程序未運行時觸發警報),因此您的BroadcastReceiver必須定義爲擴展BroadcastReceiver的公共類。
  3. 您正在致電PendingIntent.getActivity()。如果你想開始BroadcastReceiver,那麼你需要撥打PendingIntent.getBroadcast()
  4. 在您的onReceive()方法中,您正在使用的成員變量是null,當您的應用程序未運行時觸發警報。由於即使您的應用程序未運行,AlarmManager也會觸發警報,因此在調用onReceive()時,不能指望已設置任何成員變量

我建議你看看如何做到這一點的一些例子。有很多可用的。

2

甚至沒有看到堆棧跟蹤,我會猜測,AlarmManager試圖提供警報,但由於您的應用程序已被殺害和Receiver你註冊已被殺害,NullPointerExceptionAlarmManager中的某處。根據設計,當您知道您的Activity正在遠離(例如在onStop())時,您必須取消註冊/刪除警報。如果你想讓你的報警器工作時,你的應用程序是不可見的和/或它的封閉後:

  1. 你需要在你AndroidManifest.xml註冊的接收器。在應用程序離開導航後,應用程序內以編程方式註冊的接收者不應該活動 - 並且如果用戶退出應用程序,則會與應用程序一起銷燬。

  2. 您可能還想在您的接收器中註冊BOOT_COMPLETED。當設備重新啓動時,所有報警丟失,因此無論何時重新啓動設備,您都需要重新設置報警(檢查SharedPreferences標誌以查看是否應該有一組報警)。

+0

感謝的對你有所幫助,這裏是我的清單: <接收器的android:NAME = 「MainActivity。」> <意圖過濾器> <操作機器人:名字= 「MY_ALARM_NOTIFICATION」/> zb22 2014-10-21 08:14:25

相關問題