簡體   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