如何存储和删除各个对象的警报

How to store and delete alarms for respective object

我有一个小问题,如果你能帮助我,我将不胜感激。我有一个应用程序,例如客户药物的本地数据库,在添加药丸时,他可以在需要服用该特定药丸时添加提醒。他只能设置一个小时(临时)和 select 一周中的某些天。因此,该应用程序会在每天的特定时间发出警报,我的应用程序会以这种方式发出许多警报,我认为这不是最好的方法,但是是的,这就是我的方法。如果这是更好的方法,请帮助我。但我现在的主要问题是如何存储未决意图,以便在客户想要删除药物时禁用相应药丸的警报。

public class Home extends AppCompatActivity implements View.OnClickListener {

////////////////////DECLARARI///////////////////
LinearLayout[] med = new LinearLayout[11];
TextView[] name = new TextView[11];
TextView[] nr = new TextView[11];
TextView[] plus = new TextView[11];
TextView[] minus = new TextView[11];
TextView[] info = new TextView[11];

public static final String PREFS_NAME = "MyMeds";
////////////////////////////////////////////////

public void calendar(View view, final EditText dateMed){
    final Calendar calendar = Calendar.getInstance();
    final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener(){
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, monthOfYear);
            calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);

            String data = "dd/MM/yy";
            SimpleDateFormat sdf = new SimpleDateFormat(data, Locale.ENGLISH);
            dateMed.setText(sdf.format(calendar.getTime()));
        }
    };

    view.findViewById(R.id.dateMed).setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
            new DatePickerDialog(Home.this, date, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)).show();
        }
    });
}

public void clock(View view, final Calendar setat){
    final TextView ora = (TextView)view.findViewById(R.id.clock);
    ora.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final Calendar time = Calendar.getInstance();
            int hour = time.get(Calendar.HOUR_OF_DAY);
            int minute = time.get(Calendar.MINUTE);

            TimePickerDialog timePickerDialog;
            timePickerDialog = new TimePickerDialog(Home.this, new TimePickerDialog.OnTimeSetListener(){
                @Override
                public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute){
                    if(selectedHour < 10 && selectedMinute >= 10) ora.setText("0"+selectedHour + ":" + selectedMinute);
                    if(selectedHour >= 10 && selectedMinute < 10) ora.setText(selectedHour + ":" + "0" + selectedMinute);
                    if(selectedHour < 10 && selectedMinute < 10) ora.setText("0" + selectedHour + ":" + "0" + selectedMinute);
                    if(selectedHour >= 10 && selectedMinute >= 10) ora.setText(selectedHour + ":" + selectedMinute);
                    setat.set(Calendar.HOUR_OF_DAY, selectedHour);
                    setat.set(Calendar.MINUTE, selectedMinute);
                }
            }, hour, minute, true);
            timePickerDialog.setTitle("");
            timePickerDialog.show();
        }
    });
}

public void setAlarm(int day , Calendar setat){
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.DAY_OF_WEEK, day+1);
    calendar.set(Calendar.HOUR_OF_DAY, setat.get(Calendar.HOUR_OF_DAY));
    calendar.set(Calendar.MINUTE, setat.get(Calendar.MINUTE));
    calendar.set(Calendar.SECOND, 0);

    long time = calendar.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();

    Log.d("day", String.valueOf(calendar.get(Calendar.DAY_OF_WEEK)));
    Log.d("time", String.valueOf(setat.get(Calendar.HOUR_OF_DAY)) + ":" + String.valueOf(setat.get(Calendar.MINUTE)));
    Log.d("actual", String.valueOf(Calendar.getInstance().get(Calendar.MINUTE)));

    Intent intent = new Intent(getApplicationContext(), NotificationService.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), Calendar.getInstance().get(Calendar.MILLISECOND), intent, PendingIntent.FLAG_UPDATE_CURRENT);

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

    if(calendar.getTimeInMillis() > System.currentTimeMillis())
        Log.d("bigger", "yes");
    else
        Log.d("bigger", "no");

    alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),  pendingIntent);
}

public void addMedNou(){
    findViewById(R.id.add).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AlertDialog.Builder builder = new AlertDialog.Builder(Home.this);
            View view = getLayoutInflater().inflate(R.layout.adddialog, null);
            builder.setView(view);
            final AlertDialog dialog = builder.create();

            final EditText nameMed = (EditText)view.findViewById(R.id.nameMed);
            final EditText nrMed = (EditText)view.findViewById(R.id.nrMed);
            final EditText comm = (EditText)view.findViewById(R.id.comm);
            final EditText dateMed = (EditText)view.findViewById(R.id.dateMed);
            FrameLayout add = (FrameLayout)view.findViewById(R.id.add);
            FrameLayout cancel = (FrameLayout)view.findViewById(R.id.cancel);
            calendar(view, dateMed);
            reminder(view);

            add.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(!nameMed.getText().toString().isEmpty() && !nrMed.getText().toString().isEmpty()){
                        SharedPreferences valoriSalvate = getSharedPreferences(PREFS_NAME, 0);
                        SharedPreferences.Editor edit = valoriSalvate.edit();

                        int total = valoriSalvate.getInt("total", 0);
                        total++;
                        if(total <= 10){
                            edit.putInt("total", total);
                            edit.putString("nume" + total, nameMed.getText().toString());
                            edit.putInt("nr" + total, Integer.parseInt(nrMed.getText().toString()));
                            edit.putString("comm" + total, comm.getText().toString());
                            edit.putString("date" + total, dateMed.getText().toString());
                        }
                        edit.commit();
                        dialog.dismiss();
                        Intent repeat = new Intent(Home.this, Home.class);
                        startActivity(repeat);
                    }
                    else
                        dialog.dismiss();
                }
            });

            cancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                }
            });

            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            dialog.show();
        }
    });
}

public void reminder(final View view){
    view.findViewById(R.id.reminder).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AlertDialog.Builder reminder = new AlertDialog.Builder(Home.this);
            final View layout = getLayoutInflater().inflate(R.layout.alarm, null);
            reminder.setView(layout);
            final AlertDialog dialog = reminder.create();

            final Calendar setat = Calendar.getInstance();
            clock(layout, setat);
            layout.findViewById(R.id.confirm).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    CheckBox[] boxes = new CheckBox[8];
                    boxes[0] = (CheckBox)layout.findViewById(R.id.check0);
                    boxes[1] = (CheckBox)layout.findViewById(R.id.check1);
                    boxes[2] = (CheckBox)layout.findViewById(R.id.check2);
                    boxes[3] = (CheckBox)layout.findViewById(R.id.check3);
                    boxes[4] = (CheckBox)layout.findViewById(R.id.check4);
                    boxes[5] = (CheckBox)layout.findViewById(R.id.check5);
                    boxes[6] = (CheckBox)layout.findViewById(R.id.check6);

                    if(boxes[0].isChecked()) {setAlarm(1, setat);}
                    if(boxes[1].isChecked()) {setAlarm(2, setat);}
                    if(boxes[2].isChecked()) {setAlarm(3, setat);}
                    if(boxes[3].isChecked()) {setAlarm(4, setat);}
                    if(boxes[4].isChecked()) {setAlarm(5, setat);}
                    if(boxes[5].isChecked()) {setAlarm(6, setat);}
                    if(boxes[6].isChecked()) {setAlarm(7, setat);}

                    Toast.makeText(Home.this, "Alarm has been set!", Toast.LENGTH_SHORT).show();
                    dialog.dismiss();
                }
            });

            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            dialog.show();
        }
    });
}

public void declarari(){
    for(int i=1;i<=10;i++){
        String mID = "m" + i;
        String nrID = "nr" + i;
        String nameID = "name" + i;
        String plusID = "plus" + i;
        String minusID = "minus" + i;
        String infoID = "info" + i;
        int resID = getResources().getIdentifier(mID, "id", getPackageName());
        int resNrID = getResources().getIdentifier(nrID, "id", getPackageName());
        int resNameID = getResources().getIdentifier(nameID, "id", getPackageName());
        int resPlusID = getResources().getIdentifier(plusID, "id", getPackageName());
        int resMinusID = getResources().getIdentifier(minusID, "id", getPackageName());
        int resInfoID = getResources().getIdentifier(infoID, "id", getPackageName());
        med[i] = ((LinearLayout)findViewById(resID));
        nr[i] = ((TextView)findViewById(resNrID));
        name[i] = ((TextView)findViewById(resNameID));
        plus[i] = ((TextView)findViewById(resPlusID));
        plus[i].setOnClickListener(this);
        minus[i] = ((TextView)findViewById(resMinusID));
        minus[i].setOnClickListener(this);
        info[i] = ((TextView)findViewById(resInfoID));
        info[i].setOnClickListener(this);
    }
}

public void afisare(){
    SharedPreferences valoriSalvate = getSharedPreferences(PREFS_NAME, 0);
    SharedPreferences.Editor edit = valoriSalvate.edit();

    int total = valoriSalvate.getInt("total", 0);
    for(int i=1;i<=total;i++){
        med[i].setVisibility(View.VISIBLE);
        String keyNume = "nume" + i;
        name[i].setText(valoriSalvate.getString(keyNume, null));
        String keyNr = "nr" + i;
        nr[i].setText(String.valueOf(valoriSalvate.getInt(keyNr, 0)));
    }

    edit.commit();
}

public void setari(){
    findViewById(R.id.setari).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent setari = new Intent(Home.this, setari.class);
            startActivity(setari);
        }
    });
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);
    addMedNou();
    setari();
    declarari();
    afisare();
}

@Override
public void onClick(View v){
    int actual;

    SharedPreferences valoriSalvate = getSharedPreferences(PREFS_NAME, 0);
    SharedPreferences.Editor edit = valoriSalvate.edit();

    AlertDialog.Builder builder = new AlertDialog.Builder(Home.this);
    View info = getLayoutInflater().inflate(R.layout.infoo, null);
    builder.setView(info);
    AlertDialog dialog = builder.create();
    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

    TextView title = (TextView)info.findViewById(R.id.title);
    TextView pastile = (TextView)info.findViewById(R.id.pastile);
    TextView date = (TextView)info.findViewById(R.id.date);
    TextView comentariu = (TextView)info.findViewById(R.id.comentariu);

非常感谢您的关注,希望您至少能帮我一点忙。祝你有个美好的一天!

这段代码有问题。首先,您说您要设置多个警报。为了让您设置多个闹钟,您需要保证每个 PendingIntent 都是唯一的。你这样做:

Intent intent = new Intent(getApplicationContext(), NotificationService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
    Calendar.getInstance().get(Calendar.MILLISECOND), intent,
    PendingIntent.FLAG_UPDATE_CURRENT);

除了 requestId 参数(第二个参数)外,您的所有警报都使用与 PendingIntent 相同的参数,您使用的是 Calendar.MILLISECOND 字段。这 不是唯一的 Calendar.MILLISECOND 将为您提供一个介于 0 和 999 之间的数字,表示特定时间戳的第二 内的 毫秒。这不能保证是唯一的。可能是也可能不是。


你问如何存储PendingIntent以便取消闹钟。实际上,您不需要存储 PendingIntent。您可以重新创建 PendingIntent 以取消警报。只需与最初设置闹钟时完全相同的操作即可。像这样:

Intent intent = new Intent(getApplicationContext(), NotificationService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
    Calendar.getInstance().get(Calendar.MILLISECOND), intent,
    PendingIntent.FLAG_UPDATE_CURRENT);
// Cancel the alarm
AlarmManager alarmManager = (AlarmManager)getApplicationContext()
                               .getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
// Now cancel the PendingIntent also (just to be sure)
pendingIntent.cancel();

这里的技巧是 PendingIntent.getBroadcast() 调用的 requestId(第二个参数)需要与您设置警报时使用的 requestId 完全匹配。所以你必须存储它。由于时间的毫秒部分不是唯一的,因此您需要找到一个更好的唯一数字用作 requestId。如果您每天只设置一个闹钟,您可以使用天数作为 requestId,例如 Calendar.DAY_OF_WEEK,或者您可以使用其他一些唯一 ID。设置和取消闹钟时使用相同的值。