カメラの実装に少し問題があります。現在、カメラのプレビューを開いて電話をロックし、戻ってきたときにロックを解除しても、プレビューは問題なく実行されています。
問題は、電話のホームボタンを押すと、アプリケーションに戻ったときにプレビューが表示されなくなり、黒い画面だけで、クラッシュもプレビューも表示されないことです。
これが私のコードです。onResume()
間違いはメソッドのどこかにあるはずだと推測していますがonPause()
、onStop()
正確にはわかりません。
これは私の更新されたソリューションです:::::
package ro.gebs.captoom.activities;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.util.List;
import ro.gebs.captoom.R;
import ro.gebs.captoom.asynctasks.SavePictAsync;
import ro.gebs.captoom.interfaces.FinishTakePictureCallback;
import ro.gebs.captoom.utils.Utils;
import ro.gebs.captoom.utils.fonts.CustomFontButton;
import ro.gebs.captoom.utils.fonts.TopMenu;
@SuppressLint("SimpleDateFormat")
public class TakePicture extends Activity implements FinishTakePictureCallback {
private SurfaceView surfaceView = null;
private Camera camera = null;
private Button buttonTakePicture;
private boolean isFlashOn = false;
private long the_folder_id;
private boolean inPreview = true;
Camera.AutoFocusCallback myAutoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera arg1) {
if (success) {
camera.takePicture(null, null, myPictureCallback_JPG);
} else {
Utils.showToast(TakePicture.this, "Not focused, try again", Toast.LENGTH_SHORT);
buttonTakePicture.setEnabled(true);
}
}
};
final Camera.PictureCallback myPictureCallback_JPG = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
new SavePictAsync(arg0, TakePicture.this, camera, the_folder_id, buttonTakePicture).execute();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_control);
surfaceView = (SurfaceView) findViewById(R.id.preview);
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
System.out.println("------------ surf Created");
if (camera == null) {
camera = Camera.open();
Camera.Parameters params = camera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
try {
System.out.println("------------ 1");
camera.setPreviewDisplay(holder);
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
for (Size size : sizes) {
Log.d("TakePicture", size.height + "X" + size.width + "height" + surfaceView.getHeight() + "width" + surfaceView.getWidth());
}
Size optimalSize = getOptimalPreviewSize(sizes, surfaceView.getHeight(), surfaceView.getWidth());
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
camera.setDisplayOrientation(90);
camera.setParameters(parameters);
camera.startPreview();
inPreview = true;
} catch (IOException e) {
Log.e("Take Picture", "Error", e);
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
System.out.println("------------ surf Destroyed");
if (inPreview) {
try {
if (camera != null) {
camera.cancelAutoFocus();
camera.stopPreview();
}
inPreview = false;
} catch (RuntimeException e) {
e.printStackTrace();
} finally {
if (camera != null) {
camera.release();
camera = null;
}
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (!inPreview) {
try {
System.out.println("------------ surf Changed");
camera = Camera.open();
camera.setPreviewDisplay(surfaceView.getHolder());
camera.setDisplayOrientation(90);
camera.startPreview();
inPreview = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
);
LayoutInflater controlInflater = LayoutInflater.from(getBaseContext());
ViewGroup viewControl = (ViewGroup) controlInflater.inflate(R.layout.camera_control, null);
assert viewControl != null;
final CustomFontButton cancel_btn = (CustomFontButton) findViewById(R.id.cancel_btn);
cancel_btn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
finish();
}
}
);
buttonTakePicture = (Button) findViewById(R.id.take_picture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(View arg0) {
try {
Utils.showToast(TakePicture.this, "Focusing...", Toast.LENGTH_SHORT);
camera.autoFocus(myAutoFocusCallback);
buttonTakePicture.setEnabled(false);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
);
RelativeLayout headerView = (RelativeLayout) findViewById(R.id.top_header_green);
ImageButton menu_btn = (ImageButton) findViewById(R.id.menu_btn);
new
TopMenu(this, this, headerView, menu_btn);
ImageButton flashBtn = (ImageButton) findViewById(R.id.flash_btn);
flashBtn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view) {
Context context = getApplicationContext();
if (context.getPackageManager().hasSystemFeature(getPackageManager().FEATURE_CAMERA_FLASH)) {
Camera.Parameters params = camera.getParameters();
if (isFlashOn) {
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
isFlashOn = false;
Utils.showToast(context, getString(R.string.FlashOff), Toast.LENGTH_SHORT);
} else {
params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
camera.setParameters(params);
isFlashOn = true;
Utils.showToast(context, getString(R.string.FlashAuto), Toast.LENGTH_SHORT);
}
}
}
}
);
}
@Override
public void finishTakePicture() {
finish();
}
@Override
protected void onResume() {
the_folder_id = getIntent().getLongExtra("the_folder_id", 0);
buttonTakePicture.setEnabled(true);
super.onResume();
}
@Override
public void onBackPressed() {
super.onBackPressed();
if (PreviewPhoto.photos != null) {
for (String image : PreviewPhoto.photos) {
File file = new File(image);
file.delete();
}
PreviewPhoto.photos.clear();
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Log.d("TakePicture", "TargetRatio: " + targetRatio);
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - h) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - h);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - h) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - h);
}
}
}
Log.d("TakePicture", "The optimal size is:" + optimalSize.height + "X" + optimalSize.width);
return optimalSize;
}
}
私はすでに をオーバーライドsurfaceDestroyed
していたので、メソッドsurfaceCreated
で行うことはあまりありませんでした。onPause
onResume
この質問が多くの人に役立つことを願っています.Androidの優れたカメラ実装であることが証明されています.
どう思いますか?
これは実用的なソリューションなので、これが効率的な実装だと思うかどうか疑問に思っていましたか? 一部のデバイスでしかテストしていないため、これを尋ねています...