我想在個人項目中實現計劃功能。 因此我用Google搜索了一個警報管理器程序,可是找不到任何示例。 java
有人能夠經過基本的警報管理器程序幫助我嗎? android
這是一個至關獨立的示例。 5秒後,按鈕變爲紅色。 app
public void SetAlarm() { final Button button = buttons[2]; // replace with a button from your own UI BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive( Context context, Intent _ ) { button.setBackgroundColor( Color.RED ); context.unregisterReceiver( this ); // this == BroadcastReceiver, not Activity } }; this.registerReceiver( receiver, new IntentFilter("com.blah.blah.somemessage") ); PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent("com.blah.blah.somemessage"), 0 ); AlarmManager manager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE )); // set alarm to fire 5 sec (1000*5) from now (SystemClock.elapsedRealtime()) manager.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000*5, pintent ); }
請記住,即便您的應用程序未運行,AlarmManager也會觸發。 若是調用此功能並按「主頁」按鈕,請等待5秒鐘,而後再返回到您的應用程序,該按鈕將變爲紅色。 ide
我不知道若是您的應用程序根本不在內存中,您將獲得什麼樣的行爲,所以請當心嘗試保持哪一種狀態。 ui
我嘗試了來自XXX的解決方案,雖然該解決方案最初確實有效,但在某個時候它中止了工做。 onReceive
再也不被調用。 我花了幾個小時試圖弄清楚它多是什麼。 我開始意識到,再也不出於任何神祕緣由而調用Intent
。 爲了解決這個問題,我發現您確實須要爲清單中的接收者指定一個操做。 例: this
<receiver android:name=".Alarm" android:exported="true"> <intent-filter> <action android:name="mypackage.START_ALARM" > </action> </intent-filter> </receiver>
請注意,名稱是帶有句點的".Alarm"
。 在XXX的setAlarm
方法中,以下建立Intent
: spa
Intent i = new Intent("mypackage.START_ALARM");
START_ALARM
消息能夠是您想要的任何消息。 我只是給這個名字起示範做用。 code
我沒有在清單中定義沒有指定動做的意圖過濾器的接收者。 按照XXX指定的方式建立它們彷佛是虛假的。 經過指定動做名稱,Android將被迫使用與該動做相對應的類建立BroadcastReceiver
的實例。 若是您依賴上下文,請注意,Android有幾個不一樣的對象,它們所有稱爲上下文,而且可能不會致使建立BroadcastReceiver
。 強迫Android僅使用操做消息建立類的實例要比依靠某些可能永遠沒法工做的虛假上下文好得多。 orm
此代碼將幫助您發出重複警報。 重複時間能夠由您設置。 xml
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#000000" android:paddingTop="100dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" > <EditText android:id="@+id/ethr" android:layout_width="50dp" android:layout_height="wrap_content" android:ems="10" android:hint="Hr" android:singleLine="true" > <requestFocus /> </EditText> <EditText android:id="@+id/etmin" android:layout_width="55dp" android:layout_height="wrap_content" android:ems="10" android:hint="Min" android:singleLine="true" /> <EditText android:id="@+id/etsec" android:layout_width="50dp" android:layout_height="wrap_content" android:ems="10" android:hint="Sec" android:singleLine="true" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:paddingTop="10dp"> <Button android:id="@+id/setAlarm" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClickSetAlarm" android:text="Set Alarm" /> </LinearLayout> </LinearLayout>
MainActivity.java
public class MainActivity extends Activity { int hr = 0; int min = 0; int sec = 0; int result = 1; AlarmManager alarmManager; PendingIntent pendingIntent; BroadcastReceiver mReceiver; EditText ethr; EditText etmin; EditText etsec; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ethr = (EditText) findViewById(R.id.ethr); etmin = (EditText) findViewById(R.id.etmin); etsec = (EditText) findViewById(R.id.etsec); RegisterAlarmBroadcast(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override protected void onDestroy() { unregisterReceiver(mReceiver); super.onDestroy(); } public void onClickSetAlarm(View v) { String shr = ethr.getText().toString(); String smin = etmin.getText().toString(); String ssec = etsec.getText().toString(); if(shr.equals("")) hr = 0; else { hr = Integer.parseInt(ethr.getText().toString()); hr=hr*60*60*1000; } if(smin.equals("")) min = 0; else { min = Integer.parseInt(etmin.getText().toString()); min = min*60*1000; } if(ssec.equals("")) sec = 0; else { sec = Integer.parseInt(etsec.getText().toString()); sec = sec * 1000; } result = hr+min+sec; alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), result , pendingIntent); } private void RegisterAlarmBroadcast() { mReceiver = new BroadcastReceiver() { // private static final String TAG = "Alarm Example Receiver"; @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Alarm time has been reached", Toast.LENGTH_LONG).show(); } }; registerReceiver(mReceiver, new IntentFilter("sample")); pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent("sample"), 0); alarmManager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE)); } private void UnregisterAlarmBroadcast() { alarmManager.cancel(pendingIntent); getBaseContext().unregisterReceiver(mReceiver); } }
若是您只須要一次警報,請更換
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), result , pendingIntent);
與
alarmManager.set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + result , pendingIntent );
我已經實現了本身的實現,以儘量簡單的方式作到這一點。
import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import junit.framework.Assert; /** * Created by Daniel on 28/08/2016. */ public abstract class AbstractSystemServiceTask { private final Context context; private final AlarmManager alarmManager; private final BroadcastReceiver broadcastReceiver; private final PendingIntent pendingIntent; public AbstractSystemServiceTask(final Context context, final String id, final long time, final AlarmType alarmType, final BackgroundTaskListener backgroundTaskListener) { Assert.assertNotNull("ApplicationContext can't be null", context); Assert.assertNotNull("ID can't be null", id); this.context = context; this.alarmManager = (AlarmManager) this.context.getSystemService(Context.ALARM_SERVICE); this.context.registerReceiver( this.broadcastReceiver = this.getBroadcastReceiver(backgroundTaskListener), new IntentFilter(id)); this.configAlarmManager( this.pendingIntent = PendingIntent.getBroadcast(this.context, 0, new Intent(id), 0), time, alarmType); } public void stop() { this.alarmManager.cancel(this.pendingIntent); this.context.unregisterReceiver(this.broadcastReceiver); } private BroadcastReceiver getBroadcastReceiver(final BackgroundTaskListener backgroundTaskListener) { Assert.assertNotNull("BackgroundTaskListener can't be null.", backgroundTaskListener); return new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { backgroundTaskListener.perform(context, intent); } }; } private void configAlarmManager(final PendingIntent pendingIntent, final long time, final AlarmType alarmType) { long ensurePositiveTime = Math.max(time, 0L); switch (alarmType) { case REPEAT: this.alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ensurePositiveTime, pendingIntent); break; case ONE_TIME: default: this.alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + ensurePositiveTime, pendingIntent); } } public interface BackgroundTaskListener { void perform(Context context, Intent intent); } public enum AlarmType { REPEAT, ONE_TIME; } }
惟一的下一步,實施它。
import android.content.Context; import android.content.Intent; import android.util.Log; import ...AbstractSystemServiceTask; import java.util.concurrent.TimeUnit; /** * Created by Daniel on 28/08/2016. */ public class UpdateInfoSystemServiceTask extends AbstractSystemServiceTask { private final static String ID = "UPDATE_INFO_SYSTEM_SERVICE"; private final static long REPEAT_TIME = TimeUnit.SECONDS.toMillis(10); private final static AlarmType ALARM_TYPE = AlarmType.REPEAT; public UpdateInfoSystemServiceTask(Context context) { super(context, ID, REPEAT_TIME, ALARM_TYPE, new BackgroundTaskListener() { @Override public void perform(Context context, Intent intent) { Log.i("MyAppLog", "-----> UpdateInfoSystemServiceTask"); //DO HERE WHATEVER YOU WANT... } }); Log.i("MyAppLog", "UpdateInfoSystemServiceTask started."); } }
我喜歡使用此實現,可是另外一種可能的好方法是,不要將AbstractSystemServiceTask
類抽象化,而是經過Builder進行構建。
但願對您有幫助。
UPDATED改進,容許在同一BroadCastReceiver
上使用多個BackgroundTaskListener
。
import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import junit.framework.Assert; import java.util.HashSet; import java.util.Set; /** * Created by Daniel on 28/08/2016. */ public abstract class AbstractSystemServiceTask { private final Context context; private final AlarmManager alarmManager; private final BroadcastReceiver broadcastReceiver; private final PendingIntent pendingIntent; private final Set<BackgroundTaskListener> backgroundTaskListenerSet; public AbstractSystemServiceTask(final Context context, final String id, final long time, final AlarmType alarmType) { Assert.assertNotNull("ApplicationContext can't be null", context); Assert.assertNotNull("ID can't be null", id); this.backgroundTaskListenerSet = new HashSet<>(); this.context = context; this.alarmManager = (AlarmManager) this.context.getSystemService(Context.ALARM_SERVICE); this.context.registerReceiver( this.broadcastReceiver = this.getBroadcastReceiver(), new IntentFilter(id)); this.configAlarmManager( this.pendingIntent = PendingIntent.getBroadcast(this.context, 0, new Intent(id), 0), time, alarmType); } public synchronized void registerTask(final BackgroundTaskListener backgroundTaskListener) { Assert.assertNotNull("BackgroundTaskListener can't be null", backgroundTaskListener); this.backgroundTaskListenerSet.add(backgroundTaskListener); } public synchronized void removeTask(final BackgroundTaskListener backgroundTaskListener) { Assert.assertNotNull("BackgroundTaskListener can't be null", backgroundTaskListener); this.backgroundTaskListenerSet.remove(backgroundTaskListener); } public void stop() { this.backgroundTaskListenerSet.clear(); this.alarmManager.cancel(this.pendingIntent); this.context.unregisterReceiver(this.broadcastReceiver); } private BroadcastReceiver getBroadcastReceiver() { return new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { for (BackgroundTaskListener backgroundTaskListener : AbstractSystemServiceTask.this.backgroundTaskListenerSet) { backgroundTaskListener.perform(context, intent); } } }; } private void configAlarmManager(final PendingIntent pendingIntent, final long time, final AlarmType alarmType) { long ensurePositiveTime = Math.max(time, 0L); switch (alarmType) { case REPEAT: this.alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ensurePositiveTime, pendingIntent); break; case ONE_TIME: default: this.alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + ensurePositiveTime, pendingIntent); } } public interface BackgroundTaskListener { void perform(Context context, Intent intent); } public enum AlarmType { REPEAT, ONE_TIME; } }
MainActivity.java
package com.example.alarmexample; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { Button b1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startAlert(); } public void startAlert() { int timeInSec = 2; Intent intent = new Intent(this, MyBroadcastReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast( this.getApplicationContext(), 234, intent, 0); AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (timeInSec * 1000), pendingIntent); Toast.makeText(this, "Alarm set to after " + i + " seconds",Toast.LENGTH_LONG).show(); } }
MyBroadcastReceiver.java
package com.example.alarmexample; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.media.MediaPlayer; import android.widget.Toast; public class MyBroadcastReceiver extends BroadcastReceiver { MediaPlayer mp; @Override public void onReceive(Context context, Intent intent) { mp=MediaPlayer.create(context, R.raw.alarm); mp.start(); Toast.makeText(context, "Alarm", Toast.LENGTH_LONG).show(); } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.alarmexample" > <uses-permission android:name="android.permission.VIBRATE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.alarmexample.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name="MyBroadcastReceiver" > </receiver> </application> </manifest>