具有不同数据的新警报覆盖已设置的警报

New alarm with different data overrides already set alarm

我正在创建一个简单的应用程序,它将在未来的指定时间打开我的 wifi off/on。例如,我打开了 wifi,我想在晚上 10 点切换它的状态(将其关闭),然后在早上 8 点切换回来(打开)。 为此,我编写了一些有一个错误的代码块。 好吧,当我在晚上 10 点设置第一个警报(让我们按照上面的示例),在早上 8 点设置第二个警报时,只有第二个警报会触发。 根据这里的答案: 关于未决意图 我在设置警报时检查了这些警报的未决意图,它们不同

好的,我会提供一些代码,我不会给出一大堆代码来设置日历,因为没有错误。

WiFi.class

 //This class also stores and loads scheduled alarm from database, 
 //that's why here is variable Uri = mUri. 
    private void setAlarm(){
    ContentValues values = new ContentValues();
    values.put(AlarmReminderEntry.KEY_TITLE, title);
    values.put(AlarmReminderEntry.KEY_DATE, mDate);
    values.put(AlarmReminderEntry.KEY_TIME, mTime);
    values.put(AlarmReminderEntry.KEY_REPEAT, repeat);
    values.put(AlarmReminderEntry.KEY_YEAR, mYear);
    values.put(AlarmReminderEntry.KEY_MONTH, mMonth);
    values.put(AlarmReminderEntry.KEY_DAY, mDay);
    values.put(AlarmReminderEntry.KEY_HOUR, mHour);
    values.put(AlarmReminderEntry.KEY_MINUTE, mMinute);
    values.put(AlarmReminderEntry.KEY_REPEAT_NO, mRepeatNo);

    if (mUri == null) {
        Uri newUri = 
  getContentResolver().insert(AlarmReminderEntry.CONTENT_URI, values);
    if (newUri == null) {
            Toast.makeText(context, "error saving alarm", 
                Toast.LENGTH_SHORT).show();
} else {
//WiFiScheduler() is an instance of another class, see code below
//setAlarm(Context context, long timeInMilis, Uri uri)
     new WiFiScheduler().setAlarm(getApplicationContext(), 
 calendar.getTimeInMillis(), mUri);
 Toast.makeText(context, "Alarm will fire one time 
 only", Toast.LENGTH_SHORT).show();
                Log.v("Alarm time", 
String.valueOf(calendar.getTime()));
}

WifiScheduler.class --> class 调用方法 setAlarm 的地方。 public class WiFiScheduler {

public void setAlarm(Context context, long alarmTime, Uri 
reminderTask) {
            AlarmManager alarmManager = (AlarmManager) 
                   context.getSystemService(Context.ALARM_SERVICE); 
    Log.v("AlarmManager", "Initializing AM");

//Here in PendingIntent instance there is another class called called
// WiFiService
    PendingIntent operation =
            WiFiService.getReminderPendingIntent
                           (context,reminderTask);
    if (Build.VERSION.SDK_INT >= 23) {
        assert alarmManager != null;
 alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 
                                           alarmTime, operation);
    } else {
        assert alarmManager != null;
        alarmManager.setExact(AlarmManager.RTC_WAKEUP,
                                 alarmTime,operation);
    }
  }
}

最后 WiFiService.class

 public class WiFiService extends IntentService {
 private static final String TAG = WiFiService.class.getSimpleName();
 public static PendingIntent getReminderPendingIntent(Context context, 
 Uri uri) {
    Intent action = new Intent(context, WiFiService.class);
    action.setData(uri);
    Log.v(TAG, "uri passed into intent");
    String pi = String.valueOf(PendingIntent.getService(context, 0, 
 action, PendingIntent.FLAG_UPDATE_CURRENT));
    Log.v(TAG, pi); <-- 

我将在本文末尾给出的 2 个警报的输出 post,但它们是不同的

    return PendingIntent.getService(context, 0, action, 
PendingIntent.FLAG_UPDATE_CURRENT);
}


public WiFiService() {
    super(TAG);
}

@Override
protected void onHandleIntent(@Nullable Intent intent) {
    WifiManager wifiManager = (WifiManager) 
 getApplicationContext().getSystemService(WIFI_SERVICE);
    if (wifiManager.isWifiEnabled()) {
        wifiManager.setWifiEnabled(false);
        Log.v(TAG, "Wifi is turning off");
    } else {
        wifiManager.setWifiEnabled(true);
        Log.v(TAG, "Wifi is turning on");
    }
    Calendar calendar = Calendar.getInstance();
    int h = calendar.get(Calendar.HOUR_OF_DAY);
    int m = calendar.get(Calendar.MINUTE);
    int ms = calendar.get(Calendar.SECOND);
    Log.v("Time", String.valueOf(h) + ":" + String.valueOf(m) + ":" + 
  String.valueOf(ms));
  }
}

WiFiService.class 在清单中定义为:

服务android:name=".WiFiScheduler.WiFiService"
android:exported="false"

上面没有括号,页面不想接受它们,在代码中显然是。

现在 PendingIntent.getBroadcast 的输出,读取两次, 设置第一个闹钟后的第一个,设置第二个后的第二个。

V/WiFiService: PendingIntent{d3aacca: android.os.BinderProxy@dd4e3b}
V/WiFiService: PendingIntent{3acdbb: android.os.BinderProxy@d5ac2d8}

那么,我可能哪里出错了?

最后,请问在哪里可以找到奥利奥股票警报应用程序源代码或类似应用程序? (它必须是为 Marshmallow 及以上版本编写的,GitHub 上的大多数应用程序都是为 Lollipop 及以上版本编写的,我发现只有 2 个用于牛轧糖)

最佳

检查您在 Intent 中输入的 Uri 并确保 2 个 Uri 对于 2 个不同的调用是不同的。另外,绝对确保传递给 AlarmManager.

的时间是正确的

您可以做的另一件事是,在设置每个闹钟后,执行 adb shell dumpsys alarm 并检查是否已使用正确的值设置了闹钟。如果您需要帮助了解如何阅读 adb shell dumpsys alarm

的输出,请参阅