如何解决尝试使用 CameraX 和 MLKit 构建条形码扫描仪,但在 BarcodeScanning.getClient() 处出现“MlKitContext 尚未初始化”异常
我目前正在尝试使用 CameraX 和 MLKit 构建条形码扫描仪,但在我的 BarcodeAnalyzer 应用程序中调用 BarcodeScanning.getClient() 时,我不断收到“MlKitContext 尚未初始化”异常。我试过在 SO 和其他网站上搜索,但我发现的所有其他示例和解决方案看起来都像我的代码,或者是用 Kotlin 编写的。我想不通这是哪里出了问题!仅使用没有任何图像分析的相机预览效果很好,但由于某种原因,上下文似乎没有正确传输到条形码分析器或其他东西。我错过了什么?
错误信息如下:
E/PreviewUseCase: Binding Failed in startCameraPreview:
java.lang.IllegalStateException: MlKitContext has not been initialized
at com.google.android.gms.common.internal.Preconditions.checkState(com.google.android.gms:play-services-basement@@17.4.0:29)
at com.google.mlkit.common.sdkinternal.MlKitContext.getInstance(com.google.mlkit:common@@17.1.1:2)
at com.google.mlkit.vision.barcode.BarcodeScanning.getClient(com.google.android.gms:play-services-mlkit-barcode-scanning@@16.1.4:1)
at com.myscannerapp.ap.barcode.BarcodeAnalyzerX.<init>(BarcodeAnalyzerX.java:29)
at com.myscannerapp.ap.camera.ScanningCameraX$1.<init>(ScanningCameraX.java:66)
at com.myscannerapp.ap.camera.ScanningCameraX.lambda$startCameraPreview$0(ScanningCameraX.java:66)
at com.myscannerapp.ap.camera.-$$Lambda$ScanningCameraX$WAwB0W8s9LNCXGHteEApbFdwKUk.run(UnkNown Source:8)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
以下是我的扫描片段、扫描相机类和我的条形码分析器类的代码。我试图删除不相关的代码以使其更易于阅读,希望能有所帮助。哦,“BarcodeCallback”类只是我用来向活动发送数据的接口。
这是我的 ScanningFragment 的代码:
public class ScanningFragment extends Fragment implements FragmentCommunicationInterface {
private BarcodeCallback mBarcodeCallback;
private ScanningCameraX mScanningCameraX;
private Context mContext;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_barcode_scanner,container,false);
mScanningCameraX = new ScanningCameraX(mContext,view.findViewById(R.id.rt_scan_camera),mBarcodeCallback);
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
mBarcodeCallback = (BarcodeCallback)getActivity();
}
@Override
public void onResume() {
super.onResume();
mScanningCameraX.startCameraPreview();
}
}
这是我的 ScanningCameraX 类的代码:
public class ScanningCameraX {
private Context mContext;
private PreviewView mPreviewView;
private BarcodeCallback mBarcodeCallback;
private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
public ScanningCameraX (Context context,PreviewView previewView,BarcodeCallback barcodeCallback){
mContext = context;
mPreviewView = previewView;
mBarcodeCallback = barcodeCallback;
}
public void startCameraPreview() {
cameraProviderFuture = ProcessCameraProvider.getInstance(mContext);
final Context CONTEXT = mContext;
final PreviewView PREVIEW_VIEW = mPreviewView;
final BarcodeCallback BARCODE_CALLBACK = mBarcodeCallback;
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
Preview preview = new Preview.Builder()
.build();
preview.setSurfaceProvider(PREVIEW_VIEW.getSurfaceProvider());
ImageAnalysis imageAnalysis =
new ImageAnalysis.Builder()
.setTargetResolution(new Size(1280,720))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(CONTEXT),new BarcodeAnalyzerX(BARCODE_CALLBACK) {
@Override
public void analyze(@NonNull ImageProxy image) {
int rotationdegrees = image.getimageInfo().getRotationdegrees();
// insert future code here.
}
});
CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
cameraProvider.unbindAll();
cameraProvider.bindToLifecycle((LifecycleOwner) CONTEXT,cameraSelector,preview,imageAnalysis);
} catch (Exception e) {
Log.e("PreviewUseCase","Binding Failed in startCameraPreview: ",e);
}
},ContextCompat.getMainExecutor(mContext));
}
}
最后这里是我的 BarcodeAnalyzerX 的代码,它在“scanner = BarcodeScanning.getClient();”中出错了部分:
public class BarcodeAnalyzerX implements ImageAnalysis.Analyzer {
private BarcodeScanner scanner;
private BarcodeCallback mBarcodeCallback;
public BarcodeAnalyzerX(BarcodeCallback barcodeCallback) {
scanner = BarcodeScanning.getClient();
mBarcodeCallback = barcodeCallback;
}
@Override
public void analyze(ImageProxy imageProxy) {
Image mediaimage = imageProxy.getimage();
final BarcodeCallback BARCODE_CALLBACK = mBarcodeCallback;
if (mediaimage != null) {
Inputimage image = Inputimage.fromMediaimage(mediaimage,imageProxy.getimageInfo().getRotationdegrees());
Task<List<Barcode>> result = scanner.process(image)
.addOnSuccessListener(new OnSuccessListener<List<Barcode>>() {
@Override
public void onSuccess(List<Barcode> barcodes) {
for (Barcode barcode:barcodes){
BARCODE_CALLBACK.UpdateBarcode(barcode);
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.d("BarcodeAnalyzer","Analyzer Failed with exception: " + e);
}
})
.addOnCompleteListener(new OnCompleteListener<List<Barcode>>() {
@Override
public void onComplete(@NonNull Task<List<Barcode>> task) {
imageProxy.close();
}
});
}
}
}
解决方法
Troque a linha mScanningCameraX = new ScanningCameraX(mContext,view.findViewById(R.id.rt_scan_camera),mBarcodeCallback);
PARA mScanningCameraX = new ScanningCameraX(this.getActivity().getApplicationContext(),mBarcodeCallback);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。