понедельник, 10 декабря 2012 г.

Android Camera API. Используем камеру в Android приложениях

1. Камера Android


Большинство устройств на Android имеют камеру. А некоторые даже две - переднюю и заднюю. Использовать камеру можно с помощью существующих приложений. В этом случае нужно запустить существующее приложение и получить после этого данные в нашем приложении. А можно напрямую интегрировать камеру в приложение с помощью API.

2. Создание фото установленными приложениями

Создаем новый Android проект com.osmsoft.cameraexample с Activity ImagePickActivity.
Изменяем класс ImagePickActivity следующим образом:


package com.osmsoft.cameraexample;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class ImagePickActivity extends Activity {
  private static final int REQUEST_CODE = 1;
  private Bitmap bitmap;
  private ImageView imageView;

  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    imageView = (ImageView) findViewById(R.id.result);
  }

  public void pickImage(View View) {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    startActivityForResult(intent, REQUEST_CODE);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK)
      try {
        // We need to recyle unused bitmaps
        if (bitmap != null) {
          bitmap.recycle();
        }
        InputStream stream = getContentResolver().openInputStream(data.getData());
        bitmap = BitmapFactory.decodeStream(stream);
        stream.close();
        imageView.setImageBitmap(bitmap);
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
    super.onActivityResult(requestCode, resultCode, data);
  }
} 

3. Создание фото используя встроенный API

В этом примере мы создадим приложение, которое позволяет сделать фотографию с помощью фронтальной камеры и сохраним его на карту SD. Если вы используете эмулятор Android убедитесь, что вы добавили SD карту при создании вашего виртуального устройства Android.

Создаем новый Android проект com.osmsoft.cameraapiexample с Activity MakePhotoActivity.

Добавим
в AndroidManifest.xml разрешения android.permission.CAMERA для доступа к вашей камере и android.permission.WRITE_EXTERNAL_STORAGE, чтобы иметь возможность писать на карту памяти SD.


    
    
    

    
        
            
                

                
            
        
    

  

Изменяем в директории res/layout главный лэйаут нашего приложения:



      


Создаем класс PhotoHandler, который требуется для сохранения фото на SD

package com.osmsoft.cameraapi.example;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

public class PhotoHandler implements PictureCallback {

  private final Context context;

  public PhotoHandler(Context context) {
    this.context = context;
  }

  @Override
  public void onPictureTaken(byte[] data, Camera camera) {

    File pictureFileDir = getDir();

    if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {

      Log.d(Constants.DEBUG_TAG, "Can't create directory to save image.");
      Toast.makeText(context, "Can't create directory to save image.",
          Toast.LENGTH_LONG).show();
      return;

    }

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
    String date = dateFormat.format(new Date());
    String photoFile = "Picture_" + date + ".jpg";

    String filename = pictureFileDir.getPath() + File.separator + photoFile;

    File pictureFile = new File(filename);

    try {
      FileOutputStream fos = new FileOutputStream(pictureFile);
      fos.write(data);
      fos.close();
      Toast.makeText(context, "New Image saved:" + photoFile,
          Toast.LENGTH_LONG).show();
    } catch (Exception error) {
      Log.d(Constants.DEBUG_TAG, "File" + filename + "not saved: "
          + error.getMessage());
      Toast.makeText(context, "Image could not be saved.",
          Toast.LENGTH_LONG).show();
    }
  }

  private File getDir() {
    File sdDir = Environment
      .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    return new File(sdDir, "CameraAPIDemo");
  }
} 

Изменяем главное Activity:

package com.osmsoft.cameraapi.example;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.osmsoft.camearaapi.example.R;

public class MakePhotoActivity extends Activity {
  private final static String DEBUG_TAG = "MakePhotoActivity";
  private Camera camera;
  private int cameraId = 0;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // do we have a camera?
    if (!getPackageManager()
        .hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
      Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG)
          .show();
    } else {
      cameraId = findFrontFacingCamera();
      camera = Camera.open(cameraId);
      if (cameraId < 0) {
        Toast.makeText(this, "No front facing camera found.",
            Toast.LENGTH_LONG).show();
      }
    }
  }

  public void onClick(View view) {
    camera.takePicture(null, null,
        new PhotoHandler(getApplicationContext()));
  }

  private int findFrontFacingCamera() {
    int cameraId = -1;
    // Search for the front facing camera
    int numberOfCameras = Camera.getNumberOfCameras();
    for (int i = 0; i < numberOfCameras; i++) {
      CameraInfo info = new CameraInfo();
      Camera.getCameraInfo(i, info);
      if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
        Log.d(DEBUG_TAG, "Camera found");
        cameraId = i;
        break;
      }
    }
    return cameraId;
  }

  @Override
  protected void onPause() {
    if (camera != null) {
      camera.release();
      camera = null;
    }
    super.onPause();
  }

} 

Комментариев нет: