【问题标题】:startActivityForResult to create pending notification triggering immediatelystartActivityForResult 立即创建待处理的通知触发
【发布时间】:2015-03-17 14:58:20
【问题描述】:

我有以下两个活动的代码,其中我在 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 (BroadcastReceiver)

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 开始时立即创建通知。

【问题讨论】:

  • 那么问题是什么?你把闹钟定在明天,今天就响了?还是您将其设置为昨天并在今天触发?
  • 你发的代码太多了,但是我看到的是你正在设置当前时间的闹钟,见alarmManager.set()中的calendar.getTimeInMillis(),你需要设置你想要闹钟的时间被触发。
  • @DerGolem 如果我在任何时候设置警报,它会在数据传递到 onActivityResult 方法后立即触发通知(无论设置的日期如何)。跨度>
  • 如果日期已经到期,警报将立即触发。
  • @Apurva 我尝试使用calendar.set(year, month, day); 在 setResult 方法 (sendToListView) 中添加一个 set 方法,但无论选择什么日期,它都会将生成通知的日期设置为我保存信息的时间。

标签: android android-intent android-activity android-notifications


【解决方案1】:

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

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

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

这是当前时间,而不是您想要设置的时间,这就是为什么在您设置时会触发警报。

要在特定时间设置闹钟,首先在日历中将所需的time和/或date设置为,

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() 中设置您想要的年月日值,以便在您想要的时间发出警报。

【讨论】:

  • 现在我明白你说的有什么不同了。现在我遇到的问题是我需要找到一种方法来通过变量private int year, month, day 设置日历 YEAR、MONTH 和 DAY_OF_MONTH 的值,因为用户将通过 Calendar 函数选择任意日期.
  • 成功!!!我将把你的答案标记为正确,因为它对程序的运行至关重要!我需要做的是在onDateSet 函数中添加一行代码。我添加到方法末尾的是int newYear = arg1; int newMonth = arg2; int newDay = arg3; 然后在sendToListView 方法中我使用了您的代码并用新变量替换了这些值。太感谢了! :)
【解决方案2】:

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

无论何时调用Calendar.getInstance(),它都会返回一个设置为当前日期和时间的Calendar 对象。在调用alarmManager.set 之前,您必须至少调用返回的Calendar 实例上的set 方法之一。

【讨论】:

  • 正如我上面提到的,无论我使用calendar.set(year, month, day) 设置什么日期,创建通知的日期都是我保存数据的那一刻。因此,如果我在 2017 年 3 月 3 日下午 1:00 单击保存按钮将数据发送到列表,则通知显示的日期/时间是 2015 年 3 月 17 日下午 1:00。无论我做什么,日期都不会设置为今天以外的任何日期/时间。
猜你喜欢
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-11
  • 1970-01-01
  • 2016-03-10
  • 1970-01-01
  • 2018-06-22
相关资源
最近更新 更多