Flutter:是否可以通过 MethodChannel 将数据从 Android 模块发送到 Flutter 项目而不关闭 Activity(仍在 Android Activity 中)?

发布于 2025-01-18 01:13:58 字数 4313 浏览 0 评论 0原文

我有屏幕。

  1. 故事屏幕(来自颤音)
  2. 主动脉(来自Android活动,扩展到颤音)
  3. mainnitivitivity(从Android活动,扩展到AppCompatactivity)

实际屏幕仅为两个,storyscreen mainnunityActivityMainActivity仅适用于主机。

MainActivity中,我们定义意图方法频道

class MainActivity : FlutterActivity() {
    private val tag = "MAIN"
    private val channel = "NATIVE_EXPERIMENT"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor, channel).setMethodCallHandler { call, result ->
            if (call.method.equals("goToUnityActivity")) {
                val arg = call.arguments as Map<String, Any>
                val gameType = arg.getValue("gameType") as String
                val catalogURL = arg.getValue("catalogURL") as String
                goToUnityActivity(gameType, catalogURL)
                result.success(null)
            } else {
                result.notImplemented()
            }
        }
    }

    private fun goToUnityActivity(gameType: String, catalogURL: String) {
        val intent = Intent(this, MainUnityActivity::class.java)
        intent.putExtra("gameType", gameType)
        intent.putExtra("catalogURL", catalogURL)
        startActivityForResult(intent, MainUnityActivity.REQUEST_CODE_FROM_UNITY)
    }

    private fun notifyFlutterBackFromUnity(data: String?) {
        MethodChannel(flutterEngine?.dartExecutor, channel).invokeMethod("backFromUnity", data)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == MainUnityActivity.REQUEST_CODE_FROM_UNITY) {
            if (resultCode == MainUnityActivity.RESULT_CODE_BACK_FROM_UNITY) {
                val listOfReport = data!!.getStringExtra("listOfReport")
                Log.i(tag, "/// [MainActivity] back from unity --> $listOfReport")
                notifyFlutterBackFromUnity(listOfReport)
            }
        }
    }
}

如果我从mainnityActivity退出,我可以将数据从Android发送到颤音侧,但是如果我们仍在mainnityActivity中,但是想从Android发送数据到Flutter sine?

class MainUnityActivity : UnityPlayerActivity() {
    private val tag = "MIDDLEWARE_UNITY"
    private val listOfVehicleNames: MutableList<String> = mutableListOf()

    companion object {
        const val RESULT_CODE_BACK_FROM_UNITY = 110
        const val REQUEST_CODE_FROM_UNITY = 1
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        listOfVehicleNames.clear()
    }

    private fun backFromUnity() {
        Log.i(tag, "/// [MainUnityActivity] BackButtonClick")
        val resultIntent = Intent().apply {
            putExtra("listOfReport", listOfVehicleNames.toString())
        }
        setResult(RESULT_CODE_BACK_FROM_UNITY, resultIntent)
        finish()
    }

    override fun BackButtonClick() {
        Log.i(tag, "/// [MainUnityActivity] BackButtonClick")
        backFromUnity()
    }

    override fun ReportButtonClick() {
        Log.i(tag, "/// [MainUnityActivity] ReportButtonClick")
        showDialog()
    }

    private fun notifyFlutterReportFromUnity() {
        val json = """{"title": "JSON Title", "notes": "JSON Notes"}"""
        Log.i(tag, "/// [MainUnityActivity] YesReportClick :$json")
        listOfVehicleNames.add(json)
        // TODO: I want send data to Flutter without close this activity
    }

    private fun showDialog() {
        val builder = AlertDialog.Builder(this)
        builder.setTitle("Report")
        builder.setMessage("Is there something wrong ?")

        builder.setPositiveButton(
            "Yes"
        ) { _, _ ->
            Toast.makeText(this, "Okay, we're sorry", Toast.LENGTH_SHORT).show()
            notifyFlutterReportFromUnity()
        }

        builder.setNegativeButton(
            "No"
        ) { _, _ ->
            // User click no
        }

        builder.setNeutralButton("Cancel") { _, _ ->
            // User cancelled the dialog
        }
        builder.show()
    }
}

I have screens.

  1. StoryScreen (from Flutter)
  2. MainActivity (from Android Activity, extend to FlutterActivity)
  3. MainUnityActivity (from Android Activity, extend to AppCompatActivity)

The actually screen is only two, StoryScreen and MainUnityActivity. MainActivity only for host.

In MainActivity we define intent and method channel.

class MainActivity : FlutterActivity() {
    private val tag = "MAIN"
    private val channel = "NATIVE_EXPERIMENT"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor, channel).setMethodCallHandler { call, result ->
            if (call.method.equals("goToUnityActivity")) {
                val arg = call.arguments as Map<String, Any>
                val gameType = arg.getValue("gameType") as String
                val catalogURL = arg.getValue("catalogURL") as String
                goToUnityActivity(gameType, catalogURL)
                result.success(null)
            } else {
                result.notImplemented()
            }
        }
    }

    private fun goToUnityActivity(gameType: String, catalogURL: String) {
        val intent = Intent(this, MainUnityActivity::class.java)
        intent.putExtra("gameType", gameType)
        intent.putExtra("catalogURL", catalogURL)
        startActivityForResult(intent, MainUnityActivity.REQUEST_CODE_FROM_UNITY)
    }

    private fun notifyFlutterBackFromUnity(data: String?) {
        MethodChannel(flutterEngine?.dartExecutor, channel).invokeMethod("backFromUnity", data)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == MainUnityActivity.REQUEST_CODE_FROM_UNITY) {
            if (resultCode == MainUnityActivity.RESULT_CODE_BACK_FROM_UNITY) {
                val listOfReport = data!!.getStringExtra("listOfReport")
                Log.i(tag, "/// [MainActivity] back from unity --> $listOfReport")
                notifyFlutterBackFromUnity(listOfReport)
            }
        }
    }
}

If I exit from MainUnityActivity, I can send data from Android to Flutter side, but how if we still in MainUnityActivity but want to send data from Android to Flutter side?

class MainUnityActivity : UnityPlayerActivity() {
    private val tag = "MIDDLEWARE_UNITY"
    private val listOfVehicleNames: MutableList<String> = mutableListOf()

    companion object {
        const val RESULT_CODE_BACK_FROM_UNITY = 110
        const val REQUEST_CODE_FROM_UNITY = 1
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        listOfVehicleNames.clear()
    }

    private fun backFromUnity() {
        Log.i(tag, "/// [MainUnityActivity] BackButtonClick")
        val resultIntent = Intent().apply {
            putExtra("listOfReport", listOfVehicleNames.toString())
        }
        setResult(RESULT_CODE_BACK_FROM_UNITY, resultIntent)
        finish()
    }

    override fun BackButtonClick() {
        Log.i(tag, "/// [MainUnityActivity] BackButtonClick")
        backFromUnity()
    }

    override fun ReportButtonClick() {
        Log.i(tag, "/// [MainUnityActivity] ReportButtonClick")
        showDialog()
    }

    private fun notifyFlutterReportFromUnity() {
        val json = """{"title": "JSON Title", "notes": "JSON Notes"}"""
        Log.i(tag, "/// [MainUnityActivity] YesReportClick :$json")
        listOfVehicleNames.add(json)
        // TODO: I want send data to Flutter without close this activity
    }

    private fun showDialog() {
        val builder = AlertDialog.Builder(this)
        builder.setTitle("Report")
        builder.setMessage("Is there something wrong ?")

        builder.setPositiveButton(
            "Yes"
        ) { _, _ ->
            Toast.makeText(this, "Okay, we're sorry", Toast.LENGTH_SHORT).show()
            notifyFlutterReportFromUnity()
        }

        builder.setNegativeButton(
            "No"
        ) { _, _ ->
            // User click no
        }

        builder.setNeutralButton("Cancel") { _, _ ->
            // User cancelled the dialog
        }
        builder.show()
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

勿挽旧人 2025-01-25 01:13:58

最后,我使用 MethodChannelEventChannelBroadcastReceiver 修复了该问题。

方法通道:使用异步方法调用与平台插件进行通信的命名通道。

事件通道:使用事件流与平台插件进行通信的命名通道。

示例项目位于:https://github.com/rrifafauzikomara/example_flutter_method_channel

Finally, I fix it using MethodChannel, EventChannel, and BroadcastReceiver.

Method channel: A named channel for communicating with platform plugins using asynchronous method calls.

Event Channel: A named channel for communicating with platform plugins using event streams.

The example project is here: https://github.com/rrifafauzikomara/example_flutter_method_channel

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文