我一直在尝试为我的项目开发自定义相机应用程序。我已经在Android开发者网站上关注了已弃用的android.hardware.Camera
类的几乎所有步骤,因为我需要保持与旧设备的兼容性。我添加了相机的权限以及相机和自动对焦的功能。我目前正在使用android studio提供的模拟器进行测试,Nexus 5 API 23 x86,前置和后置摄像头均设置为模拟。当我的代码到达Camera.open()
位时,我收到错误-13:Fail to connect to camera service
。
我在许多地方移动了我的相机初始化,但它总是抛出该错误并返回null。模拟器中的内置Camera应用程序可以在两个摄像头上正常工作,并且在我的代码中都可以检测到它们。我根本找不到为什么它不起作用。
这是我的代码以防万一:
CameraActivity.java
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*/
public class CameraActivity extends AppCompatActivity {
private static final boolean AUTO_HIDE = true;
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
private static final int UI_ANIMATION_DELAY = 300;
private View mControlsView;
private boolean mVisible;
private CameraView mCameraView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
mVisible = true;
mControlsView = findViewById(R.id.fullscreen_content_controls);
mCameraView = new CameraView(this);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_view);
preview.addView(mCameraView);
// Set up the user interaction to manually show or hide the system UI.
mCameraView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toggle();
}
});
// Upon interacting with UI controls, delay any scheduled hide()
// operations to prevent the jarring behavior of controls going away
// while interacting with the UI.
findViewById(R.id.capture_button).setOnTouchListener(mDelayHideTouchListener);
//// TODO: 2015-11-05 Create a preview class extending SurfaceView and implementing SurfaceHolder.callback and put camera code there
//// TODO: 2015-11-05 http://developer.android.com/guide/topics/media/camera.html#custom-camera
//// TODO: 2015-11-05 http://stackoverflow.com/questions/26305107/how-to-fix-fail-to-connect-to-camera-service-exception-in-android-emulator
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Trigger the initial hide() shortly after the activity has been
// created, to briefly hint to the user that UI controls
// are available.
delayedHide(100);
}
/**
* Touch listener to use for in-layout UI controls to delay hiding the
* system UI. This is to prevent the jarring behavior of controls going away
* while interacting with activity UI.
*/
private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
return false;
}
};
private void toggle() {
if (mVisible) {
hide();
} else {
show();
}
}
private void hide() {
// Hide UI first
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.hide();
}
mControlsView.setVisibility(View.GONE);
mVisible = false;
// Schedule a runnable to remove the status and navigation bar after a delay
mHideHandler.removeCallbacks(mShowPart2Runnable);
mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
}
private final Runnable mHidePart2Runnable = new Runnable() {
@SuppressLint("InlinedApi")
@Override
public void run() {
// Delayed removal of status and navigation bar
// Note that some of these constants are new as of API 16 (Jelly Bean)
// and API 19 (KitKat). It is safe to use them, as they are inlined
// at compile-time and do nothing on earlier devices.
mCameraView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
};
@SuppressLint("InlinedApi")
private void show() {
// Show the system bar
mCameraView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
mVisible = true;
// Schedule a runnable to display UI elements after a delay
mHideHandler.removeCallbacks(mHidePart2Runnable);
mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
}
private final Runnable mShowPart2Runnable = new Runnable() {
@Override
public void run() {
// Delayed display of UI elements
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.show();
}
mControlsView.setVisibility(View.VISIBLE);
}
};
private final Handler mHideHandler = new Handler();
private final Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
hide();
}
};
/**
* Schedules a call to hide() in [delay] milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
mHideHandler.removeCallbacks(mHideRunnable);
mHideHandler.postDelayed(mHideRunnable, delayMillis);
}
@Override
protected void onPause(){
super.onPause();
mCameraView.releaseCamera();
}
}
CameraView.java
import android.hardware.Camera; //This is the good import!
/**
* TODO: document your custom view class.
*/
@SuppressWarnings("deprecation")
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraView(Context context) {
super(context);
try{
mCamera = Camera.open();
} catch (Exception e){
Log.e("CameraView", "Error creating camera: " + e.getMessage());
}
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e){
Log.d("surfaceCreated", "Error starting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if(mHolder.getSurface() == null)
return;
try{
mCamera.stopPreview();
} catch (Exception e) {
//Non-existent o.O
}
//Resize, etc
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("CameraView", "Error starting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(mCamera != null)
mCamera.stopPreview();
}
public void releaseCamera(){
if(mCamera != null){
mCamera.release();
mCamera = null;
}
}
}
logcat:
11-09 14:13:13.144 7791-7791/? I/art: Not late-enabling -Xcheck:jni (already on)
11-09 14:13:13.144 7791-7791/? I/art: Late-enabling JIT
11-09 14:13:13.146 7791-7791/? I/art: JIT created with code_cache_capacity=2MB compile_threshold=1000
11-09 14:13:13.212 7791-7791/com.weebly.olipro007.cameracontrol W/System: ClassLoader referenced unknown path: /data/app/com.weebly.olipro007.cameracontrol-1/lib/x86
11-09 14:13:13.427 7791-7791/com.weebly.olipro007.cameracontrol W/CameraBase: An error occurred while connecting to camera: 0
11-09 14:13:13.427 7791-7791/com.weebly.olipro007.cameracontrol E/CameraView: Error creating camera: Fail to connect to camera service
11-09 14:13:13.489 7791-7820/com.weebly.olipro007.cameracontrol D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
11-09 14:13:13.508 7791-7791/com.weebly.olipro007.cameracontrol D/: HostConnection::get() New Host Connection established 0xab645030, tid 7791
11-09 14:13:13.584 7791-7820/com.weebly.olipro007.cameracontrol D/: HostConnection::get() New Host Connection established 0xab6451c0, tid 7820
11-09 14:13:13.611 7791-7820/com.weebly.olipro007.cameracontrol I/OpenGLRenderer: Initialized EGL, version 1.4
11-09 14:13:13.693 7791-7820/com.weebly.olipro007.cameracontrol W/EGL_emulation: eglSurfaceAttrib not implemented
11-09 14:13:13.693 7791-7820/com.weebly.olipro007.cameracontrol W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xabdff9a0, error=EGL_SUCCESS
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol D/AndroidRuntime: Shutting down VM
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: FATAL EXCEPTION: main
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: Process: com.weebly.olipro007.cameracontrol, PID: 7791
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.setPreviewDisplay(android.view.SurfaceHolder)' on a null object reference
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at com.weebly.olipro007.cameracontrol.CameraView.surfaceCreated(CameraView.java:43)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.SurfaceView.updateWindow(SurfaceView.java:582)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2055)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.Choreographer.doCallbacks(Choreographer.java:670)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:606)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11-09 14:13:13.699 7791-7791/com.weebly.olipro007.cameracontrol E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
11-09 14:13:16.909 7791-7791/? I/Process: Sending signal. PID: 7791 SIG: 9
答案 0 :(得分:0)
好吧,似乎该服务完全被Marshmallow中的旧api阻止了。我将模拟器切换到棒棒糖并加载......