在此选项卡中(因此它是一个片段),用户可以选择上传照片或从相机拍摄新照片。 一旦他单击按钮是否决定某个选项,应用程序就会关闭,Logcat 就会给我这个错误:
2021-06-01 12:49:45.680 16355-16355/com.example.nlp_expense_tracker E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.nlp_expense_tracker, PID: 16355
kotlin.UninitializedPropertyAccessException: lateinit property receiptsViewModel has not been initialized
at com.example.nlp_expense_tracker.fragments.Scanner.getReceiptsViewModel(Scanner.kt:56)
at com.example.nlp_expense_tracker.fragments.Scanner.onCreateView$lambda-2$lambda-0(Scanner.kt:84)
at com.example.nlp_expense_tracker.fragments.Scanner.lambda$swyIeEDCHOralrhRcI5ZMLiEfwM(Unknown Source:0)
at com.example.nlp_expense_tracker.fragments.-$$Lambda$Scanner$swyIeEDCHOralrhRcI5ZMLiEfwM.onClick(Unknown Source:2)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:174)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我不太确定还有什么地方可以启动该属性。 这是片段代码:
class Scanner : Fragment() {
private lateinit var imageView: ImageView
private lateinit var photoImage: Bitmap
private lateinit var mlkitImage: InputImage
private lateinit var editLocation: EditText
private lateinit var editVAT: EditText
private lateinit var editTotal: EditText
private val REQUEST_CODE_KAMERA = 42
private val REQUEST_CODE_GALLERY = 69
private val CAMERA_PERMISSION_CODE = 100
@Inject
lateinit var receiptsViewModel: ReceiptsViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?):
View? {val view: View = inflater.inflate(R.layout.fragment_scan, container, false)
val btnTakePicture: Button = view.findViewById(R.id.btnTakePicture)
imageView = view.findViewById(R.id.imageView)
editLocation = view.findViewById(R.id.editLocation)
editTotal =view.findViewById(R.id.editTotal)
editVAT = view.findViewById(R.id.editVAT)
//Button Picture
btnTakePicture.setOnClickListener {
checkPermission(Manifest.permission.CAMERA,
CAMERA_PERMISSION_CODE)
val builder: AlertDialog.Builder = AlertDialog.Builder(requireActivity())
builder.setTitle("Choose a Receipt")
builder.setMessage("Either upload a Receipt or take a picture of one")
// add the buttons
builder.setPositiveButton("Use camera", DialogInterface.OnClickListener { dialog, which ->
startActivityForResult(receiptsViewModel.uploadIntent(), REQUEST_CODE_KAMERA)
})
builder.setNegativeButton("Upload from gallery", DialogInterface.OnClickListener { dialog, which ->
startActivityForResult(receiptsViewModel.cameraIntent(activity!!), REQUEST_CODE_GALLERY)
})
val dialog: AlertDialog = builder.create()
dialog.show()
}
return view
}
private fun uploadAction(data: Intent) {
try {
val resolver = requireActivity().contentResolver
val stream = resolver!!.openInputStream(data.getData()!!)
if (::photoImage.isInitialized) photoImage.recycle()
photoImage = BitmapFactory.decodeStream(stream)
mlkitImage = InputImage.fromBitmap(photoImage,0)
imageView.setImageBitmap(photoImage)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
}
private fun cameraAction() {
try {
Picasso.get().load(receiptsViewModel.imageURI).into(imageView)
mlkitImage = InputImage.fromFilePath(activity!!, receiptsViewModel.imageURI)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
}
private fun textRecognitionAction() {
var text = ""
receiptsViewModel.textDetector.process(mlkitImage)
.addOnSuccessListener {
for (block in it.textBlocks) text += block.text + "\n"
val receipts = receiptsViewModel.getReceipts(text)
editTotal.setText(receipts.total, TextView.BufferType.EDITABLE)
editLocation.setText(receipts.type, TextView.BufferType.EDITABLE)
editVAT.setText(receipts.vat, TextView.BufferType.EDITABLE)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_CODE_GALLERY -> uploadAction(data!!)
REQUEST_CODE_KAMERA -> cameraAction()
}
textRecognitionAction()
}
}
private fun checkPermission(permission: String, requestCode: Int) {
if (ContextCompat.checkSelfPermission(activity!!, permission) == PackageManager.PERMISSION_DENIED) {
// Requesting the permission
ActivityCompat.requestPermissions(activity!!, arrayOf(permission), requestCode)
} else {
Toast.makeText(activity!!, "Permission already granted", Toast.LENGTH_SHORT).show()
}
}
}
class ReceiptsViewModel @Inject constructor() {
lateinit var imageURI: Uri
var textDetector = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
fun uploadIntent(): Intent {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
intent.addCategory(Intent.CATEGORY_OPENABLE)
return intent
}
fun cameraIntent(context: Context): Intent {
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val imageFileName = "IMG_" + timeStamp + "_"
val storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val filephoto = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
)
imageURI = FileProvider.getUriForFile(context, "com.example.nlp_expense_tracker.provider", filephoto)
val pictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageURI)
return pictureIntent
}
fun getReceipts(text: String): Receipts {
val originalResult = text.findFloat()
if (originalResult.isEmpty()) return Receipts()
else {
val receipts = Receipts()
val totalF = Collections.max(originalResult)
val secondLargestF = findSecondLargestFloat(originalResult)
receipts.total = totalF.toString()
receipts.vat = if (secondLargestF == 0.0f) "0" else "%.2f".format(totalF - secondLargestF)
receipts.type = text.firstLine()
return receipts
}
}
private fun findSecondLargestFloat(input: ArrayList<Float>?): Float {
if (input == null || input.isEmpty() || input.size == 1) return 0.0f
else {
try {
val tempSet = HashSet(input)
val sortedSet = TreeSet(tempSet)
return sortedSet.elementAt(sortedSet.size - 2)
} catch (e: Exception) {
return 0.0f
}
}
}
}
答案 0 :(得分:0)
您的依赖注入似乎没有像此处的错误所暗示的那样工作
lateinit property receiptsViewModel has not been initialized
其余的属性似乎没问题,这段代码不起作用。您可以检查您正在使用的任何东西,看看为什么会失败。
@Inject
lateinit var receiptsViewModel: ReceiptsViewModel