繁体   English   中英

从通知启动活动并在BackPressed上传递数据

[英]Starting an Activity from a Notification and passing data onBackPressed

我在该应用上有3个活动:

MainMenuActivity-> ExecuteTrainingActivity-> ExecuteExerciseActivity。

从MainMenuActivity到ExecuteTrainingActivity,我为ExecuteTrainingActivity查询传递了idExecution和idExercise并加载了初始数据。

ExecuteTrainingActivity onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {
//...
    initialize();
    setupRecyclerView(exercises);
}

private void initialize() {
    Bundle extras = getIntent().getExtras();

    if (extras != null) {
        if (extras.containsKey("id_execution")) {
            idExecution = extras.getLong("id_execution");
            idExercise = extras.getLong("id_exercise");

            execution = queryExecution(idExecution);
        } else {
            insertExecution();
        }
    }
}

在第三个活动ExecuteExerciseActivity中,我有一个TimerFragment,当TimerCountdown达到0时,它将打开一个Notification弹出窗口,单击该窗口时将打开一个新的ExecuteExerciseActivity。

在此TimerFragment上,我为Extras传递了相同的id,因此可以在新的ExecuteExerciseActivity中获取它们:

public class TimerFragment extends Fragment {

//...
private void showNotification(){
    Intent intent = new Intent(getActivity(), ExecuteExerciseActivity.class);
    intent.putExtra("id_execution", idExecution);
    intent.putExtra("id_exercise", idExercise);
    intent.putExtra("position", position);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(getActivity());
    stackBuilder.addNextIntentWithParentStack(intent);

    PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

    /*=== CHECK IF NOTIFICATION CHANNEL IS ACTIVE ===*/
    boolean ok = isNotificationChannelEnabled(getActivity(), Constants.CHANNEL_ID);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(requireNonNull(getActivity()), Constants.CHANNEL_ID)
            .setSmallIcon(R.drawable.d77)
            .setContentTitle("Teste Notificação")
            .setContentText("Ababa")
            .setPriority(NotificationCompat.PRIORITY_HIGH)

            .setContentIntent(pendingIntent)
            .setAutoCancel(true);

    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getActivity());

    notificationManager.notify(0, mBuilder.build());
}

从这个新的新ExecuteExerciseActivity中,我希望使系统保持相同的Activity导航流,但是当我从新的ExecuteExerciseActivity反压到ExecuteTrainingActivity时,我无法为ExecuteTrainingActivity查询和加载传递ID。

有没有办法在BackPress上传递参数? 最好的方法是否替代onBackPress创建新的意图并启动新的Activity?

**我的清单正确使用了parentActivityName。

将查询和ID保存到ExecuteExerciseActivity的onDestroy中的SharedPreferences中,然后在旧的ExecuteTrainingActivity中再次拉出查询和ID。 onBackPressed会触发活动生命周期的onDestroy事件。 然后在ExecuteTrainingActivity的onResume中拉出此数据。

我认为您可以通过重写ExecuteExerciseActivity的onOptionsItemSelected()方法来实现。 尝试这个:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == android.R.id.home) {
        Intent intent = new Intent(this, ExecuteExerciseActivity.class);
        //Add the extras to the intent
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

在Android中,如果您的“活动”启动了另一个“活动”,并希望将数据传递给该“活动”,则可以将这些数据添加为Intent Extras。

这种活动A到活动B的发送数据类型已经在使用。

但是对于将活动B返回活动A的方法,实际上有一个内置解决方案,它是通过startActivityForResult(Intent, REQUEST_CODE)而不是startActivity(Intent)

现在在活动B中,您只需要编写代码:

@Override
public void onBackPressed()
{
     Intent resultIntent = getIntent();
     resultIntent.putExtra(EXTRA_NAME, extra_value);
     setResult(Activity.RESULT_OK, resultIntent);
     finish();
}

基本上,在活动B中,您要设置要发送回启动活动B的活动A的数据,因为这两个活动之间存在联系。

接下来,在您的活动A中,只需重写onActivityResult()方法。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
             // get data through data.getIntExtra() and etc
        }
    }
}

请求代码需要与您用于活动B的REQUEST_CODE匹配,因此活动A知道要响应哪个活动。 结果代码只是对从活动B返回的结果类型进行分类的一种快速方法,因为从活动B返回的结果可能不止一种。

这种传递数据的解决方案比创建新的Intent和启动新的Activity更好,因为您无需启动新的Activity。 您的活动A已经存在,因此没有理由重建整个布局,重新加载所有数据以及在活动堆栈上存在新的活动。

由于您的唯一目的是将数据从活动B传递回启动它的活动A,因此请使用startActivityForResult()onActivityResult()处理此类数据共享。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM