Lateinit 属性未初始化

时间:2021-06-01 11:47:02

标签: android kotlin fragment

在此选项卡中(因此它是一个片段),用户可以选择上传照片或从相机拍摄新照片。 一旦他单击按钮是否决定某个选项,应用程序就会关闭,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
        }
    }
}

}

1 个答案:

答案 0 :(得分:0)

您的依赖注入似乎没有像此处的错误所暗示的那样工作

lateinit property receiptsViewModel has not been initialized

其余的属性似乎没问题,这段代码不起作用。您可以检查您正在使用的任何东西,看看为什么会失败。

@Inject
lateinit var receiptsViewModel: ReceiptsViewModel