0

試圖在我的Android應用程序中使用Facebook Live API。我使用camera2拉起我的流媒體直播活動的相機,但我得到這個錯誤:嘗試在空對象上調用「... CameraCaptureSession.abortCaptures()」

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.camera2.CameraCaptureSession.abortCaptures()' on a null object reference 
                    at com.example.mapdemo.StreamingActivity$4.onClick(StreamingActivity.java:151) 
                    at android.view.View.performClick(View.java:6261) 
                    at android.widget.TextView.performClick(TextView.java:11157) 
                    at android.view.View$PerformClick.run(View.java:23748) 
                    at android.os.Handler.handleCallback(Handler.java:751) 
                    at android.os.Handler.dispatchMessage(Handler.java:95) 

我不知道爲什麼這是一個錯誤。這是圍繞在錯誤所在行的代碼...有錯誤的行以mCaptureCameraSession.abortCaptures():

package com.example.mapdemo; 

import android.content.pm.PackageManager; 
import android.hardware.camera2.CameraAccessException; 
import android.hardware.camera2.CameraCaptureSession; 
import android.hardware.camera2.CameraCharacteristics; 
import android.hardware.camera2.CameraDevice; 
import android.hardware.camera2.CameraManager; 
import android.hardware.camera2.CaptureRequest; 
import android.hardware.camera2.TotalCaptureResult; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.HandlerThread; 
import android.support.annotation.NonNull; 
import android.support.v13.app.ActivityCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.view.Surface; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.widget.Button; 

import com.facebook.AccessToken; 
import com.facebook.GraphRequest; 
import com.facebook.GraphResponse; 
import com.facebook.HttpMethod; 

import org.json.JSONException; 

import java.util.ArrayList; 

public class StreamingActivity extends AppCompatActivity implements SurfaceHolder.Callback2 { 

    private static final String TAG = "StreamingActivity"; 
    private static final String[] REQUEST_PERMISSIONS = new String[]{ 
      android.Manifest.permission.CAMERA, 
      android.Manifest.permission.RECORD_AUDIO, 
      android.Manifest.permission.WRITE_EXTERNAL_STORAGE 
    }; 
    private static final int REQUEST_CODE_CAMERA = 1; 

    private CameraManager mCameraManager; 
    private VideoEncoderCore mVideoEncoderCore; 
    private String mFrontCameraId, streamURL,name,surname; 
    private CameraDevice mCameraDevice; 
    private Handler mBackgroundHandler; 
    private HandlerThread mBackgroundThread; 
    private SurfaceView mSurfacView; 
    private Button buttonRecord; 
    private boolean isRecording = false; 
    private ArrayList<Surface> mSurfaces; 
    private CaptureRequest mCaptureRequestPreview; 
    private StreamModel streamModel; 
    private CaptureRequest mCaptureRequestRecord; 
    private CameraCaptureSession mCameraCaptureSession; 
    private CameraCaptureSession.StateCallback mCaptureSessionCallback = new CameraCaptureSession.StateCallback() { 
     @Override 
     public void onConfigured(@NonNull CameraCaptureSession session) { 
      mCameraCaptureSession = session; 
      try { 
       mCameraCaptureSession.setRepeatingRequest(
         mCaptureRequestPreview, 
         new CameraCaptureSession.CaptureCallback() {}, 
         mBackgroundHandler 
       ); 
      } catch (CameraAccessException e) { 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void onConfigureFailed(@NonNull CameraCaptureSession session) { 
      Log.d(TAG, "fafea") ; 
     } 
    }; 
    private CameraDevice.StateCallback mCameraDeviceCallback = new CameraDevice.StateCallback() { 
     @Override 
     public void onOpened(@NonNull CameraDevice camera) { 
      mCameraDevice = camera; 
//   mCameraDevice.createCaptureSession(); 
// 
//   try { 
//    mCameraManager.setTorchMode(mFrontCameraId, true); 
//   } catch (CameraAccessException e) { 
//    e.printStackTrace(); 
//   } 
     } 

     @Override 
     public void onDisconnected(@NonNull CameraDevice camera) { 

     } 

     @Override 
     public void onError(@NonNull CameraDevice camera, int error) { 
      //@IntDef(value = {CameraDevice.StateCallback.ERROR_CAMERA_IN_USE, CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE, CameraDevice.StateCallback.ERROR_CAMERA_DISABLED, CameraDevice.StateCallback.ERROR_CAMERA_DEVICE, CameraDevice.StateCallback.ERROR_CAMERA_SERVICE}) 
     } 
    }; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_streaming); 


     mSurfacView = (SurfaceView) findViewById(R.id.surfaceView); 
     mSurfacView.getHolder().addCallback(StreamingActivity.this); 
     streamModel = new StreamModel(); 
/** 
LoginManager.getInstance().logInWithPublishPermissions(
this, 
Arrays.asList("publish_actions"));*/ 

     new GraphRequest(
       AccessToken.getCurrentAccessToken(), "/me/live_videos", null, HttpMethod.POST, 
       new GraphRequest.Callback() { 
        public void onCompleted(GraphResponse response) { 
         //Gson mGson = new Gson(); 
         //streamModel=mGson.fromJson(response.toString(),StreamModel.class); 
         try { 
          streamURL=response.getJSONObject().get("stream_url").toString(); 
          Log.e(TAG,response.getJSONObject().get("stream_url").toString()); 
         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 
        } 
       } 
     ).executeAsync(); 

     buttonRecord =(Button) findViewById(R.id.buttonRecord); 
     buttonRecord.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (isRecording){ 
        try { 
         mCameraCaptureSession.abortCaptures(); 
         mCameraCaptureSession.setRepeatingRequest(
           mCaptureRequestPreview, 
           new CameraCaptureSession.CaptureCallback() {}, 
           mBackgroundHandler 
         ); 
        } catch (CameraAccessException e) { 
         e.printStackTrace(); 
        } 
        isRecording = false; 
        buttonRecord.setText("Play"); 
       } 
       else{ 
        isRecording = true; 
        try { 
         mCameraCaptureSession.abortCaptures(); 
         mCameraCaptureSession.setRepeatingRequest(mCaptureRequestRecord, new CameraCaptureSession.CaptureCallback() { 
          @Override 
          public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { 
           super.onCaptureCompleted(session, request, result); 
           mVideoEncoderCore.drainEncoder(false); 
          } 

          @Override 
          public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session, int sequenceId) { 
           super.onCaptureSequenceAborted(session, sequenceId); 
           mVideoEncoderCore.drainEncoder(true); 
          } 
         }, mBackgroundHandler); 
        } catch (CameraAccessException e) { 
         e.printStackTrace(); 
        } 
        buttonRecord.setText("Stop"); 
       } 
      } 
     }); 
     mCameraManager = (CameraManager) getSystemService(CAMERA_SERVICE); 
     try { 
      String[] cameraIds = mCameraManager.getCameraIdList(); 
      if (cameraIds.length != 0) { 
       for (int i = 0; i < cameraIds.length; i++){ 
        if (mCameraManager.getCameraCharacteristics(cameraIds[i]).get(CameraCharacteristics.LENS_FACING) 
          == CameraCharacteristics.LENS_FACING_FRONT){ 
         mFrontCameraId = cameraIds[i]; 
        } 
       } 
      } 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     if (mVideoEncoderCore != null) { 
      mVideoEncoderCore.release(); 
     } 
    } 

    private void startBackgroundThread() { 
     mBackgroundThread = new HandlerThread("CameraBackground"); 
     mBackgroundThread.start(); 
     mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); 
    } 

    private void openCamera(){ 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { 
      ActivityCompat.requestPermissions(this, REQUEST_PERMISSIONS, REQUEST_CODE_CAMERA); 
      return; 
     } 
     try { 
      mCameraManager.openCamera(mFrontCameraId, mCameraDeviceCallback, mBackgroundHandler); 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { // there were 2 different types pf activity compats to import 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return; 
     } 
     try { 
      mCameraManager.openCamera(mFrontCameraId, mCameraDeviceCallback, mBackgroundHandler); 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void surfaceRedrawNeeded(SurfaceHolder holder) { 

    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     startBackgroundThread(); 
     openCamera(); 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 

    } 
/** 
private String getVideoFilePath(Context context) { 
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/" 
+ System.currentTimeMillis() + ".mp4"; 
} 
*/ 
/** 
public void createCaptureSession(){ 
try { 
mVideoEncoderCore = new VideoEncoderCore(
1280, 
720, 
4000000, 
streamURL 
); 
Surface previewSurface = mSurfacView.getHolder().getSurface(); 
Surface encoderSurface = mVideoEncoderCore.getInputSurface(); 
CaptureRequest.Builder captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
captureRequestBuilder.addTarget(previewSurface); 
mSurfaces = new ArrayList<>(); 
mSurfaces.add(previewSurface); 
mSurfaces.add(encoderSurface); 
mCaptureRequestPreview = captureRequestBuilder.build(); 
captureRequestBuilder.addTarget(encoderSurface); 
mCaptureRequestRecord = captureRequestBuilder.build(); 
mCameraDevice.createCaptureSession(mSurfaces, mCaptureSessionCallback, mBackgroundHandler); 
} catch (CameraAccessException e) { 
e.printStackTrace(); 
} catch (IOException e) { 
e.printStackTrace(); 
} 
} 
*/ 



    } 

回答

0

的Camera2 API有許多與其相關的異步任務 - 在運行的任務完成一些工作的背景,如打開相機,關閉相機,獲得焦點等。

這些任務使用回調來報告它們何時完成。

除此之外,活動或片段本身可能會調用背景中的其他任務,這些任務也使用回調進行通信,也可能會與相機交互 - 例如,相機通常會在活動或片段暫停事件期間關閉。

管理所有回調可能會非常棘手,競爭條件可能存在 - 您還可以在Stackoverflow上找到其他Camera2競爭條件問題和答案。

就你而言,錯誤告訴你captureSession對象爲null。最可能的原因是因爲它已被設置爲null,或者是由於競爭條件造成的無序回調,或者是因爲您在完全清理之前將其無意中設置爲null。

+0

非常感謝這個答案。我如何着手尋找競爭條件並解決它? @Mick – redtayls

+0

不幸的是,這很棘手 - 使用調試器將改變時間並可能導致問題。我通常會發現混合搜索代碼中使用變量的位置,以及在其最佳使用周圍添加調試日誌。 – Mick

+0

Thanks @Mick我不確定你是否可以,但是如果你可以看一下我上面發佈的整個Streaming活動,看看有沒有什麼東西會跳出來,那會很棒。 – redtayls

相關問題