Android Fragment中使用Intent组件拍照

要在activity里面去接受,然后传递给fragment对象,fragment有很多回调调用不到

你的设备有摄像头吗?

为了确保市场上的大多数设备都能运行你的程序,必须在项目中做一些检测,保证使用的设备可以执行你的代码。

我们可以这么做:

  • 在程序的配置清单文件中标明要求使用摄像头;
  • 在代码中用PackageManager进行设备功能检测;

在项目的androidManifest文件中添加使用摄像头权限

android.hardware.camera

(在一个Fragment中)用PackageManager在代码中检测设备是否含有摄像头,代码如下:

  Context context = getActivity();
    PackageManager packageManager = context.getPackageManager();
    if(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA) == false){
        Toast.makeText(getActivity(),
           "This device does not have a camera.",
            Toast.LENGTH_SHORT) .show();
        return;
     }

如果有一个或者多个摄像头怎么办?

在一些安卓设备上会有前置摄像头和后置摄像头,我们可以用PackageManager来对摄像头进行功能检测,例如:

context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)

通常我们需要检测的是摄像头的这些功能:

Fragment和摄像头Intent组件

用Android Studio打开我们的示例代码,然后在navigation drawer中选择“Simple Camera Intent”,你会看到如下画面:

当你选择”Take Photo“,外部的拍照程序就会弹出来,然后我们就可以拍照了。拍照的结果会被显示在主界面上,缩略图也会显示在一个小区域里。打开SimpleCameraIntentFragment.java,可以看到下面这个方法(摘录自Google’s Simple Camera documentation):

 /** * Start the camera by dispatching a camera intent. */
    protected void dispatchTakePictureIntent() {
        // Check if there is a camera.
        Context context = getActivity();
        PackageManager packageManager = context.getPackageManager();
        if(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA) == false){
            Toast.makeText(getActivity(), "This device does not have a camera.", Toast.LENGTH_SHORT) .show(); return;
        } // Camera exists? Then proceed...
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there‘s a camera activity to handle the intent CameraActivity activity = (CameraActivity)getActivity();
        if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) {
             // Create the File where the photo should go.
             // If you don‘t do this, you may get a crash in some devices.
             File photoFile = null;
             try {
                 photoFile = createImageFile();
            } catch (IOException ex) {
             // Error occurred while creating the File
                Toast toast = Toast.makeText(activity, "There was a problem saving the photo...", Toast.LENGTH_SHORT);
                 toast.show();
             } // Continue only if the File was successfully created
            if (photoFile != null) {
                Uri fileUri = Uri.fromFile(photoFile); activity.setCapturedImageURI(fileUri); activity.setCurrentPhotoPath(fileUri.getPath()); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, activity.getCapturedImageURI()); startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
         }
    }

这里我对摄像头的检测并不完美,因为只是简单判断是否有后置摄像头。如果用户的设备只有一个前置摄像头,那这种检测就没有什么用了。

下一步我们要从摄像头中接收图像数据,然后保存下来。以下就是实现的代码,重复的部分就不一一贴出来了:

   ** * The activity returns with the photo.
        * @param requestCode
        * @param resultCode
        * @param data */
        * @Override
         public void onActivityResult(int requestCode, int resultCode, Intent data) {
          if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
            addPhotoToGallery();
             CameraActivity activity = (CameraActivity)getActivity();
            // Show the full sized image. setFullImageFromFilePath(activity.getCurrentPhotoPath(), mImageView); setFullImageFromFilePath(activity.getCurrentPhotoPath(), mThumbnailImageView);
            } else {
            Toast.makeText(getActivity(), "Image Capture Failed", Toast.LENGTH_SHORT) .show();
            }
         }

在Fragment中获取Activity返回结果

接下来我们关注这几行代码:

  Uri fileUri = Uri.fromFile(photoFile);
    activity.setCapturedImageURI(fileUri);
    activity.setCurrentPhotoPath(fileUri.getPath());

我们知道,当选择使用(由Activity管理的)Fragment时,为了保证所有部件运行正常,需要额外处理一些Fragment限制。在某些设备上(比如三星),你必须把返回结果的图像数据保存到一个文件中(该文件在使用Intent时需要提供)。但是当程序从照相程序中返回到前台时,这个文件就不可用了,然后程序会莫名崩溃了。

为了防止程序崩溃,我已经写了一个特别的Activity——“CameraActivity”,可以自动保存和恢复摄像头的数据文件和Uri数据。当程序的生命周期改变时,我们需要这些数据。

安全地获取图片数据

我们来看看CameraActivity,这里就不全部贴出代码了,但是你可以看到这个Activity会在resume中保存和恢复摄像头的数据文件和Uri数据。

private final static String CAPTURED_PHOTO_PATH_KEY = "mCurrentPhotoPath";
    private final static String CAPTURED_PHOTO_URI_KEY = "mCapturedImageURI";
    // Required for camera operations in order to save the image file on resume.
    private String mCurrentPhotoPath = null;
    private Uri mCapturedImageURI = null;
    @Override public void onSaveInstanceState(Bundle savedInstanceState) {
        if (mCurrentPhotoPath != null) {
            savedInstanceState.putString(CAPTURED_PHOTO_PATH_KEY, mCurrentPhotoPath);
        }
        if (mCapturedImageURI != null) {
            savedInstanceState.putString(CAPTURED_PHOTO_URI_KEY, mCapturedImageURI.toString());
        }
        super.onSaveInstanceState(savedInstanceState);
    }
     @Override protected void onRestoreInstanceState(Bundle savedInstanceState) {
        if (savedInstanceState.containsKey(CAPTURED_PHOTO_PATH_KEY)) {
            mCurrentPhotoPath = savedInstanceState.getString(CAPTURED_PHOTO_PATH_KEY);
        }
        if (savedInstanceState.containsKey(CAPTURED_PHOTO_URI_KEY)) {
             mCapturedImageURI = Uri.parse(savedInstanceState.getString(CAPTURED_PHOTO_URI_KEY));
        }
        super.onRestoreInstanceState(savedInstanceState);
    }

事实上我做的只是对这些需要的信息用Intent进行保存和恢复。这样,程序就知道该从哪里找到需要引用的文件。加入没有这些代码,程序在onResume中会崩溃。

以上这就是关于在Fragment中怎么用摄像头Intent组件进行拍照的简单教程,你可以随意使用以上所提供的源码进行修改使用。

- 导航条 -
首页
最新文章
经典回顾
开发
- Web前端
- Python
- Android
- iOS
- Java
- C/C++
- PHP
- .NET
- Ruby
- Go
设计
- UI设计
- 网页设计
- 交互设计
- 用户体验
- 设计教程
- 设计职场
极客
IT技术
- Linux
- UNIX
- MySQL
- NoSQL
- 数据库
- Git
- 机器学习
- 算法
- 测试
- 信息安全
- Vim
业界
职场
创业
访谈
在国外

伯乐在线 > 首页 > 所有文章 > Android > 在安卓Fragment中使用Intent组件拍照

在安卓Fragment中使用Intent组件拍照

2014/03/26 · Android开发 · 1 评论· 安卓开发摄像应用

分享到:0

本文由 伯乐在线 - chris 翻译。未经许可,禁止转载!
英文出处:airpair。欢迎加入翻译组

说明: 这篇文章主要介绍了如何在安卓Fragment中使用摄像头拍照并保存图像和缩略图。

这篇文章是我的“Android Studio下用Fragment进行摄像头开发系列文章五篇”的第一篇,如果你还没做好准备,可以先看看我的代码,GitHub:UltimateAndroidCameraGuide。这篇教程中也会详细对代码进行说明,主要参考这个文件:SimpleCameraIntentFragment.java

在开始之前,先花点时间说明一下手机设备的功能和发布App时需要考虑的设备功能检测问题。

你的设备有摄像头吗?

为了确保市场上的大多数设备都能运行你的程序,必须在项目中做一些检测,保证使用的设备可以执行你的代码。

我们可以这么做:

  • 在程序的配置清单文件中标明要求使用摄像头;
  • 在代码中用PackageManager进行设备功能检测;

在项目的androidManifest文件中要求使用摄像头,代码如下:

1

2

;html-script:false]

<uses-feature android:name="android.hardware.camera"android:required="true"/>

(在一个Fragment中)用PackageManager在代码中检测设备是否含有摄像头,代码如下:

Java

1

2

3

4

5

6

7

8

9

;html-script:false]

Context context=getActivity();

PackageManager packageManager=context.getPackageManager();

if(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)==false){

Toast.makeText(getActivity(),

"This device does not have a camera.",

Toast.LENGTH_SHORT).show();

return;

}

如果有一个或者多个摄像头怎么办?

在一些安卓设备上会有前置摄像头和后置摄像头,我们可以用PackageManager来对摄像头进行功能检测,例如:

Java

1

2

;html-script:false]

context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)

通常我们需要检测的是摄像头的这些功能:

Fragment和摄像头Intent组件

用Android Studio打开我们的示例代码,然后在navigation drawer中选择“Simple Camera Intent”,你会看到如下画面:

当你选择”Take Photo“,外部的拍照程序就会弹出来,然后我们就可以拍照了。拍照的结果会被显示在主界面上,缩略图也会显示在一个小区域里。打开SimpleCameraIntentFragment.java,可以看到下面这个方法(摘录自Google’s Simple Camera documentation):

时间: 2024-07-29 08:08:22

Android Fragment中使用Intent组件拍照的相关文章

Android开发中使用Intent跳转到系统应用中的拨号界面、联系人界面、短信界面

现在开发中的功能需要直接跳转到拨号.联系人.短信界面等等,查找了很多资料,自己整理了一下. 首先,我们先看拨号界面,代码如下: Intent intent =new Intent(); intent.setAction("android.intent.action.CALL_BUTTON"); startActivity(intent); 和 Uri uri = Uri.parse("tel:xxxxxx"); Intent intent = new Intent(

Android系统中标准Intent的使用

一 Android系统用于Activity的标准Intent 1 根据联系人ID显示联系人信息 Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); //显示联系人信息 intent.setData(Uri.parse("content://contacts/people/492")); startActivity(intent); 2 根据联系人ID显示拨号面板 Intent intent = new

activity怎么控制fragment中的textview组件

============问题描述============ 如题,viewpager中含有多个fragment, 怎么才能够使用fragment中的textview的setText()功能. 例如 fragment1的textview写1 fragment2的textview写2 以此类推. ============解决方案1============ 写一个公用fragment,其它子fragment去继承他,父类里面有个公用方法settext ============解决方案2=========

关于android开发中的Intent(意图)

Intent在程序运行的过程中连接两个不同的组件(Acvivity) 例如当我们点击手机上的某个联系人,查看其信息时,便需要通过intent告诉android,我要做“查看”动作了 以此实现从界面A到界面B的跳转 声明方式:Intent intent = new Intent(MainActivity.this, OtherActivity.class); MainActivity为上文中的A,OtherActivity为上文中的B 而OtherActivity是从ManiFest中去寻找的,如

Android 开发中使用Intent传递数据的方法

Activity之间通过Intent传递值,支持基本数据类型和String对象及它们的数组对象byte.byte[].char.char[].boolean.boolean[].short.short[].int.int[].long.long[].float.float[].double.double[].String.String[],还有采用实现Serializable.Parcelable接口的类对象传递数据的两种方法:一种是Bundle.putSerializable(Key,Obje

调用Android系统设置中的Intent

开发Android软件时,常常需要打开系统设置或信息界面,来设置相关系统项或查看系统的相关信息,这时我们就可以使用以下语句来实现:(如打开“无线和网络设置”界面) Intent intent = new Intent(); ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.WirelessSettings"); intent.setComponen

Android Fragment中调用getActivity为null的问题

在使用fragment的时候经常会遇到getActivity()为null的情况.比如我在一个异步网路请求的回调中调用了getActivity()就会出现空指针问题.之前解决这个问题,通常都是直接加空指针判断来规避,但是这并没有真正解决问题. 很多人都曾被这个问题所困扰,如果app长时间在后台运行,再次进入app的时候可能会出现crash,而且fragment会有重叠现象.如果系统内存不足.切换横竖屏.app长时间在后台运行,Activity都可能会被系统回收然后重建,但Fragment并不会随

Android Fragment中ListView的OnItemClickListener无效

人可能会变,但代码不一样,一个地方出错说不执行就是不执行. 网上说是ListView的 OnItemClick监听失效的原因.还有网上给出的解决方案是把加载ListView数据的每一项都加上 android:focusable="false" 然后一切问题就OK 了. 因为点击的焦点被ListView列表里的其他控件给获取了,所以就出现未反应情况.

Android --Fragment中异步HTTP请求

1.自定义异步Task /** * 异步获取实时数据 */ public class TimerDataTask extends AsyncTask<Void, Void, Boolean> { @Override protected Boolean doInBackground(Void... params) { String getUrl = mUrl + "/RealTimeData.ashx?type=data"; URL loginUrl = null; Inpu