Я пытаюсь показать предварительный просмотр в устройстве Android (API 19) на SurfaceView. Я могу получить доступ к CameraPReviews и выбрать один. Как вы, наверное, знаете, обычно camerapreviews не подходит для поверхностей. Как я обычно вижу, люди пытаются выбрать лучший предварительный просмотр, который соответствует виду поверхности. Я пробую новый подход, который изменяет вид поверхности в соответствии с форматным соотношением cameraPreviews. так что для этого я провел небольшой эксперимент, и результаты были хороши.
НО ... в обратном вызове SurfaceView существуют методы обратного вызова, созданные с поверхности и поверхности. И чтобы сделать расчеты, мне нужно знать ширину и высоту поверхности. Размеры поверхности обновляются в методе surfaceChanged. поэтому я использую эти значения для определения размеров поверхности. проблема в том, что SurfaceCreated работает «до» SurfaceChanged, так что мне нужно подождать, пока поверхность не изменится. сейчас я использую две логические переменные-члены. и вызывая стартовую камеру в обоих методах. Есть ли лучший способ сделать это? это может быть совершенно другой подход или другое решение этой конкретной проблемы «обработки обратного вызова»?
ps: я просто не могу рассчитывать на то, что изменилась поверхность, чтобы запустить камеру, потому что ее вызывают слишком много.
Основная активность и OnCreate
public class MainActivity extends AppCompatActivity {
SurfaceView mainactivity_surfaceview;
CameraSource cameraSource;
BarcodeDetector barcodeDetector;
int surfaceWidth;
int surfaceHeight;
boolean surfaceCreatedWorked = false;
boolean surfaceChangedWorked = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// define elements
mainactivity_surfaceview = findViewById(R.id.mainactivity_surfaceview);
mainactivity_surfaceview.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
System.out.println("surfaceCreated ÇALIŞTI");
surfaceCreatedWorked = true;
startCamera("surfaceCreated");
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
System.out.println("surfaceChanged ÇALIŞTI");
surfaceChangedWorked = true;
surfaceWidth = width;
surfaceHeight = height;
startCamera("surfaceChanged");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
}
...
...
...
}
Метод StartCamera
private void startCamera(String caller) {
System.out.println("ÇAĞIRAN " + caller);
// bunların ikisi de çalışmadıkça bu metod çalışmasın.
if (surfaceCreatedWorked && surfaceChangedWorked) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 1001);
return;
}
Camera camera;
try {
camera = Camera.open();
} catch (RuntimeException e) {
Log.e("benimtagim", "init_camera: " + e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
//modify parameter
param.setPreviewFrameRate(20);
//test
Camera.Size fittingSize = findFittingSize(param.getSupportedPreviewSizes());
if (fittingSize != null) {
param.setPreviewSize(fittingSize.width, fittingSize.height);
android.view.ViewGroup.LayoutParams lp = mainactivity_surfaceview.getLayoutParams();
System.out.println(surfaceWidth + "&&&" + surfaceHeight);
// get the values that satisfy image ratio and surfacesize.
//region
// because we are in portraid mode, surfacewidth should be multiply of cameraHeight and
// surfaceheight should be multiply of camerawidth @eddy
// int newSurfaceWidth = 100;
// int newSurfaceHeight = 100;
// float widthFactor = (float) surfaceWidth / (float) fittingSize.height;
// float heightFactor = (float) surfaceHeight / (float) fittingSize.width;
// float selectedFactor = widthFactor > heightFactor ? widthFactor : heightFactor;
// newSurfaceWidth = Math.round((float) fittingSize.height * selectedFactor);
// newSurfaceHeight = Math.round((float) fittingSize.width * selectedFactor);
//endregion
//now its in a method. all cases has been handled.
MySize mySize = getNewSurfaceSizes(surfaceWidth, surfaceHeight, fittingSize.width, fittingSize.height);
lp.width = mySize.getWidth(); // required width
lp.height = mySize.getHeight(); // required height
mainactivity_surfaceview.setLayoutParams(lp);
}
camera.setParameters(param);
camera.setDisplayOrientation(90);
try {
camera.setPreviewDisplay(mainactivity_surfaceview.getHolder());
camera.startPreview();
//camera.takePicture(shutter, raw, jpeg)
} catch (Exception e) {
Log.e("benimtagim", "init_camera: " + e);
return;
}
//
// if (cam != null) {
// Camera.Parameters param = cam.getParameters();
// List<Camera.Size> sizes = param.getSupportedPreviewSizes();
// for (Camera.Size size : sizes) {
// System.out.println(size.width + " &&&&" + size.height);
// }
// } else {
// Toast.makeText(MainActivity.this, "Kamera Yok", Toast.LENGTH_SHORT).show();
// }
surfaceCreatedWorked = false;
surfaceChangedWorked = false;
}
}