繁体   English   中英

如何使AlarmBootReceiver在指定时间发送通知?

[英]How to make AlarmBootReceiver send notification at specified time?

我有一个AlarmResiver类,如果用户设置了时间并且拨动开关已打开,它将发送通知。 但是此类不好,因为当设备重新启动时,不再收到通知。 然后,我决定创建一个AlarmBootResiver类,该类将在设备重启后发送通知。 现在,该类正在运行,但是在打开设备后立即发送通知。 如何使AlarmBootResiver在用户在AlarmResiver类中设置的时间发送通知?

AlarmActivity代码:

public class AlarmActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener {

    private EditText mondayText;
    public SwitchCompat mondaySwitch;
    SharedPreferences sPref;
    String timeText = "";
    final String SAVED_TEXT = "saved_text";
    boolean switch_On_Off;
    public static final String PREFS_NAME = "Switch_On_Off_check";
    final Calendar c = Calendar.getInstance();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alarm);
        mondayText = findViewById(R.id.monday_time);
        mondaySwitch = findViewById(R.id.switch_monday);
        // load SharedPref save text in mondayText and save switch On else Off
        loadText();
        loadSwitchCheck();

        mondaySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (mondaySwitch.isChecked()) {
                    startAlarm(c);
                    bootStartAlarm(c);
                }
                saveSwitchCheck();
            }
        });

        mondayText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DialogFragment timePicker = new TimePickerFragment();
                timePicker.show(getSupportFragmentManager(), "time picker");
            }
        });
    }

    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        c.set(Calendar.HOUR_OF_DAY, hourOfDay);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, 0);
        updateTimeText(c);
        saveText();
        mondaySwitch.setChecked(false);
        bootStopAlarm(c);
    }

    private void updateTimeText(Calendar c) {
        timeText = "";
        timeText += DateFormat.getTimeInstance(DateFormat.SHORT).format(c.getTime());
        mondayText.setText(timeText);
    }

    public void startAlarm(Calendar c) {

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, AlertReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
        if (c.before(Calendar.getInstance())) {
            c.add(Calendar.DATE, 1);
        }
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
    }

    public void bootStartAlarm(Calendar c) {

        PackageManager packageManager = AlarmActivity.this.getPackageManager();
        ComponentName componentName = new ComponentName(AlarmActivity.this, AlarmBootReceiver.class);
        packageManager.setComponentEnabledSetting(componentName,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, AlarmBootReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
    }

    public void bootStopAlarm(Calendar c) {
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, AlarmBootReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
        PackageManager packageManager = AlarmActivity.this.getPackageManager();
        ComponentName componentName = new ComponentName(AlarmActivity.this, AlarmBootReceiver.class);
        packageManager.setComponentEnabledSetting(componentName,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);
    }

我的AlertReciever

public class AlertReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationHelper notificationHelper = new NotificationHelper(context);
        NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
        notificationHelper.getManager().notify(1, nb.build());
    }
}

我的AlarmBootReciever

public class AlarmBootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        if (Objects.equals(intent.getAction(), "android.intent.action.BOOT_COMPLETED")) {
            NotificationHelper notificationHelper = new NotificationHelper(context);
            NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
            notificationHelper.getManager().notify(1, nb.build());
        }
    }
}

我的清单文件

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

        <receiver
            android:name=".AlarmBootReceiver"
            android:enabled="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
                <action android:name="android.intent.action.REBOOT" />
            </intent-filter>
        </receiver>
    </application>


    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.QUICKBOOT_POWERON" />
    <uses-permission android:name="android.permission.VIBRATE" />

我的NotificationHelper

public class NotificationHelper extends ContextWrapper {

    public static final String channelID = "channelID";
    public static final String channelName = "Channel Name";

    private NotificationManager mManager;

    public NotificationHelper(Context base) {
        super(base);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel();
        }
    }

    @TargetApi(Build.VERSION_CODES.O)
    private void createChannel() {
        NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
        getManager().createNotificationChannel(channel);
    }

    public NotificationManager getManager() {
        if (mManager == null) {
            mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return mManager;
    }

    public NotificationCompat.Builder getChannelNotification() {
        Intent resultIntent = new Intent(this, DashBoardActivity.class);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 1, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        return new NotificationCompat.Builder(getApplicationContext(), channelID)
                .setContentTitle("ЭЙ ТЫ!")
                .setContentText("Пора на тренировку!")
                .setSmallIcon(R.drawable.ic_training)
                .setAutoCancel(true)
                .setContentIntent(resultPendingIntent);
    }
}

您可以为此使用BroadcastReceiver 即使重新启动设备或锁定设备,此代码也将起作用, PowerManager会为您执行此操作。 请参阅此处以获取更多信息https://developer.android.com/reference/android/os/PowerManager

    public class AlarmReceiver extends BroadcastReceiver  {
    @Override
    public void onReceive(Context context, Intent intent) {

            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(context)
                            .setSmallIcon(YOUR DRAWABLE)
                            .setContentTitle("YOUR TITLE")
                            .setAutoCancel(true)
                            .setLights(0xFFFF0000, 500, 500)
                            .setColor(context.getResources().getColor(R.color.red))
                            .setDefaults(NotificationCompat.DEFAULT_SOUND)
                            .setContentText("THIS IS THE CONTENT OF THE NOTIFICATION");

            PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
            @SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
            wakeLock.acquire();

            PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);

            mBuilder.setContentIntent(contentIntent);
            NotificationManager mNotificationManager =
                    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

// mNotificationId is a unique integer your app uses to identify the
// notification. For example, to cancel the notification, you can pass its ID
// number to NotificationManager.cancel().
            mNotificationManager.notify(0, mBuilder.build());
        }
}

您可以在MainActivity使用它来触发AlarmReceiver,例如,您可以在其中设置触发时间,请参见注释。

 public void doNotification() {

        AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(this, AlarmReceiver.class);
        PendingIntent pending = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());


// InexactRepeating allows Android to optimize the energy consumption //ms, s, min
        alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24 * 30, pending); //every month
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM