【发布时间】: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