【发布时间】:2013-12-03 00:21:08
【问题描述】:
我已经为这个问题苦苦挣扎了好几天。我还检查了文档和几个主题,但没有找到任何解决方案/解释。
我正在 LG p500 上测试我的应用程序,但我也在 Droid 上做了一些测试,得到了相同的结果。
我的应用程序使用 AlarmHandler 来安排警报。应用程序在模拟器和设备上正常工作,直到设备有足够的可用内存。 当我在设备上启动其他几个应用程序并且内存不足时,警报将不再触发。一旦我停止“其他”应用程序,警报就会再次正常工作。
让我报告测试和结果。
- 10 分钟后,我在应用程序上设置了闹钟。
- 我启动了几个应用程序(浏览器、谷歌地图、gmail、K9Mail ......)
- 我启动 catlog 以查看我的应用程序的日志
- 等待 15 分钟,不要在手机上工作
- 10 分钟后应该会触发警报,但在我按下按钮唤醒手机之前什么都没有发生
- 当我唤醒手机时,警报会立即响起,所有通知都会发生。
- 我停止了之前启动的“其他”应用程序(浏览器、谷歌地图……)
- 10 分钟后再次设置闹钟
- 我启动 catlog 以查看我的应用程序的日志
- 等待,不要在手机上工作
- 10 分钟后警报响起,我收到通知。
我做了几次这个测试,我得到了相同的结果。
然后我尝试使用我之前从市场上下载的“Catch”应用程序设置警报,我得到了相同的行为,所以看起来这不是我的应用程序的问题。
查看我的应用程序的日志,我没有看到任何错误/异常,但看起来当系统内存不足时会发生某些事情并且广播接收器在通过键盘唤醒手机之前不会启动。一旦我唤醒手机,接收器就会启动并且所有通知都会发生。
这里是我使用的代码:
接收者:
public class NotificationReceiver extends BroadcastReceiver
{
public static final String LOG_TAG = "YAAS - Notification Receiver";
@Override
public void onReceive(Context context, Intent intent)
{
ScheduleActivityService.acquireStaticLock(context);
Log.i(LOG_TAG, "Received alarm - id: " + intent.getIntExtra("id", -1));
Intent intent2 = new Intent(context, ScheduleActivityService.class);
intent2.putExtra("id", intent.getIntExtra("id", -1));
context.startService(intent2);
}
}
服务
public class ScheduleActivityService extends Service
{
public static final String LOCK_NAME_STATIC="it.hp.yaas.AppService.Static";
public static final String LOG_TAG = "YAAS - ActivityService";
private static PowerManager.WakeLock lockStatic = null;
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder
{
public ScheduleActivityService getService()
{
return ScheduleActivityService.this;
}
}
@Override
public IBinder onBind(Intent intent)
{
return mBinder;
}
public static void acquireStaticLock(Context context) {
getLock(context).acquire();
}
synchronized private static PowerManager.WakeLock getLock(Context context)
{
if (lockStatic == null)
{
PowerManager mgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOCK_NAME_STATIC);
lockStatic.setReferenceCounted(true);
}
return(lockStatic);
}
/**
* This method is called when an alarm fires that is its alarm time is reached.
* The system assume that the alarm fired match the alarm time of the first
* activity.
* @param intent intent fired
* @param flag
* @param startId
*/
@Override
public int onStartCommand(Intent intent, int flag, int startId)
{
super.onStartCommand(intent, flag, startId);
try {
Log.i(LOG_TAG, "Alarm fired: " + startId + " - id: " + intent.getIntExtra("id", -1));
AlarmHandler.getInstance().onAlarmFired(intent.getIntExtra("id", -1));
}
finally { getLock(this).release(); }
return START_STICKY;
}
@Override
public void onDestroy()
{
super.onDestroy();
Log.i(LOG_TAG, "Destroy");
}
}
来自 AlarmHandler 的一段代码,调用来安排警报的例程:
public synchronized void onAlarmFired(int alarmId)
{
scheduledAlarmId = -1;
Alarm alarmFired = pop();
if (alarmFired == null) return;
Log.i(LOG_TAG, "onAlarmFired (Alarm: " + alarmFired + ") at (time: " + Utilities.convertDate(new Date(), "HH:mm:ss") + ")");
notifyAlarmListener(alarmFired);
if (alarmFired.reschedule(null) != null) add(alarmFired);
Alarm alarm = peek();
if (alarm != null && scheduledAlarmId != alarm.getId()) scheduleEvent(alarm);
}
/**
* Schedule an alarm through AlarmManager that trigger next activity notification
* @param alarm alarm to be scheduled
*/
private void scheduleEvent(Alarm alarm)
{
Log.i(LOG_TAG, "scheduleEvent - (Alarm: " + alarm + ")");
Intent intent = new Intent(context, NotificationReceiver.class);
intent.putExtra("id", alarm.getId());
// In reality, you would want to have a static variable for the request code instead of 192837
PendingIntent sender = PendingIntent.getBroadcast(context, 192837, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, alarm.getTime().getTime(), sender);
scheduledAlarmId = alarm.getId();
}
最后这是一段 Manifest 文件:
<activity android:name=".ListActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".EditActivity"/>
<activity android:name=".SettingsActivity"/>
<service android:name="ScheduleActivityService"
android:label="YAAS Service"/>
<receiver android:name="NotificationReceiver" />
【问题讨论】:
-
这个问题你解决了吗?
-
@AZ_ 链接已损坏 :-(
-
很遗憾我不知道为什么
标签: android alarmmanager