问题描述:

I want to display notification every morning at 9 AM from my app.

So I am using Notification Manager, Alarm Manager, BroadcastReciever and Service to make that possible.

But I have a problem, because the notification shows randomly. When I first start the app and set the time, it works OK, but later the app fires and shows notification at random time.

How I can solve that?

Here is my code:

MainActivity

@Override

protected void onStart() {

super.onStart();

setAlarm();

}

public void setAlarm(){

Calendar calendar = Calendar.getInstance();

Calendar now = Calendar.getInstance();

calendar.set(Calendar.HOUR_OF_DAY, 15);

calendar.set(Calendar.MINUTE, 43);

calendar.set(Calendar.SECOND, 0);

if(calendar.getTime().after(now.getTime())) {

alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

alarmIntent = new Intent(MainActivity.this, HoroscopeNotification.class);

pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent); }

}

HoroscopNotification (BroadcastReciever)

public class HoroscopeNotification extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent arg1) {

showNotification(context);

}

private void showNotification(Context context) {

Intent service1 = new Intent(context, AlarmService.class);

context.startService(service1);

}

}

AlarmService

public class AlarmService extends Service {

private static final int NOTIFICATION_ID = 1;

private NotificationManager notificationManager;

private PendingIntent pendingIntent;

@Override

public IBinder onBind(Intent arg0)

{

return null;

}

@SuppressWarnings("static-access")

@Override

public void onStart(Intent intent, int startId)

{

super.onStart(intent, startId);

Context context = this.getApplicationContext();

notificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);

Intent mIntent = new Intent(this, MainActivity.class);

pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

builder.setContentTitle("Horoskop");

builder.setContentText("Pročitajte današnji horoskop");

builder.setSmallIcon(R.drawable.ic_bik);

builder.setAutoCancel(true);

builder.setContentIntent(pendingIntent);

notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

notificationManager.notify(NOTIFICATION_ID, builder.build());

}

}

网友答案:

You'll notice in the Android SDK Reference material for the AlarmManager.setRepeating() states:

Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.

You need to use AlarmManager.set() on pre-APIv19 and AlarmManager.setExact() on APIv19+. When your PendingIntent is fired and you receive your Broadcast in your BroadcastReceiver.onReceive() you can set another exact alarm for the next day.

网友答案:

Alarm Manager Example

I think you should follow above link. From my point of view, your design pattern (setting alarm in Activity class is not a good approach). Instead (like showed in the answer above) you should set your alarm from a service. Also the code for notification goes in BroadcastReceiver class, method OnReceive (In the example it is commented "Put here YOUR code").

Good luck

相关阅读:
Top