尝试在我的Android应用中使用Facebook Live api。我正在使用camera2在我的直播活动中拉出相机,但我收到了这个错误:
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 :(得分:1)
Camera2 API有许多与之相关的异步任务 - 在后台运行以完成某些工作的任务,例如打开相机,关闭相机,获得焦点等。
这些任务使用回调来报告它们何时完成。
除此之外,活动或片段本身可以在后台调用其他任务,这些任务也使用回调进行通信,也可以与摄像机进行交互 - 例如,摄像机通常会在活动或片段暂停事件期间关闭。
管理所有回调可能会很棘手并且竞争条件可能存在 - 您还可以在Stackoverflow上找到其他Camera2竞争条件问题和答案。
在您的情况下,错误告诉您captureSession对象为null。最可能的原因是因为它已被设置为null,无论是由于竞争条件导致的无序回调,还是因为在您完成它之前无意中将其设置为null作为清理的一部分。