片段创建的 Intent 不会触发 onNewIntent

Posted

技术标签:

【中文标题】片段创建的 Intent 不会触发 onNewIntent【英文标题】:Intent created by fragment does not trigger onNewIntent 【发布时间】:2021-05-08 21:45:50 【问题描述】:

我正在开发一个使用 sdk 的应用程序,该 sdk 利用意图在 sdk 和我的代码之间进行通信。 在我的应用程序中,每当用户扫描条形码时,活动片段都会发送包含扫描意图的广播。 MainActivity 类解码此意图并通过共享视图模型将其发送回片段。

我目前面临的问题是我的 onNewIntent 永远不会被调用。我尝试使用自定义函数手动处理它,但这似乎不是正确的方法(而且它似乎也不起作用)。 我想要么是我的意图有问题,要么我的视图模型运行不正常,或者可能是两者兼而有之。

class LoginFragment : Fragment() 
    private val intentViewModel by activityViewModels<IntentViewModel>()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        val view = inflater.inflate(R.layout.fragment_login, container, false)
        val btnScanner = view.findViewById<Button>(R.id.btnScan)

        //If usercredentials get a value, that means the user has succesfully authenticated
        intentViewModel.userCredentials.observe(viewLifecycleOwner, Observer  credentials ->
            if (credentials[0] != "" && credentials[1] != "") 
             
                navigateToHome(intentViewModel.userCredentials.value!!)
            
        )

        //Intent set by activity
        intentViewModel.intent.observe(viewLifecycleOwner, Observer  intent ->
            Timber.plant(Timber.DebugTree())
            val decodedData =
                intent!!.getStringExtra(
                    resources.getString(R.string.datawedge_intent_key_data)
                )
            //Never gets called --> intent never gets registered by activity
            Timber.d("Intent observer got called with value $decodedData")
            getUserCredentials(decodedData!!)
        )

        //Creates an intent based on motionevent, which gets broadcasted
        btnScanner.setOnTouchListener  v, motionEvent ->
            decodeEvent(v, motionEvent)
        
        return view
    
    
    //Hardcoded authentication example
    private fun getUserCredentials(badgeId: String) 
        var creds = Array(2)  "" 
        creds[0] = "12345678"
        creds[1] = "Logistics"
        intentViewModel.userCredentials.value = creds
    

    private fun decodeEvent(v: View, motionEvent: MotionEvent): Boolean 
        if (motionEvent.action == MotionEvent.ACTION_DOWN) 
            //  Button pressed, start scan
            val dwIntent = Intent()
            dwIntent.action = "com.symbol.datawedge.api.ACTION"
            dwIntent.putExtra("com.symbol.datawedge.api.SOFT_SCAN_TRIGGER", "START_SCANNING")
            dwIntent.putExtra("Type", "START")
            activity?.sendBroadcast(dwIntent)
            //(activity as MainActivity).handleIntent(dwIntent)
         else if (motionEvent.action == MotionEvent.ACTION_UP) 
            //  Button released, end scan
            val dwIntent = Intent()
            dwIntent.action = "com.symbol.datawedge.api.ACTION"
            dwIntent.putExtra("com.symbol.datawedge.api.SOFT_SCAN_TRIGGER", "STOP_SCANNING")
            dwIntent.putExtra("Type", "END")
            activity?.sendBroadcast(dwIntent)
            //  (activity as MainActivity).handleIntent(dwIntent)
        
        return true
    

    fun navigateToHome(userCredentials: Array<String>) 
        Navigation.findNavController(requireView())
            .navigate(LoginFragmentDirections.actionLoginFragmentToHomeFragment(userCredentials))
    


class MainActivity : AppCompatActivity()
    private val  intentViewModel by viewModels<IntentViewModel>()

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

   //User scanned a barcode, which created an intent in the fragment
    override fun onNewIntent(intent: Intent) 
        super.onNewIntent(intent)
        intentViewModel.intent.value = intent
    


class IntentViewModel: ViewModel() 
    var intent = MutableLiveData<Intent?>()
    var userCredentials = MutableLiveData<Array<String>>()

【问题讨论】:

【参考方案1】:

OnNewIntent 将调用,如果您在清单中将您的活动指定为启动模式为“singleTop”

【讨论】:

我的清单中已经有android:launchMode="singleTop",但这并不能解决问题。

以上是关于片段创建的 Intent 不会触发 onNewIntent的主要内容,如果未能解决你的问题,请参考以下文章

使用BroadcastReciever传递Intent.EXTRAS

导致活动不工作的片段中的按钮(更新)

Intent 不会从 Fragment 启动 Activity

如何将数据从 Intent 传递到 Fragment

如何从片段到活动而不会干扰片段的可重用性

选择选项卡片段时触发啥事件