【问题标题】:How to implement camera functionality in fragment in android?如何在android的片段中实现相机功能?
【发布时间】:2016-07-30 11:07:17
【问题描述】:

我在fragment 中有一个button。当fragment 被调用并点击button 我希望camera 打开。我已经阅读了很多教程。但是我找不到在fragment 中实现camera 的解决方案。

这是我的java代码camera.java:

public class camera extends Fragment {

private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
Button btnCapture;
ImageView imageView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    final View rootView = inflater.inflate(R.layout.camera,
            container, false);
    btnCapture=(Button) rootView.findViewById(R.id.btnCapturePicture);
    //imageView = (ImageView) rootView.findViewById(R.id.imageview);

    btnCapture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(intent,
                    CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

        }
    });

    return rootView;

}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK) {

            Bitmap bmp = (Bitmap) data.getExtras().get("data");
            ByteArrayOutputStream stream = new ByteArrayOutputStream();

            bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();

            // convert byte array to Bitmap

            Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
                    byteArray.length);

            imageView.setImageBitmap(bitmap);

        }
    }
}
}

这是我的 camera.xml 布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false"
tools:context="com.example.prakash.eduqueri.fragments.camera">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:layout_gravity="center_vertical">
     <!--  Capture picture button
  -->
<Button
    android:id="@+id/btnCapturePicture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Take a Picture"
    android:layout_gravity="center_horizontal"
    android:layout_marginBottom="10dp" />

这是我的日志:

FATAL EXCEPTION: main
                                                                          Process: com.example.prakash.eduqueri, PID: 14511
                                                                          java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65636, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.prakash.eduqueri/com.example.prakash.eduqueri.MainActivity}: java.lang.NullPointerException
                                                                              at android.app.ActivityThread.deliverResults(ActivityThread.java:3367)
                                                                              at android.app.ActivityThread.handleSendResult(ActivityThread.java:3410)
                                                                              at android.app.ActivityThread.access$1300(ActivityThread.java:141)
                                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1260)
                                                                              at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                              at android.os.Looper.loop(Looper.java:136)
                                                                              at android.app.ActivityThread.main(ActivityThread.java:5052)
                                                                              at java.lang.reflect.Method.invokeNative(Native Method)
                                                                              at java.lang.reflect.Method.invoke(Method.java:515)
                                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
                                                                              at dalvik.system.NativeStart.main(Native Method)
                                                                           Caused by: java.lang.NullPointerException
                                                                              at com.example.prakash.eduqueri.camera.onActivityResult(camera.java:87)
                                                                              at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:176)
                                                                              at android.app.Activity.dispatchActivityResult(Activity.java:5437)
                                                                              at android.app.ActivityThread.deliverResults(ActivityThread.java:3363)
                                                                              at android.app.ActivityThread.handleSendResult(ActivityThread.java:3410) 
                                                                              at android.app.ActivityThread.access$1300(ActivityThread.java:141) 
                                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1260) 
                                                                              at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                              at android.os.Looper.loop(Looper.java:136) 
                                                                              at android.app.ActivityThread.main(ActivityThread.java:5052) 
                                                                              at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                              at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609) 
                                                                              at dalvik.system.NativeStart.main(Native Method) 

新的logcat:

Unable to decode stream: java.io.FileNotFoundException: /external/images/media/24097: open failed: ENOENT (No such file or directory)

04-12 12:43:02.688 29890-29890/com.example.prakash.eduqueri I/Adreno-EGL: : EGL 1.4 高通构建:AU_LINUX_ANDROID_LNX.LA.3.5.2.2.2_RB1.04.04.04.154.004_msm8226_LNX。 LA.3.5.2.2.2_RB1__release_AU() OpenGL ES 着色器编译器版本:E031.24.00.15 建造日期:2014 年 8 月 6 日星期三 本地分支:mybranch4057433 远程分支:quic/LNX.LA.3.5.2.2.2_rb1 本地补丁:无 重建分支:AU_LINUX_ANDROID_LNX.LA.3.5.2.2.2_RB1.04.04.04.154.004 + NOTHING 04-12 12:43:02.848 29890-29890/com.example.prakash.eduqueri I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@424bdc50 time:262597724

【问题讨论】:

  • 至少表明你做了什么。
  • 你真的需要自己实现相机吗?如果它已经发明了,为什么还要再次发明轮子?而是启动一个cameraintent,然后将拍摄的照片取回。
  • 相机打开,我收到一个错误,无法恢复活动

标签: android android-fragments android-studio


【解决方案1】:

试试这个,

在单击按钮时添加此代码。

int TAKE_OR_PICK = 1;
                    Intent takePictureIntent = new Intent(
                            MediaStore.ACTION_IMAGE_CAPTURE);
                    if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
                        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                    }

覆盖 onActivityResult

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == getActivity().RESULT_OK && null != data  && TAKE_OR_PICK == 1) {
        imageView = (ImageView) findViewById(R.id.imageView1);
        Bitmap photo = (Bitmap) data.getExtras().get("data");
        imageView.setImageBitmap(photo)
if (imageBitmap != null) {
            try {
                long fileName = System.currentTimeMillis();
                File outputFile = new File(Environment.getExternalStorageDirectory(), "photo_" + fileName + ".jpg");
                FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
                imageBitmap=Bitmap.createScaledBitmap(imageBitmap, 300, 300, true);
                imageBitmap.compress(Bitmap.CompressFormat.JPEG, 75, fileOutputStream);
                fileOutputStream.flush();
                fileOutputStream.close();
                File imageFile = new File(Environment.getExternalStorageDirectory() +File.separator + "photo_" + fileName + ".jpg");
                picturePath = imageFile.getPath();
                System.out.println("FILE PATH -> "+picturePath);
            }catch (Exception e) {
                e.printStackTrace();
                Toast.makeText(getActivity(), "Something went wrong", Toast.LENGTH_SHORT).show();
            }

        }
    }
}

【讨论】:

  • 我得到的错误是因为我在布局文件中没有 imagepreview 小部件。现在我清除了它。
  • 如何将我拍摄的照片保存到内存中?
  • 请检查更新后的答案。如果您对此有帮助,请接受并投票给我的答案
  • 图片未存储在内存中。
【解决方案2】:

如果当前fragment在另一个fragment中并且fragment在一个activity中,你首先需要在父fragment或activity中定义onActivityResult然后首先在父fragment和父Activity中定义onResultActivity。很可能我猜(当您使用 viewPager 时)您的片段在某个片段中,而父片段在活动中,因此请按照以下步骤操作:

首先在 Activity 中定义 onActivityResult,然后在片段中定义您使用相机意图的片段。

根父Activity中的onActivityResult。

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}

}

子片段内部:

  @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    for (Fragment fragment : getChildFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }    super.onActivityResult(requestCode, resultCode, data);
}

注意:如果你的相机意图片段在这个片段中,那么只有你需要做这个另一个跳过这一步。

现在终于在你的 cameraIntent 片段中实现 onActivityResult:

@Override
public void onActivityResult(int requestCode, int resultCode, final Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
        if (resultCode == HomeActivity.RESULT_OK) {
try{
           BitmapFactory.Options options = new BitmapFactory.Options();

        // downsizing image as it throws OutOfMemory Exception for larger
        // images
        options.inSampleSize = 8;
        final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
                options);

        imageView.setImageBitmap(bitmap); } catch (NullPointerException e) {
        e.printStackTrace();
    }           }
        } else if (resultCode == HomeActivity.RESULT_CANCELED) {
            // user cancelled Image capture
            Toast.makeText(getActivity(),
                    "User cancelled image capture", Toast.LENGTH_SHORT)
                    .show();
        } else {
            // failed to capture image
            Toast.makeText(getActivity(),
                    "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
                    .show();
        }
}

fileUri 变量在相机 Intent 启动时在按钮的 onClick 中初始化。

最后一件重要的事情是在启动你的相机意图时你必须使用getParentFragment().startActivityForResult(intent,yourrequestCode);

所以你的明星意图看起来像:

  btnCapture.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

        String fileName = System.currentTimeMillis()+".jpg";
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, fileName);
    fileUri = getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        getParentFragment().startActivityForResult(intent,
                CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

    }
});

在上述方法中,fileUri 是一个字符串类型的变量,并在方法外部定义,因为它应该用于设置图像的预览,如 onActivityResult() 所示

希望这会有所帮助,如果您遇到任何问题,请发表评论,我会帮助您:) Have a happy codeing :)

【讨论】:

  • 我在 Bitmap bmp=(Bitmap)fileUri.getData() 行中遇到错误。它说无法解析方法 getData()
  • 抱歉我忘了编辑 onActivityResult(),检查 onActivity 结果,现在可以正常工作了
  • getParentFragment() 处出现空指针异常。当我删除它时它工作正常并且图像成功存储在 SD 卡中。但无法获得图像预览
  • 这意味着您没有正确处理父 Activity 和 Fragment 中的 onActivityResult,要获得预览,您必须处理父 Activity 和 Fragment 中的 onActivityResult,如上所示
  • 如果您在 onResume() 方法中预览图像,则更好的方法,只需将代码复制到 if(resultCode==...) 中,然后在 onResume 中复制一个 if 条件为 if(fileUri!=null ){//通过 onActivityResult} 处理的代码,这将预览图像,确保 imageView 是公开的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
相关资源
最近更新 更多