Android

时间:2016-12-31 09:28:07

标签: android android-service alarmmanager android-notifications

我正在开发一个用于咨询服务的Android应用程序。客户可以在应用中查看他们的预约。例如,

下次预约: 2016年12月31日上午10:00

现在我需要这样做,用户将收到2个通知 - 有关约会的提醒。一天前7天,另一天前3天。我将此日期(2016年12月31日上午10:00)保存为String,以便我可以提取年,月等。 我发现我需要编写某种服务来发送这些通知。这是我尝试过的(未完成):

public class NotificationService extends Service {
    @Override
    public void onCreate() {
        Intent resultIntent=new Intent(this, MainActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this, 0, resultIntent, 0);
        Notification nBuilder = new Notification.Builder(this)
                .setContentTitle("Don't miss! ")
                .setTicker("Notification!")
                .setContentIntent(pIntent)
                .setDefaults(Notification.DEFAULT_SOUND)
                .setAutoCancel(true)
                .setSmallIcon(R.drawable.my_logo)
                .setContentText("7 days left till your appointment...")
                //.setWhen(System.currentTimeMillis())
                .build();
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        nBuilder.flags |=Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(1,nBuilder);
    }

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

我不知道从哪里打电话的方法:

public void reminder() {
    Intent intent  = new Intent(getActivity(), MainActivity.class);

    AlarmManager manager =(AlarmManager) getActivity().getSystemService(Activity.ALARM_SERVICE);
    PendingIntent pendingIntent = PendingIntent.getService(getActivity().getApplicationContext(),
            0,intent, 0);
    Calendar cal=Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, 8); 
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    manager.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),24*60*60*1000,pendingIntent);
}

出于测试目的,我手动设置了小时/分钟/秒,但显然我需要从日期String中提取它。

1 个答案:

答案 0 :(得分:2)

您需要先写一个IntentService。这是一个示例,您可以编写代码以在processNotification函数中显示通知。

public class NotificationIntentService extends IntentService {

    private static final String ACTION_START = "ACTION_START";

    public NotificationIntentService() {
        super(NotificationIntentService.class.getSimpleName());
    }

    public static Intent createIntentStartNotificationService(Context context) {
        Intent intent = new Intent(context, NotificationIntentService.class);
        intent.setAction(ACTION_START);
        return intent;
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            String action = intent.getAction();
            if (ACTION_START.equals(action))
                processNotification();

        } finally {
            WakefulBroadcastReceiver.completeWakefulIntent(intent);
        }
    }

    private void processNotification() {
        Intent resultIntent=new Intent(this, MainActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this, 0, resultIntent, 0);
        Notification nBuilder = new Notification.Builder(this)
                .setContentTitle("Don't miss! ")
                .setTicker("Notification!")
                .setContentIntent(pIntent)
                .setDefaults(Notification.DEFAULT_SOUND)
                .setAutoCancel(true)
                .setSmallIcon(R.drawable.my_logo)
                .setContentText("7 days left till your appointment...")
                .build();
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        nBuilder.flags |=Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(1, nBuilder);
    }
}

然后创建NotificationEventReceiver

public class NotificationEventReceiver extends WakefulBroadcastReceiver {

    private static final String ACTION_START_NOTIFICATION_SERVICE = "ACTION_START_NOTIFICATION_SERVICE";

    public static void setupAlarm(Context context, long interval) {
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent alarmIntent = getStartPendingIntent(context);

        alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), interval, alarmIntent);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Intent serviceIntent = null;
        if (ACTION_START_NOTIFICATION_SERVICE.equals(action)) {
            serviceIntent = NotificationIntentService.createIntentStartNotificationService(context);
        }

        if (serviceIntent != null) {
            startWakefulService(context, serviceIntent);
        }
    }

    private static PendingIntent getStartPendingIntent(Context context) {
        Intent intent = new Intent(context, NotificationEventReceiver.class);
        intent.setAction(ACTION_START_NOTIFICATION_SERVICE);
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }
}

NotificationServiceStarterReceiver

public final class NotificationServiceStarterReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        long interval = getIntent().getLongExtra("alarm_interval", 0);
        NotificationEventReceiver.setupAlarm(context, interval);
    }
}

AndroidManifest.xml<application>标记

中添加这些内容
<service
    android:name="YourPackage.NotificationIntentService"
    android:enabled="true"
    android:exported="false" />

<receiver android:name="YourPackage.BroadcastReceiver.NotificationEventReceiver" />
<receiver android:name="YourPackage.BroadcastReceiver.NotificationServiceStarterReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.TIMEZONE_CHANGED" />
        <action android:name="android.intent.action.TIME_SET" />
    </intent-filter>
</receiver>

现在,您可以通过Activity调用setupAlarm()内部onCreate功能。

NotificationEventReceiver.setupAlarm(getApplicationContext(), interval);

您需要在清单中添加WAKE_LOCK权限。

<uses-permission android:name="android.permission.WAKE_LOCK" />

您在此处看到可以传递下一个要显示的通知的interval。明智地使用interval。您可以考虑在数据库中保存约会的当前状态,然后在必要时通过传递下一个警报的适当间隔来触发警报。这就是主意。

<强>更新

因此,在您的情况下,您不希望在用户注销时显示通知。因此,在这种情况下,您可以考虑保留SharedPreference来存储登录状态。您可以根据存储的值调用processNotification函数。

所以伪代码可能看起来像这样。

if(pref.getBoolean("login_status", false)) {
    // If the login status is true, process the notification
    processNotification();
} else {
    // Do nothing
}