首页 > 解决方案 > 使用相机模块 NFC 读/写

问题描述

我们使用 Android Studio 开发了一个 Android 应用程序,它可以使用相机扫描二维码,选择相关内容(一堆数据),然后通过 NFC 将所述内容写入 NFC 标签。

在多台设备上的实施和测试都很顺利,直到我们在搭载 Android 11 的三星 S21 上进行了测试,我们发现了一个特殊问题:每当应用程序使用相机时,任何后续的 NFC 写入或读取都将不起作用,标签根本没有系统不再拾取。

这个问题似乎只出现在 Android 11 设备上,以前的版本都可以正常工作。我们试图从大多数应用程序代码中“分离”以隔离相机和 NFC 功能,但我们仍然在这个最小规模的应用程序上重现了这个问题(源代码在这里)。我们有三个片段(Home、Camera 和 Nfc),我们可以在这三个片段之间切换;Nfc 工作正常,可以检测和读取标签,摄像头本身工作正常并且可以拾取二维码,但是每当我们先使用摄像头(拾取代码或点击“返回”)时,nfc 将不再工作。

我们确保正确释放相机但没有结果。这是我们的相机片段:

public class CameraFragment extends Fragment {

    private FragmentCameraBinding binding;
    private CameraSource cameraSource;

    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {
        binding = FragmentCameraBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        BarcodeDetector detector = new BarcodeDetector.Builder(requireActivity()).build();
        this.cameraSource = new CameraSource.Builder(getActivity(), detector).build();

        binding.cameraSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                try {
                    if (ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                        requestPermissions(new String[]{Manifest.permission.CAMERA}, MainActivity.CAMERA_PERMISSION_CODE);
                        return;
                    }
                    cameraSource.start(holder);
                } catch (IOException ignored) {
                }
            }

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

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
                cameraSource.release();
                cameraSource = null;
            }
        });
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}

这是NFC片段:

public class NfcFragment extends Fragment {

    private FragmentNfcBinding binding;
    private NFCAdapter adapter;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentNfcBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        adapter = new NFCAdapter(getActivity());
        adapter.EnableReaderMode();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
        adapter = null;
    }
}

我们在网络上收集的信息很少,但大多数都指向 Android 11 的问题。我们用相同的结果测试了另一台 Android 11 设备(不同的三星)。我们在这里做错了吗?

目前,我们找到了一个似乎可行的解决方法:我们在释放相机时模拟“后台运行”和应用程序的恢复(MainActivity 的暂停和恢复):

@Override
public void onDestroy() {
   this.context.onPause();
   this.context.onResume();

   super.onDestroy();
}

但这不是一个令人愉快的解决方案。

罪魁祸首可能是什么?任何帮助将不胜感激。

标签: javaandroidandroid-cameranfc

解决方案


推荐阅读