SDK v21をSamsung Galaxy A3(2014)でテストし、v23をNexus 5Xでテストします。 Camera2Basicの例もテストしましたが、両方のデバイスで動作します。私は私の小さなコードの再構築は、(私が代わりにフラグメントの活性を使用)、両方のデバイスの一つだけに、このエラーが発生するか疑問:SurfaceTextureを使用したCamera2プレビューはSDK v21で完全に動作しますが、v23では黒く表示されます
// ...
protected void onCreate() {
// setContentView ...
viewfinder = (AutoFitTextureView)findViewById(R.id.viewfinder);
// Choose back camera device, choose maxPictureSize (for JPEG), find out whether dimensions must be swapped
if (!swappedDimensions)
viewfinder.setAspectRatio(maxPictureSize.getWidth(), maxPictureSize.getHeight());
else
viewfinder.setAspectRatio(maxPictureSize.getHeight(), maxPictureSize.getWidth());
// initialize image reader
}
protected void onResume() {
if (viewfinder.isAvailable()) {
// Alternative to call in onSurfaceTextureAvailable()
init();
}
else {
viewfinder.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
Log.d(tag(), "surfaceTexture available: " + width + " x " + height);
configureSurface(width, height);
init();
}
public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
Log.d(tag(), "surfaceTexture size changed: " + width + " x " + height);
// Currently, don't react to changes. In opposite to the surface change listener, this method is not called after onSurfaceTextureAvailable and only needs to be implemented if the texture view size will change during the app is running
}
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
Log.d(tag(), "surfaceTexture destroyed");
return true;
}
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
Log.d(tag(), "surfaceTexture updated");
}
});
}
try {
if (!openCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
cameraManager.openCamera(deviceId, new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
openCloseLock.release();
device = camera;
init();
}
// ...
}, null);
}
catch(InterruptedException e) {
// ...
}
}
protected void configureSurface(int view_width, int view_height) {
SurfaceTexture surfaceTexture = viewfinder.getSurfaceTexture();
if (surfaceTexture == null)
return;
// Can this be changed after the session has been started?:
Size rotatedSurfaceSize = swappedDimensions
? new Size(view_height, view_width)
: new Size(view_width, view_height);
Size previewSize = bestOutputSize(SurfaceTexture.class, rotatedSurfaceSize, Sizes.aspectRatio(maxPictureSize));
Log.i(tag(), "Preview size for " + rotatedSurfaceSize + " (" + Sizes.aspectRatio(maxPictureSize) + ":1): "+previewSize);
surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
//
// Copied from Camera2Basic, just changed var names:
int rotation = getWindowManager().getDefaultDisplay().getRotation();
Matrix matrix = new Matrix();
RectF viewRect = new RectF(0, 0, view_width, view_height);
RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());
float centerX = viewRect.centerX();
float centerY = viewRect.centerY();
if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
float scale = Math.max(
(float) view_height/previewSize.getHeight(),
(float) view_width/previewSize.getWidth());
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(90 * (rotation - 2), centerX, centerY);
} else if (Surface.ROTATION_180 == rotation) {
matrix.postRotate(180, centerX, centerY);
}
viewfinder.setTransform(matrix);
//
}
/**
* Prerequisites:
* - The device must be opened.
* - The surface texture must be available.
*/
protected void init() {
// Executed only after second call, loadingState makes sure both prerequisites are true
if (++loadingState != 2)
return;
final CameraDevice d = device;
final Surface surface = new Surface(viewfinder.getSurfaceTexture());
try {
previewRequestBuilder = d.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewRequestBuilder.addTarget(surface);
} catch (CameraAccessException e) {
e.printStackTrace();
}
CameraCaptureSession.StateCallback cb = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (d == null) {
return;
}
Log.d(tag(), "Configured!");
// When the session is ready, we start displaying the preview.
captureSession = cameraCaptureSession;
try {
Log.d(tag(), "Surface: " + surface);
previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF);
previewRequest = previewRequestBuilder.build();
captureSession.setRepeatingRequest(previewRequest, previewCallback, null);
Log.d(tag(), "Preview started!");
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
Log.e(tag(), "Configure failed!");
}
};
try {
d.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()), cb, null);
Log.d(tag(), "Session started");
}
catch (CameraAccessException e) {
}
}
// ...
私自身のログ出力がスローされたエラーまたは例外なしに両方のデバイスで同じです、 CameraCaptureSession.CaptureCallback.onCaptureCompleted
とTextureView.SurfaceTextureListener.onSurfaceTextureUpdated
の両方が定期的に呼び出されます。 (おそらく別の物語を伝えるカメラサービスのエントリがあるかもしれませんが、そのエラーはアクティビティに明示されたエラーによって反映されるはずです) プレビューは自分のSamsungデバイスにのみ公開され、Nexusでは正しいサイズ黒いままです。