【问题标题】:Multiple results from activity to fragment从活动到片段的多个结果
【发布时间】:2020-09-10 10:09:16
【问题描述】:

我有一个关于从活动到片段的结果/回调的问题。 到目前为止,我有一个片段调用相机活动来扫描二维码。所以我从带有startActivityForResult 的片段开始活动。如果成功扫描了二维码,我会收到一个回调 Intent,它在 onActivityResult 中处理。 这完美无缺。

现在我想处理多个扫描。详细地说,每次成功扫描都应该调用onActivityResult 函数而不关闭活动。此时我遇到的问题是,只有在相机活动中调用finish() 时才会调用onActivityResult

所以我的问题是,如何在不关闭活动的情况下多次调用onActivityResult 或不调用finish()?或者还有其他方法可以处理从活动到片段的回调吗?

这是我的片段代码:

class ScanFragment : Fragment() {

    private val CHECKIN_CODE = 0
    private val CHECKOUT_CODE = 1

    companion object {
        fun newInstance(): LeadScanFragment = LeadScanFragment()
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_lead_scan, container, false)

        view.checkin.setOnClickListener {view ->
            val intent = Intent(activity, CodeScannerActivity::class.java)
            startActivityForResult(intent, CHECKIN_CODE)
        }

        view.checkout.setOnClickListener {view ->
            val intent = Intent(activity, CodeScannerActivity::class.java)
            startActivityForResult(intent, CHECKOUT_CODE)
        }

        return view
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == CHECKIN_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                val returnString = data!!.getStringExtra("hash")
                Log.d("scaned in", returnString)
            }
        }

        if (requestCode == CHECKOUT_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                val returnString = data!!.getStringExtra("hash")
                Log.d("scaned out", returnString)
            }
        }
    }
}

这是相机活动代码:

class CodeScannerActivity : AppCompatActivity() {

    private val requestCodeCameraPermission = 1001
    private lateinit var cameraSource: CameraSource
    private lateinit var detector: BarcodeDetector

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_code_scanner)

        if (ContextCompat.checkSelfPermission(this@CodeScannerActivity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            askForCameraPermission()
        } else {
            setup()
        }
    }

    private fun setup() {
        detector = BarcodeDetector.Builder(this@CodeScannerActivity).build()
        cameraSource = CameraSource.Builder(this@CodeScannerActivity, detector).setAutoFocusEnabled(true).build()

        cameraSurfaceView.holder.addCallback(surfaceCallback)
        detector.setProcessor(processor)
    }

    private fun askForCameraPermission() {
        ActivityCompat.requestPermissions(this@CodeScannerActivity, arrayOf(Manifest.permission.CAMERA), requestCodeCameraPermission)
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        if(requestCode == requestCodeCameraPermission && grantResults.isNotEmpty()) {
            if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                setup()
            } else {
                Toast.makeText(applicationContext, "Permission denied!", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private val surfaceCallback = object : SurfaceHolder.Callback {
        override fun surfaceCreated(surfaceHolder: SurfaceHolder?) {
            try {
                cameraSource.start(surfaceHolder)
            } catch (exception: Exception) {
                Toast.makeText(applicationContext, "Something went wrong", Toast.LENGTH_SHORT).show()
            }
        }

        override fun surfaceChanged(p0: SurfaceHolder?, p1: Int, p2: Int, p3: Int) {

        }

        override fun surfaceDestroyed(p0: SurfaceHolder?) {
            cameraSource.stop()
        }
    }

    private val processor = object : Detector.Processor<Barcode> {
        override fun release() {

        }

        override fun receiveDetections(detections: Detector.Detections<Barcode>?) {
            val intent = Intent()

            if(detections != null && detections.detectedItems.isNotEmpty()) {
                val qrCodes: SparseArray<Barcode> = detections.detectedItems
                val code = qrCodes.valueAt(0)

                intent.putExtra("hash", code.displayValue)
                setResult(Activity.RESULT_OK, intent)
                finish()
            } else {
                setResult(Activity.RESULT_CANCELED, intent)
                finish()
            }
        }
    }
}

receiveDetections 在相机活动代码下部区域的 processor 内是回调 Intent 发送回onActivityResult 的位置。

【问题讨论】:

    标签: android kotlin android-fragments android-activity callback


    【解决方案1】:

    您可以让扫描仪Activity 发送本地广播Intent 以将“结果”转发给呼叫FragmentFragment(或其托管Activity)应该设置一个监听器来监听广播“结果”。通过这种方式,您可以执行多次扫描并将每个结果发送回底层Activity

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多