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 );
}
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 );
2
我已经尽可能以最简单的方式实现了自己的实现 .
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.");
}
}
6 回答
MainActivity.java
MyBroadcastReceiver.java
AndroidManifest.xml中
This is working code. It wakes CPU every 10 minutes until the phone turns off.
添加到Manifest.xml:
你班上的代码:
Set Alarm from Service:
If you want set alarm repeating at phone boot time:
向Manifest.xml添加权限和服务:
并创建新类:
我尝试了XXX的解决方案,虽然它最初工作,但在某些时候它停止了工作 .
onReceive
再也没有被召唤过 . 我花了好几个小时试图找出它可能是什么 . 我意识到的是,不管是什么神秘的原因,都不再被召唤出来了 . 为了解决这个问题,我发现你确实需要在清单中为接收者指定一个动作 . 例:请注意,名称为
".Alarm"
,包含句点 . 在XXX的setAlarm
方法中,按如下方式创建Intent
:START_ALARM
消息可以是您想要的任何消息 . 我只是为了演示目的给了它这个名字 .我没有看到清单中定义的接收器没有指定操作的intent过滤器 . 按照XXX指定的方式创建它们似乎有点虚伪 . 通过指定操作名称,Android将被强制使用与操作对应的类创建
BroadcastReceiver
的实例 . 如果你依赖于上下文,请注意Android有几个不同的对象,它们都被称为上下文,可能不会导致创建BroadcastReceiver
. 强制Android仅使用操作消息创建类的实例远比依赖于某些可能无法工作的iffy上下文要好得多 .这是一个相当独立的例子 . 它在5秒后变成红色按钮 .
请记住,即使应用程序未运行,AlarmManager也会触发 . 如果您调用此功能并点击主页按钮,等待5秒钟,然后返回到您的应用程序,该按钮将变为红色 .
如果你的应用程序根本不在内存中,我不知道你会得到什么样的行为,所以要小心你试图保留什么样的状态 .
此代码将帮助您进行重复警报 . 重复时间可以由您设定 .
activity_main.xml中
MainActivity.java
如果您只需要一次报警,请更换
同
我已经尽可能以最简单的方式实现了自己的实现 .
唯一的下一步,实施它 .
我喜欢使用这个实现,但另一种可能的好方法是,'s don' t使
AbstractSystemServiceTask
类抽象,并通过Builder构建它 .我希望它可以帮到你 .
UPDATED 改进了允许多个
BackgroundTaskListener
在同一个BroadCastReceiver
上 .