我已经看到很多关于错误的SurfaceView回调的问题,但没有一个有明确的解决方案。我有一个非常简单的布局文件,它有一个SurfaceView,一个TextView和一个不确定的进度指示器。根据我的日志,我的ScanActivity将自身注册为SurfaceView的布局回调,但只调用surfaceDestroyed(SurfaceHolder holder)
。但是活动成功地预览了相机,这很奇怪,因为我将SurfaceView附加为surfaceCreated
中的相机预览,以及" Surface创建。"在#34; Surface销毁时永远不会记录。"是
scan.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/black"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_gravity="bottom|center_horizontal">
<TextView
android:id="@+id/scan_instructions"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textSize="16sp"
android:gravity="center"
android:visibility="visible"
android:textColor="@android:color/primary_text_dark"
android:text="@string/scan_instructions"
/>
<ProgressBar
android:id="@+id/progress"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="5dp"
android:indeterminate="true"
/>
</LinearLayout>
</FrameLayout>
ScanActivity.java
public class ScanActivity extends Activity implements SurfaceHolder.Callback {
private Camera camera;
private Scanner scanner;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scan);
scanner = new Scanner(20) {
@Override
public void onPostExecute(String result) {
System.out.println("Read QR: " + result);
onQRScanned(result);
}
};
}
/**
* Registers this class as the callback for the image surface in the layout XML.
*/
@Override
public void onStart() {
super.onStart();
((SurfaceView) findViewById(R.id.camera_preview)).getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
System.out.println("Surface created.");
surfaceDestroyed(holder);
try {
// Open the camera.
camera = Camera.open();
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(scanner);
System.out.println("Connected QR scan task.");
} catch (NullPointerException e) {
// Didn't find a camera to open.
e.printStackTrace();
surfaceDestroyed(holder);
return;
} catch (IOException e) {
// Camera preview setup failed.
e.printStackTrace();
surfaceDestroyed(holder);
return;
} catch (RuntimeException e) {
// The app was denied permission to camera services.
e.printStackTrace();
surfaceDestroyed(holder);
return;
}
// Set auto-focus mode
Parameters params = camera.getParameters();
List<String> modes = params.getSupportedFocusModes();
if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
else if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
else if (modes.contains(Parameters.FOCUS_MODE_AUTO)) {
params.setFocusMode(Parameters.FOCUS_MODE_AUTO);
}
camera.setParameters(params);
}
/**
* If the preview surface is altered for some reason, fixes it and refreshes the preview.
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
System.out.println("Surface changed.");
if (camera == null)
return;
camera.setDisplayOrientation(90);
camera.startPreview();
}
/**
* When the activity is closed, release the camera.
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
System.out.println("Surface destroyed.");
if (camera == null)
return;
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
scanner.cancel(true);
}
/**
* Called when a QR code is successfully read from the preview.
* @param content The text encoded in the QR.
*/
private void onQRScanned(String content) {
if (content != null) {
getIntent().putExtra("qr_content", content);
setResult(RESULT_OK, getIntent());
finish();
} else {
setResult(RESULT_CANCELED);
finish();
}
}
}
答案 0 :(得分:1)
我已尝试过您的代码,surfaceCreated()
已按预期调用。你错误地检查了你的logcat。尝试使用Log.d("MainActivity", "Surface created.");
代替System.out.println
。还要学习how to use debugger。