问题 在清理我的代码时,我想将我的Android摄像头方法移动到一个单独的类,符合我认为的最佳实践。经过一整天的搜索,我仍然在努力弄清楚如何做到这一点。主要问题是实现方法的差异以及从相机API到相机2 API的转变导致在线找到我无法复制的解决方案。请注意,我是Java的初学者,因此,这可能是一个非常新的错误,由于网络上的各种信息,我无法解决这个错误。
当前代码
我的主要问题是,startCamera()中的SurfaceTexture texture = surfaceView.getSurfaceTexture();
表示Cannot resolve method 'getSurfaceTexture()'
,而previewBuilder.addTarget(texture);
抱怨addTarget (android.view.surface) in Builder cannot be applied to (android.graphics.SurfaceTexture)
。
public class CameraView extends TextureView implements TextureView.SurfaceTextureListener{
private Size previewsize;
private CameraDevice cameraDevice;
private CaptureRequest.Builder previewBuilder;
private CameraCaptureSession previewSession;
private final Context context;
public SurfaceView surfaceView;
public TextureView textureView;
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
// Once the surface is created, simply open a handle to the camera hardware.
openCamera();
}
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
}
public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
try {
//cameraDevice.setPreviewDisplay(holder);
//cameraDevice.startPreview();
} catch (Exception e){
e.printStackTrace();
}
}
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
// stopPreview();
cameraDevice.close();
return true;
}
public void openCamera()
{
CameraManager manager = (CameraManager) context.getSystemService (Context.CAMERA_SERVICE);
try
{
String cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics=manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
previewsize = map.getOutputSizes(SurfaceTexture.class)[0];
try {
manager.openCamera(cameraId, stateCallback, null);
} catch (SecurityException e){
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
cameraDevice = camera;
startCamera();
}
@Override
public void onClosed(CameraDevice camera) {
// nothing
}
@Override
public void onDisconnected(CameraDevice camera) {
}
@Override
public void onError(CameraDevice camera, int error) {
}
};
void startCamera()
{
if (cameraDevice == null || previewsize==null)
{
return;
}
SurfaceTexture texture = surfaceView.getSurfaceTexture();
texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight());
Surface surface = new Surface(texture);
try
{
// add all the standard stuff to the previewBuilder
previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
} catch (Exception e) {}
previewBuilder.addTarget(texture);
try
{
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
previewSession = session;
getChangedPreview();
}
@Override
public void onConfigureFailed(CameraCaptureSession session{
}
},null);
} catch (Exception e) {}
}
void getChangedPreview()
{
previewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
HandlerThread thread = new HandlerThread("changed Preview");
thread.start();
Handler handler = new Handler(thread.getLooper());
try
{
previewSession.setRepeatingRequest(previewBuilder.build(), null, handler);
}catch (Exception e){}
}
}
目标
为了保持我的代码清洁和易懂,我想限制MainActivity类在视图之间切换,而不是在那里有大量的方法。我想通过将以下对象从INVISIBLE
切换到VISIBLE
来激活我的应用中的相机视图。其他建议表示赞赏。
cameraView = (CameraView) findViewById(R.id.camera);
然后 MainActivity.java
看起来像:
public class MainActivity extends AppCompatActivity {
private TextView mTextMessage;
private CameraView cameraView;
private MainSurfaceView mGLView;
private TextureView textureView;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
mTextMessage.setText(R.string.title_home);
return true;
case R.id.navigation_dashboard:
mTextMessage.setText(R.string.title_dashboard);
return true;
case R.id.navigation_notifications:
mTextMessage.setText(R.string.title_notifications);
return true;
}
return false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextMessage = (TextView) findViewById(R.id.message);
cameraView = (CameraView) findViewById(R.id.camera);
mGLView = (MainSurfaceView) findViewById(R.id.glSurfaceView);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
}
感谢您的帮助!
答案 0 :(得分:0)
SurfaceTexture texture = surfaceView.getSurfaceTexture();
表示Cannot resolve method 'getSurfaceTexture()'
您调用surfaceView的方法getSurfaceTexture。 surfaceView是一个SurfaceView。我们来看看文档:
https://developer.android.com/reference/android/view/SurfaceView.html
显然,SurfaceView没有名为" getSurfaceTexture()"的方法。但是,在Google上搜索" getSurfaceTexture()Android"向我们展示了该方法属于TextureView类。您的类CameraView有一个名为" textureView"的字段,因此(我不知道您想要实现什么)可以根据需要调用该字段上的方法。另外你的类CameraView本身就是一个TextureView(你想要吗),所以如果你想在类本身上调用它,你也可以调用getSurfaceTexture()
。
previewBuilder.addTarget(texture);
抱怨addTarget (android.view.surface) in Builder cannot be applied to (android.graphics.SurfaceTexture).
让我们再看看文档:{{3}}
显然,CaptureRequest.builder(previewBuilder的类型)有一个名为addTarget
的方法,但该方法只接受Surface!你正在传递一个纹理。您可能希望将texture
更改为surface