我正在使用前置摄像头制作一个应用程序,当用户点击其NFC卡时,它将捕获其图像。因此,我为相机和NFC读卡器制作了Surfaceview,并在活动中同时添加了这两种功能。两者都是分开工作的,但是当我点击卡片时,表面外观变得卷曲,我没有得到任何回报。在此行出现错误


  空指针异常


 mCamera.takePicture(null, null, ReadCardActivity.this);


如果单击的图像没有任何问题,我还添加了一个按钮,也可以在曲面视图下面显示。

我的代码如下-

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_read_card);
    ButterKnife.bind(this);

    mPreview = (SurfaceView) findViewById(R.id.preview);
    mPreview.getHolder().addCallback(this);
    mPreview.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    mDialog = new AlertDialog.Builder(this).setNeutralButton("Ok", null).create();

    mAdapter = NfcAdapter.getDefaultAdapter(this);
    if (mAdapter == null) {
        showMessage(R.string.error, R.string.no_nfc);
        finish();
        return;
    }

    // do we have a camera?
    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG).show();
        finish();
    } else {
        cameraId = findFrontFacingCamera();
        //cameraId = findBackFacingCamera();
        if (cameraId < 0) {
            Toast.makeText(this, "Sorry you don't have secondary camera", Toast.LENGTH_LONG).show();
            finish();
        } else {
            releaseCameraAndPreview();
            mCamera = Camera.open(cameraId);
        }
    }

    mPendingIntent = PendingIntent.getActivity(this, 0,
            new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    mAdapter = NfcAdapter.getDefaultAdapter(this);

    mNdefPushMessage = new NdefMessage(new NdefRecord[]{newTextRecord(
            "Message from NFC Reader :-)", Locale.ENGLISH, true)});
}


private void releaseCameraAndPreview() {
    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    mCamera.release();
    mAdapter.disableForegroundDispatch(this);
    Log.d("CAMERA", "Destroy");
}

@OnClick(R.id.buttonCaptureImage)
public void capturingImage() {
    System.gc();
    mPreview.post(new Runnable() {
        public void run() {
            mCamera.takePicture(null, null, ReadCardActivity.this);
        }
    });
}

最佳答案

我认为您需要自己的Callback而不是ReadCardActivity.this

我要处理同一件事(当用户陪同标签,然后前置摄像头拍照时),所以我可以给出代码(但在C#Xamarin中)

这是回调类

    private class PictureTakenCallback : Java.Lang.Object, Camera.IPictureCallback
{
  private Context parentContext;
  public event PictureTakenEventHandler OnPictureTakenAndReady;
  public PictureTakenCallback()
  {//There have to empty construtor
  }
  public PictureTakenCallback(Context pParentContext)
  {
    this.parentContext = pParentContext;
  }
  public void OnPictureTaken(byte[] pData, Camera pCamera)
  {
    try
    {
      if (OnPictureTakenAndReady != null) OnPictureTakenAndReady(null, new PictureTakenEventArgs(pData));
    }
    catch (Exception ex)
    {
      string msg = ex.Message;
       ((Activity)parentContext).RunOnUiThread(() => { Toast.MakeText(parentContext, "PictureTakenCallback Exception", ToastLength.Long).Show(); });
    }
  }
}


打开相机后,您可以创建回调

          pictureTakenCallback = new PictureTakenCallback(parentContext);
          pictureTakenCallback.OnPictureTakenAndReady += new PictureTakenEventHandler(pictureTakenCallback_OnPictureTakenAndReady);


当您接受nfcAdapter的意图时,请调用此方法

 public void TakePicture()
    {
      if (cameraFront != null)
      {
        try
        {
          cameraFront.TakePicture(null, null, null, pictureTakenCallback);
          ((Activity)parentContext).RunOnUiThread(() => { Toast.MakeText(parentContext, "After TakePicture", ToastLength.Long).Show(); });
        }
        catch (Exception ex)
        {
          ((Activity)parentContext).RunOnUiThread(() => { Toast.MakeText(parentContext, "Exception during TakePicture", ToastLength.Long).Show(); }); string msg = ex.Message;
        }
      }
    }


如果相机正确拍摄照片,则来此事件

private void pictureTakenCallback_OnPictureTakenAndReady(object sender, PictureTakenEventArgs e)
    {
      if (e.Data != null && e.Data.Length > 0) byte[] photoInBytes = e.Data;
      if (cameraFront != null)
      {
        cameraFront.StartPreview();
        CameraController.IsPreviewStopped = true;
      }
    }


注意,您需要StartPreview权限,并且SurfaceView必须可见

就个人而言,我建议将相机的所有内容都放在一个单独的文件/类中,并提供一个简单的界面,而不是直接将其提供给活动。

08-26 07:15