setResult không hoạt động khi nút BACK được nhấn


90

Tôi đang cố gắng đặtResult sau khi nhấn nút BACK. Tôi gọi onDestroy

Intent data = new Intent(); 
setResult(RESULT_OK, data) 

Nhưng khi nói đến

onActivityResult(int requestCode, int resultCode, Intent data) 

các resultCode là 0 (RESULT_CANCELED) và dữ liệu là 'null'.

Vì vậy, làm cách nào tôi có thể vượt qua kết quả từ hoạt động bị chấm dứt bằng nút BACK?

9

Tôi đã cấu trúc lại mã của mình. Ban đầu tôi đã chuẩn bị một số dữ liệu và đặt nó là activity result trong onDestroy (điều này không hoạt động). Bây giờ tôi đặt dữ liệu activity mỗi khi dữ liệu được trả về được cập nhật và không có gì trong onDestroy.

  0

Điều này không có tác dụng với tôi vì dữ liệu của tôi cập nhật trong "onPause" 22 jul. 122012-07-22 17:49:53

  0

Nếu hoạt động của bạn được tạo lại sau khi bạn gọi 'setResult()', dữ liệu của bạn sẽ bị mất. 12 may. 162016-05-12 13:40:41


0

onDestroy quá muộn trong chuỗi — thay vì ghi đè và kiểm tra isFinishing() để kiểm tra xem hoạt động của bạn có ở cuối vòng đời của nó hay không.

+1

Không, điều này cũng đã quá muộn. 22 apr. 102010-04-22 03:01:15

+1

Ồ, rất tiếc .. :) 22 apr. 102010-04-22 04:39:11

  0

Tôi thực sự gọi đây là lỗi: http://code.google.com/p/android/issues/detail?id=1671. Trong các ứng dụng phức tạp, tôi nghĩ vì điều này chỉ có một số hành vi bạn không thể lập trình. 16 mar. 112011-03-16 22:21:54

  0

Nó cũng rất phản trực giác. Vì vậy, nhiều mà tôi tiếp tục làm cho cùng một sai lầm, trong một khoảng thời gian 2 năm nay đã. 16 mar. 112011-03-16 22:28:31

  0

Thực ra - điều này còn tệ hơn nữa. Và nó tồn tại trong JB khi tôi đang viết mã. Nếu tôi gọi setResult từ onPause, nó được thực thi nhưng kết quả nether resultCode và dữ liệu không được thiết lập khi onActivityReturn được thực hiện. Tại sao? 22 jul. 122012-07-22 17:49:20

  0

Và đó là lý do: "Việc triển khai phương pháp này (onPause) phải rất nhanh vì hoạt động tiếp theo sẽ không được tiếp tục cho đến khi phương thức này trả về" http://goo.gl/8S2Y 22 jul. 122012-07-22 17:52:47


56

Activity kết quả phải được đặt trước khifinish() được gọi. Nhấp LẠI thực sự gọi finish() trên activity của bạn, vì vậy bạn có thể sử dụng đoạn mã sau:

@Override 
public void finish() { 
    Intent data = new Intent(); 
    setResult(RESULT_OK, data); 

    super.finish(); 
} 

Nếu bạn gọi NavUtils.navigateUpFromSameTask(); trong onOptionsItemSelected(), finish() được gọi, nhưng bạn sẽ nhận được sai result code. Vì vậy, bạn phải gọi finish() không navigateUpFromSameTask trong onOptionsItemSelected(). wrong requestCode in onActivityResult

  0

Điều này hoạt động trong trường hợp OPs, nhưng không nói chung, phải không? Có nhiều phương thức hơn là kết thúc() làm cho kết thúc vòng đời của ứng dụng (thông qua onPause() và onDestroy())? Cũng xem bình luận của tôi ở câu trả lời khác. 16 mar. 112011-03-16 22:24:08

  0

Và ngay cả khi không có, bạn sẽ không biết về nó khi nó sẽ được giới thiệu trong một bản cập nhật API. Không dễ như bạn làm khi hành vi của onPause() hoặc onDestroy() thay đổi. Đó là những phương pháp bạn đang * giả định * để ghi đè lên. 16 mar. 112011-03-16 22:31:58

+5

@pjv - Tôi không nhận được điểm của bạn, những gì 'kết thúc' phải làm với' onPause' và 'onDestroy'? Chúng hoàn toàn không liên quan ngoại trừ 'kết thúc' bắt đầu quá trình chấm dứt mà' onPause' và 'onDestroy' là một phần của. 30 aug. 112011-08-30 19:45:13


3

Tham khảo onActivityResult(int, int, Intent) doc

Giải pháp là để kiểm tra resultCode cho giá trị Activity.RESULT_CENCELED. Nếu có, thì điều đó có nghĩa là BACK đã được nhấn hoặc hoạt động bị lỗi. Hy vọng nó hoạt động cho các bạn, làm việc cho tôi :).

  0

Đây là giải pháp chính xác .. Bạn phải kết quả Mã .. Không ai có thể đặt kết quả khác với bạn trong mã. Vì vậy, nếu kết quả là không OK có nghĩa là một trong hai trở lại ép Hoặc Crashed .. 15 sep. 152015-09-15 14:16:26


0

Hãy thử ghi đè trênTrởPressPress (từ cấp android 5 trở lên) hoặc ghi đè lênKeyDown() và bắt KeyEvent.BUTTON_BACK (xem Android Activity Results) Điều này có lợi cho tôi.


128

Bạn cần overide phương pháp onBackPressed() và thiết lập kết quả trước khi cuộc gọi đến lớp cha, tức là

@Override 
public void onBackPressed() { 
    Bundle bundle = new Bundle(); 
    bundle.putString(FIELD_A, mA.getText().toString()); 

    Intent mIntent = new Intent(); 
    mIntent.putExtras(bundle); 
    setResult(RESULT_OK, mIntent); 
    super.onBackPressed(); 
} 
+16

Do lưu ý rằng nếu bạn sử dụng phương pháp này, lời gọi super.onBackPressed() phải xảy ra sau khi cuộc gọi đến setResult() như được hiển thị ở trên hoặc bạn sẽ có bản gốc vấn đề trên một lần nữa! 24 may. 122012-05-24 18:28:43

+1

Câu trả lời hay nhất ở đây. Nếu chúng ta ghi đè onPause() hoặc onDestroy(), onBackPressed() sẽ được gọi đầu tiên và nó sẽ đặt kết quả là 0. Hãy lưu ý điều đó! 05 jul. 132013-07-05 05:02:13

  0

hoặc bạn có thể đặt kết quả mặc định trong onCreate. Bất kỳ nơi nào trước khi kết thúc() đều ổn. 26 sep. 132013-09-26 15:35:03

+4

Tôi đã triển khai cách tiếp cận tương tự nhưng vẫn không hoạt động. Ví dụ FOr Tôi có mã yêu cầu và ý định làm việc nhưng resultCode luôn là 0. 30 apr. 152015-04-30 14:35:19


0

Đừng dựa vào bất kỳ logic thực hiện trong onPause của một hoạt động khi bạn quay lại ban đầu một. Theo các tài liệu:

Triển khai phương pháp này (onPause) phải rất nhanh chóng vì hoạt động kế tiếp sẽ không được tiếp tục cho đến khi phương thức này trả

Xem http://goo.gl/8S2Y để biết chi tiết.

Cách an toàn nhất là để thiết lập kết quả sau mỗi hoạt động kết quả làm thay đổi hoàn tất (như bạn đề cập đến trong câu trả lời của bạn)


2

Bạn nên ghi đè onOptionsItemSelected như thế này:

@Override 
public boolean onOptionsItemSelected(final MenuItem item) { 
    switch (item.getItemId()) { 
    case android.R.id.home: 
     final Intent mIntent = new Intent(); 
     mIntent.putExtra("param", "value"); 
     setResult(RESULT_OK, mIntent); 
     finish(); 
     return true; 
    default: 
     return super.onOptionsItemSelected(item); 
    } 
} 

0

i dán câu trả lời có thể sẽ hữu ích cho người khác: khi tập hợp launcheMode với android: launchMode = "singleTask" tôi cũng không thể nhận kết quả, tài liệu nói:

 /* <p>Note that this method should only be used with Intent protocols 
* that are defined to return a result. In other protocols (such as 
* {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may 
* not get the result when you expect. For example, if the activity you 
* are launching uses the singleTask launch mode, it will not run in your 
* task and thus you will immediately receive a cancel result. 
*/ 

và:

 /* <p>As a special case, if you call startActivityForResult() with a requestCode 
* >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your 
* activity, then your window will not be displayed until a result is 
* returned back from the started activity. This is to avoid visible 
* flickering when redirecting to another activity. 
*/ 

13

Nếu bạn muốn thiết lập một số tùy chỉnh RESULT_CODE trong onBackPressed sự kiện thì bạn cần phải đầu tiên thiết lập các result và sau đó gọi các super.onBackPressed() và bạn sẽ nhận được cùng một RESULT_CODE trong hoạt động của người gọi onActivityResult phương pháp

@Override 
    public void onBackPressed() 
    { 
     setResult(SOME_INTEGER); 
     super.onBackPressed(); 
    }