Android: AlarmManager 用来调用一个Service来通知用户

标签 android android-service alarmmanager android-notifications

编辑 在我的 list 中添加这一行解决了我的问题(服务 创建良好)。

<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); 

    }

我希望这个方法可以添加一个警报。即使设备处于 sleep 模式,也应调用警报。它应该在 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 中写什么吗?

谢谢你的帮助

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

最佳答案

由于您所做的只是一次通知您的用户,因此服务并不是最好的方法。服务旨在在后台工作。通知并不是真正适合服务的工作类型——它太短了。因此,我建议您改为使用 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()

最后您需要一个 list 声明:

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

关于Android: AlarmManager 用来调用一个Service来通知用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14443448/

相关文章:

android - 从 WallpaperService 启动 Intent 或向 WallpaperService 启动 Intent

android - 如何使用服务每小时显示本地通知

android - 无法停止使用 alarmManager 启动的服务

android - 在 Android 的资源中存储短字符串和数值

android - Kotlin 中带参数的单例

android GCM 推送通知

python - 如何为基于 python 的 Android 应用程序生成 APK

java - 开关只能工作一次

android - 默认情况下在 "allow"中设置 "Asus auto start manager"权限

android - 使用 AlarmManager 将多个 pendingIntent 安排到同一 Activity