片段onActivityResult返回null

时间:2015-06-02 09:57:55

标签: android android-fragments

在我正在开发的应用中,用户可以在他的个人资料中定义图像。第一次执行应用程序时,会显示一个介绍活动,用户可以选择从galery中选择一张照片或者使用相机拍摄一张新照片。

这很好用。用户设置个人资料图片后,我将其保存在app文件夹中,稍后我可以在应用程序中使用该图片。

我的应用程序基于导航抽屉(支持),因此它由片段组成。其中一个片段用于显示配置文件pic的用户配置文件。在这里,用户有机会再次改变这张照片。这是我遇到麻烦的地方。

要选择一个新的图片,我使用的相同代码用于在介绍活动中获取图片,只是将一些内容调整到片段(放置getActivity())。但似乎并没有将图像返回到片段而且它正在抛出一个NPE。

这就是在SettingsFragment中从图库中选择图片的方式:

Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, PICK_IMAGE_REQUEST_FRAG);

这里也是SettingsFragment中的onActivityResult:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case PICK_IMAGE_REQUEST_FRAG:
            if (resultCode == getActivity().RESULT_OK && data != null) {
                /*We get the image URI*/
                Uri selectedImageUri = data.getData();
                Bitmap srcBmp = null;
                try {
                    srcBmp = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), selectedImageUri);
                } catch (FileNotFoundException e) {
                    Log.e("GET_IMAGE", e.getMessage(), e);
                } catch (IOException e) {
                    Log.e("GET_IMAGE", e.getMessage(), e);
                }

                /*Transform the original image to landscape to use it as profile background*/
                Bitmap landBmp = null;
                if (srcBmp.getWidth() <= srcBmp.getHeight()) {
                    landBmp = Bitmap.createBitmap(
                            srcBmp,
                            0,
                            srcBmp.getHeight()/2 - srcBmp.getWidth()/2, //srcBmp.getHeight()/4 ?
                            srcBmp.getWidth(),
                            srcBmp.getWidth() /2
                    );
                }

                /*Scale the bitmap*/
                int originalWidth = srcBmp.getWidth();
                int originalHeight = srcBmp.getHeight();
                int newWidth = 400;
                int newHeight = (originalHeight*newWidth)/originalWidth;
                Bitmap fullbitmap = Bitmap.createScaledBitmap(landBmp, newWidth, newHeight, true);
                /*Save the bitmap in app-folder*/
                ContextWrapper cw1 = new ContextWrapper(getActivity().getApplicationContext());
                File directory1 = cw1.getDir("profile", Context.MODE_PRIVATE);
                if (!directory1.exists()) {
                    directory1.mkdir();
                }
                File filepath1 = new File(directory1, "profile_pic.png");
                FileOutputStream fos1 = null;
                try {
                    fos1 = new FileOutputStream(filepath1);
                    fullbitmap.compress(Bitmap.CompressFormat.PNG, 100, fos1);
                    fos1.close();
                } catch (Exception e) {
                    Log.e("SAVE_FULL_IMAGE", e.getMessage(), e);
                }

                /*Show background profile pic*/
                Drawable drawable = new BitmapDrawable(getResources(), fullbitmap);
                header_container.setBackgroundDrawable(drawable);
            }
            break;

但是如上所述,应用程序崩溃了这就是logcat所说的:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131073, result=-1, 
    data=Intent { dat=content://media/external/images/media/204 flg=0x1 }}   
    to activity {com.myproject.executer/com.myproject.executer.MainActivity}: 
java.lang.NullPointerException at android.app.ActivityThread.deliverResults(ActivityThread.java:3389)

Caused by: java.lang.NullPointerException at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:590) 
    at com.myproject.executer.SettingsFragment.onActivityResult(SettingsFragment.java:275)

第275行是Bitmap fullbitmap = Bitmap.createScaledBitmap(landBmp, newWidth, newHeight, true);

所以,我不太了解发生了什么,因为它说的是没有将结果归结为MainActivity的东西,它必须将结果传递给SettingsFragment。

2 个答案:

答案 0 :(得分:1)

如果onActivityResult()方法没有完成并返回,系统会将其计为交付失败,这就是错误从该消息开始的原因。

在您的代码中,似乎landBmp为空,因为条件srcBmp.getWidth() <= srcBmp.getHeight()为false,在这种情况下您不会初始化landBmp。这会抛出NullPointerException,并在onActivityResult()返回之前暂停执行。

答案 1 :(得分:0)

您可以阅读http://inthecheesefactory.com/blog/how-to-fix-nested-fragment-onactivityresult-issue/en?fb_action_ids=780839882030502&fb_action_types=og.comments

创建ActivityResultEvent.java

import android.content.Intent;

/**
 * Created by nuuneoi on 3/12/2015.
 */
public class ActivityResultEvent {

    private int requestCode;
    private int resultCode;
    private Intent data;

    public ActivityResultEvent(int requestCode, int resultCode, Intent data) {
        this.requestCode = requestCode;
        this.resultCode = resultCode;
        this.data = data;
    }

    public int getRequestCode() {
        return requestCode;
    }

    public void setRequestCode(int requestCode) {
        this.requestCode = requestCode;
    }

    public int getResultCode() {
        return resultCode;
    }

    public void setResultCode(int resultCode) {
        this.resultCode = resultCode;
    }

    public Intent getData() {
        return data;
    }

    public void setData(Intent data) {
        this.data = data;
    }
}

创建ActivityResultBus.java

import android.os.Handler;
import android.os.Looper;

import com.squareup.otto.Bus;

/**
 * Created by nuuneoi on 3/12/2015.
 */
public class ActivityResultBus extends Bus {

    private static ActivityResultBus instance;

    public static ActivityResultBus getInstance() {
        if (instance == null)
            instance = new ActivityResultBus();
        return instance;
    }

    private Handler mHandler = new Handler(Looper.getMainLooper());

    public void postQueue(final Object obj) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                ActivityResultBus.getInstance().post(obj);
            }
        });
    }

}

//&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; 覆盖活动上的onActivityResult

public class MainActivity extends ActionBarActivity {

    ...

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        ActivityResultBus.getInstance().postQueue(
                    new ActivityResultEvent(requestCode, resultCode, data));
    }

    ...

}

片段:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // Don't forget to check requestCode before continuing your job
        if (requestCode == 12345) {
            // Do your job
            tvResult.setText("Result Code = " + resultCode);
        }
    }
 @Override
    public void onStart() {
        super.onStart();
        ActivityResultBus.getInstance().register(mActivityResultSubscriber);
    }

    @Override
    public void onStop() {
        super.onStop();
        ActivityResultBus.getInstance().unregister(mActivityResultSubscriber);
    }

    private Object mActivityResultSubscriber = new Object() {
        @Subscribe
        public void onActivityResultReceived(ActivityResultEvent event) {
            int requestCode = event.getRequestCode();
            int resultCode = event.getResultCode();
            Intent data = event.getData();
            onActivityResult(requestCode, resultCode, data);
        }
    };