Fragment获取本地照片显示之Activity 的ontActivityResult()

MainActivity中有一个fragment,fragment需要上传头像,所以肯定要跳到onActivityResult()方法


关于onActivityResult()写到哪会调到的问题,相信大家都知道,这个案例1中fragment中startActivityForResult调onActivityResult()是不行的

案例2 :当我们从一个Activity启动了一个Fragment,然后在这个Fragment中又去实例化了一些子Fragment,在子Fragment中去有返回的启动了另外一个Activity,即通过startActivityForResult方式去启动,这时候造成的现象会是,子Fragment接收不到OnActivityResult,如果在子Fragment中是以getActivity.startActivityForResult方式启动,那么只有Activity会接收到OnActivityResult,如果是以getParentFragment.startActivityForResult方式启动,那么只有父Fragment能接收(此时Activity也能接收),但无论如何子Fragment接收不到OnActivityResult。

这是一个非常奇怪的现象,按理说,应该是让子Fragment接收到OnActivityResult才对,究竟是什么造成的呢?

在网上搜了一大丢,发现都很讲的不详细,于是自己把解决的过程分享下:

没错最近我在项目中就是遇到了,第2中情况:MainActivity  里面实例化一个 fragment,在有这个fragment去实话子fragment 在有子fragment去调用系统的相册,相机,发现子fragment显示不了图片,于是我选择了走一条复杂的路

看源码:

public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            final View decor = mWindow != null ? mWindow.peekDecorView() : null;
            if (decor != null) {
                decor.cancelPendingInputEvents();
            }
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }
看看这个方法:mParent.startActivityFromChild(this, intent, requestCode)
public void startActivityFromChild(Activity child, Intent intent, 
            int requestCode, Bundle options) {
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, child,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, child.mEmbeddedID, requestCode,
                ar.getResultCode(), ar.getResultData());
        }
    }

ar为null,你的请求就被丢弃了,无法回调到你当前实现的 。。 Result(。。。){ }

 
   为什么会这样呢?
我们回到启动的时候,getActivity(). startActivityForResult()
    if(mParent == null){
       .....
}
else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }

最后我发现源码是花了时间看,可是问题还是纯在:
 
因为当启动Intent调用系统的action的时候,肯定会回调到 ,此fragment所依赖的
 于是,想到了用接口的回调:   Activity:<pre name="code" class="java">	private onActivityResultListener resultlistener;
	public interface onActivityResultListener{
	   void onResultlistener(int requestCode, int resultCode, Intent data);
	}
	public void setOnActivityResultListener(onActivityResultListener resultlistener){
		this.resultlistener = resultlistener;
	}
	 
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		resultlistener.onResultlistener(requestCode, resultCode, data);
		super.onActivityResult(requestCode, resultCode, data);
	}

 
fragment:
  <pre name="code" class="java">@Override
	public void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		((MainActivity)getActivity()).setOnActivityResultListener(new onActivityResultListener() {
			@Override
			public void onResultlistener(int requestCode, int resultCode, Intent data) {
				// TODO Auto-generated method stub
				if (resultCode == FragmentActivity.RESULT_OK) {
					uri = data.getData();
					ContentResolver cr = getActivity().getContentResolver();
					try {
						Bitmap bitmap = MediaStore.Images.Media.getBitmap(cr, uri);
						if (bitmap != null) {
							Bitmap smallBitmap = ImageTools.zoomBitmap(bitmap, bitmap.getWidth() / SCALE, 
									bitmap.getHeight() / SCALE);  
							bitmap.recycle();
							if (flag == 1) {
								 bytePhoto1 = Bitmap2Bytes(smallBitmap);
								 dan_photo1.setImageBitmap(smallBitmap);
								 String path = uri.getPath(); 
								 Toast.makeText(getActivity(), "路径="+path, 2000).show();
							} else if(flag == 2) {
								dan_photo2.setImageBitmap(smallBitmap);
								String photo_two = uri.toString();
								 bytePhoto2 =Bitmap2Bytes(smallBitmap);
							} else if(flag == 3) {
								bytePhoto3 = Bitmap2Bytes(smallBitmap);
								dan_photo3.setImageBitmap(smallBitmap);
								String photo_three = uri.toString();
							} else {
								return;
							}
							//photo.append(uri.toString());
						}
					} catch (Exception e) {
						ToastUtil.show(getActivity(), getResources().getString(R.string.read_photo_failed));
					}
				}										
				
			}
		});
	}
调用系统相册:
 
     <pre name="code" class="java">	private void commonMethod() {
		Intent intent = new Intent();  
		intent.setType("image/*");  
		intent.setAction(Intent.ACTION_GET_CONTENT);   
		startActivityForResult(intent, 1);
	}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值