1
package com.example.mobilewarehousesystem.ui.import

import android.Manifest
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.example.mobilewarehousesystem.databinding.FragmentImportBinding
import com.google.mlkit.vision.barcode.Barcode
import com.google.mlkit.vision.barcode.BarcodeScanner
import com.google.mlkit.vision.common.InputImage
import androidx.appcompat.app.AlertDialog

class ImportFragment : Fragment() {
    //show UI
    private var _binding: FragmentImportBinding?=null
    private val binding get() = _binding!!
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        _binding = FragmentImportBinding.inflate(inflater, container, false)
        setHasOptionsMenu(true)
        return binding.root
    }

    private val CAMERA_PERMISSION_CODE=123
    private val READ_STORAGE_PERMISSION_CODE=113
    private val WRITE_STORAGE_PERMISSION_CODE=113
    private lateinit var cameraLauncher: ActivityResultLauncher<Intent>
    private lateinit var galleryLauncher: ActivityResultLauncher<Intent>
    private val TAG = "My Tag"
    lateinit var inputImage: InputImage
    lateinit var barcodeScanner: BarcodeScanner
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        cameraLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult(), object :ActivityResultCallback<ActivityResult>{
            override fun onActivityResult(result: ActivityResult?) {
                    val data=result?.data
                    try{
                        val photo = data?.extras?.get("data") as Bitmap
                        inputImage= InputImage.fromBitmap(photo, 0)
                        processQr()
                    }catch(e:Exception){
                        Log.d(TAG, "onActivityResult:"+e.message)
                    }
                }
            })
        galleryLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult(), object :ActivityResultCallback<ActivityResult>{
                override fun onActivityResult(result: ActivityResult?) {
                    val data=result?.data
                    inputImage = InputImage.fromFilePath(this@ImportFragment, data?.data)
                    processQr()
                }
            })
        binding.btnScanBarcode.setOnClickListener{
            val options=arrayOf("camera","gallery")

            val builder=AlertDialog.Builder(this@ImportFragment)
            builder.setTitle("Pick a option")

            builder.setItems(options, DialogInterface.OnClickListener { dialog, which ->
                if(which==0){
                    val cameraIntent=Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                    cameraLauncher.launch(cameraIntent)
                }else{
                    val storageIntent=Intent()
                    storageIntent.setType("image/*")
                    storageIntent.setAction(Intent.ACTION_GET_CONTENT)
                    galleryLauncher.launch(storageIntent)
                }
            })
            builder.show()
        }
    }
    private fun processQr(){
        binding.ivQrCode.visibility=View.GONE
        binding.tvResult.visibility=View.GONE
        barcodeScanner.process(inputImage).addOnSuccessListener{
            for (barcode:Barcode in it){
                val valueType=barcode.valueType
                when (valueType) {
                    Barcode.TYPE_WIFI -> {
                        val ssid = barcode.wifi!!.ssid
                        val password = barcode.wifi!!.password
                        val type = barcode.wifi!!.encryptionType
                        binding.tvResult.text = "ssid ${ssid} \n password ${password} \n type ${type}"
                    }
                    Barcode.TYPE_URL -> {
                        val title = barcode.url!!.title
                        val url = barcode.url!!.url
                        binding.tvResult.text = "title ${title} \n url ${url}"
                    }
                    Barcode.TYPE_TEXT->{
                        val data = barcode.displayValue
                        binding.tvResult.text="Result ${data}"
                    }
                }
            }
        }.addOnFailureListener{
            Log.d(TAG, "processQr: ${it.message}")
        }
    }
    override fun onResume() {
        super.onResume()
        checkPermission(Manifest.permission.CAMERA,CAMERA_PERMISSION_CODE)
    }
    private fun checkPermission(permission:String, requestCode:Int){
        if(ContextCompat.checkSelfPermission(this@ImportFragment, permission)== PackageManager.PERMISSION_DENIED){
            ActivityCompat.requestPermissions(this@ImportFragment, arrayOf(permission),requestCode)
        }
    }
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        if(requestCode==CAMERA_PERMISSION_CODE){
            if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                checkPermission(
                    android.Manifest.permission.READ_EXTERNAL_STORAGE,
                    READ_STORAGE_PERMISSION_CODE)
            }else{
                Toast.makeText(this@ImportFragment, "Camera Permission Denied", Toast.LENGTH_SHORT).show()
            }
        }else if(requestCode==READ_STORAGE_PERMISSION_CODE){
            if((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)){
                checkPermission(
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    WRITE_STORAGE_PERMISSION_CODE)
            }else{
                Toast.makeText(this@ImportFragment, "Storage Permission Denied", Toast.LENGTH_SHORT).show()
            }
        }else if(requestCode==WRITE_STORAGE_PERMISSION_CODE) {
            if (!(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                Toast.makeText(this@ImportFragment, "Storage Permission Denied", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

I consist 7 error, it is all of them are implementation error?? Those code were converted 1 by 1 from MainActivity into Fragment with the limited knowledge, i found some solution but still didnt know how to apply into mine.

code error line
inputImage = InputImage.fromFilePath(this@ImportFragment, data?.data) Type mismatch: inferred type is ImportFragment but Context! was expected 63
val builder=AlertDialog.Builder(this@ImportFragment) Type mismatch: inferred type is ImportFragment but Context! was expected 70
if(ContextCompat.checkSelfPermission(this@ImportFragment, permission)== PackageManager.PERMISSION_DENIED){ Type mismatch: inferred type is ImportFragment but Context! was expected 120
ActivityCompat.requestPermissions(this@ImportFragment, arrayOf(permission),requestCode) Type mismatch: inferred type is ImportFragment but Activity was expected 121
Toast.makeText(this@ImportFragment, "Camera Permission Denied", Toast.LENGTH_SHORT).show() None of the following functions can be called with the arguments supplied:
public open fun makeText(context: Context!, text: CharSequence!, duration: Int): Toast! defined in android.widget.Toast
public open fun makeText(context: Context!, resId: Int, duration: Int): Toast! defined in android.widget.Toast
133
Toast.makeText(this@ImportFragment, "Storage Permission Denied", Toast.LENGTH_SHORT).show() None of the following functions can be called with the arguments supplied:
public open fun makeText(context: Context!, text: CharSequence!, duration: Int): Toast! defined in android.widget.Toast
public open fun makeText(context: Context!, resId: Int, duration: Int): Toast! defined in android.widget.Toast
141, 145
Low Jung Xuan
  • 25
  • 1
  • 7
  • I want thank Doctor Who giving hints for me to do the further find out the solution. Below step I done just now. ```val context: Context = requiredContext()``` at line 61 after I delete this code also didnt have any error come out replace other to ```requiredContext()``` but **line 121** replace as ```requireActivity()``` I'm not sure whether correct or not because I still cannot get what I need to done – Low Jung Xuan Aug 18 '21 at 14:01

1 Answers1

2

you must use a context and not this@ImportFragment.

Replace:

this@ImportFragment

with

requireContext()

or try to put

 context!!

Generally if you write context!! Android studio suggest you to replace it with requireContext() and here more details:

/**
 * Return the {@link Context} this fragment is currently associated with.
 *
 * @throws IllegalStateException if not currently associated with a context.
 * @see #getContext()
 */
@NonNull
public final Context requireContext() {
    Context context = getContext();
    if (context == null) {
        throw new IllegalStateException("Fragment " + this + " not attached to a context.");
    }
    return context;
}
DoctorWho
  • 1,044
  • 11
  • 34