BACK 버튼을 눌렀을 때 setResult가 작동하지 않습니다.


111

BACK 버튼을 누른 후 setResult를 시도하고 있습니다. 나는 onDestroy를 호출합니다.

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

그러나 그것에 관해서

onActivityResult(int requestCode, int resultCode, Intent data) 

resultCode는 0 (RESULT_CANCELED)이고 데이터는 'null'입니다.

그렇다면 BACK 버튼으로 종료 된 활동의 결과를 어떻게 전달할 수 있습니까?

답변:


159

onBackPressed()메서드 를 재정의하고 수퍼 클래스를 호출 하기 전에 결과 설정 해야 합니다.

@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();
}

23
이 방법을 사용하면 위에 표시된대로 setResult () 호출 후에 super.onBackPressed () 호출이 발생해야합니다. 그렇지 않으면 원래 문제가 다시 발생합니다!
jengelsma

1
이것이 가장 좋은 대답입니다. onPause () 또는 onDestroy ()를 재정의하면 onBackPressed ()가 먼저 호출되고 결과가 0으로 설정됩니다.주의하십시오!
Marek

또는 onCreate에서 기본 결과를 설정할 수 있습니다. finish () 전 어느 곳이든 괜찮습니다.
Helin Wang 2013

5
비슷한 접근 방식을 구현했지만 여전히 작동하지 않습니다. 예를 들어 요청 코드와 인 텐트가 작동하지만 resultCode는 항상 0입니다.
Neon Warge

68

Activity를 호출 하기 전에 결과를 설정해야합니다 finish(). 클릭 BACK 실제로 호출 finish()당신에 activity당신이 다음 코드를 사용할 수 있도록 :

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

    super.finish();
}

당신이 호출 할 경우 NavUtils.navigateUpFromSameTask();onOptionsItemSelected(), finish()라고,하지만 당신은 잘못을 얻을 것이다 result code. 그래서 당신은 호출 할 필요가 finish()없습니다 navigateUpFromSameTaskonOptionsItemSelected(). onActivityResult의 잘못된 requestCode


이것은 OP의 경우에서 작동하지만 일반적으로 작동하지는 않습니다. onPause () 및 onDestroy ()를 통해 앱 수명주기의 종료를 유도하는 finish ()보다 더 많은 메서드가 있습니까? 또한 다른 답변에서 내 의견을 참조하십시오.
pjv

그리고 없었더라도 API 업데이트에 언제 도입 될지 알 수 없습니다. onPause () 또는 onDestroy ()의 동작이 변경되었을 때처럼 쉽지 않습니다. 그것들은 당신이 재정의 해야하는 방법 입니다.
pjv

6
@pjv - 나는 당신의 포인트를 얻을하지 않습니다 무엇을 finish함께 할 수있다 onPauseonDestroy? 사람들은 완전히 그 위해를 제외하고 관련이없는 finish종료 프로세스를 시작 onPause하고 onDestroy의 일부를.
JBM

20

일부 사용자 지정 설정하려는 경우 RESULT_CODEonBackPressed다음 이벤트를 첫 번째로 설정해야 result하고 전화 super.onBackPressed()와 같은를 받게됩니다 RESULT_CODE발신자 활동의에 onActivityResult방법

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

10

내 코드를 리팩토링했습니다. 처음에 나는 일부 데이터를 준비로 설정 activity result에서 onDestroy(이 작동하지 않았다). 이제 activity반환 할 데이터가 업데이트 될 때마다 데이터를 설정 하고 onDestroy.


이것은 내 데이터가 업데이트 "onPause"에 있기 때문에 나를 위해 작동하지 않습니다
Bostone

를 호출 한 후 활동이 다시 생성되면 setResult()데이터가 손실됩니다.
Jarett Millard

3

다음 과 같이 onOptionsItemSelected 를 재정의해야 합니다.

@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);
    }
}

2

참조 하여 onActivityResult (INT, INT, 의도) 문서를

해결책은 Activity.RESULT_CENCELED 값에 대한 resultCode 를 확인하는 것 입니다. 그렇다면 BACK을 누르거나 활동이 중단되었음을 의미합니다. 그것이 당신들에게 효과가 있기를 바랍니다.


이것이 정확한 해결책입니다 .. Result Code가 필요합니다 .. 코드에서 당신 외에는 아무도 결과를 설정할 수 없습니다. 그래서 만약 결과가 OK가 아니라면 그것의 back presses 또는 Crashed를 의미합니다.
John

0

onDestroy체인에서 너무 늦었습니다. 대신 활동이 수명주기가 끝났는지 onPause확인 isFinishing()하기 위해 재정의 하고 확인하십시오 .


1
아니, 너무 늦었 어.
alex2k8 2010

실제로 이것을 버그라고 부릅니다 : code.google.com/p/android/issues/detail?id=1671 . 복잡한 응용 프로그램에서는 이로 인해 프로그래밍 할 수없는 동작이 있다고 생각합니다.
pjv

그것은 또한 매우 반 직관적입니다. 나는 이미 2 년 동안 같은 실수를 계속하고 있습니다.
pjv

실제로-이것은 더 나쁩니다. 그리고 내가 코딩 할 때 JB에 존재합니다. onPause에서 setResult를 호출하면 실행되지만 onActivityReturn이 실행될 때 nether resultCode 또는 데이터가 설정됩니다. 왜?
Bostone 2012

그 이유는 다음과 같습니다. "이 메서드가 반환 될 때까지 다음 활동이 재개되지 않기 때문에이 메서드 (onPause)의 구현은 매우 빨라야
Bostone

0

onBackPressed (안드로이드 레벨 5 이상)를 재정의하거나 onKeyDown ()을 재정의하고 KeyEvent.BUTTON_BACK을 잡으십시오 ( Android Activity Results 참조 ) 이것은 나를 위해 트릭을 수행합니다.


0

초기 활동으로 돌아갈 때 한 활동의 ​​onPause에서 실행되는 논리에 의존하지 마십시오. 문서에 따르면 :

이 메서드 (onPause)의 구현은이 메서드가 반환 될 때까지 다음 활동이 재개되지 않으므로 매우 빠릅니다.

자세한 내용은 http://goo.gl/8S2Y 를 참조하세요.

가장 안전한 방법은 각 결과 변경 작업이 완료된 후 결과를 설정하는 것입니다 (답변에서 언급했듯이)


0

대답을 붙여 넣으면 다른 사람들에게 도움이 될 수 있습니다. android : launchMode = "singleTask"를 사용하여 launcheMode를 설정하면 결과를 얻을 수 없습니다.

     /* <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.
 */

과:

     /* <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. 
 */
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.