0

コードから camera.takepicture を呼び出そうとしていますが、常に実行時例外がスローされます。コードでエラーが見つからないようです。ボタンを使用して同じことを呼び出すと、takepicture は問題なく動作します。ユーザーが実際に別のアクティビティを実行しているときに写真をランダムにキャプチャする必要があるため、コードを介して takepicture を呼び出す必要があります。これらの写真が撮られていることを確認するには、タイマー/間隔を設定する必要があります。プログラムのこの部分でのユーザーの操作に依存することはできません。

詳細については、コードを次に示します。logcat も添付されています。

CameraActivity.class

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

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.View.OnClickListener;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class CameraActivity extends Activity implements Callback {

final static String DEBUG_TAG = "CameraActivity";
final static String TAG = "CameraActivity";
Camera camera;
private int cameraId = 0;
Button photo;
PhotoHandler mPhotoHandler = null;

Camera.Parameters parameters;
private SurfaceHolder sHolder;

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@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();
        if (cameraId < 0) {
            Toast.makeText(this, "No front facing camera found.",
                    Toast.LENGTH_LONG).show();
        } else {
            camera = Camera.open(cameraId);
            SurfaceView sv = new SurfaceView(getApplicationContext());
            setContentView(R.layout.camera);
            sv = (SurfaceView) findViewById(R.id.surfaceview);
            photo = (Button) findViewById(R.id.takepicture);
            photo.setText("Click a photo!!");
            // Get a surface
            sHolder = sv.getHolder();
            sHolder.addCallback(this);
            sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            try {
                camera.setPreviewDisplay(sHolder);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            parameters = camera.getParameters();
            // set camera parameters
            camera.setParameters(parameters);
            camera.startPreview();
            camera.setDisplayOrientation(90);
            try {

                photo.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View arg0) {
                        // TODO Auto-generated method stub
                        // Toast.makeText(getApplicationContext(),
                        // "photo clicked!",
                        // Toast.LENGTH_SHORT).show();

                        // just calling the function which captures the
                        // photo
                        takePhoto();
                    }
                });
                photo.performClick();

                // finish();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    try {
        camera.setPreviewDisplay(holder);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    // set any cam params you need...
    camera.startPreview();
}

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, "CameraActivity found");
            cameraId = i;
            break;
        }
    }
    return cameraId;
}

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

Camera.ShutterCallback shuttercallback = new Camera.ShutterCallback() {

    @Override
    public void onShutter() {
        // TODO Auto-generated method stub
        Log.d(TAG, "onShutter'd");
    }
};

Camera.PictureCallback rawpicture = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub
        Log.d(TAG, "onPictureTaken - raw");
    }

};

Camera.PictureCallback jpegcallback = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera arg1) {
        // TODO Auto-generated method stub
        File pictureFileDir = getDir();

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

            Log.d(CameraActivity.DEBUG_TAG,
                    "Can't create directory to save image.");
            Toast.makeText(CameraActivity.this,
                    "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(CameraActivity.this,
                    "New Image saved:" + photoFile, Toast.LENGTH_LONG)
                    .show();
        } catch (Exception error) {
            Log.d(CameraActivity.DEBUG_TAG, "File" + filename
                    + "not saved: " + error.getMessage());
            Toast.makeText(CameraActivity.this,
                    "Image could not be saved.", Toast.LENGTH_LONG).show();
        }
    }

};

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // set any cam params you need...
    camera.startPreview();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    camera.stopPreview();
    camera.release();

}

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

public void takePhoto() {

    camera.takePicture(shuttercallback, rawpicture, jpegcallback);
}

}

添付はlogcat出力です

*

> 04-17 00:41:03.264: D/CameraActivity(19076): CameraActivity found
> 04-17 00:41:03.444: D/Camera(19076): app passed NULL surface 04-17
> 00:41:03.474: W/System.err(19076): java.lang.RuntimeException:
> takePicture failed 04-17 00:41:03.474: W/System.err(19076):   at
> android.hardware.Camera.native_takePicture(Native Method) 04-17
> 00:41:03.474: W/System.err(19076):    at
> android.hardware.Camera.takePicture(Camera.java:1095) 04-17
> 00:41:03.474: W/System.err(19076):    at
> android.hardware.Camera.takePicture(Camera.java:1040) 04-17
> 00:41:03.474: W/System.err(19076):    at
> com.egnoita.ignoramus.CameraActivity.takePhoto(CameraActivity.java:226)
> 04-17 00:41:03.474: W/System.err(19076):  at
> com.egnoita.ignoramus.CameraActivity$4.onClick(CameraActivity.java:93)
> 04-17 00:41:03.474: W/System.err(19076):  at
> android.view.View.performClick(View.java:4204) 04-17 00:41:03.484:
> W/System.err(19076):  at
> com.egnoita.ignoramus.CameraActivity.onCreate(CameraActivity.java:96)
> 04-17 00:41:03.484: W/System.err(19076):  at
> android.app.Activity.performCreate(Activity.java:5104) 04-17
> 00:41:03.484: W/System.err(19076):    at
> android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
> 04-17 00:41:03.484: W/System.err(19076):  at
> android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
> 04-17 00:41:03.484: W/System.err(19076):  at
> android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
> 04-17 00:41:03.484: W/System.err(19076):  at
> android.app.ActivityThread.access$600(ActivityThread.java:141) 04-17
> 00:41:03.484: W/System.err(19076):    at
> android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
> 04-17 00:41:03.484: W/System.err(19076):  at
> android.os.Handler.dispatchMessage(Handler.java:99) 04-17
> 00:41:03.484: W/System.err(19076):    at
> android.os.Looper.loop(Looper.java:137) 04-17 00:41:03.484:
> W/System.err(19076):  at
> android.app.ActivityThread.main(ActivityThread.java:5041) 04-17
> 00:41:03.484: W/System.err(19076):    at
> java.lang.reflect.Method.invokeNative(Native Method) 04-17
> 00:41:03.484: W/System.err(19076):    at
> java.lang.reflect.Method.invoke(Method.java:511) 04-17 00:41:03.484:
> W/System.err(19076):  at
> com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
> 04-17 00:41:03.484: W/System.err(19076):  at
> com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 04-17
> 00:41:03.484: W/System.err(19076):    at
> dalvik.system.NativeStart.main(Native Method) 04-17 00:41:03.534:
> D/libEGL(19076): loaded /system/lib/egl/libEGL_adreno200.so 04-17
> 00:41:03.534: D/libEGL(19076): loaded
> /system/lib/egl/libGLESv1_CM_adreno200.so 04-17 00:41:03.544:
> D/libEGL(19076): loaded /system/lib/egl/libGLESv2_adreno200.so 04-17
> 00:41:03.554: I/Adreno200-EGL(19076): <eglInitialize:269>: EGL 1.4
> QUALCOMM build: Nondeterministic
> AU_full_mako_PARTNER-ANDROID/JB-MR1-DEV_CL2961380_release_AU
> (CL2961380) 04-17 00:41:03.554: I/Adreno200-EGL(19076): Build Date:
> 12/10/12 Mon 04-17 00:41:03.554: I/Adreno200-EGL(19076): Local Branch:
> 04-17 00:41:03.554: I/Adreno200-EGL(19076): Remote Branch:
> m/partner-android/jb-mr1-dev 04-17 00:41:03.554:
> I/Adreno200-EGL(19076): Local Patches: NONE 04-17 00:41:03.554:
> I/Adreno200-EGL(19076): Reconstruct Branch: NOTHING 04-17
> 00:41:03.624: D/OpenGLRenderer(19076): Enabling debug mode 0

* 他に何か必要なことがあればお知らせください。すべての権限と機能がマニフェストに追加されます

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_DATA" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
4

2 に答える 2

1

私は同じ問題を抱えていました。それを修正するために、takephoto を static として定義し、コールバックを static として定義しました。これを行った後、コードから takephoto を呼び出すことができました。

例えば:

public static void takePhoto() {

    camera.takePicture(shuttercallback, rawpicture, jpegcallback);
}

static Camera.PictureCallback jpegcallback = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera arg1) {
        // TODO Auto-generated method stub
        File pictureFileDir = getDir();

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

            Log.d(CameraActivity.DEBUG_TAG,
                    "Can't create directory to save image.");
            Toast.makeText(CameraActivity.this,
                    "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(CameraActivity.this,
                    "New Image saved:" + photoFile, Toast.LENGTH_LONG)
                     .show();
        } catch (Exception error) {
            Log.d(CameraActivity.DEBUG_TAG, "File" + filename
                    + "not saved: " + error.getMessage());
            Toast.makeText(CameraActivity.this,
                    "Image could not be saved.", Toast.LENGTH_LONG).show();
        }
    }

};

static Camera.ShutterCallback shuttercallback = new Camera.ShutterCallback() {

    @Override
    public void onShutter() {
        // TODO Auto-generated method stub
        Log.d(TAG, "onShutter'd");
    }
};

static Camera.PictureCallback rawpicture = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub
        Log.d(TAG, "onPictureTaken - raw");
    }

};

これがあなたや同じ問題を抱えている他の誰かに役立つことを願っています.

于 2013-12-31T11:11:55.087 に答える
0

takePhoto()onClick() から呼び出されるので、ラウンドする必要はありません。プログラムによるアプローチが失敗する理由は、camera.takePicture( ) はcamera.startPreview()が完了した後に のみ呼び出すことができるためです。これは、Android カメラのライフサイクルに関するよくある誤解です。

肝心なのは、onCreate()では、アクティビティが写真を撮る準備を整え、必要なすべてのコールバックが順番に呼び出されるようにする必要があるということです。これは、コードの最小限の書き直しです。仕事をするだけでなく、カメラを適切に扱う方法を理解するのにも役立つことを願っています.

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

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.View.OnClickListener;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class CameraActivity extends Activity implements Callback {

final static String DEBUG_TAG = "CameraActivity";
final static String TAG = "CameraActivity";
Camera camera;
private int cameraId = 0;
Button photo;
PhotoHandler mPhotoHandler = null;
private boolean wantPhoto = false;

Camera.Parameters parameters;
private SurfaceHolder sHolder;

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@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();
        if (cameraId < 0) {
            Toast.makeText(this, "No front facing camera found.",
                    Toast.LENGTH_LONG).show();
        } else {
            camera = Camera.open(cameraId);
            SurfaceView sv = new SurfaceView(getApplicationContext());
            setContentView(R.layout.camera);
            sv = (SurfaceView) findViewById(R.id.surfaceview);
            photo = (Button) findViewById(R.id.takepicture);
            photo.setText("Click a photo!!");
            // Get a surface
            sHolder = sv.getHolder();
            sHolder.addCallback(this);
            sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            try {
                camera.setPreviewDisplay(sHolder);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            parameters = camera.getParameters();
            // set camera parameters
            camera.setParameters(parameters);
            camera.startPreview();
            camera.setDisplayOrientation(90);
            try {

                photo.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View arg0) {
                        // TODO Auto-generated method stub
                        // Toast.makeText(getApplicationContext(),
                        // "photo clicked!",
                        // Toast.LENGTH_SHORT).show();

                        // just calling the function which captures the
                        // photo
                        takePhoto();
                    }
                });
//                photo.performClick();
                wantPhoto = true;

                // finish();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    try {
        camera.setPreviewDisplay(holder);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    // set any cam params you need...
    camera.startPreview();
    if (wantPhoto) {
        wantPhoto = false;
        takePhoto();
    }
}

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, "CameraActivity found");
            cameraId = i;
            break;
        }
    }
    return cameraId;
}

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

Camera.ShutterCallback shuttercallback = new Camera.ShutterCallback() {

    @Override
    public void onShutter() {
        // TODO Auto-generated method stub
        Log.d(TAG, "onShutter'd");
    }
};

Camera.PictureCallback rawpicture = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub
        Log.d(TAG, "onPictureTaken - raw");
    }

};

Camera.PictureCallback jpegcallback = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera arg1) {
        // TODO Auto-generated method stub
        File pictureFileDir = getDir();

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

            Log.d(CameraActivity.DEBUG_TAG,
                    "Can't create directory to save image.");
            Toast.makeText(CameraActivity.this,
                    "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(CameraActivity.this,
                    "New Image saved:" + photoFile, Toast.LENGTH_LONG)
                    .show();
        } catch (Exception error) {
            Log.d(CameraActivity.DEBUG_TAG, "File" + filename
                    + "not saved: " + error.getMessage());
            Toast.makeText(CameraActivity.this,
                    "Image could not be saved.", Toast.LENGTH_LONG).show();
        }
    }

};

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // set any cam params you need...
    camera.startPreview();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    camera.stopPreview();
    camera.release();

}

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

public void takePhoto() {

    camera.takePicture(shuttercallback, rawpicture, jpegcallback);
}

}

コードに役立ついくつかの重要な改善点があることを理解してください。たとえば、バックグラウンド スレッドで camera.open() を呼び出すことをお勧めします。これは、一部のデバイスでは時間がかかり、UI が 1 秒以上フリーズする可能性があるためです。

于 2014-01-01T06:42:36.853 に答える