从库中选择图像在 Android 的 Fragment 类中不起作用

Posted

技术标签:

【中文标题】从库中选择图像在 Android 的 Fragment 类中不起作用【英文标题】:select image from gallery not working in Fragment Class in Android 【发布时间】:2016-01-04 18:51:27 【问题描述】:

从片段类中的图库中选择图像不起作用。

我尝试了更多的堆栈代码。

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) 
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
 else 
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);

以上代码在活动类中工作。不适用于纯片段类。

【问题讨论】:

请解释“不工作”是什么意思。 我在尝试使用嵌套片段时遇到了这个问题。 嗨 Commonsware,从库中选择图片在 Fragment 类中不起作用 您是从某些覆盖方法(如 onclick 或其他方法)调用 Startactivity 吗? 据我了解,您必须使用子片段中的 onActivityResult 您可能想查看here 【参考方案1】:

如果您Fragment 调用startActivityForResult() 方法,您有两种选择

    直接拨打startActivityForResult() 致电getActivity().startActivityForResult()

在您的情况下,如果您想处理 Activity 上的结果,请以这种方式更改您的代码:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) 
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    getActivity().startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
 else 
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    getActivity().startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);

否则,如果您需要处理调用 Fragment 中的结果并且它当前无法正常工作,您可能会遇到 传播 问题。此类问题在this post中已被广泛描述。

关于startActivityForResult和嵌套片段的详细文章可以在here找到。

【讨论】:

嗨 Bonnyz,我尝试使用上面的 getActivity().startActivityForResult() 代码..这也不起作用..在这里,无需将数据从父活动发送到 fragent,或将片段发送到父活动。 . 只是,在片段类中,只需打开画廊并选择一个图像并在imageview中显示..就是这样..这些都只需要在片段类中完成.. @harikrishnan 因此,如果需要直接在片段中启动/接收 onActivtyResult,请查看关于传播问题的答案的第二部分【参考方案2】:

如果上面的代码不起作用,你应该检查你的片段导入语句。

我认为您在片段中使用片段。如果是,请发布您的导入代码。

【讨论】:

是的 Rahul.. 我在这里使用 Material Tab FRagment.inside 一个 TabFragment 类。我想做,比如从图库中选择图像并将其上传到网络服务.. 代码只工作 startActivityForResult() 直到..下一个 public void onActivityResult(int requestCode, int resultCode, Intent data) 方法没有被调用..那是我的问题..我只想在里面做这个片段类。我不想将任何数据从 Fragment 传输到 Activity ..... ok 尝试使用 getActivity.startActivityForResult 并告诉我结果【参考方案3】:

希望对您有所帮助。

Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(i, RESULT_LOAD_IMAGE);
// write this in your fragment or method or listener which will invoke gallery.

然后把它写在你的片段中

public void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == RESULT_LOAD_IMAGE && resultCode == getActivity().RESULT_OK
            && null != data) 
        Uri selectedImage = data.getData();
        String[] filePathColumn =  MediaStore.Images.Media.DATA ;
        Cursor cursor = getActivity().getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);
        cursor.moveToFirst();
        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        Log.d("Picture Path", "Picture Path:"+picturePath);

        long total_Images_size=0;

        File f=new File(picturePath);
        //total_Images_size+=f.length();
        /*if(total_Images_size>MAX_IMAGE_FILES_SIZE)
        
            Toast.makeText(getActivity(), "Image attachments size cannot exceed 5MB(total).", Toast.LENGTH_LONG).show();
            return;
        */
        String selectedFilename=picturePath.substring(picturePath.lastIndexOf("/"));

        addPicture(picturePath,  imageCount);


    

尝试一下,如果有任何错误请告诉我。谢谢

【讨论】:

【参考方案4】:

如果您在附加到 Activity 的 Fragment 上使用此代码,则:

    getActivity().startActivityForResult() 将调用活动的onActivityResult()

    startActivityForResult() 将调用活动和片段的onActivityResult()。这里的问题是,片段的onActivityResult() 会得到正确的requestCode。但是那个activity的会得到一个修改过的requestCode。

但嵌套片段并非如此。在 NestedFragments 的情况下,始终调用getActivity().startActivityForResult() 并在活动的onActivityResult() 中处理结果。如果您不想在片段和活动之间创建强依赖关系,则必须有一个设计模式来进行这种解耦(我为此使用了 Otto 库)。更好的是始终从附加到活动的片段中调用getActivity().startActivityForResult(),而不是嵌套的片段。

最佳实践:根据我的经验,仅在活动中处理onActivityResult()!这将减少很多维护噩梦。使用其他机制将此委托给片段。

【讨论】:

【参考方案5】:

由于您要做的就是从图库 Intent 中检索图像并填充 FRAGMENT 中存在的图像视图,因此您可以做的是在您的活动中保留对此图像视图的引用并使用 getActivity().startActivityForResult() 然后设置位图用于您活动中的图像视图参考。

代码:

// YOUR FRAGMENT

// fragment code...
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) 
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
 else 
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    // Update your activity's imageview reference
    mListener.setImageViewRef(fragmentImgView);
    getActivity().startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);


// more code..

@Override
public void onAttach(Context context) 
    super.onAttach(context);
    try 
        mListener = (OnFragmentInteractionListener) getActivity();
     catch (ClassCastException e) 
        throw new ClassCastException(activity.toString()
                + " must implement OnFragmentInteractionListener");
    


// Create interface to communicate with your activity

public interface OnFragmentInteractionListener 
    void setImageViewRef(ImageView imgView);


// END FRAGMENT CODE.

// YOUR ACTIVITY

public class MyActivity extends FragmentActivity implements MyFragment.OnFragmentInteractionListener 
    ...
    private ImageView myFragmentsImageViewReference;
    ...
    @Override
    void setImageViewRef(ImageView imgView) 
        this.myFragmentsImageViewReference = imgView;
    

    public void onActivityResult(int requestCode, int resultCode, Intent data)

        ... get Image from intent ...
        myFragmentsImageViewReference.setImageBitmap(myBitmapRetrievedFromIntent);
        ...
    


// END ACTIVITY CODE

【讨论】:

【参考方案6】:

请检查您的活动的 onActivityResult() 方法,如果您没有在 Fragment 的 onActivityResult() 中获得回调,它将被调用。如果您在父活动中获得回调,那么您可以从那里调用 Fragment 的 onActivityResult() 方法...如果您需要更多帮助,请告诉我...

【讨论】:

以上是关于从库中选择图像在 Android 的 Fragment 类中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

android - 从库中获取资源ID

在 Core Data 中从库中保存和获取多个图像选择

Cordova 相机插件 IOS 11 无法从库中选择图像

如何在 Swift 中使用 URL 从库中获取图像? [复制]

如何获取从 iPhone 库中选择的多个图像的路径?

渲染 CCSprite 纹理会给出旧图像