Android:AlarmManager用于调用服务来通知用户

时间:2013-01-21 16:52:27

标签: android android-service alarmmanager android-notifications

修改在我的清单中添加此行解决了我的问题(Service创建得很好。)

<service android:name=".TimersService" >

发表

我目前正在尝试实施警报以通知用户倒计时已完成。我有一个方法createAlarm(),可以通过AlarmManager添加新的警报。此方法当前在Fragment中调用。它看起来像这样:

private final void createAlarm(String name, long milliInFuture) {

        Intent myIntent = new Intent(getActivity().getApplication(),
                TimersService.class);

        AlarmManager alarmManager = (AlarmManager) getActivity()
                .getSystemService(Context.ALARM_SERVICE);

        PendingIntent pendingIntent = PendingIntent.getService(getActivity()
                .getApplication(), 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);

        alarmManager.set(AlarmManager.RTC_WAKEUP,
                milliInFuture, pendingIntent); 

    }

我希望这种方法能够添加一个警报。即使设备处于睡眠模式,也应该调用警报。它应该在milliInFuture时调用(System.currentTimeMillis() +一段时间)。当闹钟响起时,它应该启动一个服务。该服务如下。这个Service应该只做一件事:通知用户警报已经完成。我的Service课程如下:

public class TimersService extends Service {

    private NotificationManager mNM;
    private int NOTIFICATION = 3456;


    public class LocalBinder extends Binder {
        TimersService getService() {
            return TimersService.this;
        }
    }

    @Override
    public void onCreate() {
        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        showNotification();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("LocalService", "Received start id " + startId + ": " + intent);
            return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mNM.cancel(NOTIFICATION);
        Toast.makeText(this, "Alarm", Toast.LENGTH_SHORT).show();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

        private final IBinder mBinder = new LocalBinder();

    private void showNotification() {

        final NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
        builder.setSmallIcon(R.drawable.clock_alarm);
        builder.setContentTitle("Time is up");
        builder.setContentText("SLIMS");
        builder.setVibrate(new long[] { 0, 200, 100, 200 });
        final Notification notification = builder.build(); 

        mNM.notify(NOTIFICATION, notification);
        NOTIFICATION += 1;
    }

}

当我运行我的代码时,我的方法createAlarm被调用。但我的服务从未创建过。我根据Alexander的Fragotsis发现的here编写了这段代码。我的Service课程受到Service class

的Android参考资料的启发

知道为什么我的Service没有被调用?我在Manifest中有关于警报,服务或通知的任何内容吗?

感谢您的帮助

何,我将不胜感激任何关于我的代码的建议。如果您知道在一段固定时间后通知用户的更简单方法,请告诉我们!

1 个答案:

答案 0 :(得分:2)

由于您所做的一切都是通知您的用户一次,因此服务并非最佳方法。服务旨在在后台工作。通知实际上不是适合服务的工作类型 - 它太短了。因此,我建议您使用BroadcastReceiver。

课程应该是这样的:

public class TimerReceiver extends BroadcastReceiver {
  private static final int NOTIFICATION = 3456; 

/*since you're always doing a 1-time notification, we can make this final and static, the number
 won't change. If you want it to change, consider using SharedPreferences or similar to keep track 
 of the number. You would have the same issue with a Service since you call stopself() and so,
 you would delete the object every time.*/

  @Override
  public void onReceive(Context context,Intent intent) {

    final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
    builder.setSmallIcon(R.drawable.clock_alarm);
    builder.setContentTitle("Time is up");
    builder.setContentText("SLIMS");
    builder.setVibrate(new long[] { 0, 200, 100, 200 });
    final Notification notification = builder.build(); 

    mNM.notify(NOTIFICATION, notification);
  }

要调用接收者,您需要更改Intent以指向新类,getService()需要getBroadcast()。所以这个

Intent myIntent = new Intent(getActivity().getApplication(),
                TimersService.class);


PendingIntent pendingIntent = PendingIntent.getService(getActivity()
                .getApplication(), 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);

需要

Intent myIntent = new Intent(getActivity().getApplication(),
                TimerReceiver.class);

PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity()
                .getApplication(), 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);

此外,您应该能够安全地将getActivity().getApplication()更改为getActivity()

最后你需要一个清单声明:

<receiver android:name=".TimerReceiver" ></receiver>