Как сделать фото на Android?

Управлять ресурсами устройства не так и сложно,  и в этом уроке я вам покажу как я заставлял Android сфотографировать меня.

Шаг 1

Начнем с создания проекта. File -> New project -> Android Module.

И первым делом что нам нужно будет сделать это добавить в AndroidManifest.xml разрешение на управление камерой и на запись файлов на sdcard:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.photosender"
          android:versionCode="1"
          android:versionName="1.0">

    <uses-sdk android:minSdkVersion="17"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
        <activity android:name=".MakePhotoActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

После того как Android разрешил делать фото и сохранять их переходим дальше.

Шаг 2

Дальше заходим в layout и создаем main.xml со следующим содержимым:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

    <Button
            android:id="@+id/captureFront"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:onClick="makePhoto"
            android:text="Сфотографировать" />

</RelativeLayout>

У вас получится просто одна кнопка по центру при нажатии на которую будет делаться фото.

Когда вы нажмете <Сфотографировать> фото сохранится на sdcard и выведется соответствующее сообщение.

Шаг 3

Теперь создаем класс PhotoHandler.java и наследуем его от PictureCallback это класс будет отвечать за то чтобы сделать фото:

package com.example.photosender;

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(MakePhotoActivity.DEBUG_TAG, "Невозможно создать папку для сохранения изображений.");
            Toast.makeText(context, "Невозможно создать папку для сохранения изображений.", 
                                                                             Toast.LENGTH_LONG).show();
            return;
        }

        // генерируем имя для фото
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
        String date = dateFormat.format(new Date());
        String namePhoto = "Photo_" + date;
        String photoFile = namePhoto + ".jpg";

        String photoFilename = pictureFileDir.getPath() + File.separator + photoFile;
        File pictureFile = new File(photoFilename);

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            // записываем фото полученное в байтах
            fos.write(data);
            fos.close();
            Toast.makeText(context, "Фото сохранено:" + pictureFile.getAbsolutePath(), 
                                                                      Toast.LENGTH_LONG).show();
            MakePhotoActivity.photo = pictureFile;
        } catch (Exception error) {
            Log.d(MakePhotoActivity.DEBUG_TAG, "Файл" + photoFilename + "не сохранен: " + error.getMessage());
            Toast.makeText(context, "Фото не сохраненно.", Toast.LENGTH_LONG).show();
        }

    }

    // этот метод будет получать путь к папке где нужно сохранить фото
    public File getDir() {
        File sdDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        return new File(sdDir, "CameraAPIDemo");
    }
}

Теперь у нас есть класс который создаст фото, теперь пора создать Activity.

Шаг 4

Создаем Activity с именем MakePhotoActivity,java со следующим содержимым:

package com.example.photosender;

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 java.io.File;

public class MakePhotoActivity extends Activity {

    public final static String DEBUG_TAG = "MakePhotoActivity";
    private Camera camera;
    private int cameraId = 0;
    public static File photo;

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

        // проверяем есть ли камера на устройстве
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            Toast.makeText(this, "На этом устройстве не камеры.", Toast.LENGTH_LONG).show();
        } else {
            // получаем ID камеры
            cameraId = findFrontFacingCamera();
            if (cameraId < 0) {
                Toast.makeText(this, "Фронтальная камера не найдена.", Toast.LENGTH_LONG).show();
            } else {
                // открываем камеру для съемки
                camera = Camera.open(cameraId);
            }
        }
    }

    // метод, который вызывается на main.xml при клике на кнопку
    public void makePhoto(View view) {
        // сделать фото
        camera.takePicture(null, null, new PhotoHandler(getApplicationContext()));
    }

    // поиск камеры
    private int findFrontFacingCamera() {
        int cameraId = -1;

        // Поиск Фронтальной камеры
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(i, info);
            // тут вы указываете какую камеру использовать CAMERA_FACING_BACK или CAMERA_FACING_FRONT
            if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
                Log.d(DEBUG_TAG, "Камера найденна.");
                cameraId = i;
                break;
            }
        }

        // возвращаем id найденной камеры
        return cameraId;
    }

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

В результате все этого у вас будут делаться фото и сохранятся на sdcard в папку Picture.

Результат:

Урок создан: 04 августа 2013 | Просмотров: 7876 | Автор: Александр Барчук | Правила перепечатки


Добавить комментарий

Добавить комментарий

Ваш e-mail не будет опубликован.

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

  • 11 августа 2013 в 18:47

    Askar

    sd-card :) Спасибо за статью

  • 03 марта 2014 в 15:12

    konservator

    Спасибо за статью. Маленькая поправка — перед вызовом camera.takePicture нужно вызвать camera.startPreview().

  • 26 января 2015 в 14:08

    Valeriy

    не работает на новых версиях, что делать?