在本文中,我们将给您介绍关于android-如何绕过设置AlarmManager的唯一ID?的详细内容,并且为您解答安卓绕过权限的相关问题,此外,我们还将为您提供关于androidAlarmManag
在本文中,我们将给您介绍关于android-如何绕过设置AlarmManager的唯一ID?的详细内容,并且为您解答安卓绕过权限的相关问题,此外,我们还将为您提供关于android AlarmManager 多次提醒、Android AlarmManager 定时会 “失效” 的问题、android AlarmManager 讲解、Android AlarmManager和服务问题的知识。
本文目录一览:- android-如何绕过设置AlarmManager的唯一ID?(安卓绕过权限)
- android AlarmManager 多次提醒
- Android AlarmManager 定时会 “失效” 的问题
- android AlarmManager 讲解
- Android AlarmManager和服务问题
android-如何绕过设置AlarmManager的唯一ID?(安卓绕过权限)
我正在使用此代码来启动警报.
警报在用户可以启动的活动中设置.
//Setting alarm to fire off NEW_GAME intent every 24 hours.
String alarm = Context.ALARM_SERVICE;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND, 0);
Log.i("Test", "Current time: " + System.currentTimeMillis() );
Log.i("Test", "Calendar time: " + calendar.getTimeInMillis() );
int currentDate = calendar.get(Calendar.DATE);
calendar.set(Calendar.DATE, currentDate+1);
Log.i("Test", "Calendar time with a day added: " + calendar.getTimeInMillis() );
AlarmManager am = (AlarmManager)getActivity().getSystemService(alarm);
Intent intent = new Intent("NEW_ITEM");
PendingIntent sender = PendingIntent.getbroadcast(getActivity(), 0, intent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() , AlarmManager.INTERVAL_DAY, sender);
有人告诉我我需要提供一个唯一ID,以使警报不会在getbroadcast()所在的地方相互写过.
问题是当用户可以随意打开活动多少次时该怎么做?
同样,如果我每次都提供一个唯一的ID,这意味着由于唯一的ID,它可能会设置5个相同的警报.
解决这个问题的最佳方法是什么?
解决方法:
您总是可以只将目标时间的Unix时间戳用作唯一ID.这样,确切时间的警报将相互覆盖,而所有其他警报将保持分开
[编辑:]这是一些示例代码:
AlarmManager am = (AlarmManager)getActivity().getSystemService(alarm);
Intent intent = new Intent(String.valueOf(calendar.getTimeInMillis()));
PendingIntent sender = PendingIntent.getbroadcast(getActivity(), 0, intent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() , AlarmManager.INTERVAL_DAY, sender);
android AlarmManager 多次提醒
public void setTiming(ArrayList<Push> pushs) {if (pendingIntents == null) {
pendingIntents = new ArrayList<Integer>();
}
if (am == null) {
am = (AlarmManager) getSystemService(ALARM_SERVICE);
}
// if (intent == null) {
for (int i : pendingIntents) {
PendingIntent StopPendIntent0 = PendingIntent.getBroadcast(
getApplicationContext(), i, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(StopPendIntent0);
// pendingIntents.remove(StopPendIntent0)
}
pendingIntents.clear();
calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
for (Push push : pushs) {
String time = push.getTime();
String content = push.getQuest_name();
String day = push.getDay();
calendar.set(stringTOint(day.substring(0, 4)),
stringTOint(day.substring(4, 6)) - 1,
stringTOint(day.substring(6, 8)),
Integer.parseInt(time.substring(0, 2)),
Integer.parseInt(time.substring(3, 5)));
// 将秒和毫秒设置为0
int id = new Random().nextInt(1000);
pendingIntents.add(id);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
intent.putExtra("content", content);
intent.putExtra("id", Integer.parseInt(push.getId()));
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
pendingIntent);
String tmps = "设置闹钟时间为:"
+ DateUtil.getDate2(calendar.getTimeInMillis());
System.out.println(tmps);
}
}
push是一个自己建立的本地推送的类 ,从接口拿到push的推送集合 ,虚幻插入到Alarm 里面 设置的时间都是正确的 但是有时候会推送好几条 ,并且不是那个时间。求解答
Android AlarmManager 定时会 “失效” 的问题
需求: 应用需要增加一个定时接收推送信息的时间段设定的功能,如定制9:00-22:00 接收推送信息。获取推送信息的service已经编写完毕,定时这块,先想到使用AlarmManager服务,但是在设定重复任务的时候发现设定好了interval时间后,任务并没有按期望启动。
开发测试机:小米2S(非开发版,未ROOT)
//获取AlarmManager系统服务 AlarmManager manager = (AlarmManager) context .getSystemService(Context.ALARM_SERVICE); //包装需要执行Service的Intent Intent intent = new Intent(context, cls); intent.setAction(action); PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); //触发服务的起始时间,根据传来的时间启动 // long triggerAtTime = getNextAlarmTime(begintime); //@TODO 即时启动 测试用。 long triggerAtTime = SystemClock.elapsedRealtime(); /** * 测试手机用的是小米2S(非开发版,没ROOT)miui 中为了节省电量,将AlarmManager 中的repeat时间步长设为5分钟。 */ //使用AlarmManger的setRepeating方法设置定期执行的时间间隔(seconds秒)和需要执行的Service manager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime,11 * 60 * 1000, pendingIntent);
在使用小米机器(2S)开发时候发现当使用AlarmManager.RTC 类型时,interval会按照预期的设定来执行,如interval=3分钟,那么就是每3分钟执行一次任务,但是如果使用RTC_WAKEUP则发现interval会取5的步长来执行,比如interval 是3分钟,那么实际是按5分钟来repeat的,7分钟则是10,以此类推。(在虚拟机里测试时,则没有这个限制,可以随意设定interval时间并且按时执行)
miui的开发论坛上有帖子说,这样设计是为了节省电量。
manager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime,interval, pendingIntent);
附上AlarmManager中的type
public static final int ELAPSED_REALTIME
// 当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是相对时间,是从系统启动后开始计时的,包括睡眠时 间,可以通过调用SystemClock.elapsedRealtime()获得。系统值是3 (0x00000003)。
public static final int ELAPSED_REALTIME_WAKEUP
//能唤醒系统,用法同ELAPSED_REALTIME,系统值是2 (0x00000002) 。
public static final int RTC
//当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是绝对时间,所用时间是UTC时间,可以通过调用 System.currentTimeMillis()获得。系统值是1 (0x00000001) 。
public static final int RTC_WAKEUP
//能唤醒系统,用法同RTC类型,系统值为 0 (0x00000000) 。
Public static final int POWER_OFF_WAKEUP
//能唤醒系统,它是一种关机闹铃,就是说设备在关机状态下也可以唤醒系统,所以我们把它称之为关机闹铃。使用方法同RTC类型,系统值为4(0x00000004)。
// 当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是相对时间,是从系统启动后开始计时的,包括睡眠时 间,可以通过调用SystemClock.elapsedRealtime()获得。系统值是3 (0x00000003)。
android AlarmManager 讲解
Android 系统闹钟定时功能框架,总体来说就是用数据库存储定时数据,有一个状态管理器来统一管理这些定时状态的触发和更新。在 Andriod 系统中实现定时功能,最终还是要用到系统提供的 AlarmManager,只是当一个定时完成后怎么继续处理,或者中间怎么更新定时的时间或者状态,像闹钟这种应用程序,每天重复定时,或者一周选择其中的几天,闹钟响了延迟 5 分钟再次响铃,这时候就需要想一种好的办法来让管理这些数据和状态,下面就分析一下 Android 系统闹钟的实现。
1、基本结构
Alarm
代表一条定时数据
AlarmInstance
代表一个定时项目的实例,一个 AlarmInstance 对应到一个 Alarm,相比 Alarm 多存储了一些状态信息
AlarmStateManager
状态管理器,对定时项目进行调度,添加、删除、更改状态,是一个 BroadcastReciever,定时到点后发广播到这里进行下一步处理
AlarmService
响应结果,也就是定时到达后要做的事,响铃,停止响铃
ClockDataHelper
里面创建了三个表,ALARMS_TABLE,INSTANCE_TABLE,CITIES_TABLE,前两个分别对应到上面的 Alarm 和 AlarmInstance。

- private static void createAlarmsTable(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + ALARMS_TABLE_NAME + " (" +
- ClockContract.AlarmsColumns._ID + " INTEGER PRIMARY KEY," +
- ClockContract.AlarmsColumns.HOUR + " INTEGER NOT NULL, " +
- ClockContract.AlarmsColumns.MINUTES + " INTEGER NOT NULL, " +
- ClockContract.AlarmsColumns.DAYS_OF_WEEK + " INTEGER NOT NULL, " +
- ClockContract.AlarmsColumns.ENABLED + " INTEGER NOT NULL, " +
- ClockContract.AlarmsColumns.VIBRATE + " INTEGER NOT NULL, " +
- ClockContract.AlarmsColumns.LABEL + " TEXT NOT NULL, " +
- ClockContract.AlarmsColumns.RINGTONE + " TEXT, " +
- ClockContract.AlarmsColumns.DELETE_AFTER_USE + " INTEGER NOT NULL DEFAULT 0);");
- Log.i("Alarms Table created");
- }

- private static void createInstanceTable(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + INSTANCES_TABLE_NAME + " (" +
- ClockContract.InstancesColumns._ID + " INTEGER PRIMARY KEY," +
- ClockContract.InstancesColumns.YEAR + " INTEGER NOT NULL, " +
- ClockContract.InstancesColumns.MONTH + " INTEGER NOT NULL, " +
- ClockContract.InstancesColumns.DAY + " INTEGER NOT NULL, " +
- ClockContract.InstancesColumns.HOUR + " INTEGER NOT NULL, " +
- ClockContract.InstancesColumns.MINUTES + " INTEGER NOT NULL, " +
- ClockContract.InstancesColumns.VIBRATE + " INTEGER NOT NULL, " +
- ClockContract.InstancesColumns.LABEL + " TEXT NOT NULL, " +
- ClockContract.InstancesColumns.RINGTONE + " TEXT, " +
- ClockContract.InstancesColumns.ALARM_STATE + " INTEGER NOT NULL, " +
- ClockContract.InstancesColumns.ALARM_ID + " INTEGER REFERENCES " +
- ALARMS_TABLE_NAME + "(" + ClockContract.AlarmsColumns._ID + ") " +
- "ON UPDATE CASCADE ON DELETE CASCADE" +
- ");");
- Log.i("Instance table created");
- }
这里说一下几个特殊的字段,对于 Alarm 表,DAYS_OF_WEEK 表示一周内需要定时的天(闹钟有个功能是选择一周中的几天),这里是个 int 值,用位来表示设置的天数,源码中有个专门的类 DaysOfWeek 来存储和处理。
AlarmInstance 表中有一个 ALARM_ID,关联到一个 Alarm,可以看到在 AlarmInstance 表里也有时间,为什么不和 Alarm 表合成一个表?应该是这样的,Alarm 表示原始的定时项,是一个基础数据,而 AlarmInstance 则代表了一个使用中的定时项目,或者是一个已经激活的定时项目,它的时间是可以变化的,比如闹钟响了以后延时 5 分钟再响,就需要改变这里的时间,而基础数据不能变,还需要显示在那里。ALARM_STATE 代表了当前定时项目的状态,具体调度都在 AlarmStateManager 中管理。
忘了在哪里看到的,“编程最重要的是设计数据结构,接下来是分解各种代码块”。数据结构是基础,就像建筑里的钢筋水泥砖瓦,有了基础的材料后,剩下的工作就是对这些材料处理,也就是设计具体的处理逻辑。
2、具体的类分析
Alarm
从上面也可以看出,Alarm 类作为定时的基础数据结构,主要是封装了一些数据库操作,完成增删改查功能。额外有一个方法 createInstanceAfter,根据自身来创建一个 AlarmInstance 实例。代码如下

- public AlarmInstance createInstanceAfter(Calendar time) {
- Calendar nextInstanceTime = Calendar.getInstance();
- nextInstanceTime.set(Calendar.YEAR, time.get(Calendar.YEAR));
- nextInstanceTime.set(Calendar.MONTH, time.get(Calendar.MONTH));
- nextInstanceTime.set(Calendar.DAY_OF_MONTH, time.get(Calendar.DAY_OF_MONTH));
- nextInstanceTime.set(Calendar.HOUR_OF_DAY, hour);
- nextInstanceTime.set(Calendar.MINUTE, minutes);
- nextInstanceTime.set(Calendar.SECOND, 0);
- nextInstanceTime.set(Calendar.MILLISECOND, 0);
- // If we are still behind the passed in time, then add a day
- if (nextInstanceTime.getTimeInMillis() <= time.getTimeInMillis()) {
- nextInstanceTime.add(Calendar.DAY_OF_YEAR, 1);
- }
- // The day of the week might be invalid, so find next valid one
- int addDays = daysOfWeek.calculateDaysToNextAlarm(nextInstanceTime);
- if (addDays > 0) {
- nextInstanceTime.add(Calendar.DAY_OF_WEEK, addDays);
- }
- AlarmInstance result = new AlarmInstance(nextInstanceTime, id);
- result.mVibrate = vibrate;
- result.mLabel = label;
- result.mRingtone = alert;
- return result;
- }
AlarmInstance
AlarmInstance 与 Alarm 很相似,像 Alarm 中的增删改查操作在 AlarmInstance 中都有相似的方法。那有什么不同呢,就是上面说的 AlarmInstance 的时间是可以根据当前状态改变的,也就多了时间的 set 和 get 方法。

- public void setAlarmTime(Calendar calendar) {
- mYear = calendar.get(Calendar.YEAR);
- mMonth = calendar.get(Calendar.MONTH);
- mDay = calendar.get(Calendar.DAY_OF_MONTH);
- mHour = calendar.get(Calendar.HOUR_OF_DAY);
- mMinute = calendar.get(Calendar.MINUTE);
- }
- /**
- * Return the time when a alarm should fire.
- *
- * @return the time
- */
- public Calendar getAlarmTime() {
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.YEAR, mYear);
- calendar.set(Calendar.MONTH, mMonth);
- calendar.set(Calendar.DAY_OF_MONTH, mDay);
- calendar.set(Calendar.HOUR_OF_DAY, mHour);
- calendar.set(Calendar.MINUTE, mMinute);
- calendar.set(Calendar.SECOND, 0);
- calendar.set(Calendar.MILLISECOND, 0);
- return calendar;
- }
AlarmStateManager
闹钟定时的核心逻辑就在这里,AlarmStateManager 就是管理所有定时项目状态的调度器。
可以看到上面大多是 static 类型的方法,用于设置各种状态值。
先看一下定时的几种状态:
SILENT_STATE,alarm 被激活,但是不需要显示任何东西,下一个状态是 LOW_NOTIFICATION_STATE;
LOW_NOTIFICATION_STATE,这个状态表示 alarm 离触发的时间不远了,时间差是 AlarmInstance.LOW_NOTIFICATION_HOUR_OFFSET=-2,也就是 2 个小时。下一个状态会进入 HIGH_NOTIFICATION_STATE,HIDE_NOTIFICATION_STATE,DISMISS_STATE;
HIDE_NOTIFICATION_STATE,这是一个暂时态,表示用户想隐藏掉通知,这个状态会一直持续到 HIGH_NOTIFICATION_STATE;
HIGH_NOTIFICATION_STATE,这个状态和 LOW_NOTIFICATION_STATE 相似,但不允许用户隐藏通知,负责触发 FIRED_STATE 或者 DISMISS_STATE;
SNOOZED_STATE,像 HIGH_NOTIFICATION_STATE,但是会增加一点定时的时间来完成延迟功能;
FIRED_STATE,表示响铃状态,会启动 AlarmService 直到用户将其变为 SNOOZED_STATE 或者 DISMISS_STATE,如果用户放任不管,会之后进入 MISSED_STATE;
MISSED_STATE,这个状态在 FIRED_STATE 之后,会在通知栏给出一个提醒刚才响铃了;
DISMISS_STATE,这个状态表示定时结束了,会根据定时项目的设置判断是否需要重复,从而决定要删除这个项目还是继续设定一个新的定时。
上面的 setXXXState 方法就是对这些状态的处理,同时会规划一个定时转换到下一个状态。比如 setSilentState:

- public static void setSilentState(Context context, AlarmInstance instance) {
- Log.v("Setting silent state to instance " + instance.mId);
- // Update alarm in db
- ContentResolver contentResolver = context.getContentResolver();
- instance.mAlarmState = AlarmInstance.SILENT_STATE;
- AlarmInstance.updateInstance(contentResolver, instance);
- // Setup instance notification and scheduling timers
- AlarmNotifications.clearNotification(context, instance);
- scheduleInstanceStateChange(context, instance.getLowNotificationTime(),
- instance, AlarmInstance.LOW_NOTIFICATION_STATE);
- }
更新 AlarmInstance 的信息,同时通过 scheduleInstanceStateChange()规划下一个状态:

- private static void scheduleInstanceStateChange(Context context, Calendar time,
- AlarmInstance instance, int newState) {
- long timeInMillis = time.getTimeInMillis();
- Log.v("Scheduling state change " + newState + " to instance " + instance.mId +
- " at " + AlarmUtils.getFormattedTime(context, time) + " (" + timeInMillis + ")");
- Intent stateChangeIntent = createStateChangeIntent(context, ALARM_MANAGER_TAG, instance,
- newState);
- PendingIntent pendingIntent = PendingIntent.getBroadcast(context, instance.hashCode(),
- stateChangeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- if (Utils.isKitKatOrLater()) {
- am.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
- } else {
- am.set(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
- }
- }
通过 AlarmManager 发起一个定时,定时的时间从调用处可以看到是有 AlarmInstance 得到的,比如在 setSilentState () 中的定时时间是 instance.getLowNotificationTime ():

- public Calendar getLowNotificationTime() {
- Calendar calendar = getAlarmTime();
- calendar.add(Calendar.HOUR_OF_DAY, LOW_NOTIFICATION_HOUR_OFFSET);
- return calendar;
- }
LOW_NOTIFICATION_HOUR_OFFSET 值为 - 2,也就是在闹铃响之前的两小时那一刻会发这个 LOW_NOTIFICATION_STATE 的广播出来,AlarmStateManager 接收到这个广播处理再转移到下一个。广播的接收在 onReciever 方法中,

- @Override
- public void onReceive(final Context context, final Intent intent) {
- final PendingResult result = goAsync();
- final PowerManager.WakeLock wl = AlarmAlertWakeLock.createPartialWakeLock(context);
- wl.acquire();
- AsyncHandler.post(new Runnable() {
- @Override
- public void run() {
- handleIntent(context, intent);
- result.finish();
- wl.release();
- }
- });
- }
- private void handleIntent(Context context, Intent intent) {
- final String action = intent.getAction();
- Log.v("AlarmStateManager received intent " + intent);
- if (CHANGE_STATE_ACTION.equals(action)) {
- Uri uri = intent.getData();
- AlarmInstance instance = AlarmInstance.getInstance(context.getContentResolver(),
- AlarmInstance.getId(uri));
- if (instance == null) {
- // Not a big deal, but it shouldn''t happen
- Log.e("Can not change state for unknown instance: " + uri);
- return;
- }
- int globalId = getGlobalIntentId(context);
- int intentId = intent.getIntExtra(ALARM_GLOBAL_ID_EXTRA, -1);
- int alarmState = intent.getIntExtra(ALARM_STATE_EXTRA, -1);
- if (intentId != globalId) {
- Log.i("Ignoring old Intent. IntentId: " + intentId + " GlobalId: " + globalId +
- " AlarmState: " + alarmState);
- return;
- }
- if (alarmState >= 0) {
- setAlarmState(context, instance, alarmState);
- } else {
- registerInstance(context, instance, true);
- }
- } else if (SHOW_AND_DISMISS_ALARM_ACTION.equals(action)) {
- Uri uri = intent.getData();
- AlarmInstance instance = AlarmInstance.getInstance(context.getContentResolver(),
- AlarmInstance.getId(uri));
- long alarmId = instance.mAlarmId == null ? Alarm.INVALID_ID : instance.mAlarmId;
- Intent viewAlarmIntent = Alarm.createIntent(context, DeskClock.class, alarmId);
- viewAlarmIntent.putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.ALARM_TAB_INDEX);
- viewAlarmIntent.putExtra(AlarmClockFragment.SCROLL_TO_ALARM_INTENT_EXTRA, alarmId);
- viewAlarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(viewAlarmIntent);
- setDismissState(context, instance);
- }
- }
- }
在 handleIntent 方法中统一处理,状态的分发在 setAlarmState 中:

- public void setAlarmState(Context context, AlarmInstance instance, int state) {
- switch(state) {
- case AlarmInstance.SILENT_STATE:
- setSilentState(context, instance);
- break;
- case AlarmInstance.LOW_NOTIFICATION_STATE:
- setLowNotificationState(context, instance);
- break;
- case AlarmInstance.HIDE_NOTIFICATION_STATE:
- setHideNotificationState(context, instance);
- break;
- case AlarmInstance.HIGH_NOTIFICATION_STATE:
- setHighNotificationState(context, instance);
- break;
- case AlarmInstance.FIRED_STATE:
- setFiredState(context, instance);
- break;
- case AlarmInstance.SNOOZE_STATE:
- setSnoozeState(context, instance);
- break;
- case AlarmInstance.MISSED_STATE:
- setMissedState(context, instance);
- break;
- case AlarmInstance.DISMISSED_STATE:
- setDismissState(context, instance);
- break;
- default:
- Log.e("Trying to change to unknown alarm state: " + state);
- }
- }
对没一个 state 又转移相应的 setXXXState 方法中,完成下一次状态的转换,形成一个定时的循环,直到在 DISMISSED_STATE 里停用或者删除定时项目,如果需要重复则获取下一次定时的时间。
整体的框架就是这样,在 AlarmStateManager 里使用 AlarmManager 形成了一个定时的状态机,不断转移到下一个状态处理。
源码在这里 https://android.googlesource.com/platform/packages/apps/DeskClock/+/android-4.4.4_r2.0.1
本文同步分享在 博客 “xiangzhihong8”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与 “OSC 源创计划”,欢迎正在阅读的你也加入,一起分享。
Android AlarmManager和服务问题
我的应用程序中有一些文件,但是现在只有3个非常重要.这是一个带有警报声和通知的提醒应用程序.
我有一个maincode.java文件,其中包含一个复选框及其侦听器.如果用户在复选框中签入,则AlarmManager将意图发送到AlarmReceiver.java,后者将启动MyService.java. MyService java包含有关播放声音的代码.代码是不完整的.
MyService.java:
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
player = MediaPlayer.create(this, R.raw.sound);
player.setLooping(false); // Set looping
}
@Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
player.stop();
}
@Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
player.start();
}
AlarmReceiver.java:
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
player = MediaPlayer.create(this, R.raw.sound);
player.setLooping(false); // Set looping
maincode.java的重要部分:
cb1 = (CheckBox) findViewById(R.id.CheckBox01);
cb1.setonCheckedchangelistener(new CompoundButton.OnCheckedchangelistener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if (cb1.isChecked())
{
if (GlobalVars.getHourOfDay() >= 0)
{
Toast.makeText(maincode.this, "ok", Toast.LENGTH_SHORT).show();
rem1.setText(GlobalVars.getReminder1name());
Intent intent = new Intent(maincode.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getbroadcast(bInsulinReminder.this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, GlobalVars.getHourOfDay());
cal.set(Calendar.MINUTE, GlobalVars.getMinute());
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+ 3000, 6000, pendingIntent);
}
Toast.makeText(maincode.this, "Checked", Toast.LENGTH_SHORT).show();
} else {
rem1.setText("No reminder set");
Toast.makeText(maincode.this, "Not checked", Toast.LENGTH_SHORT).show();
}
}
});
(rem1是提醒按钮,其文本取决于用户所需名称的名称)
该代码的问题是,如果我启动警报,我将无法停止.我知道MyService.java中有player.stop()命令,但如何从未选中复选框的maincode.java末尾调用它呢?
解决方法:
不,您不能直接从听众那里做到这一点.您可以通过以下方式禁用警报:
Intent intent = new Intent(maincode.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getbroadcast(bInsulinReminder.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
pendingItem.cancel();
alarmManager.cancel(pendingItem);
或者(如果我想)AlarmReceiver是broadcastReceiver的实现,并且从onReceive方法中启动MyService,它是Service类的实现.
因此,如果要从maincode.java侦听器内部停止此警报,可以通过重新创建在AlarmReceiver中使用的PendingIntent并执行stopService方法来停止MyService.
希望能有所帮助.
我们今天的关于android-如何绕过设置AlarmManager的唯一ID?和安卓绕过权限的分享已经告一段落,感谢您的关注,如果您想了解更多关于android AlarmManager 多次提醒、Android AlarmManager 定时会 “失效” 的问题、android AlarmManager 讲解、Android AlarmManager和服务问题的相关信息,请在本站查询。
本文标签: