Android 服务控制及时通知不起作用

Android service control notifications in time doesn't work

我有一个 CalendarView 用户可以触摸并保存学校活动。 我会每天下午 15:00 检查数据库中是否保存了一些事件,例如家庭作业,并生成相关通知。

我需要做什么?

AlarmManager 管理何时启动 Service,在 Service 中我查询如果它 returns 我发出通知。 我不知道是否需要BroadCastReceiver

就这些了还是我还需要其他东西? 谁能告诉我怎么做?

Activity 管理 when case:

public class MainActivity extends ActionBarActivity {

private PendingIntent pendingIntent;
private AlarmManager alarmManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set the alarm to start at approximately 2:00 p.m.
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 16);
    calendar.set(Calendar.MINUTE, 40);

    Intent myIntent = new Intent(MainActivity.this, MyBroadcastReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);

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

    // With setInexactRepeating(), you have to use one of the AlarmManager interval
    // constants--in this case, AlarmManager.INTERVAL_DAY.
    alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, pendingIntent);
}
}

我的广播接收器

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent)
    {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "tag");

        //Acquire the lock
        wl.acquire();

        Log.v("ADebugTag", "It work!");

        int mId = 0;
        //Show the notification here.
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(context)
                        .setSmallIcon(R.drawable.ic_action_edit)
                        .setContentTitle("Diario Scolastico")
                        .setContentText("Hai dei compiti da svolgere per domani!");
// Creates an explicit intent for an Activity in your app
        Intent resultIntent = new Intent(context, MainActivity.class);

// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
        stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent =
                stackBuilder.getPendingIntent(
                        0,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
        mBuilder.setContentIntent(resultPendingIntent);
        NotificationManager mNotificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
        mNotificationManager.notify(mId, mBuilder.build());


        //Release the lock
        wl.release();
    }

}

清单权限

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<receiver android:name=".MyBroadcastReceiver" />

现在我收到了通知,但不是在规定的时间,我不知道为什么!

最适合您的特定情况的用途是 AlarmManager 和相应的 BroadcastReceiver,因为它们是专门为此类情况创建的。您不需要仅用于显示通知的服务。

我通过浏览您的代码看到的一些可能导致您遇到问题的问题是:

alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);

应该是:

//It's better to use the setInexactRepeating, but this is your call
int MILLIS_IN_A_DAY = 1000 * 60 * 60 * 24; //You can use an actual calculator so you don't have to compute it every time at runtime; also, lower it to something like 10000 ms to actually check if it is working
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), MILLIS_IN_A_DAY, pendingIntent);

然后你想通过这样做在你的 BroadcastReceiver onReceive 方法中获取唤醒锁:

@Override
public void onReceive(Context context, Intent intent)
{
         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

         PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 'YOUR TAG');

         //Acquire the lock
         wl.acquire();
         //You can show the notification here.

         //Release the lock
         wl.release();
 }

此外,不要忘记在 AndroidManifest.xml

中注册 BroadcastReceiver