You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中从MainActivity跳转原生Activity后回调Flutter页面的实现方法

How to Callback from Native Camera Activity to Flutter Page

Got it, let's tackle how to send callbacks from your native Camera Activity back to the Flutter page. Since you already have MethodChannel set up for launching the Camera Activity, we can extend this approach in two common ways depending on your needs:


Option 1: Callback after Camera Activity closes (Activity Result API)

This is ideal if you need to send data back only once when the Camera Activity finishes (e.g., after taking a photo and closing the camera).

Step 1: Update MainActivity to use Activity Result API

Replace the direct startActivity call with the modern Activity Result API to capture the result from Camera Activity, then forward it to Flutter via MethodChannel:

public class MainActivity extends FlutterActivity {
    final String CHANNEL = "flutter.native/helper";
    private ActivityResultLauncher<Intent> cameraLauncher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Initialize Activity Result Launcher to handle Camera Activity result
        cameraLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK && result.getData() != null) {
                        // Extract data from Camera Activity's result
                        String cameraResult = result.getData().getStringExtra("camera_result");
                        // Send the data to Flutter via MethodChannel
                        new MethodChannel(getFlutterEngine().getDartExecutor().getBinaryMessenger(), CHANNEL)
                                .invokeMethod("onCameraCallback", cameraResult);
                    }
                });
    }

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
                .setMethodCallHandler((call, result) -> {
                    if (call.method.equals("showNativeView")) {
                        Intent intent = new Intent(MainActivity.this, Camera.class);
                        cameraLauncher.launch(intent); // Launch Camera Activity via launcher
                    } else {
                        result.notImplemented();
                    }
                });
    }
}

Step 2: Modify Camera Activity to return result

In your Camera Activity, set the result data when the user completes an action (e.g., taking a photo, pressing a "Done" button) and finish the activity:

public class Camera extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        // Example: Button to trigger callback and close activity
        Button doneButton = findViewById(R.id.btn_done);
        doneButton.setOnClickListener(v -> {
            Intent resultIntent = new Intent();
            // Pass your actual data (e.g., photo path, success status)
            resultIntent.putExtra("camera_result", "Photo captured successfully! Path: /sdcard/photo.jpg");
            setResult(RESULT_OK, resultIntent);
            finish(); // Close Camera Activity to send result back
        });
    }
}

Step 3: Listen for callback in Flutter

Set up a MethodChannel handler in your Flutter code to receive the data from native:

import 'package:flutter/services.dart';
import 'package:flutter/material.dart';

class CameraDemoPage extends StatefulWidget {
  const CameraDemoPage({super.key});

  @override
  State<CameraDemoPage> createState() => _CameraDemoPageState();
}

class _CameraDemoPageState extends State<CameraDemoPage> {
  static const platform = MethodChannel('flutter.native/helper');
  String _cameraCallbackMessage = "Waiting for camera callback...";

  @override
  void initState() {
    super.initState();
    // Register handler to receive native callbacks
    platform.setMethodCallHandler((MethodCall call) async {
      if (call.method == 'onCameraCallback') {
        setState(() {
          _cameraCallbackMessage = call.arguments as String;
        });
      }
    });
  }

  // Trigger native Camera Activity
  Future<void> _openNativeCamera() async {
    try {
      await platform.invokeMethod('showNativeView');
    } on PlatformException catch (e) {
      setState(() {
        _cameraCallbackMessage = "Error: ${e.message}";
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Flutter Native Camera Callback")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: _openNativeCamera,
              child: const Text("Open Native Camera"),
            ),
            const SizedBox(height: 20),
            Text(_cameraCallbackMessage),
          ],
        ),
      ),
    );
  }
}

Option 2: Real-time Callback from Camera Activity

If you need to send data to Flutter while the Camera Activity is still open (e.g., live camera preview data, real-time status updates), you can directly use MethodChannel in the Camera Activity.

Step 1: Share Flutter BinaryMessenger from MainActivity

Store the FlutterEngine's BinaryMessenger in a static variable (or pass it via Intent) so Camera Activity can access it:

public class MainActivity extends FlutterActivity {
    final String CHANNEL = "flutter.native/helper";
    public static BinaryMessenger flutterBinaryMessenger;

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
        flutterBinaryMessenger = flutterEngine.getDartExecutor().getBinaryMessenger();
        new MethodChannel(flutterBinaryMessenger, CHANNEL)
                .setMethodCallHandler((call, result) -> {
                    if (call.method.equals("showNativeView")) {
                        Intent intent = new Intent(MainActivity.this, Camera.class);
                        startActivity(intent);
                    } else {
                        result.notImplemented();
                    }
                });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Avoid memory leaks by clearing the static reference
        flutterBinaryMessenger = null;
    }
}

Step 2: Send real-time messages from Camera Activity

Initialize MethodChannel in Camera Activity and send messages to Flutter whenever needed:

public class Camera extends AppCompatActivity {
    private MethodChannel methodChannel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        // Initialize MethodChannel using the shared BinaryMessenger
        if (MainActivity.flutterBinaryMessenger != null) {
            methodChannel = new MethodChannel(MainActivity.flutterBinaryMessenger, "flutter.native/helper");
        }

        // Example: Send real-time update when capture button is pressed
        Button captureButton = findViewById(R.id.btn_capture);
        captureButton.setOnClickListener(v -> {
            if (methodChannel != null) {
                // Send real-time data (e.g., temporary photo path)
                methodChannel.invokeMethod("onRealTimeCameraUpdate", "Captured photo: /sdcard/temp_photo.jpg");
            }
        });

        // Send callback when activity closes
        findViewById(R.id.btn_close).setOnClickListener(v -> {
            if (methodChannel != null) {
                methodChannel.invokeMethod("onCameraClosed", "Camera activity closed");
            }
            finish();
        });
    }
}

Step 3: Listen for real-time callbacks in Flutter

Update the Flutter MethodChannel handler to handle the new real-time methods:

// Inside _CameraDemoPageState's initState
platform.setMethodCallHandler((MethodCall call) async {
  switch(call.method) {
    case 'onCameraCallback':
      setState(() {
        _cameraCallbackMessage = call.arguments as String;
      });
      break;
    case 'onRealTimeCameraUpdate':
      setState(() {
        _cameraCallbackMessage = "Real-time update: ${call.arguments}";
      });
      break;
    case 'onCameraClosed':
      setState(() {
        _cameraCallbackMessage = "Status: ${call.arguments}";
      });
      break;
  }
});

Key Notes

  • Memory Leaks: For Option 2, make sure to clear the static flutterBinaryMessenger reference in MainActivity's onDestroy to avoid memory leaks.
  • Data Types: You can pass more complex data (like byte arrays for images) by converting them to supported types (e.g., base64 strings, maps).
  • Error Handling: Add null checks for methodChannel in native code to avoid crashes if the FlutterEngine is destroyed.

内容的提问来源于stack exchange,提问作者Aryanbudhiraja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 20:47:43