0

我想在我的應用中使用Google示例添加攝像頭2 API。我的應用程序具有使用相機的權限,並且舊API可以正常工作。我已經檢查了多個權限甚至是之前的行,以執行Android引發異常的代碼,但我仍然收到Lacking權限來訪問相機服務。授予權限訪問攝像頭服務

private void createCameraPreviewSession() { 
    try{ 
     SurfaceTexture texture = mTextureView.getSurfaceTexture(); 
     //assert texture != null; 

     Log.d(TAG,String.format("Textureview is null: %b, texture is null: %b",mTextureView==null, texture==null)); 
     // We configure the size of default buffer to be the size of camera preview we want. 
     texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); 

     // This is the output Surface we need to start preview. 
     Surface surface = new Surface(texture); 

     // We set up a CaptureRequest.Builder with the output Surface. 

     if (ActivityCompat.checkSelfPermission(a, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { 
      Log.d(TAG, "Permission granted"); 
      mPreviewRequestBuilder= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
      Log.d(TAG, "Capture request created"); 
     } 
     else{ 
      return ; 
     } 

     mPreviewRequestBuilder.addTarget(surface); 

     // Here, we create a CameraCaptureSession for camera preview. 

     mCameraDevice.createCaptureSession(Arrays.asList(surface), 
      new CameraCaptureSession.StateCallback() { 

       @Override 
       public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { 
        // The camera is already closed 
        if (null == mCameraDevice) { 
         return; 
        } 

        // When the session is ready, we start displaying the preview. 
        mCaptureSession = cameraCaptureSession; 
        try { 
         // Auto focus should be continuous for camera preview. 
         mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, 
           CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); 

         // Finally, we start displaying the camera preview. 
         mPreviewRequest = mPreviewRequestBuilder.build(); 
         mCaptureSession.setRepeatingRequest(mPreviewRequest, null, null); 
        } catch (CameraAccessException e) { 
         e.printStackTrace(); 
        } 
       } 

       @Override 
       public void onConfigureFailed(
         @NonNull CameraCaptureSession cameraCaptureSession) { 
        Toast.makeText(a,a.getString(R.string.error_configuring_camera),Toast.LENGTH_LONG).show(); 
       } 
      }, null); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

這裏是日誌:

12-02 20:30:07.427 697-697/kiam.cameraintentpractice.pendant D/ICAMERA2: Textureview is null: false, texture is null: false 
12-02 20:30:07.428 697-697/kiam.cameraintentpractice.pendant D/ICAMERA2: Permission granted 
12-02 20:30:07.429 697-697/kiam.cameraintentpractice.pendant D/AndroidRuntime: Shutting down VM 
12-02 20:30:07.430 697-697/kiam.cameraintentpractice.pendant E/AndroidRuntime: FATAL EXCEPTION: main 
    Process: kiam.cameraintentpractice.pendant, PID: 697 
    java.lang.SecurityException: Lacking privileges to access camera service 
     at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108) 
     at android.hardware.camera2.utils.CameraBinderDecorator$CameraBinderDecoratorListener.onAfterInvocation(CameraBinderDecorator.java:73) 
     at android.hardware.camera2.utils.Decorator.invoke(Decorator.java:81) 
     at java.lang.reflect.Proxy.invoke(Proxy.java:393) 
     at $Proxy2.createDefaultRequest(Unknown Source) 
     at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureRequest(CameraDeviceImpl.java:636) 
     at kiam.cameraintentpractice.model.CameraV2.createCameraPreviewSession(CameraV2.java:377) 
     at kiam.cameraintentpractice.model.CameraV2.access$400(CameraV2.java:55) 
     at kiam.cameraintentpractice.model.CameraV2$2.onOpened(CameraV2.java:340) 
     at android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:134) 
     at android.os.Handler.handleCallback(Handler.java:739) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:148) 
     at android.app.ActivityThread.main(ActivityThread.java:5525) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 
12-02 20:30:08.752 697-797/kiam.cameraintentpractice.pendant D/TaskManager: Error processing queue - Call: 3 

代碼被稱爲形式在這裏:

private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { 

    @Override 
    public void onOpened(@NonNull CameraDevice cameraDevice) { 
     // This method is called when the camera is opened. We start camera preview here. 
     mCameraOpenCloseLock.release(); 
     mCameraDevice = cameraDevice; 
     createCameraPreviewSession(); 
    } 

    @Override 
    public void onDisconnected(@NonNull CameraDevice cameraDevice) { 
     mCameraOpenCloseLock.release(); 
     cameraDevice.close(); 
     mCameraDevice = null; 
    } 

    @Override 
    public void onError(@NonNull CameraDevice cameraDevice, int error) { 
     mCameraOpenCloseLock.release(); 
     cameraDevice.close(); 
     mCameraDevice = null; 
     Toast.makeText(a, a.getString(R.string.error_using_camera), Toast.LENGTH_SHORT).show(); 
     a.finish(); 
    } 
}; 

而且回調進行形式在這裏:

private void openCamera(int width, int height) { 

    if (ContextCompat.checkSelfPermission(a, Manifest.permission.CAMERA) 
      != PackageManager.PERMISSION_GRANTED) { 
     Log.d(TAG, "Permission denied"); 
     return; 
    } 
    setUpCameraOutputs(width, height); 
    configureTransform(width, height); 

    try { 
     /*if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { 
      throw new RuntimeException("Time out waiting to lock camera opening."); 
     }*/ 
     if (ActivityCompat.checkSelfPermission(a, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { 
      Log.d(TAG, "Permission accepted"); 
      CameraManager manager = (CameraManager) a.getSystemService(Context.CAMERA_SERVICE); 
      manager.openCamera(mCameraId, mStateCallback, null); 
     } 
     else{ 
      Log.d(TAG, "Permission denied"); 
      return; 
     } 

    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } /*catch (InterruptedException e) { 
     throw new RuntimeException("Interrupted while trying to lock camera opening.", e); 
    }*/ 
} 

編輯 - 發佈清單根據要求

<?xml version="1.0" encoding="utf-8"?> 

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" /> 
<uses-permission android:name="android.permission.CAMERA" /> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 

<uses-feature 
    android:name="android.hardware.camera" 
    android:required="false" /> 
<uses-feature 
    android:name="android.hardware.camera.front" 
    android:required="false" /> 
<uses-feature 
    android:name="android.hardware.camera.autofocus" 
    android:required="false" /> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:largeHeap="true" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme" 
    android:screenOrientation="reversePortrait" 
    android:hardwareAccelerated="true"> 
    <activity 
     android:name=".UI.ImageAcquisition" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" 
     android:screenOrientation="reversePortrait" 
    /> 
    <activity 
     android:name=".UI.ImageManipulation" 
     android:label="@string/title_activity_image_manuplation" 
     android:launchMode="singleTop" 
     android:screenOrientation="reversePortrait" 
     android:theme="@style/AppTheme" /> 
    <activity 
     android:name=".UI.ProjectsActivity" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" 
     android:screenOrientation="reversePortrait"> 
     <intent-filter android:label="@string/app_name"> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <activity 
     android:name=".UI.IndividualProjectDetailActivity" 
     android:label="@string/title_activity_individual_project_detail" 
     android:parentActivityName=".UI.ProjectsActivity" 
     android:theme="@style/AppTheme" 
     android:screenOrientation="reversePortrait"> 

     <meta-data 
      android:name="android.support.PARENT_ACTIVITY" 
      android:value="kiam.cameraintentpractice.UI.ProjectsActivity" /> 
    </activity> 

    <service 
     android:name=".model.CalculatorService" 
     android:enabled="true" 
     android:exported="true"></service> 
    <meta-data 
     android:name="com.google.android.gms.version" 
     android:value="@integer/google_play_services_version" /> 
</application> 

+0

請張貼您的清單。 – Emmanuel

回答

1

我有像三星Galaxy S7設備相同的問題。我解決它通過打開相機如下之前添加延遲:

TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() { 
    @Override 
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 
     mSurfaceTextureAvailable = true; 
     if (ContextCompat.checkSelfPermission(CameraActivity.this, Manifest.permission.CAMERA) 
       != PackageManager.PERMISSION_GRANTED) { 
      ActivityCompat.requestPermissions(CameraActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); 
      return; 
     }else { 
      mPermissionsGranted = true; 

      // Execute some code after 500 milliseconds have passed 
      Handler handler = new Handler(); 
      handler.postDelayed(new Runnable() { 
       @Override 
       public void run() { 
        setupCameraIfPossible(); 
       } 
      }, 500); 


     } 

    } 
... 

這裏是我用來打開相機的方法:

private void setupCameraIfPossible() { 
    if (mSurfaceTextureAvailable && mPermissionsGranted) { 
     openCamera(); 
    } 
} 

我希望它會幫助你

+0

謝謝,現在它正在工作 –

1

唐不要延遲開幕相機。只需在SurfaceTextureListener的onSurfaceTextureDestroyed()方法中使用closeCamera()。