2017-11-29 13 views
0

私はMobile Vision APIを使用して、前面に向いているカメラの顔を検出しています。 GoogleのFaceTrackerデモを使用しましたが、私はそれをFragmentで使用する必要があります。動作していますが、画面を回転しようとすると、例外RuntimeException: Fail to connect to camera serviceが発生してアプリケーションがクラッシュします。画面を回転させるとアプリケーションがクラッシュする

フラグメントコード:アクティビティコードによれば

class EyeTrackerFragment : Fragment(), AnkoLogger { 

private var cameraSource: CameraSource? = null 

private lateinit var cameraSourcePreview: CameraSourcePreview 
private lateinit var graphicOverlay: GraphicOverlay 

private var callback: OnEyeContextUpdatedListener? = null 

companion object { 
    // google play services error code 
    private val RC_HANDLE_GMS = 9001 
    // permission request codes need to be < 256 
    private val RC_HANDLE_CAMERA_PERM = 2 
} 

override fun onAttach(context: Context?) { 
    super.onAttach(context) 

    try { 
     callback = activity as OnEyeContextUpdatedListener 
    } catch (e: ClassCastException) { 
     throw ClassCastException("${activity} must implement OnEyeContextUpdatedListener") 
    } 
} 

/** 
* Restarts the camera. 
*/ 
override fun onResume() { 
    super.onResume() 

    startCameraSource() 
} 

/** 
* Stops the camera. 
*/ 
override fun onPause() { 
    super.onPause() 
    cameraSourcePreview.stop() 
} 

/** 
* Releases the resources associated with the camera source, the associated detector, and the 
* rest of the processing pipeline. 
*/ 
override fun onDestroy() { 
    super.onDestroy() 
    cameraSource?.release() 
} 

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? = 
     inflater!!.inflate(R.layout.fragment_face_tracker, container, false) 

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 
    super.onViewCreated(view, savedInstanceState) 

    cameraSourcePreview = getView()!!.findViewById<View>(R.id.preview) as CameraSourcePreview 
    graphicOverlay = getView()!!.findViewById<View>(R.id.faceOverlay) as GraphicOverlay 

    if (ActivityCompat.checkSelfPermission(context.applicationContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { 
     createCameraSource() 
    } else { 
     requestCameraPermission() 
    } 
} 

/** 
* Handles the requesting of the camera permission. This includes 
* showing a "Toast" message of why the permission is needed then 
* sending the request. 
*/ 
private fun requestCameraPermission() { 
    warn("Camera permission is not granted. Requesting permission") 

    val permissions = arrayOf(Manifest.permission.CAMERA) 

    if (!ActivityCompat.shouldShowRequestPermissionRationale(activity, 
      Manifest.permission.CAMERA)) { 
     ActivityCompat.requestPermissions(activity, permissions, RC_HANDLE_CAMERA_PERM) 
     return 
    } 

    Toast.makeText(context.applicationContext, "Give me permissions", Toast.LENGTH_LONG).show() 
} 

private fun createCameraSource() { 
    val detector = FaceDetector.Builder(context.applicationContext) 
      .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS) 
      .setProminentFaceOnly(true) 
      .setTrackingEnabled(true) 
      .setMode(FaceDetector.ACCURATE_MODE) 
      .build() 

    val faceTracker = GraphicFaceTracker(graphicOverlay, callback, context) 
    val faceProcessor = LargestFaceFocusingProcessor(detector, faceTracker) 
    detector.setProcessor(faceProcessor) 

    if (!detector.isOperational) { 
     longToast("Face detector dependencies are not yet available.") 
    } 

    cameraSource = CameraSource.Builder(context, detector) 
      .setRequestedPreviewSize(640, 480) 
      .setFacing(CameraSource.CAMERA_FACING_FRONT) 
      .setRequestedFps(30.0f) 
      .build() 
} 

private fun startCameraSource() { 
    // check that the device has play services available. 
    val code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
      context.applicationContext) 
    if (code != ConnectionResult.SUCCESS) { 
     val dlg = GoogleApiAvailability.getInstance().getErrorDialog(activity, code, RC_HANDLE_GMS) 
     dlg.show() 
    } 

    if (cameraSource != null) { 
     try { 
      cameraSourcePreview.start(cameraSource!!, graphicOverlay) 
     } catch (e: IOException) { 
      error("Unable to start camera source.", e) 
      cameraSource!!.release() 
      cameraSource = null 
     } 

    } 
} 

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { 
    if (requestCode != RC_HANDLE_CAMERA_PERM) { 
     debug("Got unexpected permission result: $requestCode") 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults) 
     return 
    } 

    if (grantResults.size != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
     debug("Camera permission granted - initialize the camera source") 
     createCameraSource() 
     return 
    } 

    error("Permission not granted: results len = ${grantResults.size}. Result code = ${if (grantResults.isNotEmpty()) grantResults[0] else "(empty)"}") 

    val builder = AlertDialog.Builder(context) 
    builder.setTitle("Face Tracker sample") 
      .setMessage("Have no camera permission") 
      .setPositiveButton("Ok", { _, _ -> activity.finish() }) 
      .show() 
} 

}

。 onCreateメソッドで前のフラグメントのみをアタッチしてから何もしません。

私はカメラのインスタンスがいくつかの状況でリリースされなかったと思いますが、それはアクティビティと同様に行われます。フラグメントには、アクティビティと比較して余分なアクションが必要な特別な動作がありますか?

完全な例外ログ:Androidが破壊し、姿勢変更のためのあなたの活動を再作成するたびに

E/AndroidRuntime: FATAL EXCEPTION: main 
       Process: com.eyetracker.android.demo, PID: 22631 
       java.lang.RuntimeException: Fail to connect to camera service 
        at android.hardware.Camera.<init>(Camera.java:520) 
        at android.hardware.Camera.open(Camera.java:361) 
        at com.google.android.gms.vision.CameraSource.zzchq(Unknown Source) 
        at com.google.android.gms.vision.CameraSource.start(Unknown Source) 
        at com.eyetracker.android.camera.CameraSourcePreview.startIfReady(CameraSourcePreview.kt:82) 
        at com.eyetracker.android.camera.CameraSourcePreview.access$startIfReady(CameraSourcePreview.kt:18) 
        at com.eyetracker.android.camera.CameraSourcePreview$SurfaceCallback.surfaceCreated(CameraSourcePreview.kt:104) 
        at android.view.SurfaceView.updateWindow(SurfaceView.java:580) 
        at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:176) 
        at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:948) 
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1974) 
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1065) 
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5901) 
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) 
        at android.view.Choreographer.doCallbacks(Choreographer.java:580) 
        at android.view.Choreographer.doFrame(Choreographer.java:550) 
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) 
        at android.os.Handler.handleCallback(Handler.java:739) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:211) 
        at android.app.ActivityThread.main(ActivityThread.java:5389) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:372) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815) 
+0

コードとエラーログを追加してください – kimkevin

+0

あなたはAndroidを試しましたか?configChanges = "orientation | keyboardHidden"? – Bek

+0

どうしたら私を助けたでしょうか? –

答えて

0

が、それはonSaveInstanceState()を呼び出します。

したがって、onSaveInstanceState()のBundleに必要なデータを保存し、savedInstanceStateフィールドがnullであるかどうかを確認してonCreate()で同じデータを復元しますか?

関連する問題