我想在我的项目中实现一个时间表功能。所以我在谷歌上搜索了一个警报管理程序,但我找不到任何例子。
谁能帮我一个基本的警报管理程序?
我想在我的项目中实现一个时间表功能。所以我在谷歌上搜索了一个警报管理程序,但我找不到任何例子。
谁能帮我一个基本的警报管理程序?
当前回答
我尝试了XXX的解决方案,虽然它最初确实有效,但在某种程度上它停止了工作。onReceive再也没有被调用。我花了好几个小时想知道那是什么。我开始意识到,出于某种神秘的原因,意图不再被召唤。为了解决这个问题,我发现确实需要在清单中为接收者指定一个操作。例子:
<receiver android:name=".Alarm" android:exported="true">
<intent-filter>
<action android:name="mypackage.START_ALARM" >
</action>
</intent-filter>
</receiver>
请注意,名称是“。“Alarm”和周期。在XXX的setAlarm方法中,创建Intent,如下所示:
Intent i = new Intent("mypackage.START_ALARM");
START_ALARM消息可以是您想要的任何消息。我这样命名只是为了演示。
I have not seen receivers defined in the manifest without an intent filter that specifies the action. Creating them the way XXX has specified it seems kind of bogus. By specifying the action name, Android will be forced to create an instance of the BroadcastReceiver using the class that corresponds to the action. If you rely upon context, be aware that Android has several different objects that are ALL called context and may not result in getting your BroadcastReceiver created. Forcing Android to create an instance of your class using only the action message is far better than relying upon some iffy context that may never work.
其他回答
•AlarmManager与IntentService结合使用
我认为使用AlarmManager的最佳模式是它与IntentService的协作。IntentService由AlarmManager触发,它通过接收意图处理所需的操作。这种结构不像使用BroadcastReceiver那样对性能有影响。我在kotlin中为这个想法开发了一个示例代码,可以在这里获得:
MyAlarmManager.kt
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
object MyAlarmManager {
private var pendingIntent: PendingIntent? = null
fun setAlarm(context: Context, alarmTime: Long, message: String) {
val alarmManager: AlarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(context, MyIntentService::class.java)
intent.action = MyIntentService.ACTION_SEND_TEST_MESSAGE
intent.putExtra(MyIntentService.EXTRA_MESSAGE, message)
pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent)
}
fun cancelAlarm(context: Context) {
pendingIntent?.let {
val alarmManager: AlarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.cancel(it)
}
}
}
MyIntentService.kt
import android.app.IntentService
import android.content.Intent
class MyIntentService : IntentService("MyIntentService") {
override fun onHandleIntent(intent: Intent?) {
intent?.apply {
when (intent.action) {
ACTION_SEND_TEST_MESSAGE -> {
val message = getStringExtra(EXTRA_MESSAGE)
println(message)
}
}
}
}
companion object {
const val ACTION_SEND_TEST_MESSAGE = "ACTION_SEND_TEST_MESSAGE"
const val EXTRA_MESSAGE = "EXTRA_MESSAGE"
}
}
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aminography.alarm">
<application
... >
<service
android:name="path.to.MyIntentService"
android:enabled="true"
android:stopWithTask="false" />
</application>
</manifest>
用法:
val calendar = Calendar.getInstance()
calendar.add(Calendar.SECOND, 10)
MyAlarmManager.setAlarm(applicationContext, calendar.timeInMillis, "Test Message!")
如果你想取消预定的闹钟,试试这个:
MyAlarmManager.cancelAlarm(applicationContext)
报警经理:
添加到XML布局(*初始化这些视图在创建在主活动)
<TimePicker
android:id="@+id/timepicker"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"></TimePicker>
<Button
android:id="@+id/btn_start"
android:text="start Alarm"
android:onClick="start_alarm_event"
android:layout_width="match_parent"
android:layout_height="52dp" />
添加到清单(内部应用程序标签&&外部活动)
<receiver android:name=".AlarmBroadcastManager"
android:enabled="true"
android:exported="true"/>
创建AlarmBroadcastManager类(从BroadcastReceiver继承)
public class AlarmBroadcastManager extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
MediaPlayer mediaPlayer=MediaPlayer.create(context,Settings.System.DEFAULT_RINGTONE_URI);
mediaPlayer.start();
}
}
在Main Activity中(添加这些功能):
@RequiresApi(api = Build.VERSION_CODES.M)
public void start_alarm_event(View view){
Calendar calendar=Calendar.getInstance();
calendar.set(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
timePicker.getHour(),
timePicker.getMinute(),
0
);
setAlarm(calendar.getTimeInMillis());
}
public void setAlarm(long timeInMillis){
AlarmManager alarmManager=(AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent=new Intent(this,AlarmBroadcastManager.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(this,0,intent,0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,timeInMillis,AlarmManager.INTERVAL_DAY,pendingIntent);
Toast.makeText(getApplicationContext(),"Alarm is Set",Toast.LENGTH_SHORT).show();
}
这段代码将帮助您制作重复警报。重复时间可由您设置。
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);
with
alarmManager.set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + result , pendingIntent );
这是工作代码。它每10分钟唤醒一次CPU,直到手机关机。
添加到Manifest.xml:
...
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
...
<receiver android:process=":remote" android:name=".Alarm"></receiver>
...
类中的代码:
package yourPackage;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.widget.Toast;
public class Alarm extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
// Put here YOUR code.
Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
wl.release();
}
public void setAlarm(Context context)
{
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pi); // Millisec * Second * Minute
}
public void cancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
设置来自服务的告警:
package yourPackage;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class YourService extends Service
{
Alarm alarm = new Alarm();
public void onCreate()
{
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
alarm.setAlarm(this);
return START_STICKY;
}
@Override
public void onStart(Intent intent, int startId)
{
alarm.setAlarm(this);
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
}
如果您想设置开机时重复闹铃:
将权限和服务添加到Manifest.xml:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
...
<receiver android:name=".AutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
...
<service
android:name=".YourService"
android:enabled="true"
android:process=":your_service" >
</service>
并创建一个新类:
package yourPackage;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AutoStart extends BroadcastReceiver
{
Alarm alarm = new Alarm();
@Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
{
alarm.setAlarm(context);
}
}
}
这里有一个相当独立的例子。5秒后按钮变为红色。
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也会触发。如果你调用这个函数并点击Home键,等待5秒,然后回到你的应用程序,按钮将变成红色。
我不知道如果你的应用程序根本不在内存中,你会得到什么样的行为,所以要小心你试图保存什么样的状态。