startActivityForResult 创建挂起通知立即触发

startActivityForResult to create pending notification triggering immediately

我有以下代码和两个活动,其中我在 MainActivity 中有一个 ListActivity,然后是 AddItemsActivity 以动态地将项目添加到 ListActivity。我被困在它的一部分上,我不确定修复当前代码是否更容易,或者我是否应该以编程方式采用不同的方式。

我的目标是当数据从 AddItemActivity 发送到 MainActivity 时生成一个 PendingIntent 通知,该通知将在选定的日期触发。

我一直在搜索 Google 并在 SO 搜索了大约一个星期,尝试了各种建议的解决方案,但似乎没有任何解决方案可以满足我的需要。

我知道我最终需要一些方法来以某种存储格式保存生成的通知,但目前我只想验证该功能是否正常工作。

MainActivity.java

public class MainActivity extends ListActivity {

    static final int ADD_ITEM_REQUEST = 1; // ActivityForResult request code

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ...
    } 

    // addItems is defined in XML Button onClick
    public void addItems(View view) {
        /* Start Activity For Result */
        Intent intent = new Intent(MainActivity.this, AddItemActivity.class);
        startActivityForResult(intent, ADD_ITEM_REQUEST);
    }

    // Activity Result passed from AddItemActivity
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request to respond to
    if (requestCode == ADD_ITEM_REQUEST) {
        // Make sure the result was successful
        if (resultCode == RESULT_OK) {
            if ((data.getExtras().containsKey("editTextView") && !data.getStringExtra("editTextView").isEmpty()) && data.getExtras().containsKey("textView") && !data.getStringExtra("textView").isEmpty()) {
                // HashMap defines and sets Intent extras to ListActivity items
                HashMap<String, String> temp = new HashMap<>();
                temp.put("editTextView", data.getStringExtra("editTextView"));
                temp.put("textView", data.getStringExtra("textView"));
                list.add(temp) // list is instance of ListAdapter

                ... // what (if anything) could go here?
            }
        } else {
            Toast.makeText(this, "An Error Has Occurred", Toast.LENGTH_SHORT).show();
        }
        adapter.notifyDataSetChanged(); // notifies ListAdapter of changes
    }
  }
}

AddItemActivity.java

public class AddItemActivity extends ActionBarActivity {

    EditText itemNameET;
    Button setDateBtn;
    TextView dateView;
    private Calendar calendar;
    private int year, month, day;

    private PendingIntent pendingIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_item);

        itemNameET = (EditText) findViewById(R.id.editItemText);
        setDateBtn = (Button) findViewById(R.id.setDateButton);

        dateView = (TextView) findViewById(R.id.setDateTextView);
        calendar = Calendar.getInstance();
        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH);
        day = calendar.get(Calendar.DAY_OF_MONTH);
        showDate(year, month, day);
    }

    public void sendToListView(View view) {
        // Set result on AddItemActivity
        Intent resultIntent = new Intent();
        // Add extras or a data URI to this intent as appropriate.
        resultIntent.putExtra("editTextView", itemNameET.getText().toString()); // Item title
        resultIntent.putExtra("textView", dateView.getText().toString()); // Date
        resultIntent.putExtra("passDateYear", year); // Selected Year
        resultIntent.putExtra("passDateMonth", month); // Selected Month
        resultIntent.putExtra("passDateDay", day); // Selected Day

        Intent myIntent = new Intent(AddItemActivity.this, DateReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(AddItemActivity.this, 0, myIntent, 0);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + calendar.getTimeInMillis(), pendingIntent);
        // Toast.makeText(this, "New Item Added Successfully", Toast.LENGTH_LONG).show();
        Toast.makeText(this, "Date Passed: " + calendar.getTimeInMillis(), Toast.LENGTH_LONG).show();

        setResult(Activity.RESULT_OK, resultIntent);
        finish();
    }

    @SuppressWarnings("deprecation")
    public void setDate(View view) { // Button onClick action
        showDialog(999);
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        // TODO Auto-generated method stub
        if (id == 999) {
            return new DatePickerDialog(this, myDateListener, year, month, day);
        }
        return null;
    }

    private DatePickerDialog.OnDateSetListener myDateListener
        = new DatePickerDialog.OnDateSetListener() {

        @Override
        public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) {
            // arg1 = year
            // arg2 = month
            // arg3 = day
            showDate(arg1, arg2+1, arg3);
        }
    };

    private void showDate(int year, int month, int day) {
        dateView.setText(new StringBuilder().append(month).append("/").append(day).append("/").append(year));
    }
}

DateReceiver.java(广播接收器)

public class DateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service1 = new Intent(context, DateAlarmService.class);
        context.startService(service1);
    }
}

DateAlarmService(服务)

public class DateAlarmService extends Service {
    private NotificationManager notificationManager;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @SuppressWarnings("static-access")
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);

        notificationManager = (NotificationManager) this.getApplicationContext().getSystemService(this.getApplicationContext().NOTIFICATION_SERVICE);
    Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);

    Notification notification = new Notification(R.mipmap.ic_launcher, "Test!", System.currentTimeMillis());
    intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

    PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this.getApplicationContext(), 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
    notification.flags |= Notification.FLAG_AUTO_CANCEL;


    notification.setLatestEventInfo(this.getApplicationContext(), "Test", "Test!", pendingNotificationIntent);
    notification.defaults |= Notification.DEFAULT_SOUND; // notification sound
    notification.defaults |= Notification.DEFAULT_LIGHTS; // notification lights
    notification.defaults |= Notification.DEFAULT_VIBRATE; // notification vibration


    notificationManager.notify(0, notification);
}

提供的代码会在 onActivityResult 开始时立即创建通知,即使我将日历日期设置为提前一天或多天也是如此。

据我所知,您正在将闹钟设置为在当前系统时间响铃。

每当您调用 Calendar.getInstance() 时,它 returns 一个 Calendar 对象设置为当前日期和时间。在调用 alarmManager.set.

之前,您必须至少对返回的 Calendar 实例调用其中一种 set 方法

您设置闹钟的方式错误。在当前系统时间设置闹钟,这就是它得到的原因在您设置时触发。

要在 alarmManager.set() 中使用 calendar.getTimeInMillis() 设置闹钟,并将日历初始化为,

calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);

这是当前时间,而不是您想要设置的时间,这就是闹钟在您设置时触发的原因。

要在特定时间设置闹钟,首先在日历中设置想要的timeand/ordate为,

Calendar calendar = Calendar.getInstance();

calendar.set(Calendar.YEAR, 2015);
calendar.set(Calendar.MONTH, 3);
calendar.set(Calendar.DAY_OF_MONTH, 18);

并将闹钟设置为,

alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);

这将在 March 18, 2015 即明天触发警报。

calendar.set() 中设置您想要的年月日值,以便在您想要的时间触发警报。