添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

如果设备屏幕关闭/休眠/睡眠模式,安卓项目会在5分钟后通知。

1 人关注

我在github上看到这个开源项目。但它有一个问题,就是如果屏幕关闭,就不能准确地通知设定的时间表。我想重新编程,让它在用户设定的确切时间内发出通知,即使设备的屏幕是关闭的。

问题。"如果设备屏幕关闭/Doze/睡眠模式,安卓项目在5分钟后通知。"

注:目标SDK版本23-33

MainActivity.java

public class MainActivity extends AppCompatActivity {
public static final String NOTIFICATION_CHANNEL_ID = "10001";
private final static String default_notification_channel_id = "default";
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
//Schedule alarm notification
private void scheduleNotification(Notification notification, long delay) {
    Intent notificationIntent = new Intent(this, MyNotificationPublisher.class);
    notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION_ID, 1);
    notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION, notification);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    assert alarmManager != null;
    alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, delay, pendingIntent);
    Log.d(TAG, "scheduleNotification: Notification set successfully!");
//Build notification
private Notification getNotification(String content) {
    //on notification click open MainActivity
    Intent intent = new Intent(this, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, default_notification_channel_id);
    builder.setContentTitle("ToDo Reminder");
    builder.setContentText(content);
    builder.setContentIntent(pendingIntent);
    builder.setAutoCancel(true);
    builder.setSmallIcon(R.drawable.ic_stat_name);
    builder.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND);
    builder.setChannelId(NOTIFICATION_CHANNEL_ID);
    builder.setPriority(NotificationCompat.PRIORITY_HIGH);
    return builder.build();
final Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(System.currentTimeMillis());
    //Set custom date
    dateText.setOnClickListener(new View.OnClickListener() {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onClick(View v) {
            final DatePickerDialog datePickerDialog = new DatePickerDialog(MainActivity.this,
                    new DatePickerDialog.OnDateSetListener() {
                        @Override
                        public void onDateSet(DatePicker view, int year,
                                              int monthOfYear, int dayOfMonth) {
                            String newMonth = getMonth(monthOfYear + 1);
                            dateText.setText(dayOfMonth + " " + newMonth);
                            cal.set(Calendar.YEAR, year);
                            cal.set(Calendar.MONTH, monthOfYear);
                            cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                            Log.d(TAG, "onDateSet: Date has been set successfully");
                    }, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
            datePickerDialog.show();
            datePickerDialog.getDatePicker().setMinDate(date);
    //Set custom time
    timeText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            TimePickerDialog timePickerDialog = new TimePickerDialog(MainActivity.this,
                    new TimePickerDialog.OnTimeSetListener() {
                        @Override
                        public void onTimeSet(TimePicker view, int hourOfDay,
                                              int minute) {
                            String time;
                            String minTime = String.format("%02d", minute); //prefix zero to minute if its single digit
                            //Method to postfix AM/PM
                            if (hourOfDay >= 0 && hourOfDay < 12) {
                                time = hourOfDay + " : " + minTime + " AM";
                            } else {
                                if (hourOfDay != 12) {
                                    hourOfDay = hourOfDay - 12;
                                time = hourOfDay + " : " + minTime + " PM";
                            timeText.setText(time);
                            cal.set(Calendar.HOUR, hourOfDay);
                            cal.set(Calendar.MINUTE, minute);
                            cal.set(Calendar.SECOND, 0);
                            Log.d(TAG, "onTimeSet: Time has been set successfully");
                    }, cal.get(Calendar.HOUR), cal.get(MINUTE), false);
            timePickerDialog.show();
    dialogBuilder.setTitle("Lets add new task!");
    dialogBuilder.setPositiveButton("Done", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            String title = editTitle.getText().toString();
            String date = dateText.getText().toString();
            String time = timeText.getText().toString();
            if (title.length() != 0) {
                try {
                    insertDataToDb(title, date, time);
                    scheduleNotification(getNotification(title), cal.getTimeInMillis());
                } catch (Exception e) {
                    e.printStackTrace();
            } else {
                toastMsg("Oops, Cannot set an empty ToDo!!!");
    dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            //pass
            dialog.cancel();

MyNotificationPublisher.java

public class MyNotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    Notification notification = intent.getParcelableExtra(NOTIFICATION);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel notificationChannel = new NotificationChannel(MainActivity.NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
        assert notificationManager != null;
        notificationManager.createNotificationChannel(notificationChannel);
    int id = intent.getIntExtra(NOTIFICATION_ID, 0);
    assert notificationManager != null;
    notificationManager.notify(id, notification);

舱单文件的内部

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/LightTheme">
    <activity
        android:name=".MainActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>