2013년 7월 3일 수요일

Activity의 Fragment에서 전달한 Intent result 수신 처리

이전 블로그에서 이전 함 (원본 글 2013/07/03 작성)

Activity 내의 Fragment에서 보낸 intent의 requestCode의 값이 좀 달라서 찾다 보니
Fragment에서 전달한 intent의 request code의 값은 좀 다르게 전달 되고 있었음.

일반적인 Activity에서 intent 사용 방법
  public class MyActivity extends Activity {
     ...

     static final int PICK_CONTACT_REQUEST = 0;

     protected boolean onKeyDown(int keyCode, KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
             // When the user center presses, let them pick a contact.
             startActivityForResult(
                 new Intent(Intent.ACTION_PICK,
                 new Uri("content://contacts")),
                 PICK_CONTACT_REQUEST);
            return true;
         }
         return false;
     }

     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         if (requestCode == PICK_CONTACT_REQUEST) {
             if (resultCode == RESULT_OK) {
                 // A contact was picked.  Here we will just display it
                 // to the user.
                 startActivity(new Intent(Intent.ACTION_VIEW, data));
             }
         }
     }
 }
 

기존에 Activity에서 사용하던 Intent request code를 사용하려다보니 안되고 0xFFFF 이하의 값을 사용하도록 강제하고 있다.

또한 Fragment에서 Intent를 전송하고 Activity의 onActivityResult 코드에서 전달 받은 requestCode 값이
당초 전달한 값에서 0x40000 이 추가되어 있었음..

찾다보니 Fragment에서 전달한 intent result 처리를 다르게 해줘야 한다는 링크가 있어서

일단 대충 위 링크대로 처리하고 임의로 0x4000을 제거하여 처리했지만.. 왠지 모를 찝찝함..

더 찾다 보니 일본에서 관련 내용을 잘 정리한 링크가 있었음. 이사람 블로그 종종 찾다보면 최신 Android feature에 대해서 잘 정리하고 있는 것 같다...

Fragment에서 전송한 Intent result 처리를 위한 Activity의 onActivityResult 코드
 protected  void onActivityResult ( int requestCode, int resultCode, Intent data) {

    int index = requestCode >> 16 ;
     if (index! = 0 ) {
        index -;
        if (mFragments.mActive == null | | index < 0 | | index> = mFragments.mActive.size ()) {
            Log.w (TAG, "Activity result fragment index out of range : 0x"
                    + Integer.toHexString (requestCode));
            return ;
        }
        Fragment frag = mFragments.mActive.get (index);
        if (frag == null ) {
            Log.w (TAG, "Activity result no fragment exists for index : 0x"
                    + Integer.toHexString (requestCode));
        } else {
            frag.onActivityResult (requestCode & 0xffff , resultCode, data);
        }
        return ;
    }
        
    super . onActivityResult (requestCode, resultCode, data);
}


위 블로그에서 언급한 대로 Fragment의 startActivityForResult를 확인하니 다음과 같다.

이게 중요... 
super.startActivityForResult(intent, ((fragment.mIndex+1)<<16) + (requestCode&0xffff));

GrepCode / com.google.android / android /   4.2.2_r1   / android.app.Fragment
 Call Activity.startActivityForResult(android.content.Intent,int) on the fragment's containing Activity.
    public void startActivityForResult(Intent intentint requestCode) {
        startActivityForResult(intentrequestCodenull);
    }

    
    public void startActivityForResult(Intent intentint requestCodeBundle options) {
        if (mActivity == null) {
            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
        }
        if (options != null) {
            mActivity.startActivityFromFragment(thisintentrequestCodeoptions);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            mActivity.startActivityFromFragment(thisintentrequestCodeoptions);
        }
    }
    


GrepCode / com.google.android / android /   4.2.2_r1   / android.support.v4.app.FragmentActivity

Modifies the standard behavior to allow results to be delivered to fragments. This imposes a restriction that requestCode be <= 0xffff.
811

812
    @Override
813
    public void startActivityForResult(Intent intentint requestCode) {
814
        if (requestCode != -1 && (requestCode&0xffff0000) != 0) {
815
            throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
816
        }
817
        super.startActivityForResult(intentrequestCode);
818
    }

    
Called by Fragment.startActivityForResult() to implement its behavior.
822

823
    public void startActivityFromFragment(Fragment fragmentIntent intent
824
            int requestCode) {
825
        if (requestCode == -1) {
826
            super.startActivityForResult(intent, -1);
827
            return;
828
        }
829
        if ((requestCode&0xffff0000) != 0) {
830
            throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
831
        }
832
        super.startActivityForResult(intent, ((fragment.mIndex+1)<<16) + (requestCode&0xffff));
833
    }
834
    
835
    void invalidateSupportFragment(String who) {
836
        //Log.v(TAG, "invalidateSupportFragment: who=" + who);
837
        if (mAllLoaderManagers != null) {
838
            LoaderManagerImpl lm = mAllLoaderManagers.get(who);
839
            if (lm != null && !lm.mRetaining) {
840
                lm.doDestroy();
841
                mAllLoaderManagers.remove(who);
842
            }
843
        }
844
    }



댓글 없음:

댓글 쓰기