Adding Flutter Module to Android and Triggering a Specific Route

200 Views Asked by At

I want to add a Flutter Module into an existing Android application. I'm doing this theoretically but I couldn't get exactly the result I wanted. Because I'm using Flutter Cache Engine and when the Android application is run, my Flutter module also starts running. Since the InitState method is running, I cannot automatically display the data on the screen even if I switch to the Flutter side. To solve this, I defined Route in Flutter. In this way, my Flutter module starts from the /root screen and if I open the /home screen directly by triggering from Android, my initState method works. But I can't trigger this route through my android application. setInitialRoute didn't solve my problem, I used pushRoute but this time when the back button is pressed, it returns to /root route not to android application. I can't think of a solution other than changing the functionality of the device's back button every time I add a screen. What is the practical or correct way to do this? This is important as I will have several screens that will be triggered by android app side. Thank you in advance for your help.

MainApplication.kt:

const val FULL_SCREEN_ENGINE_ID = "fullScreenEngineId"

class MainApplication: Application(){
    override fun onCreate() {
        super.onCreate()

        val flutterEngineFullScreen = FlutterEngine(this);

        flutterEngineFullScreen.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())

        FlutterEngineCache.getInstance().put(FULL_SCREEN_ENGINE_ID, flutterEngineFullScreen)
    }
}

MainActivity:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val sendButton = findViewById<Button>(R.id.button)
        val nameInput = findViewById<EditText>(R.id.editTextText)
        val editInput = findViewById<EditText>(R.id.editTextTextEmailAddress)

        sendButton.setOnClickListener {
            val dataMap = hashMapOf(
                "name" to nameInput.text.toString(),
                "email" to editInput.text.toString()
            )

            val intent = Intent(this, CustomFlutterActivity::class.java)
            intent.putExtra("nameAndEmail", dataMap)
            startActivity(intent)

        }
    }
}

CustomFlutterActivty:

class CustomFlutterActivity: FlutterActivity() {

    companion object{
        const val CHANNEL = "net.ahmettalha.flutteroid_app"
        const val FULL_SCREEN_ENGINE_ID = "fullScreenEngineId"
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call, result ->
                when(call.method){
                    "goToFlutterWithData" -> {
                        Log.e("nameAndEmail", [email protected]("nameAndEmail").toString())
                        result.success([email protected]("nameAndEmail"))
                    }
                    else -> result.notImplemented()
                }
            }
    }

    override fun provideFlutterEngine(context: Context): FlutterEngine? {
        val flutterEngine = FlutterEngineCache.getInstance().get(FULL_SCREEN_ENGINE_ID)
        if (flutterEngine != null){
            Log.i("route fe", "engine not null")
            flutterEngine!!.navigationChannel.setInitialRoute("/home")
        }
        return flutterEngine
    }
}

Flutter MyApp:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(const MyApp());
}

ColorScheme _colorScheme = ColorScheme.fromSeed(
    seedColor: const Color.fromARGB(255, 209, 121, 5), brightness: Brightness.light);

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData().copyWith(useMaterial3: true, colorScheme: _colorScheme),
      routes: {
        "/root": (context) => const RootPage(),
        "/home": (context) => const HomeScreen(),
      },
      home: const RootPage(),
    );
  }
}
1

There are 1 best solutions below

0
On

The solution is to pass the route like below:

val intent = Intent(this, CustomFlutterActivity::class.java)
intent.putExtra("route", "/flutter_route")
startActivity(intent)

Flutter engine will automatically find and go to /flutter_route