【问题标题】:Notification at Specific Time using BroadcastReceiver and AlarmManager使用 BroadcastReceiver 和 AlarmManager 在特定时间通知
【发布时间】:2019-07-23 17:55:12
【问题描述】:

我想使用广播接收器在特定时间发送通知。在这方面已经阅读了许多教程视频和答案,所有这些都很清楚。但我找不到以下代码的问题所在,因为 CODE 仍然不起作用。 所有这些都是基于“Android 中的每日重复本地通知 - YouTube”

实现的

这是 LAUNCHER Activity 中的代码:

public class Splash extends Activity {

@RequiresApi(Build.VERSION_CODES.N)
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splash);

    NotificationCheckPoint();

}

@RequiresApi(Build.VERSION_CODES.N)
private void NotificationCheckPoint() {

    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 19);
    calendar.set(Calendar.MINUTE, 53);
    calendar.set(Calendar.SECOND, 0);

    Intent MyIntent = new Intent(getApplicationContext(), BroadastNotification.class);
    PendingIntent MyPendIntent = PendingIntent.getBroadcast(getApplicationContext(), 100,
            MyIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager MyAlarm = (AlarmManager) getSystemService(ALARM_SERVICE);
    MyAlarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, MyPendIntent);
       }
}

这是广播接收器代码:

public class BroadastNotification extends BroadcastReceiver {

@Override
 public void onReceive(Context context, Intent intent) {
MyNotification(context);
}
 private void MyNotification(Context context) {
 String BigNotificqationText = "BigNotificqationText";
 String NotificationTitle = "NotificationTitle";
 String NotificationTicker = " NotificationTicker ";

 NotificationManager MyNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

 Intent MyIntent = new Intent(context, Splash.class);
 MyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

 PendingIntent MyPendingIntent = PendingIntent.getActivity(context, 100, MyIntent,
         PendingIntent.FLAG_UPDATE_CURRENT);

 NotificationCompat.Builder MyNB = new NotificationCompat.Builder(context);
 MyNB.setSmallIcon(R.drawable.icon);
 MyNB.setContentTitle(NotificationTitle);
 MyNB.setContentText(BigNotificqationText);
 MyNB.setTicker(NotificationTicker);
 MyNB.setPriority(NotificationCompat.PRIORITY_MAX);
 MyNB.setDefaults(NotificationCompat.DEFAULT_SOUND);
 MyNB.setAutoCancel(true);
 MyNB.setContentIntent(MyPendingIntent);

 Bitmap MyPicture = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
 MyNB.setLargeIcon(MyPicture);

 NotificationCompat.BigPictureStyle MyPicStyle = new NotificationCompat.BigPictureStyle().bigPicture(MyPicture);
 MyPicStyle.setSummaryText("Etude can makes our life Enlightened");
 MyNB.setStyle(MyPicStyle);

 NotificationCompat.BigTextStyle MyTextStyle = new NotificationCompat.BigTextStyle();

 MyTextStyle.bigText(BigNotificqationText);
 MyTextStyle.setBigContentTitle(NotificationTitle);
 MyNB.setStyle(MyTextStyle);


 MyNotifyManager.notify(100, MyNB.build());

 }

最后是清单定义:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.ietude.etude">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    tools:replace="icon, label">

    <receiver android:name=".BroadastNotification">
        <!--android:enabled="true"-->
        <!--android:exported="true">-->
        <!--<intent-filter>-->
            <!--<action android:name="android.media.VOLUME_CHANGED_ACTION" />-->
        <!--</intent-filter>-->
    </receiver>

    <activity android:name=".Splash"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

【问题讨论】:

  • 当你运行这段代码时会发生什么? onReceive() 会被调用吗?
  • 我通过放置 Toast 消息对其进行了测试,似乎 onReceive() 没有调用,但是当我在清单中添加接收器的意图操作(例如 VOLUMECONTROLCHANGED)时,在音量更改时调用了广播。
  • 确认一下 - 你等到 19:53 过去了?
  • 是的,我很挑衅地改了它可能的时间,然后等待过去,但似乎有一个问题,我找不到它。我也用华为和三星设备测试过,结果是一样的
  • 您能否更新问题以包含广播接收器的完整清单和完整类?

标签: android android-studio


【解决方案1】:

如果您希望计时器在准确的时间到期,那么您可以按如下方式配置计时器。

Calendar alarmFor = Calendar.getInstance();
alarmFor.set(Calendar.HOUR_OF_DAY, 7);
alarmFor.set(Calendar.MINUTE, 45);
alarmFor.set(Calendar.SECOND, 0);

Intent MyIntent = new Intent(getApplicationContext(), BroadcastNotification.class);
PendingIntent MyPendIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, MyIntent, PendingIntent.FLAG_CANCEL_CURRENT);

AlarmManager MyAlarm = (AlarmManager) getSystemService(ALARM_SERVICE);
MyAlarm.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmFor.getTimeInMillis(), MyPendIntent);

在本例中,onReceive() 如下:

@Override
public void onReceive(Context context, Intent intent) {
    Log.d("MyAPP", "onReceive() called");
}

当我运行它时,会在请求的确切时间记录以下内容:

11-22 07:45:00.730 5833-5833/com.sap.myapplication D/MyAPP: onReceive() called

【讨论】:

  • 非常感谢亲爱的 Paul,我只是逐个字母地复制并粘贴您的 CODE,并禁用了与我的应用程序相关的额外代码,但我没有收到您的测试结果。我真的很困惑。我的应用发生了什么。
  • 我的代码和你的唯一区别是@RequiresApi(Build.VERSION_CODES.N)。你认为这是改变我的结果吗?,当我使用 Calendar 时,它会给出错误并需要 Api
  • 我不需要使用@RequiresApi 并且没有收到任何错误。请检查您的导入:您使用的是 android.icu.util.Calendar 吗?请注意,在我的示例中,我使用了 java.util.Calendar。
  • 终于解决了,问题就是这样,我导入java.util.Calendar后一切正常,非常感谢亲爱的保罗的支持。
  • 不客气。我很高兴听到它现在对你有用。
【解决方案2】:

检测到问题,在这方面我再次搜索时发现,当日历设置为 10 秒时calendar.set(Calendar.SECOND, 10);这意味着 BroadcastReceiver() 必须在 10 秒后触发通知。它不在乎一天中的时间。 问题仍然存在,我们如何才能告诉 broadcastreceiver() 根据我们在 CODE 中准确定义的时间来显示通知? 例如 16:33:24 (hh:mm:ss)

【讨论】:

    【解决方案3】:

    您可以通过以下方法在每天的特定时间发送通知

    Calendar calendar = Calendar.getInstance();
             calendar.set(Calendar.HOUR_OF_DAY, 12);
             calendar.set(Calendar.MINUTE, 0);
             calendar.set(Calendar.SECOND, 0);
    
    Intent notifyIntent = new Intent(getApplicationContext(),showNotification.class);
           notifyIntent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(etApplicationContext(),0,notifyIntent,PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
           alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,  calendar.getTimeInMillis(),1000 * 60 * 60 * 24, pendingIntent);
    

    然后在 showNotification 类中

    public class showNotification extends BroadcastReceiver {
    
    public showNotification() {
    
    }
    
    @Override
    public void onReceive(Context context, Intent intent) {
       sendNotification(context);
    }
    
    private void sendNotification(Context context) {
    
    
        Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    
        Intent intent = new Intent(context, SecondActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
    
        NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        String NOTIFICATION_CHANNEL_ID = "101";
    
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            @SuppressLint("WrongConstant") NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Notification", NotificationManager.IMPORTANCE_MAX);
    
            //Configure Notification Channel
            notificationChannel.setDescription("Game Notifications");
            notificationChannel.enableLights(true);
            notificationChannel.setVibrationPattern(new long[]{200});
            notificationChannel.enableVibration(false);
    
            notificationManager.createNotificationChannel(notificationChannel);
        }
    
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setContentTitle(title.get("Title of notification"))
                .setContentText(subText.get("Sub text of notification"))
                .setAutoCancel(true)
                .setSound(defaultSound)
                .setContentIntent(pendingIntent)
                .setWhen(System.currentTimeMillis())
                .setPriority(Notification.PRIORITY_MAX);
    
    
        notificationManager.notify(1, notificationBuilder.build());
    
    }
    

    }

    【讨论】:

    • 不要忘记将接收者记录到清单文件中:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多