我正在使用前置摄像头制作一个应用程序,当用户点击其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必须可见
就个人而言,我建议将相机的所有内容都放在一个单独的文件/类中,并提供一个简单的界面,而不是直接将其提供给活动。